25#include "absl/algorithm/container.h"
26#include "absl/container/flat_hash_map.h"
27#include "absl/container/flat_hash_set.h"
28#include "absl/log/check.h"
29#include "absl/random/distributions.h"
30#include "absl/strings/str_cat.h"
31#include "absl/strings/string_view.h"
32#include "absl/types/span.h"
60 if (mapping_.IsBoolean(var)) {
61 return boolean_assignment_.VariableIsAssigned(
62 mapping_.Literal(var).Variable());
63 }
else if (mapping_.IsInteger(var)) {
64 return integer_trail_.IsFixed(mapping_.Integer(var));
70 if (mapping_.IsBoolean(var)) {
72 return boolean_assignment_.LiteralIsTrue(l) ? 1 : 0;
73 }
else if (mapping_.IsInteger(var)) {
74 return integer_trail_.LowerBound(mapping_.Integer(var)).value();
80 if (mapping_.IsBoolean(var)) {
82 return boolean_assignment_.LiteralIsFalse(l) ? 0 : 1;
83 }
else if (mapping_.IsInteger(var)) {
84 return integer_trail_.UpperBound(mapping_.Integer(var)).value();
90 int64_t value)
const {
93 if (mapping_.IsBoolean(var)) {
94 DCHECK(value == 0 || value == 1);
98 }
else if (mapping_.IsInteger(var)) {
100 mapping_.Integer(var), IntegerValue(value));
106 int64_t value)
const {
109 if (mapping_.IsBoolean(var)) {
110 DCHECK(value == 0 || value == 1);
114 }
else if (mapping_.IsInteger(var)) {
116 IntegerValue(value));
124 if (mapping_.IsBoolean(var)) {
126 }
else if (mapping_.IsInteger(var)) {
127 const IntegerVariable variable = mapping_.Integer(var);
128 const std::vector<ValueLiteralPair> encoding =
129 integer_encoder_.FullDomainEncoding(variable);
134 const int target = (
static_cast<int>(encoding.size()) + 1) / 2 - 1;
144 if (mapping_.IsBoolean(var)) {
145 if (absl::Bernoulli(random_, 0.5)) {
150 }
else if (mapping_.IsInteger(var)) {
151 if (absl::Bernoulli(random_, 0.5)) {
153 mapping_.Integer(var), IntegerValue(lb + (ub - lb) / 2));
156 mapping_.Integer(var), IntegerValue(ub - (ub - lb) / 2));
171bool ModelHasSchedulingConstraints(
const CpModelProto& cp_model_proto) {
179void AddExtraSchedulingPropagators(SatParameters& new_params) {
180 new_params.set_exploit_all_precedences(
true);
181 new_params.set_use_hard_precedences_in_cumulative(
true);
182 new_params.set_use_overload_checker_in_cumulative(
true);
183 new_params.set_use_strong_propagation_in_disjunctive(
true);
184 new_params.set_use_timetable_edge_finding_in_cumulative(
true);
185 new_params.set_use_conservative_scale_overload_checker(
true);
186 new_params.set_max_pairs_pairwise_reasoning_in_no_overlap_2d(5000);
187 new_params.set_use_timetabling_in_no_overlap_2d(
true);
188 new_params.set_use_energetic_reasoning_in_no_overlap_2d(
true);
189 new_params.set_use_area_energetic_reasoning_in_no_overlap_2d(
true);
190 new_params.set_use_try_edge_reasoning_in_no_overlap_2d(
true);
191 new_params.set_no_overlap_2d_boolean_relations_limit(100);
199 bool operator<=(
const NoisyInteger& other)
const {
200 return value < other.value ||
201 (value == other.value && noise <= other.noise);
203 bool operator>(
const NoisyInteger& other)
const {
204 return value > other.value || (value == other.value && noise > other.noise);
214 std::vector<DecisionStrategyProto> strategies;
216 strategies.push_back(proto);
224 return [&view, ¶meters, random, strategies]() {
226 int candidate_ref = -1;
227 int64_t candidate_value = std::numeric_limits<int64_t>::max();
233 const bool randomize_decision =
234 parameters.search_random_variable_pool_size() > 1;
236 randomize_decision ? parameters.search_random_variable_pool_size()
240 const int var = expr.vars(0);
241 if (view.IsFixed(var))
continue;
243 int64_t coeff = expr.coeffs(0);
244 int64_t offset = expr.offset();
245 int64_t lb = view.Min(var);
246 int64_t ub = view.Max(var);
256 switch (strategy.variable_selection_strategy()) {
260 value = coeff * lb + offset;
263 value = -(coeff * ub + offset);
271 value = -(ub - lb + 1);
274 LOG(FATAL) <<
"Unknown VariableSelectionStrategy "
275 << strategy.variable_selection_strategy();
278 if (randomize_decision) {
281 const double noise = absl::Uniform(*random, 0., 1.0);
282 top_variables.
Add(ref, {-value, noise});
283 candidate_value = std::min(candidate_value, value);
284 }
else if (value < candidate_value) {
286 candidate_value = value;
291 if (strategy.variable_selection_strategy() ==
293 !randomize_decision) {
299 if (candidate_value == std::numeric_limits<int64_t>::max())
continue;
302 if (randomize_decision) {
304 candidate_ref = candidates[absl::Uniform(
305 *random, 0,
static_cast<int>(candidates.size()))];
309 strategy.domain_reduction_strategy();
330 const int64_t lb = view.Min(var);
331 const int64_t ub = view.Max(var);
334 return view.LowerOrEqual(var, lb);
336 return view.GreaterOrEqual(var, ub);
338 return view.LowerOrEqual(var, lb + (ub - lb) / 2);
340 return view.GreaterOrEqual(var, ub - (ub - lb) / 2);
342 return view.MedianValue(var);
344 return view.RandomSplit(var, lb, ub);
346 LOG(FATAL) <<
"Unknown DomainReductionStrategy "
347 << strategy.domain_reduction_strategy();
357 if (ModelHasSchedulingConstraints(cp_model_proto)) {
360 bool possible_new_constraints =
false;
361 if (params.use_dynamic_precedence_in_disjunctive()) {
362 possible_new_constraints =
true;
365 if (params.use_dynamic_precedence_in_cumulative()) {
366 possible_new_constraints =
true;
375 if (possible_new_constraints && params.new_linear_propagation()) {
385std::function<BooleanOrIntegerLiteral()>
387 absl::Span<const IntegerVariable> variable_mapping,
388 IntegerVariable objective_var,
Model* model) {
390 if (!params.instantiate_all_variables()) {
394 std::vector<IntegerVariable> decisions;
395 for (
const IntegerVariable var : variable_mapping) {
402 decisions.push_back(objective_var);
404 decisions.push_back(var);
413 std::vector<BooleanOrIntegerVariable> vars;
414 std::vector<IntegerValue> values;
436 if (user_search !=
nullptr) {
437 heuristics.push_back(user_search);
439 if (heuristic_search !=
nullptr) {
440 heuristics.push_back(heuristic_search);
442 if (integer_completion !=
nullptr) {
443 heuristics.push_back(integer_completion);
451 absl::Span<const IntegerVariable> variable_mapping,
454 std::vector<int> ref_to_display;
458 ref_to_display.push_back(
i);
460 std::sort(ref_to_display.begin(), ref_to_display.end(), [&](
int i,
int j) {
461 return cp_model_proto.variables(i).name() <
462 cp_model_proto.variables(j).name();
465 std::vector<std::pair<int64_t, int64_t>> old_domains(variable_mapping.size());
466 return [instrumented_strategy, model, variable_mapping, &cp_model_proto,
467 old_domains, ref_to_display]()
mutable {
469 if (!decision.
HasValue())
return decision;
473 LOG(INFO) <<
"Boolean decision " << l;
475 for (
const IntegerLiteral i_lit : encoder->GetIntegerLiterals(l)) {
476 LOG(INFO) <<
" - associated with " << i_lit;
478 for (
const auto [var, value] : encoder->GetEqualityLiterals(l)) {
479 LOG(INFO) <<
" - associated with " << var <<
" == " << value;
484 const int level = model->
Get<
Trail>()->CurrentDecisionLevel();
485 std::string to_display =
486 absl::StrCat(
"Diff since last call, level=", level,
"\n");
488 for (
const int ref : ref_to_display) {
489 const IntegerVariable var = variable_mapping[ref];
490 const std::pair<int64_t, int64_t> new_domain(
493 if (new_domain != old_domains[ref]) {
494 absl::StrAppend(&to_display, cp_model_proto.variables(ref).name(),
" [",
495 old_domains[ref].first,
",", old_domains[ref].second,
496 "] -> [", new_domain.first,
",", new_domain.second,
498 old_domains[ref] = new_domain;
501 LOG(INFO) << to_display;
508 absl::flat_hash_map<std::string, SatParameters> strategies;
516 strategies[
"default"] = base_params;
522 strategies[
"no_lp"] = new_params;
524 strategies[
"default_lp"] = new_params;
527 strategies[
"max_lp"] = new_params;
529 strategies[
"max_lp_sym"] = new_params;
543 strategies[
"core"] = new_params;
552 strategies[
"core_default_lp"] = new_params;
560 strategies[
"core_max_lp"] = new_params;
568 strategies[
"max_hs"] = new_params;
579 strategies[
"lb_tree_search_no_lp"] = new_params;
583 AddExtraSchedulingPropagators(new_params);
588 strategies[
"lb_tree_search"] = new_params;
596 strategies[
"objective_lb_search_no_lp"] = new_params;
599 strategies[
"objective_lb_search"] = new_params;
602 AddExtraSchedulingPropagators(new_params);
605 strategies[
"objective_lb_search_max_lp"] = new_params;
615 AddExtraSchedulingPropagators(new_params);
618 strategies[
"objective_shaving"] = new_params;
621 strategies[
"objective_shaving_no_lp"] = new_params;
624 strategies[
"objective_shaving_max_lp"] = new_params;
636 strategies[
"variables_shaving"] = new_params;
639 strategies[
"variables_shaving_no_lp"] = new_params;
642 AddExtraSchedulingPropagators(new_params);
645 strategies[
"variables_shaving_max_lp"] = new_params;
657 AddExtraSchedulingPropagators(new_params);
659 strategies[
"probing"] = new_params;
662 strategies[
"probing_no_lp"] = new_params;
668 strategies[
"probing_max_lp"] = new_params;
675 strategies[
"auto"] = new_params;
680 strategies[
"fixed"] = new_params;
689 strategies[
"quick_restart"] = new_params;
692 strategies[
"quick_restart_no_lp"] = new_params;
695 strategies[
"quick_restart_max_lp"] = new_params;
703 AddExtraSchedulingPropagators(new_params);
705 strategies[
"reduced_costs"] = new_params;
714 strategies[
"pseudo_costs"] = new_params;
721 strategies[
"less_encoding"] = new_params;
744 strategies[
"shared_tree"] = new_params;
762 strategies[
"lns"] = lns_params;
766 auto it = absl::c_find_if(
768 [](
const SatParameters& params) { return params.name() ==
"lns"; });
776 strategies[
"lns_base"] = lns_params_base;
781 strategies[
"lns_stalling"] = lns_params_stalling;
788 strategies[
"lns_routing"] = lns_params_routing;
794 auto it = strategies.find(params.name());
795 if (it != strategies.end()) {
796 it->second.MergeFrom(params);
802 strategies[params.name()] = new_params;
807 for (
auto& [name, params] : strategies) {
808 params.set_name(name);
835 ModelHasSchedulingConstraints(cp_model);
841 std::vector<std::string> names;
845 names.push_back(name);
851 names.push_back(
"default_lp");
852 names.push_back(
"fixed");
853 names.push_back(
"core");
854 names.push_back(
"no_lp");
856 names.push_back(
"max_lp_sym");
860 names.push_back(
"max_lp");
862 names.push_back(
"quick_restart");
863 names.push_back(
"reduced_costs");
864 names.push_back(
"quick_restart_no_lp");
865 names.push_back(
"pseudo_costs");
866 names.push_back(
"lb_tree_search");
867 names.push_back(
"probing");
868 names.push_back(
"objective_lb_search");
869 names.push_back(
"objective_shaving_no_lp");
870 names.push_back(
"objective_shaving_max_lp");
871 names.push_back(
"probing_max_lp");
872 names.push_back(
"probing_no_lp");
873 names.push_back(
"objective_lb_search_no_lp");
874 names.push_back(
"objective_lb_search_max_lp");
876 names.push_back(
"max_lp");
879 for (
const std::string& name : base_params.
subsolvers()) {
882 if (name ==
"core_or_no_lp") {
885 names.push_back(
"no_lp");
887 names.push_back(
"core");
890 names.push_back(name);
897 for (
const std::string& name : names) {
898 if (filter->
Keep(name)) {
899 names[new_size++] = name;
902 names.resize(new_size);
905 std::vector<SatParameters> result;
906 for (
const std::string& name : names) {
910 if (!use_fixed_strategy &&
937 if (name ==
"less_encoding")
continue;
962 base_params.
random_seed(),
static_cast<int64_t
>(result.size()) + 1));
963 result.push_back(params);
974 if (num_to_keep == 0) {
977 const int num_available =
978 std::max(0, base_params.
num_workers() - num_already_present);
980 const auto heuristic_num_workers = [](
int num_workers) {
981 DCHECK_GE(num_workers, 0);
982 if (num_workers == 1)
return 1;
983 if (num_workers <= 4)
return num_workers - 1;
984 if (num_workers <= 8)
return num_workers - 2;
985 if (num_workers <= 16)
return num_workers - (num_workers / 4 + 1);
986 return num_workers - (num_workers / 2 - 3);
989 num_to_keep = heuristic_num_workers(num_available);
992 if (result.size() > num_to_keep) {
993 result.resize(std::max(0, num_to_keep));
1000 std::vector<SatParameters> result;
1002 const auto get_base = [&result, &base_params](
bool fj) {
1017 result.push_back(new_params);
1021 for (
int i = 0;
i < 2; ++
i) {
1026 new_params.
set_name(
"fs_random_no_lp");
1031 result.push_back(new_params);
1039 result.push_back(new_params);
1043 for (
int i = 0;
i < 2; ++
i) {
1049 new_params.
set_name(
"fs_random_quick_restart_no_lp");
1052 new_params.
set_name(
"fs_random_quick_restart");
1054 result.push_back(new_params);
1064 result.push_back(new_params);
1071 absl::Span<const SatParameters> base_params,
int num_params_to_generate) {
1073 std::vector<SatParameters> result;
1074 result.assign(base_params.begin(), base_params.end());
1075 if (result.empty())
return result;
1076 if (result.size() >= num_params_to_generate) {
1077 result.resize(num_params_to_generate);
1083 const int base_size = result.size();
1084 while (result.size() < num_params_to_generate) {
1085 result.push_back(result[
i % base_size]);
1086 result.back().set_random_seed(
CombineSeed(result.back().random_seed(),
i));
1094 filter_patterns_.push_back(pattern);
1097 ignore_patterns_.push_back(pattern);
1102 filter_patterns_.push_back(
"ls*");
1103 filter_patterns_.push_back(
"fj*");
1108 filter_patterns_.push_back(
"fj*");
1109 filter_patterns_.push_back(
"fs*");
1110 filter_patterns_.push_back(
"*lns");
1116 if (!filter_patterns_.empty()) {
1118 for (
const absl::string_view pattern : filter_patterns_) {
1119 if (FNMatch(pattern, name)) {
1125 ignored_.emplace_back(name);
1129 for (
const absl::string_view pattern : ignore_patterns_) {
1130 if (FNMatch(pattern, name)) {
1131 ignored_.emplace_back(name);
1138bool SubsolverNameFilter::FNMatch(absl::string_view pattern,
1139 absl::string_view str) {
1140 bool in_wildcard_match =
false;
1142 if (pattern.empty()) {
1143 return in_wildcard_match || str.empty();
1146 return pattern.find_first_not_of(
'*') == pattern.npos;
1148 switch (pattern.front()) {
1150 pattern.remove_prefix(1);
1151 in_wildcard_match =
true;
1154 pattern.remove_prefix(1);
1155 str.remove_prefix(1);
1158 if (in_wildcard_match) {
1159 absl::string_view fixed_portion = pattern;
1160 const size_t end = fixed_portion.find_first_of(
"*?");
1161 if (
end != fixed_portion.npos) {
1162 fixed_portion = fixed_portion.substr(0,
end);
1164 const size_t match = str.find(fixed_portion);
1165 if (match == str.npos) {
1168 pattern.remove_prefix(fixed_portion.size());
1169 str.remove_prefix(match + fixed_portion.size());
1170 in_wildcard_match =
false;
1172 if (pattern.front() != str.front()) {
1175 pattern.remove_prefix(1);
1176 str.remove_prefix(1);
sat::Literal Literal(int ref) const
bool IsBoolean(int ref) const
IntegerVariable Integer(int ref) const
bool has_symmetry() const
.operations_research.sat.SymmetryProto symmetry = 8;
const ::operations_research::sat::IntegerVariableProto & variables(int index) const
const ::operations_research::sat::ConstraintProto & constraints(int index) const
bool has_objective() const
.operations_research.sat.CpObjectiveProto objective = 4;
const ::operations_research::sat::DecisionStrategyProto & search_strategy(int index) const
int variables_size() const
repeated .operations_research.sat.IntegerVariableProto variables = 2;
const ::operations_research::sat::PartialVariableAssignment & solution_hint() const
const ::operations_research::sat::CpObjectiveProto & objective() const
BooleanOrIntegerLiteral GreaterOrEqual(int var, int64_t value) const
Helpers to generate a decision.
BooleanOrIntegerLiteral LowerOrEqual(int var, int64_t value) const
BooleanOrIntegerLiteral MedianValue(int var) const
int64_t Max(int var) const
CpModelView(Model *model)
int64_t Min(int var) const
int NumVariables() const
The valid indices for the calls below are in [0, num_variables).
bool IsFixed(int var) const
Getters about the current domain of the given variable.
BooleanOrIntegerLiteral RandomSplit(int var, int64_t lb, int64_t ub) const
int vars_size() const
repeated int32 vars = 1;
::int32_t vars(int index) const
static constexpr DomainReductionStrategy SELECT_MAX_VALUE
static constexpr DomainReductionStrategy SELECT_MIN_VALUE
DecisionStrategyProto_DomainReductionStrategy DomainReductionStrategy
static constexpr VariableSelectionStrategy CHOOSE_HIGHEST_MAX
static constexpr VariableSelectionStrategy CHOOSE_FIRST
static constexpr DomainReductionStrategy SELECT_MEDIAN_VALUE
static constexpr DomainReductionStrategy SELECT_UPPER_HALF
static constexpr VariableSelectionStrategy CHOOSE_LOWEST_MIN
static constexpr VariableSelectionStrategy CHOOSE_MAX_DOMAIN_SIZE
static constexpr VariableSelectionStrategy CHOOSE_MIN_DOMAIN_SIZE
static constexpr DomainReductionStrategy SELECT_LOWER_HALF
static constexpr DomainReductionStrategy SELECT_RANDOM_HALF
IntegerValue LowerBound(IntegerVariable i) const
Returns the current lower/upper bound of the given integer variable.
IntegerValue UpperBound(IntegerVariable i) const
const ::std::string & name() const
BooleanVariable Variable() const
Literal(int signed_value)
T Get(std::function< T(const Model &)> f) const
Similar to Add() but this is const.
::int64_t values(int index) const
::int32_t vars(int index) const
bool use_probing_search() const
const ::std::string & ignore_subsolvers(int index) const
void set_use_feasibility_jump(bool value)
void set_debug_crash_on_bad_hint(bool value)
::int32_t num_full_subsolvers() const
bool use_feasibility_jump() const
const ::operations_research::sat::SatParameters & subsolver_params(int index) const
void set_use_probing_search(bool value)
void set_search_branching(::operations_research::sat::SatParameters_SearchBranching value)
void set_exploit_best_solution(bool value)
void set_solution_pool_size(::int32_t value)
static constexpr SearchBranching PORTFOLIO_SEARCH
const ::std::string & extra_subsolvers(int index) const
bool optimize_with_lb_tree_search() const
void set_boolean_encoding_level(::int32_t value)
void set_use_symmetry_in_lp(bool value)
void set_stop_after_first_solution(bool value)
void set_share_level_zero_bounds(bool value)
bool use_objective_shaving_search() const
void set_cp_model_presolve(bool value)
void set_use_sat_inprocessing(bool value)
static constexpr SearchBranching AUTOMATIC_SEARCH
static constexpr SearchBranching RANDOMIZED_SEARCH
void set_optimize_with_max_hs(bool value)
void set_use_shared_tree_search(bool value)
void set_feasibility_jump_linearization_level(::int32_t value)
void set_symmetry_level(::int32_t value)
void set_linearization_level(::int32_t value)
bool use_objective_lb_search() const
void set_optimize_with_lb_tree_search(bool value)
bool use_lns_only() const
void set_root_lp_iterations(::int32_t value)
static constexpr SearchBranching FIXED_SEARCH
bool optimize_with_core() const
void set_find_big_linear_overlap(bool value)
const ::std::string & subsolvers(int index) const
static constexpr SearchBranching PSEUDO_COST_SEARCH
bool use_dual_scheduling_heuristics() const
void set_optimize_with_core(bool value)
void set_at_most_one_max_expansion_size(::int32_t value)
void set_random_seed(::int32_t value)
void set_use_dynamic_precedence_in_cumulative(bool value)
void set_use_dynamic_precedence_in_disjunctive(bool value)
void set_use_objective_shaving_search(bool value)
void set_use_objective_lb_search(bool value)
void set_log_search_progress(bool value)
const ::std::string & filter_subsolvers(int index) const
::operations_research::sat::SatParameters_SearchBranching search_branching() const
void set_share_objective_bounds(bool value)
::int32_t random_seed() const
void set_add_lp_constraints_lazily(bool value)
void set_name(Arg_ &&arg, Args_... args)
static constexpr SearchBranching PORTFOLIO_WITH_QUICK_RESTART_SEARCH
void set_no_overlap_2d_boolean_relations_limit(::int32_t value)
void set_polarity_exploit_ls_hints(bool value)
static constexpr SearchBranching LP_SEARCH
::int32_t num_workers() const
void MergeFrom(const SatParameters &from)
void set_cp_model_probing_level(::int32_t value)
void set_search_random_variable_pool_size(::int64_t value)
void set_shaving_search_deterministic_time(double value)
bool interleave_search() const
Simple class used to filter executed subsolver names.
SubsolverNameFilter(const SatParameters ¶ms)
Warning, params must outlive the class and be constant.
bool Keep(absl::string_view name)
Shall we keep a parameter with given name?
void Add(Element e, Score score)
const std::vector< Element > & UnorderedElements() const
bool RefIsPositive(int ref)
std::function< BooleanOrIntegerLiteral()> FirstUnassignedVarAtItsMinHeuristic(absl::Span< const IntegerVariable > vars, Model *model)
std::vector< SatParameters > GetFullWorkerParameters(const SatParameters &base_params, const CpModelProto &cp_model, int num_already_present, SubsolverNameFilter *filter)
const LiteralIndex kNoLiteralIndex(-1)
std::function< BooleanOrIntegerLiteral()> DisjunctivePrecedenceSearchHeuristic(Model *model)
std::function< BooleanOrIntegerLiteral()> ConstructIntegerCompletionSearchStrategy(absl::Span< const IntegerVariable > variable_mapping, IntegerVariable objective_var, Model *model)
Constructs an integer completion search strategy.
std::vector< IntegerVariable > NegationOf(absl::Span< const IntegerVariable > vars)
Returns the vector of the negated variables.
int CombineSeed(int base_seed, int64_t delta)
We assume delta >= 0 and we only use the low bit of delta.
std::function< BooleanOrIntegerLiteral()> ConstructFixedSearchStrategy(std::function< BooleanOrIntegerLiteral()> user_search, std::function< BooleanOrIntegerLiteral()> heuristic_search, std::function< BooleanOrIntegerLiteral()> integer_completion)
std::function< BooleanOrIntegerLiteral()> ConstructHintSearchStrategy(const CpModelProto &cp_model_proto, CpModelMapping *mapping, Model *model)
Constructs a search strategy that follow the hint from the model.
const IntegerVariable kNoIntegerVariable(-1)
std::function< BooleanOrIntegerLiteral()> PseudoCost(Model *model)
std::function< BooleanOrIntegerLiteral()> ConstructHeuristicSearchStrategy(const CpModelProto &cp_model_proto, Model *model)
Constructs a search strategy tailored for the current model.
std::function< BooleanOrIntegerLiteral()> SchedulingSearchHeuristic(Model *model)
A simple heuristic for scheduling models.
std::vector< SatParameters > GetFirstSolutionBaseParams(const SatParameters &base_params)
std::vector< SatParameters > RepeatParameters(absl::Span< const SatParameters > base_params, int num_params_to_generate)
std::function< BooleanOrIntegerLiteral()> ConstructUserSearchStrategy(const CpModelProto &cp_model_proto, Model *model)
Constructs the search strategy specified in the given CpModelProto.
std::function< BooleanOrIntegerLiteral()> FollowHint(absl::Span< const BooleanOrIntegerVariable > vars, absl::Span< const IntegerValue > values, Model *model)
int NegatedRef(int ref)
Small utility functions to deal with negative variable/literal references.
absl::flat_hash_map< std::string, SatParameters > GetNamedParameters(SatParameters base_params)
std::function< BooleanOrIntegerLiteral()> InstrumentSearchStrategy(const CpModelProto &cp_model_proto, absl::Span< const IntegerVariable > variable_mapping, std::function< BooleanOrIntegerLiteral()> instrumented_strategy, Model *model)
std::function< BooleanOrIntegerLiteral()> CumulativePrecedenceSearchHeuristic(Model *model)
std::function< BooleanOrIntegerLiteral()> SequentialSearch(std::vector< std::function< BooleanOrIntegerLiteral()> > heuristics)
In SWIG mode, we don't want anything besides these top-level includes.
LinearRange operator<=(const LinearExpr &lhs, const LinearExpr &rhs)
ClosedInterval::Iterator end(ClosedInterval interval)
LiteralIndex boolean_literal_index
IntegerLiteral integer_literal
static IntegerLiteral GreaterOrEqual(IntegerVariable i, IntegerValue bound)
static IntegerLiteral LowerOrEqual(IntegerVariable i, IntegerValue bound)
Stores one variable and its strategy value.