From 587623e8e9a1bc97af1518ab67d3637987c5e828 Mon Sep 17 00:00:00 2001 From: ClemensBuechner Date: Tue, 16 Jan 2024 10:26:32 +0100 Subject: [PATCH] Migrate changes from outdated pull request. --- src/search/landmarks/landmark_graph.cc | 26 ++++++++++++++++++++++ src/search/landmarks/landmark_graph.h | 6 +++++ src/search/landmarks/landmark_heuristic.cc | 18 ++++++++++----- 3 files changed, 44 insertions(+), 6 deletions(-) diff --git a/src/search/landmarks/landmark_graph.cc b/src/search/landmarks/landmark_graph.cc index 4ce14e2ebf..5f6a8bf066 100644 --- a/src/search/landmarks/landmark_graph.cc +++ b/src/search/landmarks/landmark_graph.cc @@ -57,6 +57,11 @@ LandmarkNode &LandmarkGraph::get_disjunctive_landmark(const FactPair &fact) cons return *(disjunctive_landmarks_to_nodes.find(fact)->second); } +const vector &LandmarkGraph::get_conjunctive_landmarks( + const FactPair &fact) const { + assert(contains_conjunctive_landmark(fact)); + return conjunctive_landmarks_to_nodes.find(fact)->second; +} bool LandmarkGraph::contains_simple_landmark(const FactPair &lm) const { return simple_landmarks_to_nodes.count(lm) != 0; @@ -66,6 +71,10 @@ bool LandmarkGraph::contains_disjunctive_landmark(const FactPair &lm) const { return disjunctive_landmarks_to_nodes.count(lm) != 0; } +bool LandmarkGraph::contains_conjunctive_landmark(const FactPair &lm) const { + return conjunctive_landmarks_to_nodes.count(lm) != 0; +} + bool LandmarkGraph::contains_overlapping_disjunctive_landmark( const set &lm) const { // Test whether ONE of the facts is present in some disjunctive landmark. @@ -118,6 +127,15 @@ LandmarkNode &LandmarkGraph::add_landmark(Landmark &&landmark) { } ++num_disjunctive_landmarks; } else if (lm.conjunctive) { + for (const FactPair &lm_fact : lm.facts) { + auto it = conjunctive_landmarks_to_nodes.find(lm_fact); + if (it == conjunctive_landmarks_to_nodes.end()) { + conjunctive_landmarks_to_nodes.emplace( + lm_fact, vector{new_node_p}); + } else { + (it->second).push_back(new_node_p); + } + } ++num_conjunctive_landmarks; } else { simple_landmarks_to_nodes.emplace(lm.facts.front(), new_node_p); @@ -144,6 +162,14 @@ void LandmarkGraph::remove_node_occurrences(LandmarkNode *node) { } } else if (landmark.conjunctive) { --num_conjunctive_landmarks; + for (const FactPair &lm_fact : landmark.facts) { + vector *conjunctive_landmarks_vector = + &(conjunctive_landmarks_to_nodes.find(lm_fact)->second); + auto it = find(conjunctive_landmarks_vector->begin(), + conjunctive_landmarks_vector->end(), node); + assert(it != conjunctive_landmarks_vector->end()); + conjunctive_landmarks_vector->erase(it); + } } else { simple_landmarks_to_nodes.erase(landmark.facts[0]); } diff --git a/src/search/landmarks/landmark_graph.h b/src/search/landmarks/landmark_graph.h index f198bba02b..88941122f6 100644 --- a/src/search/landmarks/landmark_graph.h +++ b/src/search/landmarks/landmark_graph.h @@ -77,6 +77,7 @@ class LandmarkGraph { utils::HashMap simple_landmarks_to_nodes; utils::HashMap disjunctive_landmarks_to_nodes; + utils::HashMap> conjunctive_landmarks_to_nodes; Nodes nodes; void remove_node_occurrences(LandmarkNode *node); @@ -118,6 +119,9 @@ class LandmarkGraph { /* This is needed only by landmark graph factories and will disappear when moving landmark graph creation there. */ LandmarkNode &get_disjunctive_landmark(const FactPair &fact) const; + // TODO: comment? + const std::vector &get_conjunctive_landmarks( + const FactPair &fact) const; /* This is needed only by landmark graph factories and will disappear when moving landmark graph creation there. It is not needed by @@ -125,6 +129,8 @@ class LandmarkGraph { bool contains_simple_landmark(const FactPair &lm) const; /* Only used internally. */ bool contains_disjunctive_landmark(const FactPair &lm) const; + // TODO: comment? + bool contains_conjunctive_landmark(const FactPair &lm) const; /* This is needed only by landmark graph factories and will disappear when moving landmark graph creation there. It is not needed by HMLandmarkFactory*/ diff --git a/src/search/landmarks/landmark_heuristic.cc b/src/search/landmarks/landmark_heuristic.cc index b03c119a13..6e7b2ac061 100644 --- a/src/search/landmarks/landmark_heuristic.cc +++ b/src/search/landmarks/landmark_heuristic.cc @@ -118,12 +118,7 @@ void LandmarkHeuristic::compute_landmark_graph( void LandmarkHeuristic::generate_preferred_operators( const State &state, ConstBitsetView &future) { - /* - Find operators that achieve future landmarks. - TODO: Conjunctive landmarks are ignored in *lm_graph->get_node(...)*, so - they are ignored when computing preferred operators. We consider this - a bug and want to fix it in issue1072. - */ + // Find operators that achieve future landmarks. assert(successor_generator); vector applicable_operators; successor_generator->generate_applicable_ops(state, applicable_operators); @@ -139,6 +134,17 @@ void LandmarkHeuristic::generate_preferred_operators( if (lm_node && future.test(lm_node->get_id())) { set_preferred(op); } + if (lm_graph->contains_conjunctive_landmark( + fact_proxy.get_pair())) { + vector conjunctive_landmarks = + lm_graph->get_conjunctive_landmarks(fact_proxy.get_pair()); + for (auto conj_lm : conjunctive_landmarks) { + if (future.test(conj_lm->get_id())) { + set_preferred(op); + break; + } + } + } } } }