diff --git a/driver/aliases.py b/driver/aliases.py index d7b474d4ab..53f3b7eac5 100644 --- a/driver/aliases.py +++ b/driver/aliases.py @@ -141,9 +141,14 @@ def _get_lama(pref): ALIASES["seq-opt-lmcut"] = [ "--search", "astar(lmcut())"] -ALIASES["issue1134-1"] = [ +ALIASES["issue1134-if"] = [ "--search", - "astar(operatorcounting([delete_relaxation_constraints(use_time_vars=true, use_integer_vars=true)], use_integer_operator_counts=false, lpsolver=cplex, verbosity=normal, transform=no_transform(), cache_estimates=true))" + "astar(operatorcounting([delete_relaxation_constraints(use_time_vars=true, use_integer_vars=true)], use_integer_operator_counts=true, lpsolver=cplex, verbosity=normal, transform=no_transform(), cache_estimates=true))" +] # TODO issue1134 remove + +ALIASES["issue1134-rr"] = [ + "--search", + "astar(operatorcounting([delete_relaxation_constraints_rr(use_time_vars=true, use_integer_vars=true)], use_integer_operator_counts=true, lpsolver=cplex, verbosity=normal, transform=no_transform(), cache_estimates=true))" ] # TODO issue1134 remove PORTFOLIOS = {} diff --git a/src/search/CMakeLists.txt b/src/search/CMakeLists.txt index 49b7569e55..8347c08b7b 100644 --- a/src/search/CMakeLists.txt +++ b/src/search/CMakeLists.txt @@ -857,6 +857,7 @@ create_fast_downward_library( SOURCES operator_counting/constraint_generator operator_counting/delete_relaxation_constraints_if + operator_counting/delete_relaxation_constraints_rr operator_counting/lm_cut_constraints operator_counting/operator_counting_heuristic operator_counting/pho_constraints diff --git a/src/search/operator_counting/delete_relaxation_constraints_rr.cc b/src/search/operator_counting/delete_relaxation_constraints_rr.cc index 212f4b05ff..78fcad8f94 100644 --- a/src/search/operator_counting/delete_relaxation_constraints_rr.cc +++ b/src/search/operator_counting/delete_relaxation_constraints_rr.cc @@ -33,6 +33,10 @@ int DeleteRelaxationConstraintsRR::get_var_f_maps_to(FactPair f, return lp_var_id_f_maps_to.at(make_tuple(f.var, f.value, op.get_id())); } +int DeleteRelaxationConstraintsRR::get_constraint_id(FactPair f) { + return lp_con_id_f_defined[f.var][f.value]; +} + bool DeleteRelaxationConstraintsRR::is_in_effect(FactPair f, const OperatorProxy &op) { for (EffectProxy eff : op.get_effects()) { @@ -56,7 +60,6 @@ bool DeleteRelaxationConstraintsRR::is_in_precondition( void DeleteRelaxationConstraintsRR::create_auxiliary_variables( const TaskProxy &task_proxy, LPVariables &variables) { OperatorsProxy ops = task_proxy.get_operators(); - int num_ops = ops.size(); VariablesProxy vars = task_proxy.get_variables(); int num_vars = vars.size(); @@ -89,25 +92,23 @@ void DeleteRelaxationConstraintsRR::create_constraints( OperatorsProxy ops = task_proxy.get_operators(); VariablesProxy vars = task_proxy.get_variables(); - /* - f must map a proposition to at most one operator. - Constraint (2) in paper. - */ + // Constraint (2) in paper. + lp_con_id_f_defined.resize(vars.size()); for (VariableProxy var_p : vars) { + lp_con_id_f_defined[var_p.get_id()].resize(var_p.get_domain_size()); for (int value_p = 0; value_p < var_p.get_domain_size(); ++value_p) { + lp_con_id_f_defined[var_p.get_id()][value_p] = constraints.size(); constraints.emplace_back(0, 0); FactPair fact_p(var_p.get_id(), value_p); - constraints.back().insert(get_var_f_defined(fact_p), -1); + constraints.back().insert(get_var_f_defined(fact_p), 1); for (OperatorProxy op : ops) { if (is_in_effect(fact_p, op)) - constraints.back().insert(get_var_f_maps_to(fact_p, op), 1); + constraints.back().insert(get_var_f_maps_to(fact_p, op), -1); } } } - /* - Constraint (3) in paper. - */ + // Constraint (3) in paper. for (VariableProxy var_p : vars) { for (int value_p = 0; value_p < var_p.get_domain_size(); ++value_p) { FactPair fact_p(var_p.get_id(), value_p); @@ -115,6 +116,8 @@ void DeleteRelaxationConstraintsRR::create_constraints( for (int value_q = 0; value_q < var_q.get_domain_size(); ++value_q) { FactPair fact_q(var_q.get_id(), value_q); + if (fact_q != fact_p) + break; constraints.emplace_back(0, 1); constraints.back().insert(get_var_f_defined(fact_q), 1); for (OperatorProxy op : ops) { @@ -129,16 +132,12 @@ void DeleteRelaxationConstraintsRR::create_constraints( } } - /* - Constraint (4) in paper. - */ + // Constraint (4) in paper. for (FactProxy goal : task_proxy.get_goals()) { variables[get_var_f_defined(goal.get_pair())].lower_bound = 1; } - /* - Constraint (5) in paper. - */ + // Constraint (5) in paper. for (OperatorProxy op : ops) { for (EffectProxy eff : op.get_effects()) { FactPair fact_p = eff.get_fact().get_pair(); @@ -147,6 +146,8 @@ void DeleteRelaxationConstraintsRR::create_constraints( constraints.back().insert(op.get_id(), 1); } } + + // TODO: Implement Constraints (6)-(8). } void DeleteRelaxationConstraintsRR::initialize_constraints( @@ -159,14 +160,18 @@ void DeleteRelaxationConstraintsRR::initialize_constraints( bool DeleteRelaxationConstraintsRR::update_constraints( const State &state, lp::LPSolver &lp_solver) { // Unset old bounds. + int con_id; for (FactPair f : last_state) { - lp_solver.set_constraint_lower_bound(get_constraint_id(f), 0); + con_id = get_constraint_id(f); + lp_solver.set_constraint_lower_bound(con_id, 0); + lp_solver.set_constraint_upper_bound(con_id, 0); } last_state.clear(); // Set new bounds. for (FactProxy f : state) { - lp_solver.set_constraint_lower_bound(get_constraint_id(f.get_pair()), - -1); + con_id = get_constraint_id(f.get_pair()); + lp_solver.set_constraint_lower_bound(con_id, 1); + lp_solver.set_constraint_upper_bound(con_id, 1); last_state.push_back(f.get_pair()); } return false; diff --git a/src/search/operator_counting/delete_relaxation_constraints_rr.h b/src/search/operator_counting/delete_relaxation_constraints_rr.h index c40362e82b..3028115fa6 100644 --- a/src/search/operator_counting/delete_relaxation_constraints_rr.h +++ b/src/search/operator_counting/delete_relaxation_constraints_rr.h @@ -4,6 +4,7 @@ #include "constraint_generator.h" #include "../task_proxy.h" +#include "../utils/hash.h" #include @@ -21,6 +22,10 @@ using LPConstraints = named_vector::NamedVector; using LPVariables = named_vector::NamedVector; class DeleteRelaxationConstraintsRR : public ConstraintGenerator { + // TODO: Rework these. + bool use_time_vars; + bool use_integer_vars; + /* A causal partial function f maps a fact to one of its achieving operators. */ @@ -33,16 +38,26 @@ class DeleteRelaxationConstraintsRR : public ConstraintGenerator { /* [f_{p,a}] Does f map fact p to operator a? Binary, maps to LP variable index */ - std::unordered_map, int> lp_var_id_f_maps_to; + //std::unordered_map, int> lp_var_id_f_maps_to; + utils::HashMap, int> lp_var_id_f_maps_to; + + /* + Store constraint IDs of Constraints (2) in the paper. We need to + reference them when updating constraints for a given state. They are + indexed by the fact p. + */ + std::vector> lp_con_id_f_defined; + + /* The state that is currently used for setting the bounds. Remembering + this makes it faster to unset the bounds when the state changes. */ + std::vector last_state; - // TODO: Rework these. - bool use_time_vars; - bool use_integer_vars; - bool is_in_effect(FactPair f, const OperatorProxy &op); - bool is_in_precondition(FactPair f, const OperatorProxy &op); int get_var_f_defined(FactPair f); int get_var_f_maps_to(FactPair f, const OperatorProxy &op); + int get_constraint_id(FactPair f); + bool is_in_effect(FactPair f, const OperatorProxy &op); + bool is_in_precondition(FactPair f, const OperatorProxy &op); void create_auxiliary_variables( const TaskProxy &task_proxy, LPVariables &variables); diff --git a/src/search/utils/hash.h b/src/search/utils/hash.h index db13437ad3..bc755d7558 100644 --- a/src/search/utils/hash.h +++ b/src/search/utils/hash.h @@ -26,7 +26,7 @@ namespace utils { that are "fed" to the main hashing function (implemented in class HashState) one by one. This allows a compositional approach to hashing. For example, the code for a pair p is the concatenation of - code(x.first) and code(x.second). + code(p.first) and code(p.second). A simpler compositional approach to hashing would first hash the components of an object and then combine the hash values, and this @@ -258,6 +258,11 @@ void feed(HashState &hash_state, const std::vector &vec) { } } +template +void feed(HashState &hash_state, const std::tuple &t) { + std::apply([&](auto &&... element) {((feed(hash_state, element)), ...);}, t); +} + /* Public hash functions.