From ec9a7532b5995df865032d2e5e032021f43f8fef Mon Sep 17 00:00:00 2001 From: Jendrik Seipp Date: Tue, 12 Mar 2019 20:23:32 +0100 Subject: [PATCH 01/39] [issue909] Add utils::format_journal_article_reference(). --- src/search/utils/markup.cc | 14 ++++++++++++++ src/search/utils/markup.h | 5 +++++ 2 files changed, 19 insertions(+) diff --git a/src/search/utils/markup.cc b/src/search/utils/markup.cc index 2b58e848b7..257e6337f2 100644 --- a/src/search/utils/markup.cc +++ b/src/search/utils/markup.cc @@ -41,4 +41,18 @@ string format_paper_reference( ss << t2t_escape(year) << ".\n\n\n"; return ss.str(); } + +string format_journal_article_reference( + const std::vector &authors, const string &title, const string &url, + const string &journal, const string &volume, const string &pages, + const string &year) { + stringstream ss; + ss << "\n\n" + << " * " << format_authors(authors) << ".<
>\n" + << " [" << t2t_escape(title) << " " << url << "].<
>\n" + << " //" << t2t_escape(journal) << "// " + << t2t_escape(volume) << ":" << t2t_escape(pages) << ". " + << t2t_escape(year) << ".\n\n\n"; + return ss.str(); +} } diff --git a/src/search/utils/markup.h b/src/search/utils/markup.h index c1c48db335..cfaa005381 100644 --- a/src/search/utils/markup.h +++ b/src/search/utils/markup.h @@ -9,6 +9,11 @@ extern std::string format_paper_reference( const std::vector &authors, const std::string &title, const std::string &url, const std::string &venue, const std::string &pages, const std::string &publisher, const std::string &year); + +extern std::string format_journal_article_reference( + const std::vector &authors, const std::string &title, + const std::string &url, const std::string &journal, const std::string &volume, + const std::string &pages, const std::string &year); } #endif From 6272b48675b5561b5728e5d2a0c593c57955e2bb Mon Sep 17 00:00:00 2001 From: Jendrik Seipp Date: Tue, 12 Mar 2019 21:38:28 +0100 Subject: [PATCH 02/39] [issue909] Use utils::format_journal_article_reference(). --- src/search/cegar/additive_cartesian_heuristic.cc | 4 ++-- src/search/landmarks/landmark_count_heuristic.cc | 6 +++--- src/search/merge_and_shrink/merge_and_shrink_heuristic.cc | 6 +++--- src/search/utils/markup.h | 5 +++-- 4 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/search/cegar/additive_cartesian_heuristic.cc b/src/search/cegar/additive_cartesian_heuristic.cc index 43fa4107e3..5c370b77b9 100644 --- a/src/search/cegar/additive_cartesian_heuristic.cc +++ b/src/search/cegar/additive_cartesian_heuristic.cc @@ -88,14 +88,14 @@ static shared_ptr _parse(OptionParser &parser) { "2014") + "For more details on Cartesian CEGAR and saturated cost partitioning, " "see the journal paper" + - utils::format_paper_reference( + utils::format_journal_article_reference( {"Jendrik Seipp", "Malte Helmert"}, "Counterexample-Guided Cartesian Abstraction Refinement for " "Classical Planning", "https://ai.dmi.unibas.ch/papers/seipp-helmert-jair2018.pdf", "Journal of Artificial Intelligence Research", + "62", "535-577", - "", "2018")); parser.document_language_support("action costs", "supported"); parser.document_language_support("conditional effects", "not supported"); diff --git a/src/search/landmarks/landmark_count_heuristic.cc b/src/search/landmarks/landmark_count_heuristic.cc index 2bd1aa3e3f..c26401c643 100644 --- a/src/search/landmarks/landmark_count_heuristic.cc +++ b/src/search/landmarks/landmark_count_heuristic.cc @@ -258,13 +258,13 @@ static shared_ptr _parse(OptionParser &parser) { "AAAI Press", "2008") + "and" + - utils::format_paper_reference( + utils::format_journal_article_reference( {"Silvia Richter", "Matthias Westphal"}, "The LAMA Planner: Guiding Cost-Based Anytime Planning with Landmarks", "http://www.aaai.org/Papers/JAIR/Vol39/JAIR-3903.pdf", - "Journal of Artificial Intelligence Research 39", + "Journal of Artificial Intelligence Research", + "39", "127-177", - "AAAI Press", "2010") + "For the admissible variant see the papers" + utils::format_paper_reference( diff --git a/src/search/merge_and_shrink/merge_and_shrink_heuristic.cc b/src/search/merge_and_shrink/merge_and_shrink_heuristic.cc index b76477877a..26f14f9c78 100644 --- a/src/search/merge_and_shrink/merge_and_shrink_heuristic.cc +++ b/src/search/merge_and_shrink/merge_and_shrink_heuristic.cc @@ -115,14 +115,14 @@ static shared_ptr _parse(options::OptionParser &parser) { "AAAI Press", "2014") + "\n" + "For a more exhaustive description of merge-and-shrink, see the journal " - "paper" + utils::format_paper_reference( + "paper" + utils::format_journal_article_reference( {"Malte Helmert", "Patrik Haslum", "Joerg Hoffmann", "Raz Nissim"}, "Merge-and-Shrink Abstraction: A Method for Generating Lower Bounds" " in Factored State Spaces", "https://ai.dmi.unibas.ch/papers/helmert-et-al-jacm2014.pdf", - "Journal of the ACM 61 (3)", + "Journal of the ACM", + "61 (3)", "16:1-63", - "ACM", "2014") + "\n" + "Please note that the journal paper describes the \"old\" theory of " "label reduction, which has been superseded by the above conference " diff --git a/src/search/utils/markup.h b/src/search/utils/markup.h index cfaa005381..17bc64cee4 100644 --- a/src/search/utils/markup.h +++ b/src/search/utils/markup.h @@ -12,8 +12,9 @@ extern std::string format_paper_reference( extern std::string format_journal_article_reference( const std::vector &authors, const std::string &title, - const std::string &url, const std::string &journal, const std::string &volume, - const std::string &pages, const std::string &year); + const std::string &url, const std::string &journal, + const std::string &volume, const std::string &pages, + const std::string &year); } #endif From 27e895b542447090f762123c8397a88e8fc92ad1 Mon Sep 17 00:00:00 2001 From: Jendrik Seipp Date: Tue, 12 Mar 2019 21:47:10 +0100 Subject: [PATCH 03/39] [issue909] Fix style. --- src/search/utils/markup.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/search/utils/markup.cc b/src/search/utils/markup.cc index 257e6337f2..23108b594c 100644 --- a/src/search/utils/markup.cc +++ b/src/search/utils/markup.cc @@ -43,7 +43,7 @@ string format_paper_reference( } string format_journal_article_reference( - const std::vector &authors, const string &title, const string &url, + const vector &authors, const string &title, const string &url, const string &journal, const string &volume, const string &pages, const string &year) { stringstream ss; From 2d1a2dbfd219e6cd0d47e70f575e495449b88440 Mon Sep 17 00:00:00 2001 From: Silvan Sievers Date: Tue, 12 Mar 2019 22:05:51 +0100 Subject: [PATCH 04/39] [issue908] max additive subsets: use indices into the pattern/PDB collection instead of PDB pointers --- src/search/pdbs/canonical_pdbs.cc | 12 ++- src/search/pdbs/canonical_pdbs.h | 6 +- src/search/pdbs/canonical_pdbs_heuristic.cc | 28 +++--- src/search/pdbs/dominance_pruning.cc | 96 +++++++++++-------- src/search/pdbs/dominance_pruning.h | 9 +- src/search/pdbs/incremental_canonical_pdbs.cc | 6 +- src/search/pdbs/max_additive_pdb_sets.cc | 41 +++----- src/search/pdbs/max_additive_pdb_sets.h | 3 +- ...ttern_collection_generator_hillclimbing.cc | 11 ++- ...attern_collection_generator_hillclimbing.h | 1 + .../pdbs/pattern_collection_information.cc | 25 +---- src/search/pdbs/types.h | 2 +- 12 files changed, 113 insertions(+), 127 deletions(-) diff --git a/src/search/pdbs/canonical_pdbs.cc b/src/search/pdbs/canonical_pdbs.cc index efafe0f183..874b55293a 100644 --- a/src/search/pdbs/canonical_pdbs.cc +++ b/src/search/pdbs/canonical_pdbs.cc @@ -11,8 +11,10 @@ using namespace std; namespace pdbs { CanonicalPDBs::CanonicalPDBs( - const shared_ptr &max_additive_subsets_) - : max_additive_subsets(max_additive_subsets_) { + shared_ptr pdbs, + shared_ptr max_additive_subsets) + : pdbs(pdbs), max_additive_subsets(max_additive_subsets) { + assert(pdbs); assert(max_additive_subsets); } @@ -20,12 +22,12 @@ int CanonicalPDBs::get_value(const State &state) const { // If we have an empty collection, then max_additive_subsets = { \emptyset }. assert(!max_additive_subsets->empty()); int max_h = 0; - for (const auto &subset : *max_additive_subsets) { + for (const vector &subset : *max_additive_subsets) { int subset_h = 0; - for (const shared_ptr &pdb : subset) { + for (int pdb_index : subset) { /* Experiments showed that it is faster to recompute the h values than to cache them in an unordered_map. */ - int h = pdb->get_value(state); + int h = (*pdbs)[pdb_index]->get_value(state); if (h == numeric_limits::max()) return numeric_limits::max(); subset_h += h; diff --git a/src/search/pdbs/canonical_pdbs.h b/src/search/pdbs/canonical_pdbs.h index bcf729a268..62f6a374e7 100644 --- a/src/search/pdbs/canonical_pdbs.h +++ b/src/search/pdbs/canonical_pdbs.h @@ -9,11 +9,13 @@ class State; namespace pdbs { class CanonicalPDBs { + std::shared_ptr pdbs; std::shared_ptr max_additive_subsets; public: - explicit CanonicalPDBs( - const std::shared_ptr &max_additive_subsets); + CanonicalPDBs( + std::shared_ptr pdbs, + std::shared_ptr max_additive_subsets); ~CanonicalPDBs() = default; int get_value(const State &state) const; diff --git a/src/search/pdbs/canonical_pdbs_heuristic.cc b/src/search/pdbs/canonical_pdbs_heuristic.cc index 0baab9cdfa..07cf00470e 100644 --- a/src/search/pdbs/canonical_pdbs_heuristic.cc +++ b/src/search/pdbs/canonical_pdbs_heuristic.cc @@ -2,6 +2,7 @@ #include "dominance_pruning.h" #include "pattern_generator.h" +#include "utils.h" #include "../option_parser.h" #include "../plugin.h" @@ -23,28 +24,23 @@ CanonicalPDBs get_canonical_pdbs_from_options( cout << "Initializing canonical PDB heuristic..." << endl; PatternCollectionInformation pattern_collection_info = pattern_generator->generate(task); - shared_ptr pdbs = pattern_collection_info.get_pdbs(); - shared_ptr max_additive_subsets = - pattern_collection_info.get_max_additive_subsets(); double max_time_dominance_pruning = opts.get("max_time_dominance_pruning"); if (max_time_dominance_pruning > 0.0) { int num_variables = TaskProxy(*task).get_variables().size(); - max_additive_subsets = prune_dominated_subsets( - *pdbs, *max_additive_subsets, num_variables, max_time_dominance_pruning); + pattern_collection_info = prune_dominated_subsets( + pattern_collection_info, num_variables, max_time_dominance_pruning); } - /* - Once we have better data structures for storing and passing pattern - collections, we should also print the final pattern collection here - like in dump_pattern_collection_generation_statistics. To this end, - the dominance pruning code would need to not only return the max - additive subsets, but the list of patterns/PDBs together with the max - subsets, possibly as a list of list of indices into the pattern/PDB - collection. - */ - cout << "Canonical PDB heuristic computation time: " << timer << endl; - return CanonicalPDBs(max_additive_subsets); + /* Compute pdbs and max additive subsets here so that they count towards + the total computation time of the heuristic. */ + shared_ptr pdbs = pattern_collection_info.get_pdbs(); + shared_ptr max_additive_subsets = + pattern_collection_info.get_max_additive_subsets(); + // Do not dump pattern collections for size reasons. + dump_pattern_collection_generation_statistics( + "Canonical PDB heuristic", timer(), pattern_collection_info, false); + return CanonicalPDBs(pdbs, max_additive_subsets); } CanonicalPDBsHeuristic::CanonicalPDBsHeuristic(const Options &opts) diff --git a/src/search/pdbs/dominance_pruning.cc b/src/search/pdbs/dominance_pruning.cc index 87abb57f91..7a6772dbbb 100644 --- a/src/search/pdbs/dominance_pruning.cc +++ b/src/search/pdbs/dominance_pruning.cc @@ -1,5 +1,6 @@ #include "dominance_pruning.h" +#include "pattern_collection_information.h" #include "pattern_database.h" #include "../utils/countdown_timer.h" @@ -48,8 +49,8 @@ class Pruner { */ const int num_variables; - vector patterns; - vector> collections; + const PatternCollection &patterns; + const MaxAdditivePDBSubsets &collections; vector pattern_index; vector dominated_patterns; @@ -110,31 +111,11 @@ class Pruner { } public: - Pruner(const PDBCollection &pattern_databases, - const MaxAdditivePDBSubsets &max_additive_subsets, + Pruner(PatternCollectionInformation &pci, int num_variables) : - num_variables(num_variables) { - unordered_map pdb_to_pattern_index; - - int num_patterns = pattern_databases.size(); - patterns.reserve(num_patterns); - for (int i = 0; i < num_patterns; ++i) { - const PatternDatabase *pdb = pattern_databases[i].get(); - patterns.push_back(pdb->get_pattern()); - pdb_to_pattern_index[pdb] = i; - } - - int num_collections = max_additive_subsets.size(); - collections.reserve(num_collections); - for (const PDBCollection &collection : max_additive_subsets) { - vector pattern_indices; - pattern_indices.reserve(collection.size()); - for (const shared_ptr &pdb : collection) { - assert(pdb_to_pattern_index.count(pdb.get())); - pattern_indices.push_back(pdb_to_pattern_index[pdb.get()]); - } - collections.push_back(move(pattern_indices)); - } + num_variables(num_variables), + patterns(*pci.get_patterns()), + collections(*pci.get_max_additive_subsets()) { } vector get_pruned_collections(const utils::CountdownTimer &timer) { @@ -170,45 +151,76 @@ class Pruner { } }; -shared_ptr prune_dominated_subsets( - const PDBCollection &pattern_databases, - const MaxAdditivePDBSubsets &max_additive_subsets, +PatternCollectionInformation prune_dominated_subsets( + PatternCollectionInformation &pci, int num_variables, double max_time) { cout << "Running dominance pruning..." << endl; utils::CountdownTimer timer(max_time); vector pruned = Pruner( - pattern_databases, - max_additive_subsets, + pci, num_variables).get_pruned_collections(timer); - shared_ptr result = + const MaxAdditivePDBSubsets &max_additive_subsets = + *pci.get_max_additive_subsets(); + shared_ptr remaining_max_additive_subsets = make_shared(); + unordered_set remaining_pattern_indices; for (size_t i = 0; i < max_additive_subsets.size(); ++i) { if (!pruned[i]) { - result->push_back(max_additive_subsets[i]); + const vector &subset = max_additive_subsets[i]; + remaining_max_additive_subsets->push_back(subset); + for (int pattern_index : subset) { + remaining_pattern_indices.insert(pattern_index); + } + } + } + + /* + TODO: we shouldn't call get_pdbs() here because they may not be computed + and need not to be computed here. We currently do this because the only + user of this class is the CPDB heuristic for which we know it computes + PDBs anyways. Doing so allows us here to remove pruned patterns *and + PDBs*. + */ + const PatternCollection &patterns = *pci.get_patterns(); + const PDBCollection &pdbs = *pci.get_pdbs(); + shared_ptr remaining_patterns = + make_shared(); + shared_ptr remaining_pdbs = + make_shared(); + vector old_to_new_pattern_index(patterns.size(), -1); + for (int old_pattern_index : remaining_pattern_indices) { + int new_pattern_index = remaining_patterns->size(); + old_to_new_pattern_index[old_pattern_index] = new_pattern_index; + remaining_patterns->push_back(patterns[old_pattern_index]); + remaining_pdbs->push_back(pdbs[old_pattern_index]); + } + for (vector &subset : *remaining_max_additive_subsets) { + for (size_t i = 0; i < subset.size(); ++i) { + int old_pattern_index = subset[i]; + int new_pattern_index = old_to_new_pattern_index[old_pattern_index]; + assert(new_pattern_index != -1); + subset[i] = new_pattern_index; } } int num_collections = max_additive_subsets.size(); - int num_pruned_collections = num_collections - result->size(); + int num_pruned_collections = num_collections - remaining_max_additive_subsets->size(); cout << "Pruned " << num_pruned_collections << " of " << num_collections << " maximal additive subsets" << endl; - unordered_set remaining_pdbs; - for (const PDBCollection &collection : *result) { - for (const shared_ptr &pdb : collection) { - remaining_pdbs.insert(pdb.get()); - } - } - int num_patterns = pattern_databases.size(); - int num_pruned_patterns = num_patterns - remaining_pdbs.size(); + int num_patterns = patterns.size(); + int num_pruned_patterns = num_patterns - remaining_patterns->size(); cout << "Pruned " << num_pruned_patterns << " of " << num_patterns << " PDBs" << endl; cout << "Dominance pruning took " << timer.get_elapsed_time() << endl; + PatternCollectionInformation result(pci.get_task_proxy(), remaining_patterns); + result.set_pdbs(remaining_pdbs); + result.set_max_additive_subsets(remaining_max_additive_subsets); return result; } } diff --git a/src/search/pdbs/dominance_pruning.h b/src/search/pdbs/dominance_pruning.h index d6e34de914..1e3e7d0372 100644 --- a/src/search/pdbs/dominance_pruning.h +++ b/src/search/pdbs/dominance_pruning.h @@ -1,19 +1,18 @@ #ifndef PDBS_DOMINANCE_PRUNING_H #define PDBS_DOMINANCE_PRUNING_H -#include "types.h" - #include namespace pdbs { +class PatternCollectionInformation; + /* Collection superset dominates collection subset iff for every pattern p_subset in subset there is a pattern p_superset in superset where p_superset is a superset of p_subset. */ -extern std::shared_ptr prune_dominated_subsets( - const PDBCollection &pattern_databases, - const MaxAdditivePDBSubsets &max_additive_subsets, +extern PatternCollectionInformation prune_dominated_subsets( + PatternCollectionInformation &pci, int num_variables, double max_time); } diff --git a/src/search/pdbs/incremental_canonical_pdbs.cc b/src/search/pdbs/incremental_canonical_pdbs.cc index fa2c57be7d..48c9d2bbb3 100644 --- a/src/search/pdbs/incremental_canonical_pdbs.cc +++ b/src/search/pdbs/incremental_canonical_pdbs.cc @@ -34,18 +34,18 @@ void IncrementalCanonicalPDBs::add_pdb(const shared_ptr &pdb) { } void IncrementalCanonicalPDBs::recompute_max_additive_subsets() { - max_additive_subsets = compute_max_additive_subsets(*pattern_databases, + max_additive_subsets = compute_max_additive_subsets(*patterns, are_additive); } MaxAdditivePDBSubsets IncrementalCanonicalPDBs::get_max_additive_subsets( const Pattern &new_pattern) { return pdbs::compute_max_additive_subsets_with_pattern( - *max_additive_subsets, new_pattern, are_additive); + *patterns, *max_additive_subsets, new_pattern, are_additive); } int IncrementalCanonicalPDBs::get_value(const State &state) const { - CanonicalPDBs canonical_pdbs(max_additive_subsets); + CanonicalPDBs canonical_pdbs(pattern_databases, max_additive_subsets); return canonical_pdbs.get_value(state); } diff --git a/src/search/pdbs/max_additive_pdb_sets.cc b/src/search/pdbs/max_additive_pdb_sets.cc index c2bb61a79d..efefc2bc2d 100644 --- a/src/search/pdbs/max_additive_pdb_sets.cc +++ b/src/search/pdbs/max_additive_pdb_sets.cc @@ -39,16 +39,14 @@ VariableAdditivity compute_additive_vars(const TaskProxy &task_proxy) { } shared_ptr compute_max_additive_subsets( - const PDBCollection &pdbs, const VariableAdditivity &are_additive) { + const PatternCollection &patterns, const VariableAdditivity &are_additive) { // Initialize compatibility graph. vector> cgraph; - cgraph.resize(pdbs.size()); + cgraph.resize(patterns.size()); - for (size_t i = 0; i < pdbs.size(); ++i) { - for (size_t j = i + 1; j < pdbs.size(); ++j) { - if (are_patterns_additive(pdbs[i]->get_pattern(), - pdbs[j]->get_pattern(), - are_additive)) { + for (size_t i = 0; i < patterns.size(); ++i) { + for (size_t j = i + 1; j < patterns.size(); ++j) { + if (are_patterns_additive(patterns[i], patterns[j], are_additive)) { /* If the two patterns are additive, there is an edge in the compatibility graph. */ cgraph[i].push_back(j); @@ -57,36 +55,25 @@ shared_ptr compute_max_additive_subsets( } } - vector> max_cliques; - max_cliques::compute_max_cliques(cgraph, max_cliques); - - shared_ptr max_additive_sets = - make_shared(); - max_additive_sets->reserve(max_cliques.size()); - for (const vector &max_clique : max_cliques) { - PDBCollection max_additive_subset; - max_additive_subset.reserve(max_clique.size()); - for (int pdb_id : max_clique) { - max_additive_subset.push_back(pdbs[pdb_id]); - } - max_additive_sets->push_back(max_additive_subset); - } - return max_additive_sets; + shared_ptr max_cliques = make_shared(); + max_cliques::compute_max_cliques(cgraph, *max_cliques); + return max_cliques; } MaxAdditivePDBSubsets compute_max_additive_subsets_with_pattern( + const PatternCollection &patterns, const MaxAdditivePDBSubsets &known_additive_subsets, const Pattern &new_pattern, const VariableAdditivity &are_additive) { MaxAdditivePDBSubsets subsets_additive_with_pattern; - for (const auto &known_subset : known_additive_subsets) { + for (const vector &known_subset : known_additive_subsets) { // Take all patterns which are additive to new_pattern. - PDBCollection new_subset; + vector new_subset; new_subset.reserve(known_subset.size()); - for (const shared_ptr &pdb : known_subset) { + for (int pattern_index : known_subset) { if (are_patterns_additive( - new_pattern, pdb->get_pattern(), are_additive)) { - new_subset.push_back(pdb); + new_pattern, patterns[pattern_index], are_additive)) { + new_subset.push_back(pattern_index); } } if (!new_subset.empty()) { diff --git a/src/search/pdbs/max_additive_pdb_sets.h b/src/search/pdbs/max_additive_pdb_sets.h index f612038225..2add4f3847 100644 --- a/src/search/pdbs/max_additive_pdb_sets.h +++ b/src/search/pdbs/max_additive_pdb_sets.h @@ -23,7 +23,7 @@ extern bool are_patterns_additive(const Pattern &pattern1, Computes maximal additive subsets of patterns. */ extern std::shared_ptr compute_max_additive_subsets( - const PDBCollection &pdbs, const VariableAdditivity &are_additive); + const PatternCollection &patterns, const VariableAdditivity &are_additive); /* We compute additive pattern sets S with the property that we could @@ -71,6 +71,7 @@ extern std::shared_ptr compute_max_additive_subsets( "new" cliques including P. */ extern MaxAdditivePDBSubsets compute_max_additive_subsets_with_pattern( + const PatternCollection &patterns, const MaxAdditivePDBSubsets &known_additive_subsets, const Pattern &new_pattern, const VariableAdditivity &are_additive); diff --git a/src/search/pdbs/pattern_collection_generator_hillclimbing.cc b/src/search/pdbs/pattern_collection_generator_hillclimbing.cc index 32523312c2..f1035c27e4 100644 --- a/src/search/pdbs/pattern_collection_generator_hillclimbing.cc +++ b/src/search/pdbs/pattern_collection_generator_hillclimbing.cc @@ -243,7 +243,8 @@ pair PatternCollectionGeneratorHillclimbing::find_best_improving_pdb( assert(utils::in_bounds(sample_id, samples_h_values)); int h_collection = samples_h_values[sample_id]; if (is_heuristic_improved( - *pdb, sample, h_collection, max_additive_subsets)) { + *pdb, sample, h_collection, + *current_pdbs->get_pattern_databases(), max_additive_subsets)) { ++count; } } @@ -262,7 +263,7 @@ pair PatternCollectionGeneratorHillclimbing::find_best_improving_pdb( bool PatternCollectionGeneratorHillclimbing::is_heuristic_improved( const PatternDatabase &pdb, const State &sample, int h_collection, - const MaxAdditivePDBSubsets &max_additive_subsets) { + const PDBCollection &pdbs, const MaxAdditivePDBSubsets &max_additive_subsets) { // h_pattern: h-value of the new pattern int h_pattern = pdb.get_value(sample); @@ -274,12 +275,12 @@ bool PatternCollectionGeneratorHillclimbing::is_heuristic_improved( if (h_collection == numeric_limits::max()) return false; - for (const auto &subset : max_additive_subsets) { + for (const vector &subset : max_additive_subsets) { int h_subset = 0; - for (const shared_ptr &additive_pdb : subset) { + for (int pdb_index : subset) { /* Experiments showed that it is faster to recompute the h values than to cache them in an unordered_map. */ - int h = additive_pdb->get_value(sample); + int h = pdbs[pdb_index]->get_value(sample); if (h == numeric_limits::max()) return false; h_subset += h; diff --git a/src/search/pdbs/pattern_collection_generator_hillclimbing.h b/src/search/pdbs/pattern_collection_generator_hillclimbing.h index 4af3c5470d..8e20bd0fd7 100644 --- a/src/search/pdbs/pattern_collection_generator_hillclimbing.h +++ b/src/search/pdbs/pattern_collection_generator_hillclimbing.h @@ -98,6 +98,7 @@ class PatternCollectionGeneratorHillclimbing : public PatternCollectionGenerator const PatternDatabase &pdb, const State &sample, int h_collection, + const PDBCollection &pdbs, const MaxAdditivePDBSubsets &max_additive_subsets); /* diff --git a/src/search/pdbs/pattern_collection_information.cc b/src/search/pdbs/pattern_collection_information.cc index ac598e749c..9ce29d810c 100644 --- a/src/search/pdbs/pattern_collection_information.cc +++ b/src/search/pdbs/pattern_collection_information.cc @@ -41,30 +41,17 @@ bool PatternCollectionInformation::information_is_valid() const { } } if (max_additive_subsets) { - unordered_set pdbs_in_union; - for (const PDBCollection &additive_subset : *max_additive_subsets) { - for (const shared_ptr &pdb : additive_subset) { - pdbs_in_union.insert(pdb.get()); - } - } utils::HashSet patterns_in_union; - for (PatternDatabase *pdb : pdbs_in_union) { - patterns_in_union.insert(pdb->get_pattern()); + for (const vector &additive_subset : *max_additive_subsets) { + for (int pattern_index : additive_subset) { + patterns_in_union.insert((*patterns)[pattern_index]); + } } utils::HashSet patterns_in_list(patterns->begin(), patterns->end()); if (patterns_in_list != patterns_in_union) { return false; } - if (pdbs) { - unordered_set pdbs_in_list; - for (const shared_ptr &pdb : *pdbs) { - pdbs_in_list.insert(pdb.get()); - } - if (pdbs_in_list != pdbs_in_union) { - return false; - } - } } return true; } @@ -86,12 +73,10 @@ void PatternCollectionInformation::create_pdbs_if_missing() { void PatternCollectionInformation::create_max_additive_subsets_if_missing() { if (!max_additive_subsets) { - create_pdbs_if_missing(); utils::Timer timer; cout << "Computing max additive subsets for pattern collection..." << endl; - assert(pdbs); VariableAdditivity are_additive = compute_additive_vars(task_proxy); - max_additive_subsets = compute_max_additive_subsets(*pdbs, are_additive); + max_additive_subsets = compute_max_additive_subsets(*patterns, are_additive); cout << "Done computing max additive subsets for pattern collection: " << timer << endl; } diff --git a/src/search/pdbs/types.h b/src/search/pdbs/types.h index 92f1cb2a4c..ca5d82c501 100644 --- a/src/search/pdbs/types.h +++ b/src/search/pdbs/types.h @@ -9,7 +9,7 @@ class PatternDatabase; using Pattern = std::vector; using PatternCollection = std::vector; using PDBCollection = std::vector>; -using MaxAdditivePDBSubsets = std::vector; +using MaxAdditivePDBSubsets = std::vector>; } #endif From 89aae0e6c7019a8a119d4f0ef8831caad9756f66 Mon Sep 17 00:00:00 2001 From: Jendrik Seipp Date: Tue, 12 Mar 2019 22:11:41 +0100 Subject: [PATCH 05/39] [issue909] Rename reference formatting functions. --- src/search/cegar/additive_cartesian_heuristic.cc | 6 +++--- src/search/landmarks/landmark_count_heuristic.cc | 8 ++++---- src/search/merge_and_shrink/label_reduction.cc | 2 +- .../merge_and_shrink/merge_and_shrink_heuristic.cc | 8 ++++---- .../merge_and_shrink/merge_scoring_function_dfp.cc | 2 +- .../merge_and_shrink/merge_scoring_function_miasm.cc | 2 +- .../merge_scoring_function_total_order.cc | 2 +- src/search/merge_and_shrink/merge_strategy_aliases.cc | 4 ++-- .../merge_and_shrink/merge_strategy_factory_sccs.cc | 2 +- src/search/merge_and_shrink/merge_tree_factory_linear.cc | 2 +- src/search/merge_and_shrink/shrink_bisimulation.cc | 2 +- src/search/merge_and_shrink/shrink_fh.cc | 2 +- src/search/open_lists/epsilon_greedy_open_list.cc | 2 +- src/search/open_lists/type_based_open_list.cc | 2 +- src/search/operator_counting/lm_cut_constraints.cc | 4 ++-- .../operator_counting/operator_counting_heuristic.cc | 2 +- src/search/operator_counting/pho_constraints.cc | 2 +- .../operator_counting/state_equation_constraints.cc | 6 +++--- src/search/pdbs/pattern_collection_generator_genetic.cc | 2 +- .../pdbs/pattern_collection_generator_hillclimbing.cc | 4 ++-- .../pdbs/pattern_collection_generator_systematic.cc | 2 +- src/search/potentials/util.cc | 2 +- src/search/pruning/stubborn_sets_ec.cc | 2 +- src/search/pruning/stubborn_sets_simple.cc | 4 ++-- src/search/utils/markup.cc | 8 ++++---- src/search/utils/markup.h | 9 +++++---- 26 files changed, 47 insertions(+), 46 deletions(-) diff --git a/src/search/cegar/additive_cartesian_heuristic.cc b/src/search/cegar/additive_cartesian_heuristic.cc index 5c370b77b9..927d0cf741 100644 --- a/src/search/cegar/additive_cartesian_heuristic.cc +++ b/src/search/cegar/additive_cartesian_heuristic.cc @@ -67,7 +67,7 @@ static shared_ptr _parse(OptionParser &parser) { "Additive CEGAR heuristic", "See the paper introducing Counterexample-guided Abstraction " "Refinement (CEGAR) for classical planning:" + - utils::format_paper_reference( + utils::format_conference_reference( {"Jendrik Seipp", "Malte Helmert"}, "Counterexample-guided Cartesian Abstraction Refinement", "https://ai.dmi.unibas.ch/papers/seipp-helmert-icaps2013.pdf", @@ -77,7 +77,7 @@ static shared_ptr _parse(OptionParser &parser) { "AAAI Press", "2013") + "and the paper showing how to make the abstractions additive:" + - utils::format_paper_reference( + utils::format_conference_reference( {"Jendrik Seipp", "Malte Helmert"}, "Diverse and Additive Cartesian Abstraction Heuristics", "https://ai.dmi.unibas.ch/papers/seipp-helmert-icaps2014.pdf", @@ -88,7 +88,7 @@ static shared_ptr _parse(OptionParser &parser) { "2014") + "For more details on Cartesian CEGAR and saturated cost partitioning, " "see the journal paper" + - utils::format_journal_article_reference( + utils::format_journal_reference( {"Jendrik Seipp", "Malte Helmert"}, "Counterexample-Guided Cartesian Abstraction Refinement for " "Classical Planning", diff --git a/src/search/landmarks/landmark_count_heuristic.cc b/src/search/landmarks/landmark_count_heuristic.cc index c26401c643..19ee634835 100644 --- a/src/search/landmarks/landmark_count_heuristic.cc +++ b/src/search/landmarks/landmark_count_heuristic.cc @@ -248,7 +248,7 @@ static shared_ptr _parse(OptionParser &parser) { parser.document_synopsis( "Landmark-count heuristic", "For the inadmissible variant see the papers" + - utils::format_paper_reference( + utils::format_conference_reference( {"Silvia Richter", "Malte Helmert", "Matthias Westphal"}, "Landmarks Revisited", "https://ai.dmi.unibas.ch/papers/richter-et-al-aaai2008.pdf", @@ -258,7 +258,7 @@ static shared_ptr _parse(OptionParser &parser) { "AAAI Press", "2008") + "and" + - utils::format_journal_article_reference( + utils::format_journal_reference( {"Silvia Richter", "Matthias Westphal"}, "The LAMA Planner: Guiding Cost-Based Anytime Planning with Landmarks", "http://www.aaai.org/Papers/JAIR/Vol39/JAIR-3903.pdf", @@ -267,7 +267,7 @@ static shared_ptr _parse(OptionParser &parser) { "127-177", "2010") + "For the admissible variant see the papers" + - utils::format_paper_reference( + utils::format_conference_reference( {"Erez Karpas", "Carmel Domshlak"}, "Cost-Optimal Planning with Landmarks", "https://www.ijcai.org/Proceedings/09/Papers/288.pdf", @@ -277,7 +277,7 @@ static shared_ptr _parse(OptionParser &parser) { "AAAI Press", "2009") + "and" + - utils::format_paper_reference( + utils::format_conference_reference( {"Emil Keyder and Silvia Richter and Malte Helmert"}, "Sound and Complete Landmarks for And/Or Graphs", "https://ai.dmi.unibas.ch/papers/keyder-et-al-ecai2010.pdf", diff --git a/src/search/merge_and_shrink/label_reduction.cc b/src/search/merge_and_shrink/label_reduction.cc index c3a6049a1c..1d0b585d70 100644 --- a/src/search/merge_and_shrink/label_reduction.cc +++ b/src/search/merge_and_shrink/label_reduction.cc @@ -302,7 +302,7 @@ static shared_ptr_parse(OptionParser &parser) { "Exact generalized label reduction", "This class implements the exact generalized label reduction " "described in the following paper:" + - utils::format_paper_reference( + utils::format_conference_reference( {"Silvan Sievers", "Martin Wehrle", "Malte Helmert"}, "Generalized Label Reduction for Merge-and-Shrink Heuristics", "https://ai.dmi.unibas.ch/papers/sievers-et-al-aaai2014.pdf", diff --git a/src/search/merge_and_shrink/merge_and_shrink_heuristic.cc b/src/search/merge_and_shrink/merge_and_shrink_heuristic.cc index 26f14f9c78..a8fe061398 100644 --- a/src/search/merge_and_shrink/merge_and_shrink_heuristic.cc +++ b/src/search/merge_and_shrink/merge_and_shrink_heuristic.cc @@ -105,7 +105,7 @@ static shared_ptr _parse(options::OptionParser &parser) { parser.document_synopsis( "Merge-and-shrink heuristic", "This heuristic implements the algorithm described in the following " - "paper:" + utils::format_paper_reference( + "paper:" + utils::format_conference_reference( {"Silvan Sievers", "Martin Wehrle", "Malte Helmert"}, "Generalized Label Reduction for Merge-and-Shrink Heuristics", "https://ai.dmi.unibas.ch/papers/sievers-et-al-aaai2014.pdf", @@ -115,7 +115,7 @@ static shared_ptr _parse(options::OptionParser &parser) { "AAAI Press", "2014") + "\n" + "For a more exhaustive description of merge-and-shrink, see the journal " - "paper" + utils::format_journal_article_reference( + "paper" + utils::format_journal_reference( {"Malte Helmert", "Patrik Haslum", "Joerg Hoffmann", "Raz Nissim"}, "Merge-and-Shrink Abstraction: A Method for Generating Lower Bounds" " in Factored State Spaces", @@ -129,7 +129,7 @@ static shared_ptr _parse(options::OptionParser &parser) { "paper and is no longer implemented in Fast Downward.\n\n" "The following paper describes how to improve the DFP merge strategy " "with tie-breaking, and presents two new merge strategies (dyn-MIASM " - "and SCC-DFP):" + utils::format_paper_reference( + "and SCC-DFP):" + utils::format_conference_reference( {"Silvan Sievers", "Martin Wehrle", "Malte Helmert"}, "An Analysis of Merge Strategies for Merge-and-Shrink Heuristics", "https://ai.dmi.unibas.ch/papers/sievers-et-al-icaps2016.pdf", @@ -139,7 +139,7 @@ static shared_ptr _parse(options::OptionParser &parser) { "AAAI Press", "2016") + "\n" + "Details of the algorithms and the implementation are described in the " - "paper" + utils::format_paper_reference( + "paper" + utils::format_conference_reference( {"Silvan Sievers"}, "Merge-and-Shrink Heuristics for Classical Planning: Efficient " "Implementation and Partial Abstractions", diff --git a/src/search/merge_and_shrink/merge_scoring_function_dfp.cc b/src/search/merge_and_shrink/merge_scoring_function_dfp.cc index 95c93bdf3a..44ba5c3704 100644 --- a/src/search/merge_and_shrink/merge_scoring_function_dfp.cc +++ b/src/search/merge_and_shrink/merge_scoring_function_dfp.cc @@ -109,7 +109,7 @@ static shared_ptr_parse(options::OptionParser &parser) { "This scoring function computes the 'DFP' score as descrdibed in the " "paper \"Directed model checking with distance-preserving abstractions\" " "by Draeger, Finkbeiner and Podelski (SPIN 2006), adapted to planning in " - "the following paper:" + utils::format_paper_reference( + "the following paper:" + utils::format_conference_reference( {"Silvan Sievers", "Martin Wehrle", "Malte Helmert"}, "Generalized Label Reduction for Merge-and-Shrink Heuristics", "https://ai.dmi.unibas.ch/papers/sievers-et-al-aaai2014.pdf", diff --git a/src/search/merge_and_shrink/merge_scoring_function_miasm.cc b/src/search/merge_and_shrink/merge_scoring_function_miasm.cc index ad7964bdd4..f14af4c8b7 100644 --- a/src/search/merge_and_shrink/merge_scoring_function_miasm.cc +++ b/src/search/merge_and_shrink/merge_scoring_function_miasm.cc @@ -85,7 +85,7 @@ static shared_ptr_parse(options::OptionParser &parser) { "the specified size limits. A stateless merge strategy using this " "scoring function is called dyn-MIASM (nowadays also called sbMIASM " "for score-based MIASM) and is described in the following paper:" - + utils::format_paper_reference( + + utils::format_conference_reference( {"Silvan Sievers", "Martin Wehrle", "Malte Helmert"}, "An Analysis of Merge Strategies for Merge-and-Shrink Heuristics", "https://ai.dmi.unibas.ch/papers/sievers-et-al-icaps2016.pdf", diff --git a/src/search/merge_and_shrink/merge_scoring_function_total_order.cc b/src/search/merge_and_shrink/merge_scoring_function_total_order.cc index 9830512f51..6287a351c0 100644 --- a/src/search/merge_and_shrink/merge_scoring_function_total_order.cc +++ b/src/search/merge_and_shrink/merge_scoring_function_total_order.cc @@ -207,7 +207,7 @@ static shared_ptr_parse(options::OptionParser &parser) { "correponds to its position in the order. This scoring function is " "mainly intended as tie-breaking, and has been introduced in the " "following paper:" - + utils::format_paper_reference( + + utils::format_conference_reference( {"Silvan Sievers", "Martin Wehrle", "Malte Helmert"}, "An Analysis of Merge Strategies for Merge-and-Shrink Heuristics", "https://ai.dmi.unibas.ch/papers/sievers-et-al-icaps2016.pdf", diff --git a/src/search/merge_and_shrink/merge_strategy_aliases.cc b/src/search/merge_and_shrink/merge_strategy_aliases.cc index 661490033f..7ce2b950b3 100644 --- a/src/search/merge_and_shrink/merge_strategy_aliases.cc +++ b/src/search/merge_and_shrink/merge_strategy_aliases.cc @@ -22,7 +22,7 @@ static shared_ptr_parse_dfp(options::OptionParser &parser) "This merge strategy implements the algorithm originally described in the " "paper \"Directed model checking with distance-preserving abstractions\" " "by Draeger, Finkbeiner and Podelski (SPIN 2006), adapted to planning in " - "the following paper:" + utils::format_paper_reference( + "the following paper:" + utils::format_conference_reference( {"Silvan Sievers", "Martin Wehrle", "Malte Helmert"}, "Generalized Label Reduction for Merge-and-Shrink Heuristics", "https://ai.dmi.unibas.ch/papers/sievers-et-al-aaai2014.pdf", @@ -95,7 +95,7 @@ static shared_ptr _parse_linear( parser.document_synopsis( "Linear merge strategies", "These merge strategies implement several linear merge orders, which " - "are described in the paper:" + utils::format_paper_reference( + "are described in the paper:" + utils::format_conference_reference( {"Malte Helmert", "Patrik Haslum", "Joerg Hoffmann"}, "Flexible Abstraction Heuristics for Optimal Sequential Planning", "https://ai.dmi.unibas.ch/papers/helmert-et-al-icaps2007.pdf", diff --git a/src/search/merge_and_shrink/merge_strategy_factory_sccs.cc b/src/search/merge_and_shrink/merge_strategy_factory_sccs.cc index 8f800ebf1c..d04fed5d4e 100644 --- a/src/search/merge_and_shrink/merge_strategy_factory_sccs.cc +++ b/src/search/merge_and_shrink/merge_strategy_factory_sccs.cc @@ -168,7 +168,7 @@ static shared_ptr_parse(options::OptionParser &parser) { parser.document_synopsis( "Merge strategy SSCs", "This merge strategy implements the algorithm described in the paper " - + utils::format_paper_reference( + + utils::format_conference_reference( {"Silvan Sievers", "Martin Wehrle", "Malte Helmert"}, "An Analysis of Merge Strategies for Merge-and-Shrink Heuristics", "https://ai.dmi.unibas.ch/papers/sievers-et-al-icaps2016.pdf", diff --git a/src/search/merge_and_shrink/merge_tree_factory_linear.cc b/src/search/merge_and_shrink/merge_tree_factory_linear.cc index e3d9697151..f327908814 100644 --- a/src/search/merge_and_shrink/merge_tree_factory_linear.cc +++ b/src/search/merge_and_shrink/merge_tree_factory_linear.cc @@ -128,7 +128,7 @@ static shared_ptr _parse(options::OptionParser &parser) { parser.document_synopsis( "Linear merge trees", "These merge trees implement several linear merge orders, which " - "are described in the paper:" + utils::format_paper_reference( + "are described in the paper:" + utils::format_conference_reference( {"Malte Helmert", "Patrik Haslum", "Joerg Hoffmann"}, "Flexible Abstraction Heuristics for Optimal Sequential Planning", "https://ai.dmi.unibas.ch/papers/helmert-et-al-icaps2007.pdf", diff --git a/src/search/merge_and_shrink/shrink_bisimulation.cc b/src/search/merge_and_shrink/shrink_bisimulation.cc index 89204e7077..cfa815d915 100644 --- a/src/search/merge_and_shrink/shrink_bisimulation.cc +++ b/src/search/merge_and_shrink/shrink_bisimulation.cc @@ -378,7 +378,7 @@ static shared_ptr_parse(OptionParser &parser) { parser.document_synopsis( "Bismulation based shrink strategy", "This shrink strategy implements the algorithm described in" - " the paper:" + utils::format_paper_reference( + " the paper:" + utils::format_conference_reference( {"Raz Nissim", "Joerg Hoffmann", "Malte Helmert"}, "Computing Perfect Heuristics in Polynomial Time: On Bisimulation" " and Merge-and-Shrink Abstractions in Optimal Planning.", diff --git a/src/search/merge_and_shrink/shrink_fh.cc b/src/search/merge_and_shrink/shrink_fh.cc index 9821228b4d..10bc8a59e9 100644 --- a/src/search/merge_and_shrink/shrink_fh.cc +++ b/src/search/merge_and_shrink/shrink_fh.cc @@ -192,7 +192,7 @@ static shared_ptr_parse(OptionParser &parser) { parser.document_synopsis( "f-preserving shrink strategy", "This shrink strategy implements the algorithm described in" - " the paper:" + utils::format_paper_reference( + " the paper:" + utils::format_conference_reference( {"Malte Helmert", "Patrik Haslum", "Joerg Hoffmann"}, "Flexible Abstraction Heuristics for Optimal Sequential Planning", "https://ai.dmi.unibas.ch/papers/helmert-et-al-icaps2007.pdf", diff --git a/src/search/open_lists/epsilon_greedy_open_list.cc b/src/search/open_lists/epsilon_greedy_open_list.cc index f4a61875f1..d06ccfeba2 100644 --- a/src/search/open_lists/epsilon_greedy_open_list.cc +++ b/src/search/open_lists/epsilon_greedy_open_list.cc @@ -156,7 +156,7 @@ static shared_ptr _parse(OptionParser &parser) { "Epsilon-greedy open list", "Chooses an entry uniformly randomly with probability " "'epsilon', otherwise it returns the minimum entry. " - "The algorithm is based on" + utils::format_paper_reference( + "The algorithm is based on" + utils::format_conference_reference( {"Richard Valenzano", "Nathan R. Sturtevant", "Jonathan Schaeffer", "Fan Xie"}, "A Comparison of Knowledge-Based GBFS Enhancements and" diff --git a/src/search/open_lists/type_based_open_list.cc b/src/search/open_lists/type_based_open_list.cc index 385f0427de..0a753ad9a3 100644 --- a/src/search/open_lists/type_based_open_list.cc +++ b/src/search/open_lists/type_based_open_list.cc @@ -158,7 +158,7 @@ static shared_ptr _parse(OptionParser &parser) { "When retrieving an entry, a bucket is chosen uniformly at " "random and one of the contained entries is selected " "uniformly randomly. " - "The algorithm is based on" + utils::format_paper_reference( + "The algorithm is based on" + utils::format_conference_reference( {"Fan Xie", "Martin Mueller", "Robert Holte", "Tatsuya Imai"}, "Type-Based Exploration with Multiple Search Queues for" " Satisficing Planning", diff --git a/src/search/operator_counting/lm_cut_constraints.cc b/src/search/operator_counting/lm_cut_constraints.cc index 137da1cf52..98791ec8d0 100644 --- a/src/search/operator_counting/lm_cut_constraints.cc +++ b/src/search/operator_counting/lm_cut_constraints.cc @@ -55,7 +55,7 @@ static shared_ptr _parse(OptionParser &parser) { "For each landmark L the constraint sum_{o in L} Count_o >= 1 is added " "to the operator counting LP temporarily. After the heuristic value " "for the state is computed, all temporary constraints are removed " - "again. For details, see" + utils::format_paper_reference( + "again. For details, see" + utils::format_conference_reference( {"Florian Pommerening", "Gabriele Roeger", "Malte Helmert", "Blai Bonet"}, "LP-based Heuristics for Cost-optimal Planning", @@ -64,7 +64,7 @@ static shared_ptr _parse(OptionParser &parser) { " on Automated Planning and Scheduling (ICAPS 2014)", "226-234", "AAAI Press", - "2014") + utils::format_paper_reference( + "2014") + utils::format_conference_reference( {"Blai Bonet"}, "An admissible heuristic for SAS+ planning obtained from the" " state equation", diff --git a/src/search/operator_counting/operator_counting_heuristic.cc b/src/search/operator_counting/operator_counting_heuristic.cc index 5f04e09343..c9c75c7565 100644 --- a/src/search/operator_counting/operator_counting_heuristic.cc +++ b/src/search/operator_counting/operator_counting_heuristic.cc @@ -70,7 +70,7 @@ static shared_ptr _parse(OptionParser &parser) { "are guaranteed to have a solution with Count_o = occurrences(o, pi) " "for every plan pi. Minimizing the total cost of operators subject to " "some operator counting constraints is an admissible heuristic. " - "For details, see" + utils::format_paper_reference( + "For details, see" + utils::format_conference_reference( {"Florian Pommerening", "Gabriele Roeger", "Malte Helmert", "Blai Bonet"}, "LP-based Heuristics for Cost-optimal Planning", diff --git a/src/search/operator_counting/pho_constraints.cc b/src/search/operator_counting/pho_constraints.cc index e9d0eed60b..471e68635b 100644 --- a/src/search/operator_counting/pho_constraints.cc +++ b/src/search/operator_counting/pho_constraints.cc @@ -70,7 +70,7 @@ static shared_ptr _parse(OptionParser &parser) { "Posthoc optimization constraints", "The generator will compute a PDB for each pattern and add the" " constraint h(s) <= sum_{o in relevant(h)} Count_o. For details," - " see" + utils::format_paper_reference( + " see" + utils::format_conference_reference( {"Florian Pommerening", "Gabriele Roeger", "Malte Helmert"}, "Getting the Most Out of Pattern Databases for Classical Planning", "http://ijcai.org/papers13/Papers/IJCAI13-347.pdf", diff --git a/src/search/operator_counting/state_equation_constraints.cc b/src/search/operator_counting/state_equation_constraints.cc index cacd182ca0..0203682388 100644 --- a/src/search/operator_counting/state_equation_constraints.cc +++ b/src/search/operator_counting/state_equation_constraints.cc @@ -119,7 +119,7 @@ static shared_ptr _parse(OptionParser &parser) { "change of the fact, i.e., the total number of times the fact is added " "minus the total number of times is removed. The bounds of each " "constraint depend on the current state and the goal state and are " - "updated in each state. For details, see" + utils::format_paper_reference( + "updated in each state. For details, see" + utils::format_conference_reference( {"Menkes van den Briel", "J. Benton", "Subbarao Kambhampati", "Thomas Vossen"}, "An LP-based heuristic for optimal planning", @@ -128,7 +128,7 @@ static shared_ptr _parse(OptionParser &parser) { " Principles and Practice of Constraint Programming (CP 2007)", "651-665", "Springer-Verlag", - "2007") + utils::format_paper_reference( + "2007") + utils::format_conference_reference( {"Blai Bonet"}, "An admissible heuristic for SAS+ planning obtained from the" " state equation", @@ -137,7 +137,7 @@ static shared_ptr _parse(OptionParser &parser) { " Conference on Artificial Intelligence (IJCAI 2013)", "2268-2274", "AAAI Press", - "2013") + utils::format_paper_reference( + "2013") + utils::format_conference_reference( {"Florian Pommerening", "Gabriele Roeger", "Malte Helmert", "Blai Bonet"}, "LP-based Heuristics for Cost-optimal Planning", diff --git a/src/search/pdbs/pattern_collection_generator_genetic.cc b/src/search/pdbs/pattern_collection_generator_genetic.cc index 827eb49cd8..191d5140b7 100644 --- a/src/search/pdbs/pattern_collection_generator_genetic.cc +++ b/src/search/pdbs/pattern_collection_generator_genetic.cc @@ -297,7 +297,7 @@ static shared_ptr _parse(OptionParser &parser) { "to optimize the pattern collections with an objective function that " "estimates the mean heuristic value of the the pattern collections. " "Pattern collections with higher mean heuristic estimates are more " - "likely selected for the next generation." + utils::format_paper_reference( + "likely selected for the next generation." + utils::format_conference_reference( {"Stefan Edelkamp"}, "Automated Creation of Pattern Database Search Heuristics", "http://www.springerlink.com/content/20613345434608x1/", diff --git a/src/search/pdbs/pattern_collection_generator_hillclimbing.cc b/src/search/pdbs/pattern_collection_generator_hillclimbing.cc index 32523312c2..b91442b040 100644 --- a/src/search/pdbs/pattern_collection_generator_hillclimbing.cc +++ b/src/search/pdbs/pattern_collection_generator_hillclimbing.cc @@ -491,7 +491,7 @@ static shared_ptr _parse_ipdb(OptionParser &parser) { parser.document_synopsis( "iPDB", "This pattern generation method is an adaption of the algorithm " - "described in the following paper:" + utils::format_paper_reference( + "described in the following paper:" + utils::format_conference_reference( {"Patrik Haslum", "Adi Botea", "Malte Helmert", "Blai Bonet", "Sven Koenig"}, "Domain-Independent Construction of Pattern Database Heuristics for" @@ -502,7 +502,7 @@ static shared_ptr _parse_ipdb(OptionParser &parser) { "1007-1012", "AAAI Press", "2007") + - "For implementation notes, see:" + utils::format_paper_reference( + "For implementation notes, see:" + utils::format_conference_reference( {"Silvan Sievers", "Manuela Ortlieb", "Malte Helmert"}, "Efficient Implementation of Pattern Database Heuristics for" " Classical Planning", diff --git a/src/search/pdbs/pattern_collection_generator_systematic.cc b/src/search/pdbs/pattern_collection_generator_systematic.cc index 8d5dc8b94b..17b7380c1f 100644 --- a/src/search/pdbs/pattern_collection_generator_systematic.cc +++ b/src/search/pdbs/pattern_collection_generator_systematic.cc @@ -286,7 +286,7 @@ static shared_ptr _parse(OptionParser &parser) { "Systematically generated patterns", "Generates all (interesting) patterns with up to pattern_max_size " "variables. " - "For details, see" + utils::format_paper_reference( + "For details, see" + utils::format_conference_reference( {"Florian Pommerening", "Gabriele Roeger", "Malte Helmert"}, "Getting the Most Out of Pattern Databases for Classical Planning", "https://ai.dmi.unibas.ch/papers/pommerening-et-al-ijcai2013.pdf", diff --git a/src/search/potentials/util.cc b/src/search/potentials/util.cc index da2fe94618..67c734ccb3 100644 --- a/src/search/potentials/util.cc +++ b/src/search/potentials/util.cc @@ -33,7 +33,7 @@ vector sample_without_dead_end_detection( } string get_admissible_potentials_reference() { - return "The algorithm is based on" + utils::format_paper_reference( + return "The algorithm is based on" + utils::format_conference_reference( {"Jendrik Seipp", "Florian Pommerening", "Malte Helmert"}, "New Optimization Functions for Potential Heuristics", "https://ai.dmi.unibas.ch/papers/seipp-et-al-icaps2015.pdf", diff --git a/src/search/pruning/stubborn_sets_ec.cc b/src/search/pruning/stubborn_sets_ec.cc index 96619d322f..6e3201c8b6 100644 --- a/src/search/pruning/stubborn_sets_ec.cc +++ b/src/search/pruning/stubborn_sets_ec.cc @@ -335,7 +335,7 @@ static shared_ptr _parse(OptionParser &parser) { "on several design choices, there are different variants thereof. " "The variant 'StubbornSetsEC' resolves the design choices such that " "the resulting pruning method is guaranteed to strictly dominate the " - "Expansion Core pruning method. For details, see" + utils::format_paper_reference( + "Expansion Core pruning method. For details, see" + utils::format_conference_reference( {"Martin Wehrle", "Malte Helmert", "Yusra Alkhazraji", "Robert Mattmueller"}, "The Relative Pruning Power of Strong Stubborn Sets and Expansion Core", "http://www.aaai.org/ocs/index.php/ICAPS/ICAPS13/paper/view/6053/6185", diff --git a/src/search/pruning/stubborn_sets_simple.cc b/src/search/pruning/stubborn_sets_simple.cc index f5c997c6f5..d6361f362a 100644 --- a/src/search/pruning/stubborn_sets_simple.cc +++ b/src/search/pruning/stubborn_sets_simple.cc @@ -84,7 +84,7 @@ static shared_ptr _parse(OptionParser &parser) { "on several design choices, there are different variants thereof. " "The variant 'StubbornSetsSimple' resolves the design choices in a " "straight-forward way. For details, see the following papers: " - + utils::format_paper_reference( + + utils::format_conference_reference( {"Yusra Alkhazraji", "Martin Wehrle", "Robert Mattmueller", "Malte Helmert"}, "A Stubborn Set Algorithm for Optimal Planning", "https://ai.dmi.unibas.ch/papers/alkhazraji-et-al-ecai2012.pdf", @@ -93,7 +93,7 @@ static shared_ptr _parse(OptionParser &parser) { "891-892", "IOS Press", "2012") - + utils::format_paper_reference( + + utils::format_conference_reference( {"Martin Wehrle", "Malte Helmert"}, "Efficient Stubborn Sets: Generalized Algorithms and Selection Strategies", "http://www.aaai.org/ocs/index.php/ICAPS/ICAPS14/paper/view/7922/8042", diff --git a/src/search/utils/markup.cc b/src/search/utils/markup.cc index 23108b594c..e21b2aaaa8 100644 --- a/src/search/utils/markup.cc +++ b/src/search/utils/markup.cc @@ -26,15 +26,15 @@ static string format_authors(const vector &authors) { return ss.str(); } -string format_paper_reference( +string format_conference_reference( const vector &authors, const string &title, const string &url, - const string &venue, const string &pages, const string &publisher, + const string &conference, const string &pages, const string &publisher, const string &year) { stringstream ss; ss << "\n\n" << " * " << format_authors(authors) << ".<
>\n" << " [" << t2t_escape(title) << " " << url << "].<
>\n" - << " In //" << t2t_escape(venue) << "//," + << " In //" << t2t_escape(conference) << "//," << " pp. " << t2t_escape(pages) << ". "; if (!publisher.empty()) ss << t2t_escape(publisher) << ", "; @@ -42,7 +42,7 @@ string format_paper_reference( return ss.str(); } -string format_journal_article_reference( +string format_journal_reference( const vector &authors, const string &title, const string &url, const string &journal, const string &volume, const string &pages, const string &year) { diff --git a/src/search/utils/markup.h b/src/search/utils/markup.h index 17bc64cee4..963a85fa15 100644 --- a/src/search/utils/markup.h +++ b/src/search/utils/markup.h @@ -5,12 +5,13 @@ #include namespace utils { -extern std::string format_paper_reference( +extern std::string format_conference_reference( const std::vector &authors, const std::string &title, - const std::string &url, const std::string &venue, const std::string &pages, - const std::string &publisher, const std::string &year); + const std::string &url, const std::string &conference, + const std::string &pages, const std::string &publisher, + const std::string &year); -extern std::string format_journal_article_reference( +extern std::string format_journal_reference( const std::vector &authors, const std::string &title, const std::string &url, const std::string &journal, const std::string &volume, const std::string &pages, From 80ca0a13feb79b57cb63c6b058edf07f8648a116 Mon Sep 17 00:00:00 2001 From: Jendrik Seipp Date: Tue, 12 Mar 2019 22:14:29 +0100 Subject: [PATCH 06/39] [issue909] Use ostringstream instead of stringstream. --- src/search/tasks/domain_abstracted_task_factory.cc | 2 +- src/search/utils/markup.cc | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/search/tasks/domain_abstracted_task_factory.cc b/src/search/tasks/domain_abstracted_task_factory.cc index 3e4de611f5..a18b98184e 100644 --- a/src/search/tasks/domain_abstracted_task_factory.cc +++ b/src/search/tasks/domain_abstracted_task_factory.cc @@ -94,7 +94,7 @@ void DomainAbstractedTaskFactory::initialize(const AbstractTask &parent) { string DomainAbstractedTaskFactory::get_combined_fact_name( int var, const ValueGroup &values) const { - stringstream name; + ostringstream name; string sep; for (int value : values) { name << sep << fact_names[var][value]; diff --git a/src/search/utils/markup.cc b/src/search/utils/markup.cc index e21b2aaaa8..7ac1a80aa2 100644 --- a/src/search/utils/markup.cc +++ b/src/search/utils/markup.cc @@ -30,7 +30,7 @@ string format_conference_reference( const vector &authors, const string &title, const string &url, const string &conference, const string &pages, const string &publisher, const string &year) { - stringstream ss; + ostringstream ss; ss << "\n\n" << " * " << format_authors(authors) << ".<
>\n" << " [" << t2t_escape(title) << " " << url << "].<
>\n" @@ -46,7 +46,7 @@ string format_journal_reference( const vector &authors, const string &title, const string &url, const string &journal, const string &volume, const string &pages, const string &year) { - stringstream ss; + ostringstream ss; ss << "\n\n" << " * " << format_authors(authors) << ".<
>\n" << " [" << t2t_escape(title) << " " << url << "].<
>\n" From 553bc0c51db4c9627edab9b4edc5b17afecc2a6d Mon Sep 17 00:00:00 2001 From: Silvan Sievers Date: Tue, 12 Mar 2019 22:17:07 +0100 Subject: [PATCH 07/39] [issue908] experiments for issue908 --- experiments/issue908/common_setup.py | 393 ++++++++++++++++++++++++ experiments/issue908/relativescatter.py | 105 +++++++ experiments/issue908/v1.py | 54 ++++ 3 files changed, 552 insertions(+) create mode 100644 experiments/issue908/common_setup.py create mode 100644 experiments/issue908/relativescatter.py create mode 100755 experiments/issue908/v1.py diff --git a/experiments/issue908/common_setup.py b/experiments/issue908/common_setup.py new file mode 100644 index 0000000000..5231e82f99 --- /dev/null +++ b/experiments/issue908/common_setup.py @@ -0,0 +1,393 @@ +# -*- coding: utf-8 -*- + +import itertools +import os +import platform +import subprocess +import sys + +from lab.experiment import ARGPARSER +from lab import tools + +from downward.experiment import FastDownwardExperiment +from downward.reports.absolute import AbsoluteReport +from downward.reports.compare import ComparativeReport +from downward.reports.scatter import ScatterPlotReport + +from relativescatter import RelativeScatterPlotReport + + +def parse_args(): + ARGPARSER.add_argument( + "--test", + choices=["yes", "no", "auto"], + default="auto", + dest="test_run", + help="test experiment locally on a small suite if --test=yes or " + "--test=auto and we are not on a cluster") + return ARGPARSER.parse_args() + +ARGS = parse_args() + + +DEFAULT_OPTIMAL_SUITE = [ + 'agricola-opt18-strips', 'airport', 'barman-opt11-strips', + 'barman-opt14-strips', 'blocks', 'childsnack-opt14-strips', + 'data-network-opt18-strips', 'depot', 'driverlog', + 'elevators-opt08-strips', 'elevators-opt11-strips', + 'floortile-opt11-strips', 'floortile-opt14-strips', 'freecell', + 'ged-opt14-strips', 'grid', 'gripper', 'hiking-opt14-strips', + 'logistics00', 'logistics98', 'miconic', 'movie', 'mprime', + 'mystery', 'nomystery-opt11-strips', 'openstacks-opt08-strips', + 'openstacks-opt11-strips', 'openstacks-opt14-strips', + 'openstacks-strips', 'organic-synthesis-opt18-strips', + 'organic-synthesis-split-opt18-strips', 'parcprinter-08-strips', + 'parcprinter-opt11-strips', 'parking-opt11-strips', + 'parking-opt14-strips', 'pathways-noneg', 'pegsol-08-strips', + 'pegsol-opt11-strips', 'petri-net-alignment-opt18-strips', + 'pipesworld-notankage', 'pipesworld-tankage', 'psr-small', 'rovers', + 'satellite', 'scanalyzer-08-strips', 'scanalyzer-opt11-strips', + 'snake-opt18-strips', 'sokoban-opt08-strips', + 'sokoban-opt11-strips', 'spider-opt18-strips', 'storage', + 'termes-opt18-strips', 'tetris-opt14-strips', + 'tidybot-opt11-strips', 'tidybot-opt14-strips', 'tpp', + 'transport-opt08-strips', 'transport-opt11-strips', + 'transport-opt14-strips', 'trucks-strips', 'visitall-opt11-strips', + 'visitall-opt14-strips', 'woodworking-opt08-strips', + 'woodworking-opt11-strips', 'zenotravel'] + +DEFAULT_SATISFICING_SUITE = [ + 'agricola-sat18-strips', 'airport', 'assembly', + 'barman-sat11-strips', 'barman-sat14-strips', 'blocks', + 'caldera-sat18-adl', 'caldera-split-sat18-adl', 'cavediving-14-adl', + 'childsnack-sat14-strips', 'citycar-sat14-adl', + 'data-network-sat18-strips', 'depot', 'driverlog', + 'elevators-sat08-strips', 'elevators-sat11-strips', + 'flashfill-sat18-adl', 'floortile-sat11-strips', + 'floortile-sat14-strips', 'freecell', 'ged-sat14-strips', 'grid', + 'gripper', 'hiking-sat14-strips', 'logistics00', 'logistics98', + 'maintenance-sat14-adl', 'miconic', 'miconic-fulladl', + 'miconic-simpleadl', 'movie', 'mprime', 'mystery', + 'nomystery-sat11-strips', 'nurikabe-sat18-adl', 'openstacks', + 'openstacks-sat08-adl', 'openstacks-sat08-strips', + 'openstacks-sat11-strips', 'openstacks-sat14-strips', + 'openstacks-strips', 'optical-telegraphs', + 'organic-synthesis-sat18-strips', + 'organic-synthesis-split-sat18-strips', 'parcprinter-08-strips', + 'parcprinter-sat11-strips', 'parking-sat11-strips', + 'parking-sat14-strips', 'pathways', 'pathways-noneg', + 'pegsol-08-strips', 'pegsol-sat11-strips', 'philosophers', + 'pipesworld-notankage', 'pipesworld-tankage', 'psr-large', + 'psr-middle', 'psr-small', 'rovers', 'satellite', + 'scanalyzer-08-strips', 'scanalyzer-sat11-strips', 'schedule', + 'settlers-sat18-adl', 'snake-sat18-strips', 'sokoban-sat08-strips', + 'sokoban-sat11-strips', 'spider-sat18-strips', 'storage', + 'termes-sat18-strips', 'tetris-sat14-strips', + 'thoughtful-sat14-strips', 'tidybot-sat11-strips', 'tpp', + 'transport-sat08-strips', 'transport-sat11-strips', + 'transport-sat14-strips', 'trucks', 'trucks-strips', + 'visitall-sat11-strips', 'visitall-sat14-strips', + 'woodworking-sat08-strips', 'woodworking-sat11-strips', + 'zenotravel'] + + +def get_script(): + """Get file name of main script.""" + return tools.get_script_path() + + +def get_script_dir(): + """Get directory of main script. + + Usually a relative directory (depends on how it was called by the user.)""" + return os.path.dirname(get_script()) + + +def get_experiment_name(): + """Get name for experiment. + + Derived from the absolute filename of the main script, e.g. + "/ham/spam/eggs.py" => "spam-eggs".""" + script = os.path.abspath(get_script()) + script_dir = os.path.basename(os.path.dirname(script)) + script_base = os.path.splitext(os.path.basename(script))[0] + return "%s-%s" % (script_dir, script_base) + + +def get_data_dir(): + """Get data dir for the experiment. + + This is the subdirectory "data" of the directory containing + the main script.""" + return os.path.join(get_script_dir(), "data", get_experiment_name()) + + +def get_repo_base(): + """Get base directory of the repository, as an absolute path. + + Search upwards in the directory tree from the main script until a + directory with a subdirectory named ".hg" is found. + + Abort if the repo base cannot be found.""" + path = os.path.abspath(get_script_dir()) + while os.path.dirname(path) != path: + if os.path.exists(os.path.join(path, ".hg")): + return path + path = os.path.dirname(path) + sys.exit("repo base could not be found") + + +def is_running_on_cluster(): + node = platform.node() + return node.endswith(".scicore.unibas.ch") or node.endswith(".cluster.bc2.ch") + + +def is_test_run(): + return ARGS.test_run == "yes" or ( + ARGS.test_run == "auto" and not is_running_on_cluster()) + + +def get_algo_nick(revision, config_nick): + return "{revision}-{config_nick}".format(**locals()) + + +class IssueConfig(object): + """Hold information about a planner configuration. + + See FastDownwardExperiment.add_algorithm() for documentation of the + constructor's options. + + """ + def __init__(self, nick, component_options, + build_options=None, driver_options=None): + self.nick = nick + self.component_options = component_options + self.build_options = build_options + self.driver_options = driver_options + + +class IssueExperiment(FastDownwardExperiment): + """Subclass of FastDownwardExperiment with some convenience features.""" + + DEFAULT_TEST_SUITE = ["depot:p01.pddl", "gripper:prob01.pddl"] + + DEFAULT_TABLE_ATTRIBUTES = [ + "cost", + "coverage", + "error", + "evaluations", + "expansions", + "expansions_until_last_jump", + "generated", + "memory", + "planner_memory", + "planner_time", + "quality", + "run_dir", + "score_evaluations", + "score_expansions", + "score_generated", + "score_memory", + "score_search_time", + "score_total_time", + "search_time", + "total_time", + ] + + DEFAULT_SCATTER_PLOT_ATTRIBUTES = [ + "evaluations", + "expansions", + "expansions_until_last_jump", + "initial_h_value", + "memory", + "search_time", + "total_time", + ] + + PORTFOLIO_ATTRIBUTES = [ + "cost", + "coverage", + "error", + "plan_length", + "run_dir", + ] + + def __init__(self, revisions=None, configs=None, path=None, **kwargs): + """ + + You can either specify both *revisions* and *configs* or none + of them. If they are omitted, you will need to call + exp.add_algorithm() manually. + + If *revisions* is given, it must be a non-empty list of + revision identifiers, which specify which planner versions to + use in the experiment. The same versions are used for + translator, preprocessor and search. :: + + IssueExperiment(revisions=["issue123", "4b3d581643"], ...) + + If *configs* is given, it must be a non-empty list of + IssueConfig objects. :: + + IssueExperiment(..., configs=[ + IssueConfig("ff", ["--search", "eager_greedy(ff())"]), + IssueConfig( + "lama", [], + driver_options=["--alias", "seq-sat-lama-2011"]), + ]) + + If *path* is specified, it must be the path to where the + experiment should be built (e.g. + /home/john/experiments/issue123/exp01/). If omitted, the + experiment path is derived automatically from the main + script's filename. Example:: + + script = experiments/issue123/exp01.py --> + path = experiments/issue123/data/issue123-exp01/ + + """ + + path = path or get_data_dir() + + FastDownwardExperiment.__init__(self, path=path, **kwargs) + + if (revisions and not configs) or (not revisions and configs): + raise ValueError( + "please provide either both or none of revisions and configs") + + for rev in revisions: + for config in configs: + self.add_algorithm( + get_algo_nick(rev, config.nick), + get_repo_base(), + rev, + config.component_options, + build_options=config.build_options, + driver_options=config.driver_options) + + self._revisions = revisions + self._configs = configs + + @classmethod + def _is_portfolio(cls, config_nick): + return "fdss" in config_nick + + @classmethod + def get_supported_attributes(cls, config_nick, attributes): + if cls._is_portfolio(config_nick): + return [attr for attr in attributes + if attr in cls.PORTFOLIO_ATTRIBUTES] + return attributes + + def add_absolute_report_step(self, **kwargs): + """Add step that makes an absolute report. + + Absolute reports are useful for experiments that don't compare + revisions. + + The report is written to the experiment evaluation directory. + + All *kwargs* will be passed to the AbsoluteReport class. If the + keyword argument *attributes* is not specified, a default list + of attributes is used. :: + + exp.add_absolute_report_step(attributes=["coverage"]) + + """ + kwargs.setdefault("attributes", self.DEFAULT_TABLE_ATTRIBUTES) + report = AbsoluteReport(**kwargs) + outfile = os.path.join( + self.eval_dir, + get_experiment_name() + "." + report.output_format) + self.add_report(report, outfile=outfile) + self.add_step( + 'publish-absolute-report', subprocess.call, ['publish', outfile]) + + def add_comparison_table_step(self, **kwargs): + """Add a step that makes pairwise revision comparisons. + + Create comparative reports for all pairs of Fast Downward + revisions. Each report pairs up the runs of the same config and + lists the two absolute attribute values and their difference + for all attributes in kwargs["attributes"]. + + All *kwargs* will be passed to the CompareConfigsReport class. + If the keyword argument *attributes* is not specified, a + default list of attributes is used. :: + + exp.add_comparison_table_step(attributes=["coverage"]) + + """ + kwargs.setdefault("attributes", self.DEFAULT_TABLE_ATTRIBUTES) + + def make_comparison_tables(): + for rev1, rev2 in itertools.combinations(self._revisions, 2): + compared_configs = [] + for config in self._configs: + config_nick = config.nick + compared_configs.append( + ("%s-%s" % (rev1, config_nick), + "%s-%s" % (rev2, config_nick), + "Diff (%s)" % config_nick)) + report = ComparativeReport(compared_configs, **kwargs) + outfile = os.path.join( + self.eval_dir, + "%s-%s-%s-compare.%s" % ( + self.name, rev1, rev2, report.output_format)) + report(self.eval_dir, outfile) + + def publish_comparison_tables(): + for rev1, rev2 in itertools.combinations(self._revisions, 2): + outfile = os.path.join( + self.eval_dir, + "%s-%s-%s-compare.html" % (self.name, rev1, rev2)) + subprocess.call(["publish", outfile]) + + self.add_step("make-comparison-tables", make_comparison_tables) + self.add_step( + "publish-comparison-tables", publish_comparison_tables) + + def add_scatter_plot_step(self, relative=False, attributes=None): + """Add step creating (relative) scatter plots for all revision pairs. + + Create a scatter plot for each combination of attribute, + configuration and revisions pair. If *attributes* is not + specified, a list of common scatter plot attributes is used. + For portfolios all attributes except "cost", "coverage" and + "plan_length" will be ignored. :: + + exp.add_scatter_plot_step(attributes=["expansions"]) + + """ + if relative: + report_class = RelativeScatterPlotReport + scatter_dir = os.path.join(self.eval_dir, "scatter-relative") + step_name = "make-relative-scatter-plots" + else: + report_class = ScatterPlotReport + scatter_dir = os.path.join(self.eval_dir, "scatter-absolute") + step_name = "make-absolute-scatter-plots" + if attributes is None: + attributes = self.DEFAULT_SCATTER_PLOT_ATTRIBUTES + + def make_scatter_plot(config_nick, rev1, rev2, attribute): + name = "-".join([self.name, rev1, rev2, attribute, config_nick]) + print "Make scatter plot for", name + algo1 = get_algo_nick(rev1, config_nick) + algo2 = get_algo_nick(rev2, config_nick) + report = report_class( + filter_algorithm=[algo1, algo2], + attributes=[attribute], + get_category=lambda run1, run2: run1["domain"]) + report( + self.eval_dir, + os.path.join(scatter_dir, rev1 + "-" + rev2, name)) + + def make_scatter_plots(): + for config in self._configs: + for rev1, rev2 in itertools.combinations(self._revisions, 2): + for attribute in self.get_supported_attributes( + config.nick, attributes): + make_scatter_plot(config.nick, rev1, rev2, attribute) + + self.add_step(step_name, make_scatter_plots) diff --git a/experiments/issue908/relativescatter.py b/experiments/issue908/relativescatter.py new file mode 100644 index 0000000000..f74cb6e721 --- /dev/null +++ b/experiments/issue908/relativescatter.py @@ -0,0 +1,105 @@ +# -*- coding: utf-8 -*- + +from collections import defaultdict + +from matplotlib import ticker + +from downward.reports.scatter import ScatterPlotReport +from downward.reports.plot import PlotReport, Matplotlib, MatplotlibPlot + + +# TODO: handle outliers + +# TODO: this is mostly copied from ScatterMatplotlib (scatter.py) +class RelativeScatterMatplotlib(Matplotlib): + @classmethod + def _plot(cls, report, axes, categories, styles): + # Display grid + axes.grid(b=True, linestyle='-', color='0.75') + + has_points = False + # Generate the scatter plots + for category, coords in sorted(categories.items()): + X, Y = zip(*coords) + axes.scatter(X, Y, s=42, label=category, **styles[category]) + if X and Y: + has_points = True + + if report.xscale == 'linear' or report.yscale == 'linear': + plot_size = report.missing_val * 1.01 + else: + plot_size = report.missing_val * 1.25 + + # make 5 ticks above and below 1 + yticks = [] + tick_step = report.ylim_top**(1/5.0) + for i in xrange(-5, 6): + yticks.append(tick_step**i) + axes.set_yticks(yticks) + axes.get_yaxis().set_major_formatter(ticker.ScalarFormatter()) + + axes.set_xlim(report.xlim_left or -1, report.xlim_right or plot_size) + axes.set_ylim(report.ylim_bottom or -1, report.ylim_top or plot_size) + + for axis in [axes.xaxis, axes.yaxis]: + MatplotlibPlot.change_axis_formatter( + axis, + report.missing_val if report.show_missing else None) + return has_points + + +class RelativeScatterPlotReport(ScatterPlotReport): + """ + Generate a scatter plot that shows a relative comparison of two + algorithms with regard to the given attribute. The attribute value + of algorithm 1 is shown on the x-axis and the relation to the value + of algorithm 2 on the y-axis. + """ + + def __init__(self, show_missing=True, get_category=None, **kwargs): + ScatterPlotReport.__init__(self, show_missing, get_category, **kwargs) + if self.output_format == 'tex': + raise "not supported" + else: + self.writer = RelativeScatterMatplotlib + + def _fill_categories(self, runs): + # We discard the *runs* parameter. + # Map category names to value tuples + categories = defaultdict(list) + self.ylim_bottom = 2 + self.ylim_top = 0.5 + self.xlim_left = float("inf") + for (domain, problem), runs in self.problem_runs.items(): + if len(runs) != 2: + continue + run1, run2 = runs + assert (run1['algorithm'] == self.algorithms[0] and + run2['algorithm'] == self.algorithms[1]) + val1 = run1.get(self.attribute) + val2 = run2.get(self.attribute) + if val1 is None or val2 is None: + continue + category = self.get_category(run1, run2) + assert val1 > 0, (domain, problem, self.algorithms[0], val1) + assert val2 > 0, (domain, problem, self.algorithms[1], val2) + x = val1 + y = val2 / float(val1) + + categories[category].append((x, y)) + + self.ylim_top = max(self.ylim_top, y) + self.ylim_bottom = min(self.ylim_bottom, y) + self.xlim_left = min(self.xlim_left, x) + + # center around 1 + if self.ylim_bottom < 1: + self.ylim_top = max(self.ylim_top, 1 / float(self.ylim_bottom)) + if self.ylim_top > 1: + self.ylim_bottom = min(self.ylim_bottom, 1 / float(self.ylim_top)) + return categories + + def _set_scales(self, xscale, yscale): + # ScatterPlot uses log-scaling on the x-axis by default. + PlotReport._set_scales( + self, xscale or self.attribute.scale or 'log', 'log') diff --git a/experiments/issue908/v1.py b/experiments/issue908/v1.py new file mode 100755 index 0000000000..3006c58ee6 --- /dev/null +++ b/experiments/issue908/v1.py @@ -0,0 +1,54 @@ +#! /usr/bin/env python +# -*- coding: utf-8 -*- + +import itertools +import os + +from lab.environments import LocalEnvironment, BaselSlurmEnvironment + +from downward.reports.compare import ComparativeReport + +import common_setup +from common_setup import IssueConfig, IssueExperiment +from relativescatter import RelativeScatterPlotReport + +DIR = os.path.dirname(os.path.abspath(__file__)) +SCRIPT_NAME = os.path.splitext(os.path.basename(__file__))[0] +BENCHMARKS_DIR = os.environ["DOWNWARD_BENCHMARKS"] +REVISIONS = ["issue908-base", "issue908-v1"] +CONFIGS = [ + IssueConfig("cpdbs-hc", ['--search', 'astar(cpdbs(hillclimbing))']), + IssueConfig("cpdbs-sys2", ['--search', 'astar(cpdbs(systematic(2)))']), +] + +SUITE = common_setup.DEFAULT_OPTIMAL_SUITE +ENVIRONMENT = BaselSlurmEnvironment( + partition="infai_2", + email="silvan.sievers@unibas.ch", + export=["PATH", "DOWNWARD_BENCHMARKS"]) + +if common_setup.is_test_run(): + SUITE = IssueExperiment.DEFAULT_TEST_SUITE + ENVIRONMENT = LocalEnvironment(processes=1) + +exp = IssueExperiment( + revisions=REVISIONS, + configs=CONFIGS, + environment=ENVIRONMENT, +) +exp.add_suite(BENCHMARKS_DIR, SUITE) + +exp.add_parser(exp.EXITCODE_PARSER) +exp.add_parser(exp.TRANSLATOR_PARSER) +exp.add_parser(exp.SINGLE_SEARCH_PARSER) +exp.add_parser(exp.PLANNER_PARSER) + +exp.add_step('build', exp.build) +exp.add_step('start', exp.start_runs) +exp.add_fetcher(name='fetch') + +#exp.add_absolute_report_step() +exp.add_comparison_table_step() +exp.add_scatter_plot_step(relative=True, attributes=["search_time", "total_time"]) + +exp.run_steps() From 1837a323562ffb465a808095f2dce1680579b576 Mon Sep 17 00:00:00 2001 From: Silvan Sievers Date: Wed, 13 Mar 2019 10:48:16 +0100 Subject: [PATCH 08/39] [issue908] add parser --- experiments/issue908/parser.py | 8 ++++++++ experiments/issue908/v1.py | 10 +++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) create mode 100755 experiments/issue908/parser.py diff --git a/experiments/issue908/parser.py b/experiments/issue908/parser.py new file mode 100755 index 0000000000..6352d0b859 --- /dev/null +++ b/experiments/issue908/parser.py @@ -0,0 +1,8 @@ +#! /usr/bin/env python + +from lab.parser import Parser + +parser = Parser() +parser.add_pattern('computation_time', 'computation time: (.+)s', required=False, type=float) + +parser.parse() diff --git a/experiments/issue908/v1.py b/experiments/issue908/v1.py index 3006c58ee6..1ca3625dc1 100755 --- a/experiments/issue908/v1.py +++ b/experiments/issue908/v1.py @@ -5,6 +5,7 @@ import os from lab.environments import LocalEnvironment, BaselSlurmEnvironment +from lab.reports import Attribute, geometric_mean from downward.reports.compare import ComparativeReport @@ -42,13 +43,20 @@ exp.add_parser(exp.TRANSLATOR_PARSER) exp.add_parser(exp.SINGLE_SEARCH_PARSER) exp.add_parser(exp.PLANNER_PARSER) +exp.add_parser('parser.py') exp.add_step('build', exp.build) exp.add_step('start', exp.start_runs) exp.add_fetcher(name='fetch') +exp.add_parse_again_step() + +attributes=exp.DEFAULT_TABLE_ATTRIBUTES +attributes.append( + Attribute('computation_time', absolute=False, min_wins=True, functions=[geometric_mean]), +) #exp.add_absolute_report_step() -exp.add_comparison_table_step() +exp.add_comparison_table_step(attributes=attributes) exp.add_scatter_plot_step(relative=True, attributes=["search_time", "total_time"]) exp.run_steps() From 198b8057cc92335bc367f8e6db0915bb71cec044 Mon Sep 17 00:00:00 2001 From: Silvan Sievers Date: Wed, 13 Mar 2019 15:04:15 +0100 Subject: [PATCH 09/39] [issue908] parse more detailed runtimes --- experiments/issue908/parser.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/experiments/issue908/parser.py b/experiments/issue908/parser.py index 6352d0b859..0236c80fad 100755 --- a/experiments/issue908/parser.py +++ b/experiments/issue908/parser.py @@ -3,6 +3,8 @@ from lab.parser import Parser parser = Parser() -parser.add_pattern('computation_time', 'computation time: (.+)s', required=False, type=float) +parser.add_pattern('generator_computation_time', 'generator computation time: (.+)s', required=False, type=float) +parser.add_pattern('cpdbs_computation_time', 'Canonical PDB heuristic computation time: (.+)s', required=False, type=float) +parser.add_pattern('dominance_pruning_time', 'Dominance pruning took (.+)s', required=False, type=float) parser.parse() From 27a3cdbe2e82d905b09302fac1b65c893ac56cb9 Mon Sep 17 00:00:00 2001 From: Silvan Sievers Date: Wed, 13 Mar 2019 15:15:35 +0100 Subject: [PATCH 10/39] [issue908] change pruning to in-place modify patterns, PDBs, and max add subsets --- src/search/pdbs/canonical_pdbs_heuristic.cc | 34 ++++++-- src/search/pdbs/dominance_pruning.cc | 87 +++++++++------------ src/search/pdbs/dominance_pruning.h | 10 +-- 3 files changed, 71 insertions(+), 60 deletions(-) diff --git a/src/search/pdbs/canonical_pdbs_heuristic.cc b/src/search/pdbs/canonical_pdbs_heuristic.cc index 07cf00470e..b3b3a91d8d 100644 --- a/src/search/pdbs/canonical_pdbs_heuristic.cc +++ b/src/search/pdbs/canonical_pdbs_heuristic.cc @@ -24,19 +24,39 @@ CanonicalPDBs get_canonical_pdbs_from_options( cout << "Initializing canonical PDB heuristic..." << endl; PatternCollectionInformation pattern_collection_info = pattern_generator->generate(task); + shared_ptr patterns = + pattern_collection_info.get_patterns(); + /* + We compute PDBs and max additive subsets here (if they have not been + computed before) so that their computation is not taken into account + for dominance pruning time. + */ + shared_ptr pdbs = pattern_collection_info.get_pdbs(); + shared_ptr max_additive_subsets = + pattern_collection_info.get_max_additive_subsets(); double max_time_dominance_pruning = opts.get("max_time_dominance_pruning"); if (max_time_dominance_pruning > 0.0) { int num_variables = TaskProxy(*task).get_variables().size(); - pattern_collection_info = prune_dominated_subsets( - pattern_collection_info, num_variables, max_time_dominance_pruning); + /* + In principle, we could pass PatternCollectionInformation here. + However, PatternCollectionInformation is not intended to be changed. + Dominance pruning could also be computed without having access to + the PDBs, but since we want to delete patterns, we also want to + update the list of corresponding PDBs so they are synchronized. + + In the long term, we plan to have patterns and their PDBs live + together, in which case we would only need to pass their container + and the max additive subsets. + */ + prune_dominated_subsets( + *patterns, + *pdbs, + *max_additive_subsets, + num_variables, + max_time_dominance_pruning); } - /* Compute pdbs and max additive subsets here so that they count towards - the total computation time of the heuristic. */ - shared_ptr pdbs = pattern_collection_info.get_pdbs(); - shared_ptr max_additive_subsets = - pattern_collection_info.get_max_additive_subsets(); // Do not dump pattern collections for size reasons. dump_pattern_collection_generation_statistics( "Canonical PDB heuristic", timer(), pattern_collection_info, false); diff --git a/src/search/pdbs/dominance_pruning.cc b/src/search/pdbs/dominance_pruning.cc index 7a6772dbbb..752aa663c2 100644 --- a/src/search/pdbs/dominance_pruning.cc +++ b/src/search/pdbs/dominance_pruning.cc @@ -1,6 +1,5 @@ #include "dominance_pruning.h" -#include "pattern_collection_information.h" #include "pattern_database.h" #include "../utils/countdown_timer.h" @@ -8,7 +7,7 @@ #include #include -#include +#include #include using namespace std; @@ -20,12 +19,10 @@ class Pruner { "patterns" is the vector of patterns used. Each pattern is a vector of variable IDs. - This is logically const (only changed in the constructor). "collections" is the vector of pattern collections. Each collection is a vector, where each int is an index into "patterns". - This is logically const (only changed in the constructor). The algorithm works by setting a "current pattern collection" against which other patterns and collections can be tested for @@ -48,9 +45,9 @@ class Pruner { current collection is set. */ - const int num_variables; const PatternCollection &patterns; const MaxAdditivePDBSubsets &collections; + const int num_variables; vector pattern_index; vector dominated_patterns; @@ -111,11 +108,13 @@ class Pruner { } public: - Pruner(PatternCollectionInformation &pci, - int num_variables) : - num_variables(num_variables), - patterns(*pci.get_patterns()), - collections(*pci.get_max_additive_subsets()) { + Pruner( + const PatternCollection &patterns, + const MaxAdditivePDBSubsets &max_additive_subsets, + int num_variables) + : patterns(patterns), + collections(max_additive_subsets), + num_variables(num_variables) { } vector get_pruned_collections(const utils::CountdownTimer &timer) { @@ -151,53 +150,48 @@ class Pruner { } }; -PatternCollectionInformation prune_dominated_subsets( - PatternCollectionInformation &pci, +void prune_dominated_subsets( + PatternCollection &patterns, + PDBCollection &pdbs, + MaxAdditivePDBSubsets &max_additive_subsets, int num_variables, double max_time) { cout << "Running dominance pruning..." << endl; utils::CountdownTimer timer(max_time); + int num_patterns = patterns.size(); + int num_subsets = max_additive_subsets.size(); + vector pruned = Pruner( - pci, + patterns, + max_additive_subsets, num_variables).get_pruned_collections(timer); - const MaxAdditivePDBSubsets &max_additive_subsets = - *pci.get_max_additive_subsets(); - shared_ptr remaining_max_additive_subsets = - make_shared(); - unordered_set remaining_pattern_indices; + MaxAdditivePDBSubsets remaining_max_additive_subsets; + set remaining_pattern_indices; for (size_t i = 0; i < max_additive_subsets.size(); ++i) { if (!pruned[i]) { - const vector &subset = max_additive_subsets[i]; - remaining_max_additive_subsets->push_back(subset); + vector &subset = max_additive_subsets[i]; for (int pattern_index : subset) { remaining_pattern_indices.insert(pattern_index); } + remaining_max_additive_subsets.push_back(move(subset)); } } - /* - TODO: we shouldn't call get_pdbs() here because they may not be computed - and need not to be computed here. We currently do this because the only - user of this class is the CPDB heuristic for which we know it computes - PDBs anyways. Doing so allows us here to remove pruned patterns *and - PDBs*. - */ - const PatternCollection &patterns = *pci.get_patterns(); - const PDBCollection &pdbs = *pci.get_pdbs(); - shared_ptr remaining_patterns = - make_shared(); - shared_ptr remaining_pdbs = - make_shared(); - vector old_to_new_pattern_index(patterns.size(), -1); + int num_remaining_patterns = remaining_pattern_indices.size(); + PatternCollection remaining_patterns; + PDBCollection remaining_pdbs; + remaining_patterns.reserve(num_remaining_patterns); + remaining_pdbs.reserve(num_remaining_patterns); + vector old_to_new_pattern_index(num_patterns, -1); for (int old_pattern_index : remaining_pattern_indices) { - int new_pattern_index = remaining_patterns->size(); + int new_pattern_index = remaining_patterns.size(); old_to_new_pattern_index[old_pattern_index] = new_pattern_index; - remaining_patterns->push_back(patterns[old_pattern_index]); - remaining_pdbs->push_back(pdbs[old_pattern_index]); + remaining_patterns.push_back(move(patterns[old_pattern_index])); + remaining_pdbs.push_back(move(pdbs[old_pattern_index])); } - for (vector &subset : *remaining_max_additive_subsets) { + for (vector &subset : remaining_max_additive_subsets) { for (size_t i = 0; i < subset.size(); ++i) { int old_pattern_index = subset[i]; int new_pattern_index = old_to_new_pattern_index[old_pattern_index]; @@ -206,21 +200,18 @@ PatternCollectionInformation prune_dominated_subsets( } } - int num_collections = max_additive_subsets.size(); - int num_pruned_collections = num_collections - remaining_max_additive_subsets->size(); - cout << "Pruned " << num_pruned_collections << " of " << num_collections + int num_pruned_collections = num_subsets - remaining_max_additive_subsets.size(); + cout << "Pruned " << num_pruned_collections << " of " << num_subsets << " maximal additive subsets" << endl; - int num_patterns = patterns.size(); - int num_pruned_patterns = num_patterns - remaining_patterns->size(); + int num_pruned_patterns = num_patterns - num_remaining_patterns; cout << "Pruned " << num_pruned_patterns << " of " << num_patterns << " PDBs" << endl; - cout << "Dominance pruning took " << timer.get_elapsed_time() << endl; + patterns.swap(remaining_patterns); + pdbs.swap(remaining_pdbs); + max_additive_subsets.swap(remaining_max_additive_subsets); - PatternCollectionInformation result(pci.get_task_proxy(), remaining_patterns); - result.set_pdbs(remaining_pdbs); - result.set_max_additive_subsets(remaining_max_additive_subsets); - return result; + cout << "Dominance pruning took " << timer.get_elapsed_time() << endl; } } diff --git a/src/search/pdbs/dominance_pruning.h b/src/search/pdbs/dominance_pruning.h index 1e3e7d0372..67dc300351 100644 --- a/src/search/pdbs/dominance_pruning.h +++ b/src/search/pdbs/dominance_pruning.h @@ -1,18 +1,18 @@ #ifndef PDBS_DOMINANCE_PRUNING_H #define PDBS_DOMINANCE_PRUNING_H -#include +#include "types.h" namespace pdbs { -class PatternCollectionInformation; - /* Collection superset dominates collection subset iff for every pattern p_subset in subset there is a pattern p_superset in superset where p_superset is a superset of p_subset. */ -extern PatternCollectionInformation prune_dominated_subsets( - PatternCollectionInformation &pci, +extern void prune_dominated_subsets( + PatternCollection &patterns, + PDBCollection &pdbs, + MaxAdditivePDBSubsets &max_additive_subsets, int num_variables, double max_time); } From 74a248295a85c3751fa8658d1e35a77ca99c496d Mon Sep 17 00:00:00 2001 From: Silvan Sievers Date: Wed, 13 Mar 2019 15:19:06 +0100 Subject: [PATCH 11/39] [issue908] reduce diff to default --- src/search/pdbs/canonical_pdbs.cc | 4 ++-- src/search/pdbs/canonical_pdbs.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/search/pdbs/canonical_pdbs.cc b/src/search/pdbs/canonical_pdbs.cc index 874b55293a..00a65871d2 100644 --- a/src/search/pdbs/canonical_pdbs.cc +++ b/src/search/pdbs/canonical_pdbs.cc @@ -11,8 +11,8 @@ using namespace std; namespace pdbs { CanonicalPDBs::CanonicalPDBs( - shared_ptr pdbs, - shared_ptr max_additive_subsets) + const shared_ptr &pdbs, + const shared_ptr &max_additive_subsets) : pdbs(pdbs), max_additive_subsets(max_additive_subsets) { assert(pdbs); assert(max_additive_subsets); diff --git a/src/search/pdbs/canonical_pdbs.h b/src/search/pdbs/canonical_pdbs.h index 62f6a374e7..ed3260467e 100644 --- a/src/search/pdbs/canonical_pdbs.h +++ b/src/search/pdbs/canonical_pdbs.h @@ -14,8 +14,8 @@ class CanonicalPDBs { public: CanonicalPDBs( - std::shared_ptr pdbs, - std::shared_ptr max_additive_subsets); + const std::shared_ptr &pdbs, + const std::shared_ptr &max_additive_subsets); ~CanonicalPDBs() = default; int get_value(const State &state) const; From 635a4ed6d8980a35ce0447fdde42112efc01c6d5 Mon Sep 17 00:00:00 2001 From: Silvan Sievers Date: Wed, 13 Mar 2019 15:27:10 +0100 Subject: [PATCH 12/39] [issue908] v2 exp --- experiments/issue908/v2.py | 63 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100755 experiments/issue908/v2.py diff --git a/experiments/issue908/v2.py b/experiments/issue908/v2.py new file mode 100755 index 0000000000..2ae5164a66 --- /dev/null +++ b/experiments/issue908/v2.py @@ -0,0 +1,63 @@ +#! /usr/bin/env python +# -*- coding: utf-8 -*- + +import itertools +import os + +from lab.environments import LocalEnvironment, BaselSlurmEnvironment +from lab.reports import Attribute, geometric_mean + +from downward.reports.compare import ComparativeReport + +import common_setup +from common_setup import IssueConfig, IssueExperiment +from relativescatter import RelativeScatterPlotReport + +DIR = os.path.dirname(os.path.abspath(__file__)) +SCRIPT_NAME = os.path.splitext(os.path.basename(__file__))[0] +BENCHMARKS_DIR = os.environ["DOWNWARD_BENCHMARKS"] +REVISIONS = ["issue908-base", "issue908-v2"] +CONFIGS = [ + IssueConfig("cpdbs-hc", ['--search', 'astar(cpdbs(hillclimbing))']), + IssueConfig("cpdbs-sys2", ['--search', 'astar(cpdbs(systematic(2)))']), +] + +SUITE = common_setup.DEFAULT_OPTIMAL_SUITE +ENVIRONMENT = BaselSlurmEnvironment( + partition="infai_1", + email="silvan.sievers@unibas.ch", + export=["PATH", "DOWNWARD_BENCHMARKS"]) + +if common_setup.is_test_run(): + SUITE = IssueExperiment.DEFAULT_TEST_SUITE + ENVIRONMENT = LocalEnvironment(processes=1) + +exp = IssueExperiment( + revisions=REVISIONS, + configs=CONFIGS, + environment=ENVIRONMENT, +) +exp.add_suite(BENCHMARKS_DIR, SUITE) + +exp.add_parser(exp.EXITCODE_PARSER) +exp.add_parser(exp.TRANSLATOR_PARSER) +exp.add_parser(exp.SINGLE_SEARCH_PARSER) +exp.add_parser(exp.PLANNER_PARSER) +exp.add_parser('parser.py') + +exp.add_step('build', exp.build) +exp.add_step('start', exp.start_runs) +exp.add_fetcher(name='fetch') + +attributes=exp.DEFAULT_TABLE_ATTRIBUTES +attributes.extend([ + Attribute('generator_computation_time', absolute=False, min_wins=True, functions=[geometric_mean]), + Attribute('cpdbs_computation_time', absolute=False, min_wins=True, functions=[geometric_mean]), + Attribute('dominance_pruning_time', absolute=False, min_wins=True, functions=[geometric_mean]), +]) + +#exp.add_absolute_report_step() +exp.add_comparison_table_step(attributes=attributes) +exp.add_scatter_plot_step(relative=True, attributes=['generator_computation_time', 'cpdbs_computation_time', 'dominance_pruning_time', "search_time", "total_time"]) + +exp.run_steps() From 34757df58edb60f5895a352995fa3f67ad13870d Mon Sep 17 00:00:00 2001 From: Silvan Sievers Date: Wed, 13 Mar 2019 21:13:08 +0100 Subject: [PATCH 13/39] [issue908] compute PDB values once and then compute the max over max. additive subsets over the stored values --- src/search/pdbs/canonical_pdbs.cc | 16 ++++++++++------ src/search/pdbs/canonical_pdbs.h | 2 ++ 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/search/pdbs/canonical_pdbs.cc b/src/search/pdbs/canonical_pdbs.cc index 00a65871d2..f01c77c85a 100644 --- a/src/search/pdbs/canonical_pdbs.cc +++ b/src/search/pdbs/canonical_pdbs.cc @@ -16,21 +16,25 @@ CanonicalPDBs::CanonicalPDBs( : pdbs(pdbs), max_additive_subsets(max_additive_subsets) { assert(pdbs); assert(max_additive_subsets); + h_values.reserve(pdbs->size()); } int CanonicalPDBs::get_value(const State &state) const { // If we have an empty collection, then max_additive_subsets = { \emptyset }. assert(!max_additive_subsets->empty()); int max_h = 0; + h_values.clear(); + for (const shared_ptr &pdb : *pdbs) { + int h_value = pdb->get_value(state); + if (h_value == numeric_limits::max()) { + return numeric_limits::max(); + } + h_values.push_back(h_value); + } for (const vector &subset : *max_additive_subsets) { int subset_h = 0; for (int pdb_index : subset) { - /* Experiments showed that it is faster to recompute the - h values than to cache them in an unordered_map. */ - int h = (*pdbs)[pdb_index]->get_value(state); - if (h == numeric_limits::max()) - return numeric_limits::max(); - subset_h += h; + subset_h += h_values[pdb_index]; } max_h = max(max_h, subset_h); } diff --git a/src/search/pdbs/canonical_pdbs.h b/src/search/pdbs/canonical_pdbs.h index ed3260467e..3148981ebf 100644 --- a/src/search/pdbs/canonical_pdbs.h +++ b/src/search/pdbs/canonical_pdbs.h @@ -11,6 +11,8 @@ namespace pdbs { class CanonicalPDBs { std::shared_ptr pdbs; std::shared_ptr max_additive_subsets; + // Used to avoid allocating memory in each call to get_value. + mutable std::vector h_values; public: CanonicalPDBs( From 0a9fa62be57d28683e11d7cf060f85e8a783f820 Mon Sep 17 00:00:00 2001 From: Silvan Sievers Date: Wed, 13 Mar 2019 21:13:40 +0100 Subject: [PATCH 14/39] [issue908] v3 exp --- experiments/issue908/v3.py | 63 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100755 experiments/issue908/v3.py diff --git a/experiments/issue908/v3.py b/experiments/issue908/v3.py new file mode 100755 index 0000000000..31bf0b5fa5 --- /dev/null +++ b/experiments/issue908/v3.py @@ -0,0 +1,63 @@ +#! /usr/bin/env python +# -*- coding: utf-8 -*- + +import itertools +import os + +from lab.environments import LocalEnvironment, BaselSlurmEnvironment +from lab.reports import Attribute, geometric_mean + +from downward.reports.compare import ComparativeReport + +import common_setup +from common_setup import IssueConfig, IssueExperiment +from relativescatter import RelativeScatterPlotReport + +DIR = os.path.dirname(os.path.abspath(__file__)) +SCRIPT_NAME = os.path.splitext(os.path.basename(__file__))[0] +BENCHMARKS_DIR = os.environ["DOWNWARD_BENCHMARKS"] +REVISIONS = ["issue908-base", "issue908-v3"] +CONFIGS = [ + IssueConfig("cpdbs-hc", ['--search', 'astar(cpdbs(hillclimbing))']), + IssueConfig("cpdbs-sys2", ['--search', 'astar(cpdbs(systematic(2)))']), +] + +SUITE = common_setup.DEFAULT_OPTIMAL_SUITE +ENVIRONMENT = BaselSlurmEnvironment( + partition="infai_1", + email="silvan.sievers@unibas.ch", + export=["PATH", "DOWNWARD_BENCHMARKS"]) + +if common_setup.is_test_run(): + SUITE = IssueExperiment.DEFAULT_TEST_SUITE + ENVIRONMENT = LocalEnvironment(processes=1) + +exp = IssueExperiment( + revisions=REVISIONS, + configs=CONFIGS, + environment=ENVIRONMENT, +) +exp.add_suite(BENCHMARKS_DIR, SUITE) + +exp.add_parser(exp.EXITCODE_PARSER) +exp.add_parser(exp.TRANSLATOR_PARSER) +exp.add_parser(exp.SINGLE_SEARCH_PARSER) +exp.add_parser(exp.PLANNER_PARSER) +exp.add_parser('parser.py') + +exp.add_step('build', exp.build) +exp.add_step('start', exp.start_runs) +exp.add_fetcher(name='fetch') + +attributes=exp.DEFAULT_TABLE_ATTRIBUTES +attributes.extend([ + Attribute('generator_computation_time', absolute=False, min_wins=True, functions=[geometric_mean]), + Attribute('cpdbs_computation_time', absolute=False, min_wins=True, functions=[geometric_mean]), + Attribute('dominance_pruning_time', absolute=False, min_wins=True, functions=[geometric_mean]), +]) + +#exp.add_absolute_report_step() +exp.add_comparison_table_step(attributes=attributes) +exp.add_scatter_plot_step(relative=True, attributes=['generator_computation_time', 'cpdbs_computation_time', 'dominance_pruning_time', "search_time", "total_time"]) + +exp.run_steps() From 52f1d51b69de3857b895d8a0e7e90fd7c46bf4dc Mon Sep 17 00:00:00 2001 From: Silvan Sievers Date: Thu, 14 Mar 2019 09:33:58 +0100 Subject: [PATCH 15/39] [issue908] hill climbing: compute PDB values once for all samples when computing max. additive subset values --- src/search/pdbs/canonical_pdbs.cc | 6 +++--- .../pattern_collection_generator_hillclimbing.cc | 15 +++++++++------ 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/search/pdbs/canonical_pdbs.cc b/src/search/pdbs/canonical_pdbs.cc index f01c77c85a..eeb0618a8e 100644 --- a/src/search/pdbs/canonical_pdbs.cc +++ b/src/search/pdbs/canonical_pdbs.cc @@ -25,11 +25,11 @@ int CanonicalPDBs::get_value(const State &state) const { int max_h = 0; h_values.clear(); for (const shared_ptr &pdb : *pdbs) { - int h_value = pdb->get_value(state); - if (h_value == numeric_limits::max()) { + int h = pdb->get_value(state); + if (h == numeric_limits::max()) { return numeric_limits::max(); } - h_values.push_back(h_value); + h_values.push_back(h); } for (const vector &subset : *max_additive_subsets) { int subset_h = 0; diff --git a/src/search/pdbs/pattern_collection_generator_hillclimbing.cc b/src/search/pdbs/pattern_collection_generator_hillclimbing.cc index f1035c27e4..f76ab6482d 100644 --- a/src/search/pdbs/pattern_collection_generator_hillclimbing.cc +++ b/src/search/pdbs/pattern_collection_generator_hillclimbing.cc @@ -275,15 +275,18 @@ bool PatternCollectionGeneratorHillclimbing::is_heuristic_improved( if (h_collection == numeric_limits::max()) return false; + vector h_values; + h_values.reserve(pdbs.size()); + for (const shared_ptr &pdb : pdbs) { + int h = pdb->get_value(sample); + if (h == numeric_limits::max()) + return false; + h_values.push_back(h); + } for (const vector &subset : max_additive_subsets) { int h_subset = 0; for (int pdb_index : subset) { - /* Experiments showed that it is faster to recompute the - h values than to cache them in an unordered_map. */ - int h = pdbs[pdb_index]->get_value(sample); - if (h == numeric_limits::max()) - return false; - h_subset += h; + h_subset += h_values[pdb_index]; } if (h_pattern + h_subset > h_collection) { /* From 5d3a32445afe3cc77219a019d7fedc066478d684 Mon Sep 17 00:00:00 2001 From: Silvan Sievers Date: Thu, 14 Mar 2019 09:34:28 +0100 Subject: [PATCH 16/39] [issue908] v4 exp --- experiments/issue908/v4.py | 63 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100755 experiments/issue908/v4.py diff --git a/experiments/issue908/v4.py b/experiments/issue908/v4.py new file mode 100755 index 0000000000..b1b20ce4c4 --- /dev/null +++ b/experiments/issue908/v4.py @@ -0,0 +1,63 @@ +#! /usr/bin/env python +# -*- coding: utf-8 -*- + +import itertools +import os + +from lab.environments import LocalEnvironment, BaselSlurmEnvironment +from lab.reports import Attribute, geometric_mean + +from downward.reports.compare import ComparativeReport + +import common_setup +from common_setup import IssueConfig, IssueExperiment +from relativescatter import RelativeScatterPlotReport + +DIR = os.path.dirname(os.path.abspath(__file__)) +SCRIPT_NAME = os.path.splitext(os.path.basename(__file__))[0] +BENCHMARKS_DIR = os.environ["DOWNWARD_BENCHMARKS"] +REVISIONS = ["issue908-base", "issue908-v4"] +CONFIGS = [ + IssueConfig("cpdbs-hc", ['--search', 'astar(cpdbs(hillclimbing))']), + IssueConfig("cpdbs-sys2", ['--search', 'astar(cpdbs(systematic(2)))']), +] + +SUITE = common_setup.DEFAULT_OPTIMAL_SUITE +ENVIRONMENT = BaselSlurmEnvironment( + partition="infai_1", + email="silvan.sievers@unibas.ch", + export=["PATH", "DOWNWARD_BENCHMARKS"]) + +if common_setup.is_test_run(): + SUITE = IssueExperiment.DEFAULT_TEST_SUITE + ENVIRONMENT = LocalEnvironment(processes=1) + +exp = IssueExperiment( + revisions=REVISIONS, + configs=CONFIGS, + environment=ENVIRONMENT, +) +exp.add_suite(BENCHMARKS_DIR, SUITE) + +exp.add_parser(exp.EXITCODE_PARSER) +exp.add_parser(exp.TRANSLATOR_PARSER) +exp.add_parser(exp.SINGLE_SEARCH_PARSER) +exp.add_parser(exp.PLANNER_PARSER) +exp.add_parser('parser.py') + +exp.add_step('build', exp.build) +exp.add_step('start', exp.start_runs) +exp.add_fetcher(name='fetch') + +attributes=exp.DEFAULT_TABLE_ATTRIBUTES +attributes.extend([ + Attribute('generator_computation_time', absolute=False, min_wins=True, functions=[geometric_mean]), + Attribute('cpdbs_computation_time', absolute=False, min_wins=True, functions=[geometric_mean]), + Attribute('dominance_pruning_time', absolute=False, min_wins=True, functions=[geometric_mean]), +]) + +#exp.add_absolute_report_step() +exp.add_comparison_table_step(attributes=attributes) +exp.add_scatter_plot_step(relative=True, attributes=['generator_computation_time', 'cpdbs_computation_time', 'dominance_pruning_time', "search_time", "total_time"]) + +exp.run_steps() From 01d70a51542953a4c48d64e2b10e05b81bc4027c Mon Sep 17 00:00:00 2001 From: Jendrik Seipp Date: Fri, 15 Mar 2019 13:52:35 +0100 Subject: [PATCH 17/39] [issue868] Introduce compiler warning by comparing size_t to int. --- src/search/potentials/sample_based_potential_heuristics.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/search/potentials/sample_based_potential_heuristics.cc b/src/search/potentials/sample_based_potential_heuristics.cc index 17c707cb14..1c424069a9 100644 --- a/src/search/potentials/sample_based_potential_heuristics.cc +++ b/src/search/potentials/sample_based_potential_heuristics.cc @@ -47,7 +47,7 @@ static vector> create_sample_based_potential_funct vector> functions; PotentialOptimizer optimizer(opts); shared_ptr rng(utils::parse_rng_from_options(opts)); - for (int i = 0; i < opts.get("num_heuristics"); ++i) { + for (size_t i = 0; i < opts.get("num_heuristics"); ++i) { optimize_for_samples(optimizer, opts.get("num_samples"), *rng); functions.push_back(optimizer.get_potential_function()); } From 49b29f4034b10493ad49fc7463683af9a11090a9 Mon Sep 17 00:00:00 2001 From: Jendrik Seipp Date: Fri, 15 Mar 2019 13:59:20 +0100 Subject: [PATCH 18/39] [issue868] Remove -Werror compiler flag. --- src/cmake_modules/FastDownwardMacros.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cmake_modules/FastDownwardMacros.cmake b/src/cmake_modules/FastDownwardMacros.cmake index aa488aeba1..80cb84374a 100644 --- a/src/cmake_modules/FastDownwardMacros.cmake +++ b/src/cmake_modules/FastDownwardMacros.cmake @@ -14,7 +14,7 @@ macro(fast_downward_set_compiler_flags) endif() set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -pedantic -Wnon-virtual-dtor -Werror") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -pedantic -Wnon-virtual-dtor") ## Configuration-specific flags set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG -fomit-frame-pointer") From a05ec07d89f79eefe3fd661959eebfd367995151 Mon Sep 17 00:00:00 2001 From: Jendrik Seipp Date: Fri, 15 Mar 2019 14:14:43 +0100 Subject: [PATCH 19/39] [issue868] Pipelines: treat compilation warnings as errors. --- bitbucket-pipelines.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/bitbucket-pipelines.yml b/bitbucket-pipelines.yml index 1248e34b3a..5ba80de96b 100644 --- a/bitbucket-pipelines.yml +++ b/bitbucket-pipelines.yml @@ -44,5 +44,6 @@ pipelines: - rm -rf VAL - export PATH="$(pwd):$PATH" # Add uncrustify and VAL to PATH. + - export CXXFLAGS="-Werror" # Treat compilation warnings as errors. - ./misc/run-all-tests From a6da75be618a13850c2fa0101e8451b3d2c113ae Mon Sep 17 00:00:00 2001 From: Jendrik Seipp Date: Fri, 15 Mar 2019 14:37:54 +0100 Subject: [PATCH 20/39] [issue868] Fix compiler warning again. --- src/search/potentials/sample_based_potential_heuristics.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/search/potentials/sample_based_potential_heuristics.cc b/src/search/potentials/sample_based_potential_heuristics.cc index 1c424069a9..17c707cb14 100644 --- a/src/search/potentials/sample_based_potential_heuristics.cc +++ b/src/search/potentials/sample_based_potential_heuristics.cc @@ -47,7 +47,7 @@ static vector> create_sample_based_potential_funct vector> functions; PotentialOptimizer optimizer(opts); shared_ptr rng(utils::parse_rng_from_options(opts)); - for (size_t i = 0; i < opts.get("num_heuristics"); ++i) { + for (int i = 0; i < opts.get("num_heuristics"); ++i) { optimize_for_samples(optimizer, opts.get("num_samples"), *rng); functions.push_back(optimizer.get_potential_function()); } From ae547ce2f845cb763274329c68e4d1123a2dda8e Mon Sep 17 00:00:00 2001 From: Silvan Sievers Date: Fri, 15 Mar 2019 16:40:53 +0100 Subject: [PATCH 21/39] [issue908] do not use a member to avoid reallocating space for h-values in CPDB heuristic --- src/search/pdbs/canonical_pdbs.cc | 4 ++-- src/search/pdbs/canonical_pdbs.h | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/search/pdbs/canonical_pdbs.cc b/src/search/pdbs/canonical_pdbs.cc index eeb0618a8e..a8e81f5d3d 100644 --- a/src/search/pdbs/canonical_pdbs.cc +++ b/src/search/pdbs/canonical_pdbs.cc @@ -16,14 +16,14 @@ CanonicalPDBs::CanonicalPDBs( : pdbs(pdbs), max_additive_subsets(max_additive_subsets) { assert(pdbs); assert(max_additive_subsets); - h_values.reserve(pdbs->size()); } int CanonicalPDBs::get_value(const State &state) const { // If we have an empty collection, then max_additive_subsets = { \emptyset }. assert(!max_additive_subsets->empty()); int max_h = 0; - h_values.clear(); + vector h_values; + h_values.reserve(pdbs->size()); for (const shared_ptr &pdb : *pdbs) { int h = pdb->get_value(state); if (h == numeric_limits::max()) { diff --git a/src/search/pdbs/canonical_pdbs.h b/src/search/pdbs/canonical_pdbs.h index 3148981ebf..ed3260467e 100644 --- a/src/search/pdbs/canonical_pdbs.h +++ b/src/search/pdbs/canonical_pdbs.h @@ -11,8 +11,6 @@ namespace pdbs { class CanonicalPDBs { std::shared_ptr pdbs; std::shared_ptr max_additive_subsets; - // Used to avoid allocating memory in each call to get_value. - mutable std::vector h_values; public: CanonicalPDBs( From 47b9a3cf28499cf3e40461bae305cf2cd794d548 Mon Sep 17 00:00:00 2001 From: Silvan Sievers Date: Fri, 15 Mar 2019 16:41:32 +0100 Subject: [PATCH 22/39] [issue908] v5 exp --- experiments/issue908/v5.py | 63 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100755 experiments/issue908/v5.py diff --git a/experiments/issue908/v5.py b/experiments/issue908/v5.py new file mode 100755 index 0000000000..26e290d418 --- /dev/null +++ b/experiments/issue908/v5.py @@ -0,0 +1,63 @@ +#! /usr/bin/env python +# -*- coding: utf-8 -*- + +import itertools +import os + +from lab.environments import LocalEnvironment, BaselSlurmEnvironment +from lab.reports import Attribute, geometric_mean + +from downward.reports.compare import ComparativeReport + +import common_setup +from common_setup import IssueConfig, IssueExperiment +from relativescatter import RelativeScatterPlotReport + +DIR = os.path.dirname(os.path.abspath(__file__)) +SCRIPT_NAME = os.path.splitext(os.path.basename(__file__))[0] +BENCHMARKS_DIR = os.environ["DOWNWARD_BENCHMARKS"] +REVISIONS = ["issue908-v4", "issue908-v5"] +CONFIGS = [ + IssueConfig("cpdbs-hc", ['--search', 'astar(cpdbs(hillclimbing))']), + IssueConfig("cpdbs-sys2", ['--search', 'astar(cpdbs(systematic(2)))']), +] + +SUITE = common_setup.DEFAULT_OPTIMAL_SUITE +ENVIRONMENT = BaselSlurmEnvironment( + partition="infai_1", + email="silvan.sievers@unibas.ch", + export=["PATH", "DOWNWARD_BENCHMARKS"]) + +if common_setup.is_test_run(): + SUITE = IssueExperiment.DEFAULT_TEST_SUITE + ENVIRONMENT = LocalEnvironment(processes=1) + +exp = IssueExperiment( + revisions=REVISIONS, + configs=CONFIGS, + environment=ENVIRONMENT, +) +exp.add_suite(BENCHMARKS_DIR, SUITE) + +exp.add_parser(exp.EXITCODE_PARSER) +exp.add_parser(exp.TRANSLATOR_PARSER) +exp.add_parser(exp.SINGLE_SEARCH_PARSER) +exp.add_parser(exp.PLANNER_PARSER) +exp.add_parser('parser.py') + +exp.add_step('build', exp.build) +exp.add_step('start', exp.start_runs) +exp.add_fetcher(name='fetch') + +attributes=exp.DEFAULT_TABLE_ATTRIBUTES +attributes.extend([ + Attribute('generator_computation_time', absolute=False, min_wins=True, functions=[geometric_mean]), + Attribute('cpdbs_computation_time', absolute=False, min_wins=True, functions=[geometric_mean]), + Attribute('dominance_pruning_time', absolute=False, min_wins=True, functions=[geometric_mean]), +]) + +#exp.add_absolute_report_step() +exp.add_comparison_table_step(attributes=attributes) +exp.add_scatter_plot_step(relative=True, attributes=['generator_computation_time', 'cpdbs_computation_time', 'dominance_pruning_time', "search_time", "total_time"]) + +exp.run_steps() From bb381b27399a96df36a56349fa9b345adbe91e9e Mon Sep 17 00:00:00 2001 From: Jendrik Seipp Date: Mon, 18 Mar 2019 10:50:19 +0100 Subject: [PATCH 23/39] [main] Introduce compiler warning to test buildbot. --- src/search/potentials/sample_based_potential_heuristics.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/search/potentials/sample_based_potential_heuristics.cc b/src/search/potentials/sample_based_potential_heuristics.cc index 17c707cb14..1c424069a9 100644 --- a/src/search/potentials/sample_based_potential_heuristics.cc +++ b/src/search/potentials/sample_based_potential_heuristics.cc @@ -47,7 +47,7 @@ static vector> create_sample_based_potential_funct vector> functions; PotentialOptimizer optimizer(opts); shared_ptr rng(utils::parse_rng_from_options(opts)); - for (int i = 0; i < opts.get("num_heuristics"); ++i) { + for (size_t i = 0; i < opts.get("num_heuristics"); ++i) { optimize_for_samples(optimizer, opts.get("num_samples"), *rng); functions.push_back(optimizer.get_potential_function()); } From 9ff31b39ab2fb55aadef9f3d16b0594fca6c2715 Mon Sep 17 00:00:00 2001 From: Jendrik Seipp Date: Mon, 18 Mar 2019 11:44:19 +0100 Subject: [PATCH 24/39] [main] Don't treat MSVC compiler warnings as errors. --- src/cmake_modules/FastDownwardMacros.cmake | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/cmake_modules/FastDownwardMacros.cmake b/src/cmake_modules/FastDownwardMacros.cmake index 80cb84374a..67ad4369a0 100644 --- a/src/cmake_modules/FastDownwardMacros.cmake +++ b/src/cmake_modules/FastDownwardMacros.cmake @@ -32,10 +32,9 @@ macro(fast_downward_set_compiler_flags) # Enable exceptions. set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHsc") - # Use warning level 4 (/W4) and treat warnings as errors (/WX) - # -Wall currently detects too many warnings outside of our code to be useful. + # Use warning level 4 (/W4). + # /Wall currently detects too many warnings outside of our code to be useful. string(REPLACE "/W3" "/W4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /WX") # Disable warnings that currently trigger in the code until we fix them. set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4800") # forcing value to bool From 5c59dd0a982bc6ca70735617133aa402d526cfe0 Mon Sep 17 00:00:00 2001 From: Silvan Sievers Date: Mon, 18 Mar 2019 16:00:26 +0100 Subject: [PATCH 25/39] [issue908] use vector instead of set to collect remaining PDB indices --- src/search/pdbs/dominance_pruning.cc | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/src/search/pdbs/dominance_pruning.cc b/src/search/pdbs/dominance_pruning.cc index 752aa663c2..62ff497c90 100644 --- a/src/search/pdbs/dominance_pruning.cc +++ b/src/search/pdbs/dominance_pruning.cc @@ -7,7 +7,6 @@ #include #include -#include #include using namespace std; @@ -168,28 +167,36 @@ void prune_dominated_subsets( num_variables).get_pruned_collections(timer); MaxAdditivePDBSubsets remaining_max_additive_subsets; - set remaining_pattern_indices; + vector is_remaining_pattern(num_patterns, false); for (size_t i = 0; i < max_additive_subsets.size(); ++i) { if (!pruned[i]) { vector &subset = max_additive_subsets[i]; for (int pattern_index : subset) { - remaining_pattern_indices.insert(pattern_index); + is_remaining_pattern[pattern_index] = true; } remaining_max_additive_subsets.push_back(move(subset)); } } - int num_remaining_patterns = remaining_pattern_indices.size(); + int num_remaining_patterns = 0; + for (int old_pattern_index = 0; old_pattern_index < num_patterns; ++old_pattern_index) { + if (is_remaining_pattern[old_pattern_index]) { + ++num_remaining_patterns; + } + } + PatternCollection remaining_patterns; PDBCollection remaining_pdbs; remaining_patterns.reserve(num_remaining_patterns); remaining_pdbs.reserve(num_remaining_patterns); vector old_to_new_pattern_index(num_patterns, -1); - for (int old_pattern_index : remaining_pattern_indices) { - int new_pattern_index = remaining_patterns.size(); - old_to_new_pattern_index[old_pattern_index] = new_pattern_index; - remaining_patterns.push_back(move(patterns[old_pattern_index])); - remaining_pdbs.push_back(move(pdbs[old_pattern_index])); + for (int old_pattern_index = 0; old_pattern_index < num_patterns; ++old_pattern_index) { + if (is_remaining_pattern[old_pattern_index]) { + int new_pattern_index = remaining_patterns.size(); + old_to_new_pattern_index[old_pattern_index] = new_pattern_index; + remaining_patterns.push_back(move(patterns[old_pattern_index])); + remaining_pdbs.push_back(move(pdbs[old_pattern_index])); + } } for (vector &subset : remaining_max_additive_subsets) { for (size_t i = 0; i < subset.size(); ++i) { From f58829b33d0466dff83bf76d242471ffe0c0ae2a Mon Sep 17 00:00:00 2001 From: Silvan Sievers Date: Mon, 18 Mar 2019 16:02:17 +0100 Subject: [PATCH 26/39] [issue908] update comment --- src/search/pdbs/canonical_pdbs_heuristic.cc | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/search/pdbs/canonical_pdbs_heuristic.cc b/src/search/pdbs/canonical_pdbs_heuristic.cc index b3b3a91d8d..4e72454fe2 100644 --- a/src/search/pdbs/canonical_pdbs_heuristic.cc +++ b/src/search/pdbs/canonical_pdbs_heuristic.cc @@ -39,10 +39,8 @@ CanonicalPDBs get_canonical_pdbs_from_options( if (max_time_dominance_pruning > 0.0) { int num_variables = TaskProxy(*task).get_variables().size(); /* - In principle, we could pass PatternCollectionInformation here. - However, PatternCollectionInformation is not intended to be changed. - Dominance pruning could also be computed without having access to - the PDBs, but since we want to delete patterns, we also want to + NOTE: Dominance pruning could also be computed without having access + to the PDBs, but since we want to delete patterns, we also want to update the list of corresponding PDBs so they are synchronized. In the long term, we plan to have patterns and their PDBs live From 24ae1046dc07bd3bc0f1c81f979f75b6331015f4 Mon Sep 17 00:00:00 2001 From: Silvan Sievers Date: Mon, 18 Mar 2019 16:06:25 +0100 Subject: [PATCH 27/39] [issue908] simplify testing if max additive subsets contain valid indices --- src/search/pdbs/pattern_collection_information.cc | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/search/pdbs/pattern_collection_information.cc b/src/search/pdbs/pattern_collection_information.cc index 9ce29d810c..e2ca772bbc 100644 --- a/src/search/pdbs/pattern_collection_information.cc +++ b/src/search/pdbs/pattern_collection_information.cc @@ -41,17 +41,13 @@ bool PatternCollectionInformation::information_is_valid() const { } } if (max_additive_subsets) { - utils::HashSet patterns_in_union; for (const vector &additive_subset : *max_additive_subsets) { for (int pattern_index : additive_subset) { - patterns_in_union.insert((*patterns)[pattern_index]); + if (!utils::in_bounds(pattern_index, *patterns)) { + return false; + } } } - utils::HashSet patterns_in_list(patterns->begin(), - patterns->end()); - if (patterns_in_list != patterns_in_union) { - return false; - } } return true; } From b871d3e5bd1e8450b676ef6d3d788c4838f249dc Mon Sep 17 00:00:00 2001 From: Jendrik Seipp Date: Mon, 18 Mar 2019 20:44:56 +0100 Subject: [PATCH 28/39] [main] Fix compiler warning. --- src/search/potentials/sample_based_potential_heuristics.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/search/potentials/sample_based_potential_heuristics.cc b/src/search/potentials/sample_based_potential_heuristics.cc index 1c424069a9..17c707cb14 100644 --- a/src/search/potentials/sample_based_potential_heuristics.cc +++ b/src/search/potentials/sample_based_potential_heuristics.cc @@ -47,7 +47,7 @@ static vector> create_sample_based_potential_funct vector> functions; PotentialOptimizer optimizer(opts); shared_ptr rng(utils::parse_rng_from_options(opts)); - for (size_t i = 0; i < opts.get("num_heuristics"); ++i) { + for (int i = 0; i < opts.get("num_heuristics"); ++i) { optimize_for_samples(optimizer, opts.get("num_samples"), *rng); functions.push_back(optimizer.get_potential_function()); } From 7c25fb16794d7859eeee5b7fb50503ca164e26e4 Mon Sep 17 00:00:00 2001 From: Silvan Sievers Date: Tue, 19 Mar 2019 11:21:49 +0100 Subject: [PATCH 29/39] [issue908] rename MaxAdditivePDBSubsets to vector, where PatternClique = vector with PatternID = int --- src/search/pdbs/canonical_pdbs.cc | 20 +-- src/search/pdbs/canonical_pdbs.h | 4 +- src/search/pdbs/canonical_pdbs_heuristic.cc | 14 +- src/search/pdbs/dominance_pruning.cc | 134 +++++++++--------- src/search/pdbs/dominance_pruning.h | 6 +- src/search/pdbs/incremental_canonical_pdbs.cc | 20 +-- src/search/pdbs/incremental_canonical_pdbs.h | 14 +- src/search/pdbs/max_additive_pdb_sets.cc | 34 ++--- src/search/pdbs/max_additive_pdb_sets.h | 30 ++-- ...ttern_collection_generator_hillclimbing.cc | 20 +-- ...attern_collection_generator_hillclimbing.h | 4 +- .../pdbs/pattern_collection_information.cc | 32 ++--- .../pdbs/pattern_collection_information.h | 10 +- src/search/pdbs/types.h | 6 +- 14 files changed, 175 insertions(+), 173 deletions(-) diff --git a/src/search/pdbs/canonical_pdbs.cc b/src/search/pdbs/canonical_pdbs.cc index a8e81f5d3d..352360e853 100644 --- a/src/search/pdbs/canonical_pdbs.cc +++ b/src/search/pdbs/canonical_pdbs.cc @@ -12,15 +12,15 @@ using namespace std; namespace pdbs { CanonicalPDBs::CanonicalPDBs( const shared_ptr &pdbs, - const shared_ptr &max_additive_subsets) - : pdbs(pdbs), max_additive_subsets(max_additive_subsets) { + const shared_ptr> &pattern_cliques) + : pdbs(pdbs), pattern_cliques(pattern_cliques) { assert(pdbs); - assert(max_additive_subsets); + assert(pattern_cliques); } int CanonicalPDBs::get_value(const State &state) const { - // If we have an empty collection, then max_additive_subsets = { \emptyset }. - assert(!max_additive_subsets->empty()); + // If we have an empty collection, then pattern_cliques = { \emptyset }. + assert(!pattern_cliques->empty()); int max_h = 0; vector h_values; h_values.reserve(pdbs->size()); @@ -31,12 +31,12 @@ int CanonicalPDBs::get_value(const State &state) const { } h_values.push_back(h); } - for (const vector &subset : *max_additive_subsets) { - int subset_h = 0; - for (int pdb_index : subset) { - subset_h += h_values[pdb_index]; + for (const PatternClique &clique : *pattern_cliques) { + int clique_h = 0; + for (PatternID pdb_index : clique) { + clique_h += h_values[pdb_index]; } - max_h = max(max_h, subset_h); + max_h = max(max_h, clique_h); } return max_h; } diff --git a/src/search/pdbs/canonical_pdbs.h b/src/search/pdbs/canonical_pdbs.h index ed3260467e..f53fe74280 100644 --- a/src/search/pdbs/canonical_pdbs.h +++ b/src/search/pdbs/canonical_pdbs.h @@ -10,12 +10,12 @@ class State; namespace pdbs { class CanonicalPDBs { std::shared_ptr pdbs; - std::shared_ptr max_additive_subsets; + std::shared_ptr> pattern_cliques; public: CanonicalPDBs( const std::shared_ptr &pdbs, - const std::shared_ptr &max_additive_subsets); + const std::shared_ptr> &pattern_cliques); ~CanonicalPDBs() = default; int get_value(const State &state) const; diff --git a/src/search/pdbs/canonical_pdbs_heuristic.cc b/src/search/pdbs/canonical_pdbs_heuristic.cc index 4e72454fe2..abd6f0bd33 100644 --- a/src/search/pdbs/canonical_pdbs_heuristic.cc +++ b/src/search/pdbs/canonical_pdbs_heuristic.cc @@ -27,13 +27,13 @@ CanonicalPDBs get_canonical_pdbs_from_options( shared_ptr patterns = pattern_collection_info.get_patterns(); /* - We compute PDBs and max additive subsets here (if they have not been + We compute PDBs and pattern cliques here (if they have not been computed before) so that their computation is not taken into account for dominance pruning time. */ shared_ptr pdbs = pattern_collection_info.get_pdbs(); - shared_ptr max_additive_subsets = - pattern_collection_info.get_max_additive_subsets(); + shared_ptr> pattern_cliques = + pattern_collection_info.get_pattern_cliques(); double max_time_dominance_pruning = opts.get("max_time_dominance_pruning"); if (max_time_dominance_pruning > 0.0) { @@ -45,12 +45,12 @@ CanonicalPDBs get_canonical_pdbs_from_options( In the long term, we plan to have patterns and their PDBs live together, in which case we would only need to pass their container - and the max additive subsets. + and the pattern cliques. */ - prune_dominated_subsets( + prune_dominated_cliques( *patterns, *pdbs, - *max_additive_subsets, + *pattern_cliques, num_variables, max_time_dominance_pruning); } @@ -58,7 +58,7 @@ CanonicalPDBs get_canonical_pdbs_from_options( // Do not dump pattern collections for size reasons. dump_pattern_collection_generation_statistics( "Canonical PDB heuristic", timer(), pattern_collection_info, false); - return CanonicalPDBs(pdbs, max_additive_subsets); + return CanonicalPDBs(pdbs, pattern_cliques); } CanonicalPDBsHeuristic::CanonicalPDBsHeuristic(const Options &opts) diff --git a/src/search/pdbs/dominance_pruning.cc b/src/search/pdbs/dominance_pruning.cc index 62ff497c90..ebbac5924f 100644 --- a/src/search/pdbs/dominance_pruning.cc +++ b/src/search/pdbs/dominance_pruning.cc @@ -19,50 +19,48 @@ class Pruner { "patterns" is the vector of patterns used. Each pattern is a vector of variable IDs. - "collections" is the vector of pattern collections. - Each collection is a vector, where each int is an index - into "patterns". + "pattern_cliques" is the vector of pattern cliques. The algorithm works by setting a "current pattern collection" against which other patterns and collections can be tested for dominance efficiently. - "pattern_index" encodes the relevant information about the - current collection. For every variable v, pattern_index[v] is - the index of the pattern containing v in the current collection, + "variable_to_pattern_id" encodes the relevant information about the + current clique. For every variable v, variable_to_pattern_id[v] is + the id of the pattern containing v in the current clique, or -1 if the variable is not contained in the current - collection. (Note that patterns in a collection must be + clique. (Note that patterns in a pattern clique must be disjoint, which is verified by an assertion in debug mode.) To test if a given pattern v_1, ..., v_k is dominated by the - current collection, we check that all entries pattern_index[v_i] + current clique, we check that all entries variable_to_pattern_id[v_i] are equal and different from -1. "dominated_patterns" is a vector that can be used to quickly test whether a given pattern is dominated by the current - collection. This is precomputed for every pattern whenever the - current collection is set. + clique. This is precomputed for every pattern whenever the + current clique is set. */ const PatternCollection &patterns; - const MaxAdditivePDBSubsets &collections; + const std::vector &pattern_cliques; const int num_variables; - vector pattern_index; + vector variable_to_pattern_id; vector dominated_patterns; - void set_current_collection(int collection_id) { + void set_current_clique(int clique_id) { /* Set the current pattern collection to be used for is_pattern_dominated() or is_collection_dominated(). Compute dominated_patterns based on the current pattern collection. */ - pattern_index.assign(num_variables, -1); - assert(pattern_index == vector(num_variables, -1)); - for (int pattern_id : collections[collection_id]) { + variable_to_pattern_id.assign(num_variables, -1); + assert(variable_to_pattern_id == vector(num_variables, -1)); + for (PatternID pattern_id : pattern_cliques[clique_id]) { for (int variable : patterns[pattern_id]) { - assert(pattern_index[variable] == -1); - pattern_index[variable] = pattern_id; + assert(variable_to_pattern_id[variable] == -1); + variable_to_pattern_id[variable] = pattern_id; } } @@ -76,29 +74,29 @@ class Pruner { bool is_pattern_dominated(int pattern_id) const { /* Check if the pattern with the given pattern_id is dominated - by the current pattern collection. + by the current pattern clique. */ - const vector &pattern = patterns[pattern_id]; + const Pattern &pattern = patterns[pattern_id]; assert(!pattern.empty()); - int collection_pattern = pattern_index[pattern[0]]; - if (collection_pattern == -1) { + PatternID clique_pattern_id = variable_to_pattern_id[pattern[0]]; + if (clique_pattern_id == -1) { return false; } int pattern_size = pattern.size(); for (int i = 1; i < pattern_size; ++i) { - if (pattern_index[pattern[i]] != collection_pattern) { + if (variable_to_pattern_id[pattern[i]] != clique_pattern_id) { return false; } } return true; } - bool is_collection_dominated(int collection_id) const { + bool is_clique_dominated(int clique_id) const { /* Check if the collection with the given collection_id is dominated by the current pattern collection. */ - for (int pattern_id : collections[collection_id]) { + for (PatternID pattern_id : pattern_cliques[clique_id]) { if (!dominated_patterns[pattern_id]) { return false; } @@ -109,34 +107,34 @@ class Pruner { public: Pruner( const PatternCollection &patterns, - const MaxAdditivePDBSubsets &max_additive_subsets, + const std::vector &pattern_cliques, int num_variables) : patterns(patterns), - collections(max_additive_subsets), + pattern_cliques(pattern_cliques), num_variables(num_variables) { } - vector get_pruned_collections(const utils::CountdownTimer &timer) { - int num_collections = collections.size(); - vector pruned(num_collections, false); + vector get_pruned_cliques(const utils::CountdownTimer &timer) { + int num_cliques= pattern_cliques.size(); + vector pruned(num_cliques, false); /* - Already pruned collections are not used to prune other - collections. This makes things faster and helps handle - duplicate collections in the correct way: the first copy + Already pruned cliques are not used to prune other + cliques. This makes things faster and helps handle + duplicate cliques in the correct way: the first copy will survive and prune all duplicates. */ - for (int c1 = 0; c1 < num_collections; ++c1) { + for (int c1 = 0; c1 < num_cliques; ++c1) { if (!pruned[c1]) { - set_current_collection(c1); - for (int c2 = 0; c2 < num_collections; ++c2) { - if (c1 != c2 && !pruned[c2] && is_collection_dominated(c2)) + set_current_clique(c1); + for (int c2 = 0; c2 < num_cliques; ++c2) { + if (c1 != c2 && !pruned[c2] && is_clique_dominated(c2)) pruned[c2] = true; } } if (timer.is_expired()) { /* Since after each iteration, we determined if a given - collection is pruned or not, we can just break the + clique is pruned or not, we can just break the computation here if reaching the time limit and use all information we collected so far. */ @@ -149,38 +147,38 @@ class Pruner { } }; -void prune_dominated_subsets( +void prune_dominated_cliques( PatternCollection &patterns, PDBCollection &pdbs, - MaxAdditivePDBSubsets &max_additive_subsets, + std::vector &pattern_cliques, int num_variables, double max_time) { cout << "Running dominance pruning..." << endl; utils::CountdownTimer timer(max_time); int num_patterns = patterns.size(); - int num_subsets = max_additive_subsets.size(); + int num_cliques = pattern_cliques.size(); vector pruned = Pruner( patterns, - max_additive_subsets, - num_variables).get_pruned_collections(timer); + pattern_cliques, + num_variables).get_pruned_cliques(timer); - MaxAdditivePDBSubsets remaining_max_additive_subsets; + std::vector remaining_pattern_cliques; vector is_remaining_pattern(num_patterns, false); - for (size_t i = 0; i < max_additive_subsets.size(); ++i) { + for (size_t i = 0; i < pattern_cliques.size(); ++i) { if (!pruned[i]) { - vector &subset = max_additive_subsets[i]; - for (int pattern_index : subset) { - is_remaining_pattern[pattern_index] = true; + PatternClique &clique = pattern_cliques[i]; + for (PatternID pattern_id : clique) { + is_remaining_pattern[pattern_id] = true; } - remaining_max_additive_subsets.push_back(move(subset)); + remaining_pattern_cliques.push_back(move(clique)); } } int num_remaining_patterns = 0; - for (int old_pattern_index = 0; old_pattern_index < num_patterns; ++old_pattern_index) { - if (is_remaining_pattern[old_pattern_index]) { + for (PatternID old_pattern_id = 0; old_pattern_id < num_patterns; ++old_pattern_id) { + if (is_remaining_pattern[old_pattern_id]) { ++num_remaining_patterns; } } @@ -189,27 +187,27 @@ void prune_dominated_subsets( PDBCollection remaining_pdbs; remaining_patterns.reserve(num_remaining_patterns); remaining_pdbs.reserve(num_remaining_patterns); - vector old_to_new_pattern_index(num_patterns, -1); - for (int old_pattern_index = 0; old_pattern_index < num_patterns; ++old_pattern_index) { - if (is_remaining_pattern[old_pattern_index]) { - int new_pattern_index = remaining_patterns.size(); - old_to_new_pattern_index[old_pattern_index] = new_pattern_index; - remaining_patterns.push_back(move(patterns[old_pattern_index])); - remaining_pdbs.push_back(move(pdbs[old_pattern_index])); + vector old_to_new_pattern_id(num_patterns, -1); + for (PatternID old_pattern_id = 0; old_pattern_id < num_patterns; ++old_pattern_id) { + if (is_remaining_pattern[old_pattern_id]) { + PatternID new_pattern_id = remaining_patterns.size(); + old_to_new_pattern_id[old_pattern_id] = new_pattern_id; + remaining_patterns.push_back(move(patterns[old_pattern_id])); + remaining_pdbs.push_back(move(pdbs[old_pattern_id])); } } - for (vector &subset : remaining_max_additive_subsets) { - for (size_t i = 0; i < subset.size(); ++i) { - int old_pattern_index = subset[i]; - int new_pattern_index = old_to_new_pattern_index[old_pattern_index]; - assert(new_pattern_index != -1); - subset[i] = new_pattern_index; + for (PatternClique &clique : remaining_pattern_cliques) { + for (size_t i = 0; i < clique.size(); ++i) { + PatternID old_pattern_id = clique[i]; + PatternID new_pattern_id = old_to_new_pattern_id[old_pattern_id]; + assert(new_pattern_id != -1); + clique[i] = new_pattern_id; } } - int num_pruned_collections = num_subsets - remaining_max_additive_subsets.size(); - cout << "Pruned " << num_pruned_collections << " of " << num_subsets - << " maximal additive subsets" << endl; + int num_pruned_collections = num_cliques - remaining_pattern_cliques.size(); + cout << "Pruned " << num_pruned_collections << " of " << num_cliques + << " pattern cliques" << endl; int num_pruned_patterns = num_patterns - num_remaining_patterns; cout << "Pruned " << num_pruned_patterns << " of " << num_patterns @@ -217,7 +215,7 @@ void prune_dominated_subsets( patterns.swap(remaining_patterns); pdbs.swap(remaining_pdbs); - max_additive_subsets.swap(remaining_max_additive_subsets); + pattern_cliques.swap(remaining_pattern_cliques); cout << "Dominance pruning took " << timer.get_elapsed_time() << endl; } diff --git a/src/search/pdbs/dominance_pruning.h b/src/search/pdbs/dominance_pruning.h index 67dc300351..90f09cd8de 100644 --- a/src/search/pdbs/dominance_pruning.h +++ b/src/search/pdbs/dominance_pruning.h @@ -5,14 +5,14 @@ namespace pdbs { /* - Collection superset dominates collection subset iff for every pattern + Clique superset dominates clique subset iff for every pattern p_subset in subset there is a pattern p_superset in superset where p_superset is a superset of p_subset. */ -extern void prune_dominated_subsets( +extern void prune_dominated_cliques( PatternCollection &patterns, PDBCollection &pdbs, - MaxAdditivePDBSubsets &max_additive_subsets, + std::vector &pattern_cliques, int num_variables, double max_time); } diff --git a/src/search/pdbs/incremental_canonical_pdbs.cc b/src/search/pdbs/incremental_canonical_pdbs.cc index 48c9d2bbb3..cf40d9bdc9 100644 --- a/src/search/pdbs/incremental_canonical_pdbs.cc +++ b/src/search/pdbs/incremental_canonical_pdbs.cc @@ -12,13 +12,13 @@ IncrementalCanonicalPDBs::IncrementalCanonicalPDBs( patterns(make_shared(intitial_patterns.begin(), intitial_patterns.end())), pattern_databases(make_shared()), - max_additive_subsets(nullptr), + pattern_cliques(nullptr), size(0) { pattern_databases->reserve(patterns->size()); for (const Pattern &pattern : *patterns) add_pdb_for_pattern(pattern); are_additive = compute_additive_vars(task_proxy); - recompute_max_additive_subsets(); + recompute_pattern_cliques(); } void IncrementalCanonicalPDBs::add_pdb_for_pattern(const Pattern &pattern) { @@ -30,22 +30,22 @@ void IncrementalCanonicalPDBs::add_pdb(const shared_ptr &pdb) { patterns->push_back(pdb->get_pattern()); pattern_databases->push_back(pdb); size += pattern_databases->back()->get_size(); - recompute_max_additive_subsets(); + recompute_pattern_cliques(); } -void IncrementalCanonicalPDBs::recompute_max_additive_subsets() { - max_additive_subsets = compute_max_additive_subsets(*patterns, +void IncrementalCanonicalPDBs::recompute_pattern_cliques() { + pattern_cliques = compute_pattern_cliques(*patterns, are_additive); } -MaxAdditivePDBSubsets IncrementalCanonicalPDBs::get_max_additive_subsets( +std::vector IncrementalCanonicalPDBs::get_pattern_cliques( const Pattern &new_pattern) { - return pdbs::compute_max_additive_subsets_with_pattern( - *patterns, *max_additive_subsets, new_pattern, are_additive); + return pdbs::compute_pattern_cliques_with_pattern( + *patterns, *pattern_cliques, new_pattern, are_additive); } int IncrementalCanonicalPDBs::get_value(const State &state) const { - CanonicalPDBs canonical_pdbs(pattern_databases, max_additive_subsets); + CanonicalPDBs canonical_pdbs(pattern_databases, pattern_cliques); return canonical_pdbs.get_value(state); } @@ -60,7 +60,7 @@ PatternCollectionInformation IncrementalCanonicalPDBs::get_pattern_collection_information() const { PatternCollectionInformation result(task_proxy, patterns); result.set_pdbs(pattern_databases); - result.set_max_additive_subsets(max_additive_subsets); + result.set_pattern_cliques(pattern_cliques); return result; } } diff --git a/src/search/pdbs/incremental_canonical_pdbs.h b/src/search/pdbs/incremental_canonical_pdbs.h index 7107f42b94..677d25bec0 100644 --- a/src/search/pdbs/incremental_canonical_pdbs.h +++ b/src/search/pdbs/incremental_canonical_pdbs.h @@ -15,7 +15,7 @@ class IncrementalCanonicalPDBs { std::shared_ptr patterns; std::shared_ptr pattern_databases; - std::shared_ptr max_additive_subsets; + std::shared_ptr> pattern_cliques; // A pair of variables is additive if no operator has an effect on both. VariableAdditivity are_additive; @@ -23,21 +23,21 @@ class IncrementalCanonicalPDBs { // The sum of all abstract state sizes of all pdbs in the collection. int size; - // Adds a PDB for pattern but does not recompute max_additive_subsets. + // Adds a PDB for pattern but does not recompute pattern_cliques. void add_pdb_for_pattern(const Pattern &pattern); - void recompute_max_additive_subsets(); + void recompute_pattern_cliques(); public: IncrementalCanonicalPDBs(const TaskProxy &task_proxy, const PatternCollection &intitial_patterns); virtual ~IncrementalCanonicalPDBs() = default; - // Adds a new PDB to the collection and recomputes max_additive_subsets. + // Adds a new PDB to the collection and recomputes pattern_cliques. void add_pdb(const std::shared_ptr &pdb); - /* Returns a set of subsets that would be additive to the new pattern. - Detailed documentation in max_additive_pdb_sets.h */ - MaxAdditivePDBSubsets get_max_additive_subsets(const Pattern &new_pattern); + /* Returns a list of pattern cliques that would be additive to the new + pattern. Detailed documentation in max_additive_pdb_sets.h */ + std::vector get_pattern_cliques(const Pattern &new_pattern); int get_value(const State &state) const; diff --git a/src/search/pdbs/max_additive_pdb_sets.cc b/src/search/pdbs/max_additive_pdb_sets.cc index efefc2bc2d..c445014a1b 100644 --- a/src/search/pdbs/max_additive_pdb_sets.cc +++ b/src/search/pdbs/max_additive_pdb_sets.cc @@ -38,7 +38,7 @@ VariableAdditivity compute_additive_vars(const TaskProxy &task_proxy) { return are_additive; } -shared_ptr compute_max_additive_subsets( +shared_ptr> compute_pattern_cliques( const PatternCollection &patterns, const VariableAdditivity &are_additive) { // Initialize compatibility graph. vector> cgraph; @@ -55,36 +55,36 @@ shared_ptr compute_max_additive_subsets( } } - shared_ptr max_cliques = make_shared(); + shared_ptr> max_cliques = make_shared>(); max_cliques::compute_max_cliques(cgraph, *max_cliques); return max_cliques; } -MaxAdditivePDBSubsets compute_max_additive_subsets_with_pattern( +std::vector compute_pattern_cliques_with_pattern( const PatternCollection &patterns, - const MaxAdditivePDBSubsets &known_additive_subsets, + const std::vector &known_pattern_cliques, const Pattern &new_pattern, const VariableAdditivity &are_additive) { - MaxAdditivePDBSubsets subsets_additive_with_pattern; - for (const vector &known_subset : known_additive_subsets) { + std::vector cliques_additive_with_pattern; + for (const PatternClique &known_clique : known_pattern_cliques) { // Take all patterns which are additive to new_pattern. - vector new_subset; - new_subset.reserve(known_subset.size()); - for (int pattern_index : known_subset) { + PatternClique new_clique; + new_clique.reserve(known_clique.size()); + for (PatternID pattern_id : known_clique) { if (are_patterns_additive( - new_pattern, patterns[pattern_index], are_additive)) { - new_subset.push_back(pattern_index); + new_pattern, patterns[pattern_id], are_additive)) { + new_clique.push_back(pattern_id); } } - if (!new_subset.empty()) { - subsets_additive_with_pattern.push_back(new_subset); + if (!new_clique.empty()) { + cliques_additive_with_pattern.push_back(new_clique); } } - if (subsets_additive_with_pattern.empty()) { + if (cliques_additive_with_pattern.empty()) { // If nothing was additive with the new variable, then - // the only additive subset is the empty set. - subsets_additive_with_pattern.emplace_back(); + // the only clique is the empty set. + cliques_additive_with_pattern.emplace_back(); } - return subsets_additive_with_pattern; + return cliques_additive_with_pattern; } } diff --git a/src/search/pdbs/max_additive_pdb_sets.h b/src/search/pdbs/max_additive_pdb_sets.h index 2add4f3847..f80ebab0c5 100644 --- a/src/search/pdbs/max_additive_pdb_sets.h +++ b/src/search/pdbs/max_additive_pdb_sets.h @@ -20,31 +20,31 @@ extern bool are_patterns_additive(const Pattern &pattern1, const VariableAdditivity &are_additive); /* - Computes maximal additive subsets of patterns. + Computes pattern cliques of the given patterns. */ -extern std::shared_ptr compute_max_additive_subsets( +extern std::shared_ptr> compute_pattern_cliques( const PatternCollection &patterns, const VariableAdditivity &are_additive); /* - We compute additive pattern sets S with the property that we could - add the new pattern P to S and still have an additive pattern set. + We compute pattern cliques S with the property that we could + add the new pattern P to S and still have a pattern clique. - Ideally, we would like to return all *maximal* sets S with this + Ideally, we would like to return all *maximal* cliques S with this property (w.r.t. set inclusion), but we don't currently - guarantee this. (What we guarantee is that all maximal such sets + guarantee this. (What we guarantee is that all maximal such cliques are *included* in the result, but the result could contain - duplicates or sets that are subsets of other sets in the + duplicates or cliques that are subcliques of other cliques in the result.) We currently implement this as follows: - * Consider all maximal additive subsets of the current collection. - * For each additive subset S, take the subset S' that contains + * Consider all pattern cliques of the current collection. + * For each clique S, take the subclique S' that contains those patterns that are additive with the new pattern P. - * Include the subset S' in the result. + * Include the subclique S' in the result. As an optimization, we actually only include S' in the result if - it is non-empty. However, this is wrong if *all* subsets we get + it is non-empty. However, this is wrong if *all* subcliques we get are empty, so we correct for this case at the end. This may include dominated elements and duplicates in the result. @@ -58,8 +58,8 @@ extern std::shared_ptr compute_max_additive_subsets( * Return the maximal cliques of G_N. One nice thing about this alternative algorithm is that we could - also use it to incrementally compute the new set of maximal additive - pattern sets after adding the new pattern P: + also use it to incrementally compute the new set of pattern cliques + after adding the new pattern P: G_N_cliques = max_cliques(G_N) // as above new_max_cliques = (old_max_cliques \setminus G_N_cliques) \union @@ -70,9 +70,9 @@ extern std::shared_ptr compute_max_additive_subsets( (old_max_cliques \setminus G_N_cliques) and all "new" cliques including P. */ -extern MaxAdditivePDBSubsets compute_max_additive_subsets_with_pattern( +extern std::vector compute_pattern_cliques_with_pattern( const PatternCollection &patterns, - const MaxAdditivePDBSubsets &known_additive_subsets, + const std::vector &known_pattern_cliques, const Pattern &new_pattern, const VariableAdditivity &are_additive); } diff --git a/src/search/pdbs/pattern_collection_generator_hillclimbing.cc b/src/search/pdbs/pattern_collection_generator_hillclimbing.cc index f76ab6482d..d7b095631d 100644 --- a/src/search/pdbs/pattern_collection_generator_hillclimbing.cc +++ b/src/search/pdbs/pattern_collection_generator_hillclimbing.cc @@ -236,15 +236,15 @@ pair PatternCollectionGeneratorHillclimbing::find_best_improving_pdb( see above) earlier. */ int count = 0; - MaxAdditivePDBSubsets max_additive_subsets = - current_pdbs->get_max_additive_subsets(pdb->get_pattern()); + std::vector pattern_cliques = + current_pdbs->get_pattern_cliques(pdb->get_pattern()); for (int sample_id = 0; sample_id < num_samples; ++sample_id) { const State &sample = samples[sample_id]; assert(utils::in_bounds(sample_id, samples_h_values)); int h_collection = samples_h_values[sample_id]; if (is_heuristic_improved( *pdb, sample, h_collection, - *current_pdbs->get_pattern_databases(), max_additive_subsets)) { + *current_pdbs->get_pattern_databases(), pattern_cliques)) { ++count; } } @@ -263,7 +263,7 @@ pair PatternCollectionGeneratorHillclimbing::find_best_improving_pdb( bool PatternCollectionGeneratorHillclimbing::is_heuristic_improved( const PatternDatabase &pdb, const State &sample, int h_collection, - const PDBCollection &pdbs, const MaxAdditivePDBSubsets &max_additive_subsets) { + const PDBCollection &pdbs, const std::vector &pattern_cliques) { // h_pattern: h-value of the new pattern int h_pattern = pdb.get_value(sample); @@ -283,14 +283,14 @@ bool PatternCollectionGeneratorHillclimbing::is_heuristic_improved( return false; h_values.push_back(h); } - for (const vector &subset : max_additive_subsets) { - int h_subset = 0; - for (int pdb_index : subset) { - h_subset += h_values[pdb_index]; + for (const PatternClique &clilque : pattern_cliques) { + int h_clique = 0; + for (PatternID pattern_id : clilque) { + h_clique += h_values[pattern_id]; } - if (h_pattern + h_subset > h_collection) { + if (h_pattern + h_clique > h_collection) { /* - return true if a max additive subset is found for + return true if a pattern clique is found for which the condition is met */ return true; diff --git a/src/search/pdbs/pattern_collection_generator_hillclimbing.h b/src/search/pdbs/pattern_collection_generator_hillclimbing.h index 8e20bd0fd7..2d5ce2a6e1 100644 --- a/src/search/pdbs/pattern_collection_generator_hillclimbing.h +++ b/src/search/pdbs/pattern_collection_generator_hillclimbing.h @@ -90,7 +90,7 @@ class PatternCollectionGeneratorHillclimbing : public PatternCollectionGenerator /* Returns true iff the h-value of the new pattern (from pdb) plus the - h-value of all maximal additive subsets from the current pattern + h-value of all pattern cliques from the current pattern collection heuristic if the new pattern was added to it is greater than the h-value of the current pattern collection. */ @@ -99,7 +99,7 @@ class PatternCollectionGeneratorHillclimbing : public PatternCollectionGenerator const State &sample, int h_collection, const PDBCollection &pdbs, - const MaxAdditivePDBSubsets &max_additive_subsets); + const std::vector &pattern_cliques); /* This is the core algorithm of this class. The initial PDB collection diff --git a/src/search/pdbs/pattern_collection_information.cc b/src/search/pdbs/pattern_collection_information.cc index e2ca772bbc..e770af306a 100644 --- a/src/search/pdbs/pattern_collection_information.cc +++ b/src/search/pdbs/pattern_collection_information.cc @@ -20,7 +20,7 @@ PatternCollectionInformation::PatternCollectionInformation( : task_proxy(task_proxy), patterns(patterns), pdbs(nullptr), - max_additive_subsets(nullptr) { + pattern_cliques(nullptr) { assert(patterns); validate_and_normalize_patterns(task_proxy, *patterns); } @@ -40,10 +40,10 @@ bool PatternCollectionInformation::information_is_valid() const { } } } - if (max_additive_subsets) { - for (const vector &additive_subset : *max_additive_subsets) { - for (int pattern_index : additive_subset) { - if (!utils::in_bounds(pattern_index, *patterns)) { + if (pattern_cliques) { + for (const PatternClique &clique : *pattern_cliques) { + for (PatternID pattern_id : clique) { + if (!utils::in_bounds(pattern_id, *patterns)) { return false; } } @@ -67,13 +67,13 @@ void PatternCollectionInformation::create_pdbs_if_missing() { } } -void PatternCollectionInformation::create_max_additive_subsets_if_missing() { - if (!max_additive_subsets) { +void PatternCollectionInformation::create_pattern_cliques_if_missing() { + if (!pattern_cliques) { utils::Timer timer; - cout << "Computing max additive subsets for pattern collection..." << endl; + cout << "Computing pattern cliques for pattern collection..." << endl; VariableAdditivity are_additive = compute_additive_vars(task_proxy); - max_additive_subsets = compute_max_additive_subsets(*patterns, are_additive); - cout << "Done computing max additive subsets for pattern collection: " + pattern_cliques = compute_pattern_cliques(*patterns, are_additive); + cout << "Done computing pattern cliques for pattern collection: " << timer << endl; } } @@ -83,9 +83,9 @@ void PatternCollectionInformation::set_pdbs(const shared_ptr &pdb assert(information_is_valid()); } -void PatternCollectionInformation::set_max_additive_subsets( - const shared_ptr &max_additive_subsets_) { - max_additive_subsets = max_additive_subsets_; +void PatternCollectionInformation::set_pattern_cliques( + const shared_ptr> &pattern_cliques_) { + pattern_cliques = pattern_cliques_; assert(information_is_valid()); } @@ -99,8 +99,8 @@ shared_ptr PatternCollectionInformation::get_pdbs() { return pdbs; } -shared_ptr PatternCollectionInformation::get_max_additive_subsets() { - create_max_additive_subsets_if_missing(); - return max_additive_subsets; +shared_ptr> PatternCollectionInformation::get_pattern_cliques() { + create_pattern_cliques_if_missing(); + return pattern_cliques; } } diff --git a/src/search/pdbs/pattern_collection_information.h b/src/search/pdbs/pattern_collection_information.h index aacf1d4961..e4cd576ce4 100644 --- a/src/search/pdbs/pattern_collection_information.h +++ b/src/search/pdbs/pattern_collection_information.h @@ -24,10 +24,10 @@ class PatternCollectionInformation { TaskProxy task_proxy; std::shared_ptr patterns; std::shared_ptr pdbs; - std::shared_ptr max_additive_subsets; + std::shared_ptr> pattern_cliques; void create_pdbs_if_missing(); - void create_max_additive_subsets_if_missing(); + void create_pattern_cliques_if_missing(); bool information_is_valid() const; public: @@ -37,8 +37,8 @@ class PatternCollectionInformation { ~PatternCollectionInformation() = default; void set_pdbs(const std::shared_ptr &pdbs); - void set_max_additive_subsets( - const std::shared_ptr &max_additive_subsets); + void set_pattern_cliques( + const std::shared_ptr> &pattern_cliques); TaskProxy get_task_proxy() const { return task_proxy; @@ -46,7 +46,7 @@ class PatternCollectionInformation { std::shared_ptr get_patterns() const; std::shared_ptr get_pdbs(); - std::shared_ptr get_max_additive_subsets(); + std::shared_ptr> get_pattern_cliques(); }; } diff --git a/src/search/pdbs/types.h b/src/search/pdbs/types.h index ca5d82c501..3c1d52abf9 100644 --- a/src/search/pdbs/types.h +++ b/src/search/pdbs/types.h @@ -9,7 +9,11 @@ class PatternDatabase; using Pattern = std::vector; using PatternCollection = std::vector; using PDBCollection = std::vector>; -using MaxAdditivePDBSubsets = std::vector>; +using PatternID = int; +/* NOTE: pattern cliques are often called maximal additive pattern subsets + in the literature. A pattern clique is a maximal additive subset of patterns + (represented by their IDs) from a pattern collection. */ +using PatternClique = std::vector; } #endif From d090c8b077cf0d9ae7ed7f54c210d7b425864e5b Mon Sep 17 00:00:00 2001 From: Silvan Sievers Date: Tue, 19 Mar 2019 11:31:04 +0100 Subject: [PATCH 30/39] [issue908] uncrustify --- src/search/pdbs/dominance_pruning.cc | 2 +- src/search/pdbs/incremental_canonical_pdbs.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/search/pdbs/dominance_pruning.cc b/src/search/pdbs/dominance_pruning.cc index ebbac5924f..50f585622c 100644 --- a/src/search/pdbs/dominance_pruning.cc +++ b/src/search/pdbs/dominance_pruning.cc @@ -115,7 +115,7 @@ class Pruner { } vector get_pruned_cliques(const utils::CountdownTimer &timer) { - int num_cliques= pattern_cliques.size(); + int num_cliques = pattern_cliques.size(); vector pruned(num_cliques, false); /* Already pruned cliques are not used to prune other diff --git a/src/search/pdbs/incremental_canonical_pdbs.cc b/src/search/pdbs/incremental_canonical_pdbs.cc index cf40d9bdc9..8f3eaacbdb 100644 --- a/src/search/pdbs/incremental_canonical_pdbs.cc +++ b/src/search/pdbs/incremental_canonical_pdbs.cc @@ -35,7 +35,7 @@ void IncrementalCanonicalPDBs::add_pdb(const shared_ptr &pdb) { void IncrementalCanonicalPDBs::recompute_pattern_cliques() { pattern_cliques = compute_pattern_cliques(*patterns, - are_additive); + are_additive); } std::vector IncrementalCanonicalPDBs::get_pattern_cliques( From 1ecb962c8f36deab0c0a26b2e1496d5d2c6267b6 Mon Sep 17 00:00:00 2001 From: Silvan Sievers Date: Tue, 19 Mar 2019 11:31:53 +0100 Subject: [PATCH 31/39] [issue908] remove std:: from cc-files --- src/search/pdbs/canonical_pdbs.cc | 2 +- src/search/pdbs/canonical_pdbs_heuristic.cc | 2 +- src/search/pdbs/dominance_pruning.cc | 8 ++++---- src/search/pdbs/incremental_canonical_pdbs.cc | 2 +- src/search/pdbs/max_additive_pdb_sets.cc | 10 +++++----- .../pdbs/pattern_collection_generator_hillclimbing.cc | 4 ++-- 6 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/search/pdbs/canonical_pdbs.cc b/src/search/pdbs/canonical_pdbs.cc index 352360e853..b4d79b9f0e 100644 --- a/src/search/pdbs/canonical_pdbs.cc +++ b/src/search/pdbs/canonical_pdbs.cc @@ -12,7 +12,7 @@ using namespace std; namespace pdbs { CanonicalPDBs::CanonicalPDBs( const shared_ptr &pdbs, - const shared_ptr> &pattern_cliques) + const shared_ptr> &pattern_cliques) : pdbs(pdbs), pattern_cliques(pattern_cliques) { assert(pdbs); assert(pattern_cliques); diff --git a/src/search/pdbs/canonical_pdbs_heuristic.cc b/src/search/pdbs/canonical_pdbs_heuristic.cc index abd6f0bd33..5339b52989 100644 --- a/src/search/pdbs/canonical_pdbs_heuristic.cc +++ b/src/search/pdbs/canonical_pdbs_heuristic.cc @@ -32,7 +32,7 @@ CanonicalPDBs get_canonical_pdbs_from_options( for dominance pruning time. */ shared_ptr pdbs = pattern_collection_info.get_pdbs(); - shared_ptr> pattern_cliques = + shared_ptr> pattern_cliques = pattern_collection_info.get_pattern_cliques(); double max_time_dominance_pruning = opts.get("max_time_dominance_pruning"); diff --git a/src/search/pdbs/dominance_pruning.cc b/src/search/pdbs/dominance_pruning.cc index 50f585622c..107d74e919 100644 --- a/src/search/pdbs/dominance_pruning.cc +++ b/src/search/pdbs/dominance_pruning.cc @@ -43,7 +43,7 @@ class Pruner { */ const PatternCollection &patterns; - const std::vector &pattern_cliques; + const vector &pattern_cliques; const int num_variables; vector variable_to_pattern_id; @@ -107,7 +107,7 @@ class Pruner { public: Pruner( const PatternCollection &patterns, - const std::vector &pattern_cliques, + const vector &pattern_cliques, int num_variables) : patterns(patterns), pattern_cliques(pattern_cliques), @@ -150,7 +150,7 @@ class Pruner { void prune_dominated_cliques( PatternCollection &patterns, PDBCollection &pdbs, - std::vector &pattern_cliques, + vector &pattern_cliques, int num_variables, double max_time) { cout << "Running dominance pruning..." << endl; @@ -164,7 +164,7 @@ void prune_dominated_cliques( pattern_cliques, num_variables).get_pruned_cliques(timer); - std::vector remaining_pattern_cliques; + vector remaining_pattern_cliques; vector is_remaining_pattern(num_patterns, false); for (size_t i = 0; i < pattern_cliques.size(); ++i) { if (!pruned[i]) { diff --git a/src/search/pdbs/incremental_canonical_pdbs.cc b/src/search/pdbs/incremental_canonical_pdbs.cc index 8f3eaacbdb..a9d35cf13d 100644 --- a/src/search/pdbs/incremental_canonical_pdbs.cc +++ b/src/search/pdbs/incremental_canonical_pdbs.cc @@ -38,7 +38,7 @@ void IncrementalCanonicalPDBs::recompute_pattern_cliques() { are_additive); } -std::vector IncrementalCanonicalPDBs::get_pattern_cliques( +vector IncrementalCanonicalPDBs::get_pattern_cliques( const Pattern &new_pattern) { return pdbs::compute_pattern_cliques_with_pattern( *patterns, *pattern_cliques, new_pattern, are_additive); diff --git a/src/search/pdbs/max_additive_pdb_sets.cc b/src/search/pdbs/max_additive_pdb_sets.cc index c445014a1b..102e6d0354 100644 --- a/src/search/pdbs/max_additive_pdb_sets.cc +++ b/src/search/pdbs/max_additive_pdb_sets.cc @@ -38,7 +38,7 @@ VariableAdditivity compute_additive_vars(const TaskProxy &task_proxy) { return are_additive; } -shared_ptr> compute_pattern_cliques( +shared_ptr> compute_pattern_cliques( const PatternCollection &patterns, const VariableAdditivity &are_additive) { // Initialize compatibility graph. vector> cgraph; @@ -55,17 +55,17 @@ shared_ptr> compute_pattern_cliques( } } - shared_ptr> max_cliques = make_shared>(); + shared_ptr> max_cliques = make_shared>(); max_cliques::compute_max_cliques(cgraph, *max_cliques); return max_cliques; } -std::vector compute_pattern_cliques_with_pattern( +vector compute_pattern_cliques_with_pattern( const PatternCollection &patterns, - const std::vector &known_pattern_cliques, + const vector &known_pattern_cliques, const Pattern &new_pattern, const VariableAdditivity &are_additive) { - std::vector cliques_additive_with_pattern; + vector cliques_additive_with_pattern; for (const PatternClique &known_clique : known_pattern_cliques) { // Take all patterns which are additive to new_pattern. PatternClique new_clique; diff --git a/src/search/pdbs/pattern_collection_generator_hillclimbing.cc b/src/search/pdbs/pattern_collection_generator_hillclimbing.cc index d7b095631d..3b736aad03 100644 --- a/src/search/pdbs/pattern_collection_generator_hillclimbing.cc +++ b/src/search/pdbs/pattern_collection_generator_hillclimbing.cc @@ -236,7 +236,7 @@ pair PatternCollectionGeneratorHillclimbing::find_best_improving_pdb( see above) earlier. */ int count = 0; - std::vector pattern_cliques = + vector pattern_cliques = current_pdbs->get_pattern_cliques(pdb->get_pattern()); for (int sample_id = 0; sample_id < num_samples; ++sample_id) { const State &sample = samples[sample_id]; @@ -263,7 +263,7 @@ pair PatternCollectionGeneratorHillclimbing::find_best_improving_pdb( bool PatternCollectionGeneratorHillclimbing::is_heuristic_improved( const PatternDatabase &pdb, const State &sample, int h_collection, - const PDBCollection &pdbs, const std::vector &pattern_cliques) { + const PDBCollection &pdbs, const vector &pattern_cliques) { // h_pattern: h-value of the new pattern int h_pattern = pdb.get_value(sample); From e849475d80326eab197f607054803ca42ec9f5d4 Mon Sep 17 00:00:00 2001 From: Jendrik Seipp Date: Tue, 19 Mar 2019 11:35:48 +0100 Subject: [PATCH 32/39] [main] Add compiler warning for testing the buildbot. --- src/search/potentials/sample_based_potential_heuristics.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/search/potentials/sample_based_potential_heuristics.cc b/src/search/potentials/sample_based_potential_heuristics.cc index 17c707cb14..1c424069a9 100644 --- a/src/search/potentials/sample_based_potential_heuristics.cc +++ b/src/search/potentials/sample_based_potential_heuristics.cc @@ -47,7 +47,7 @@ static vector> create_sample_based_potential_funct vector> functions; PotentialOptimizer optimizer(opts); shared_ptr rng(utils::parse_rng_from_options(opts)); - for (int i = 0; i < opts.get("num_heuristics"); ++i) { + for (size_t i = 0; i < opts.get("num_heuristics"); ++i) { optimize_for_samples(optimizer, opts.get("num_samples"), *rng); functions.push_back(optimizer.get_potential_function()); } From 6a4f047a90ed5035ef4eda20af8d2cf118c8d656 Mon Sep 17 00:00:00 2001 From: Jendrik Seipp Date: Tue, 19 Mar 2019 15:00:30 +0100 Subject: [PATCH 33/39] [main] Backed out changeset 3e536118d512 --- src/search/potentials/sample_based_potential_heuristics.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/search/potentials/sample_based_potential_heuristics.cc b/src/search/potentials/sample_based_potential_heuristics.cc index 1c424069a9..17c707cb14 100644 --- a/src/search/potentials/sample_based_potential_heuristics.cc +++ b/src/search/potentials/sample_based_potential_heuristics.cc @@ -47,7 +47,7 @@ static vector> create_sample_based_potential_funct vector> functions; PotentialOptimizer optimizer(opts); shared_ptr rng(utils::parse_rng_from_options(opts)); - for (size_t i = 0; i < opts.get("num_heuristics"); ++i) { + for (int i = 0; i < opts.get("num_heuristics"); ++i) { optimize_for_samples(optimizer, opts.get("num_samples"), *rng); functions.push_back(optimizer.get_potential_function()); } From 269d65855282f98d5ad737993bee3e7175cee7ca Mon Sep 17 00:00:00 2001 From: Silvan Sievers Date: Tue, 19 Mar 2019 21:37:17 +0100 Subject: [PATCH 34/39] [issue908] doc: drop maximal; subset -> set --- src/search/pdbs/types.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/search/pdbs/types.h b/src/search/pdbs/types.h index 3c1d52abf9..c738dc436f 100644 --- a/src/search/pdbs/types.h +++ b/src/search/pdbs/types.h @@ -11,8 +11,8 @@ using PatternCollection = std::vector; using PDBCollection = std::vector>; using PatternID = int; /* NOTE: pattern cliques are often called maximal additive pattern subsets - in the literature. A pattern clique is a maximal additive subset of patterns - (represented by their IDs) from a pattern collection. */ + in the literature. A pattern clique is an additive set of patterns, + represented by their IDs (indices) in a pattern collection. */ using PatternClique = std::vector; } From e6007f5fd3e2b9cd0ae2475a068723d09e63da0b Mon Sep 17 00:00:00 2001 From: Silvan Sievers Date: Wed, 20 Mar 2019 10:04:26 +0100 Subject: [PATCH 35/39] [issue908] v6 exp --- experiments/issue908/v6.py | 64 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100755 experiments/issue908/v6.py diff --git a/experiments/issue908/v6.py b/experiments/issue908/v6.py new file mode 100755 index 0000000000..692f01cee5 --- /dev/null +++ b/experiments/issue908/v6.py @@ -0,0 +1,64 @@ +#! /usr/bin/env python +# -*- coding: utf-8 -*- + +import itertools +import os + +from lab.environments import LocalEnvironment, BaselSlurmEnvironment +from lab.reports import Attribute, geometric_mean + +from downward.reports.compare import ComparativeReport + +import common_setup +from common_setup import IssueConfig, IssueExperiment +from relativescatter import RelativeScatterPlotReport + +DIR = os.path.dirname(os.path.abspath(__file__)) +SCRIPT_NAME = os.path.splitext(os.path.basename(__file__))[0] +BENCHMARKS_DIR = os.environ["DOWNWARD_BENCHMARKS"] +REVISIONS = ["issue908-base", "issue908-v6"] +CONFIGS = [ + IssueConfig("cpdbs-hc", ['--search', 'astar(cpdbs(hillclimbing))']), + IssueConfig("cpdbs-sys2", ['--search', 'astar(cpdbs(systematic(2)))']), + IssueConfig("cpdbs-sys3", ['--search', 'astar(cpdbs(systematic(3)))']), +] + +SUITE = common_setup.DEFAULT_OPTIMAL_SUITE +ENVIRONMENT = BaselSlurmEnvironment( + partition="infai_2", + email="silvan.sievers@unibas.ch", + export=["PATH", "DOWNWARD_BENCHMARKS"]) + +if common_setup.is_test_run(): + SUITE = IssueExperiment.DEFAULT_TEST_SUITE + ENVIRONMENT = LocalEnvironment(processes=1) + +exp = IssueExperiment( + revisions=REVISIONS, + configs=CONFIGS, + environment=ENVIRONMENT, +) +exp.add_suite(BENCHMARKS_DIR, SUITE) + +exp.add_parser(exp.EXITCODE_PARSER) +exp.add_parser(exp.TRANSLATOR_PARSER) +exp.add_parser(exp.SINGLE_SEARCH_PARSER) +exp.add_parser(exp.PLANNER_PARSER) +exp.add_parser('parser.py') + +exp.add_step('build', exp.build) +exp.add_step('start', exp.start_runs) +exp.add_fetcher(name='fetch') + +attributes=exp.DEFAULT_TABLE_ATTRIBUTES +attributes.extend([ + Attribute('generator_computation_time', absolute=False, min_wins=True, functions=[geometric_mean]), + Attribute('cpdbs_computation_time', absolute=False, min_wins=True, functions=[geometric_mean]), + Attribute('dominance_pruning_time', absolute=False, min_wins=True, functions=[geometric_mean]), +]) + +#exp.add_absolute_report_step() +exp.add_comparison_table_step(attributes=attributes) +exp.add_scatter_plot_step(relative=True, attributes=['generator_computation_time', 'cpdbs_computation_time', 'dominance_pruning_time', "search_time", "total_time"]) + +exp.run_steps() From 4f2cd52996ec4f8ef547e0bf0dd0b0700fe058ce Mon Sep 17 00:00:00 2001 From: Jendrik Seipp Date: Wed, 20 Mar 2019 14:17:01 +0100 Subject: [PATCH 36/39] [main] Add compiler warning for testing the buildbot. --- src/search/potentials/sample_based_potential_heuristics.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/search/potentials/sample_based_potential_heuristics.cc b/src/search/potentials/sample_based_potential_heuristics.cc index 17c707cb14..1c424069a9 100644 --- a/src/search/potentials/sample_based_potential_heuristics.cc +++ b/src/search/potentials/sample_based_potential_heuristics.cc @@ -47,7 +47,7 @@ static vector> create_sample_based_potential_funct vector> functions; PotentialOptimizer optimizer(opts); shared_ptr rng(utils::parse_rng_from_options(opts)); - for (int i = 0; i < opts.get("num_heuristics"); ++i) { + for (size_t i = 0; i < opts.get("num_heuristics"); ++i) { optimize_for_samples(optimizer, opts.get("num_samples"), *rng); functions.push_back(optimizer.get_potential_function()); } From a0047349eee4a20b8eaf5dea22bbee42b103a380 Mon Sep 17 00:00:00 2001 From: Jendrik Seipp Date: Wed, 20 Mar 2019 14:35:13 +0100 Subject: [PATCH 37/39] [main] Backed out changeset 1c9f2276bac8 --- src/search/potentials/sample_based_potential_heuristics.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/search/potentials/sample_based_potential_heuristics.cc b/src/search/potentials/sample_based_potential_heuristics.cc index 1c424069a9..17c707cb14 100644 --- a/src/search/potentials/sample_based_potential_heuristics.cc +++ b/src/search/potentials/sample_based_potential_heuristics.cc @@ -47,7 +47,7 @@ static vector> create_sample_based_potential_funct vector> functions; PotentialOptimizer optimizer(opts); shared_ptr rng(utils::parse_rng_from_options(opts)); - for (size_t i = 0; i < opts.get("num_heuristics"); ++i) { + for (int i = 0; i < opts.get("num_heuristics"); ++i) { optimize_for_samples(optimizer, opts.get("num_samples"), *rng); functions.push_back(optimizer.get_potential_function()); } From e8061e913dd9dce0de9724e81831d7a236434498 Mon Sep 17 00:00:00 2001 From: Silvan Sievers Date: Thu, 21 Mar 2019 11:52:55 +0100 Subject: [PATCH 38/39] [issue910] fix move assignment operator of State: copy task pointer --- src/search/task_proxy.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/search/task_proxy.h b/src/search/task_proxy.h index 4ceede202b..b5b3171aa2 100644 --- a/src/search/task_proxy.h +++ b/src/search/task_proxy.h @@ -580,6 +580,7 @@ class State { State &operator=(State &&other) { if (this != &other) { + task = other.task; values = std::move(other.values); other.task = nullptr; } From 82998a630b069e5eecb87ab732cda871ec511a2d Mon Sep 17 00:00:00 2001 From: Silvan Sievers Date: Thu, 21 Mar 2019 15:45:22 +0100 Subject: [PATCH 39/39] [issue908] rename max_additive_pdb_sets.* to pattern_cliques.* --- src/search/DownwardFiles.cmake | 2 +- src/search/pdbs/incremental_canonical_pdbs.h | 2 +- .../pdbs/{max_additive_pdb_sets.cc => pattern_cliques.cc} | 2 +- .../pdbs/{max_additive_pdb_sets.h => pattern_cliques.h} | 4 ++-- src/search/pdbs/pattern_collection_information.cc | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) rename src/search/pdbs/{max_additive_pdb_sets.cc => pattern_cliques.cc} (98%) rename src/search/pdbs/{max_additive_pdb_sets.h => pattern_cliques.h} (97%) diff --git a/src/search/DownwardFiles.cmake b/src/search/DownwardFiles.cmake index 5abb20896b..4adf212a67 100644 --- a/src/search/DownwardFiles.cmake +++ b/src/search/DownwardFiles.cmake @@ -707,8 +707,8 @@ fast_downward_plugin( pdbs/dominance_pruning pdbs/incremental_canonical_pdbs pdbs/match_tree - pdbs/max_additive_pdb_sets pdbs/max_cliques + pdbs/pattern_cliques pdbs/pattern_collection_information pdbs/pattern_collection_generator_combo pdbs/pattern_collection_generator_genetic diff --git a/src/search/pdbs/incremental_canonical_pdbs.h b/src/search/pdbs/incremental_canonical_pdbs.h index 677d25bec0..e69f9f1155 100644 --- a/src/search/pdbs/incremental_canonical_pdbs.h +++ b/src/search/pdbs/incremental_canonical_pdbs.h @@ -1,7 +1,7 @@ #ifndef PDBS_INCREMENTAL_CANONICAL_PDBS_H #define PDBS_INCREMENTAL_CANONICAL_PDBS_H -#include "max_additive_pdb_sets.h" +#include "pattern_cliques.h" #include "pattern_collection_information.h" #include "types.h" diff --git a/src/search/pdbs/max_additive_pdb_sets.cc b/src/search/pdbs/pattern_cliques.cc similarity index 98% rename from src/search/pdbs/max_additive_pdb_sets.cc rename to src/search/pdbs/pattern_cliques.cc index 102e6d0354..fe25f5f669 100644 --- a/src/search/pdbs/max_additive_pdb_sets.cc +++ b/src/search/pdbs/pattern_cliques.cc @@ -1,4 +1,4 @@ -#include "max_additive_pdb_sets.h" +#include "pattern_cliques.h" #include "pattern_database.h" diff --git a/src/search/pdbs/max_additive_pdb_sets.h b/src/search/pdbs/pattern_cliques.h similarity index 97% rename from src/search/pdbs/max_additive_pdb_sets.h rename to src/search/pdbs/pattern_cliques.h index f80ebab0c5..6c6b3de4b9 100644 --- a/src/search/pdbs/max_additive_pdb_sets.h +++ b/src/search/pdbs/pattern_cliques.h @@ -1,5 +1,5 @@ -#ifndef PDBS_MAX_ADDITIVE_PDB_SETS_H -#define PDBS_MAX_ADDITIVE_PDB_SETS_H +#ifndef PDBS_PATTERN_CLIQUES_H +#define PDBS_PATTERN_CLIQUES_H #include "types.h" diff --git a/src/search/pdbs/pattern_collection_information.cc b/src/search/pdbs/pattern_collection_information.cc index e770af306a..a0ee889224 100644 --- a/src/search/pdbs/pattern_collection_information.cc +++ b/src/search/pdbs/pattern_collection_information.cc @@ -1,7 +1,7 @@ #include "pattern_collection_information.h" #include "pattern_database.h" -#include "max_additive_pdb_sets.h" +#include "pattern_cliques.h" #include "validation.h" #include "../utils/timer.h"