20#include "absl/container/flat_hash_map.h"
21#include "absl/strings/str_format.h"
73 int64_t
value)
const {
89 int64_t
value)
const {
110 const IntegerVariable variable = mapping_.
Integer(
var);
113 std::vector<ValueLiteralPair> encoding =
115 std::sort(encoding.begin(), encoding.end(),
117 std::vector<Literal> unassigned_sorted_literals;
118 for (
const auto& p : encoding) {
120 unassigned_sorted_literals.push_back(p.literal);
126 const int target = (unassigned_sorted_literals.size() + 1) / 2 - 1;
141bool ModelHasSchedulingConstraints(
const CpModelProto& cp_model_proto) {
152 const std::vector<DecisionStrategyProto>& strategies,
Model*
model) {
159 return [&view, &
parameters, random, strategies]() {
168 std::vector<VarValue> active_refs;
171 for (
int i = 0; i < strategy.variables().size(); ++i) {
172 const int ref = strategy.variables(i);
174 if (view.IsFixed(
var) || view.IsCurrentlyFree(
var))
continue;
178 while (t_index < strategy.transformations().size() &&
179 strategy.transformations(t_index).index() < i) {
182 if (t_index < strategy.transformations_size() &&
183 strategy.transformations(t_index).index() == i) {
184 coeff = strategy.transformations(t_index).positive_coeff();
185 offset = strategy.transformations(t_index).offset();
193 int64_t lb = view.Min(
var);
194 int64_t ub = view.Max(
var);
199 switch (strategy.variable_selection_strategy()) {
215 LOG(
FATAL) <<
"Unknown VariableSelectionStrategy "
216 << strategy.variable_selection_strategy();
218 if (
value < candidate_value) {
220 candidate_value =
value;
222 if (strategy.variable_selection_strategy() ==
229 active_refs.push_back({ref,
value});
236 CHECK(!active_refs.empty());
237 const IntegerValue threshold(
239 auto is_above_tolerance = [threshold](
const VarValue& entry) {
240 return entry.value > threshold;
243 active_refs.erase(std::remove_if(active_refs.begin(), active_refs.end(),
246 const int winner = absl::Uniform<int>(*random, 0, active_refs.size());
247 candidate = active_refs[winner].ref;
251 strategy.domain_reduction_strategy();
272 const int64_t lb = view.Min(
var);
273 const int64_t ub = view.Max(
var);
276 return view.LowerOrEqual(
var, lb);
278 return view.GreaterOrEqual(
var, ub);
280 return view.LowerOrEqual(
var, lb + (ub - lb) / 2);
282 return view.GreaterOrEqual(
var, ub - (ub - lb) / 2);
284 return view.MedianValue(
var);
286 LOG(
FATAL) <<
"Unknown DomainReductionStrategy "
287 << strategy.domain_reduction_strategy();
296 const std::vector<IntegerVariable>& variable_mapping,
297 IntegerVariable objective_var,
Model*
model) {
302 std::vector<DecisionStrategyProto> strategies;
305 strategies.push_back(
proto);
312 if (ModelHasSchedulingConstraints(cp_model_proto)) {
318 std::vector<IntegerVariable> decisions;
319 for (
const IntegerVariable
var : variable_mapping) {
324 decisions.push_back(objective_var);
326 decisions.push_back(
var);
337 const std::vector<IntegerVariable>& variable_mapping,
340 std::vector<int> ref_to_display;
344 ref_to_display.push_back(i);
346 std::sort(ref_to_display.begin(), ref_to_display.end(), [&](
int i,
int j) {
347 return cp_model_proto.variables(i).name() <
348 cp_model_proto.variables(j).name();
351 std::vector<std::pair<int64_t, int64_t>> old_domains(variable_mapping.size());
352 return [instrumented_strategy,
model, variable_mapping, cp_model_proto,
353 old_domains, ref_to_display]()
mutable {
355 if (!decision.
HasValue())
return decision;
359 LOG(
INFO) <<
"Boolean decision " << l;
362 LOG(
INFO) <<
" - associated with " << i_lit;
367 const int level =
model->Get<
Trail>()->CurrentDecisionLevel();
368 std::string to_display =
369 absl::StrCat(
"Diff since last call, level=", level,
"\n");
371 for (
const int ref : ref_to_display) {
372 const IntegerVariable
var = variable_mapping[ref];
373 const std::pair<int64_t, int64_t> new_domain(
376 if (new_domain != old_domains[ref]) {
377 absl::StrAppend(&to_display, cp_model_proto.variables(ref).name(),
" [",
378 old_domains[ref].first,
",", old_domains[ref].second,
379 "] -> [", new_domain.first,
",", new_domain.second,
381 old_domains[ref] = new_domain;
398 const int num_workers) {
401 std::map<std::string, SatParameters> strategies;
407 strategies[
"no_lp"] = new_params;
409 strategies[
"default_lp"] = new_params;
412 strategies[
"max_lp"] = new_params;
426 strategies[
"core"] = new_params;
435 strategies[
"core_default_lp"] = new_params;
443 strategies[
"core_max_lp"] = new_params;
454 strategies[
"lb_tree_search"] = new_params;
461 strategies[
"probing"] = new_params;
468 strategies[
"auto"] = new_params;
471 strategies[
"fixed"] = new_params;
475 strategies[
"quick_restart"] = new_params;
480 strategies[
"quick_restart_no_lp"] = new_params;
485 strategies[
"reduced_costs"] = new_params;
491 strategies[
"pseudo_costs"] = new_params;
498 strategies[
"less_encoding"] = new_params;
508 ModelHasSchedulingConstraints(cp_model);
514 std::vector<std::string> names;
519 names.push_back(
"default_lp");
520 names.push_back(use_fixed_strategy ?
"fixed" :
"pseudo_costs");
522 names.push_back(
"max_lp");
524 names.push_back(
"default_lp");
525 names.push_back(use_fixed_strategy ?
"fixed" :
"no_lp");
526 names.push_back(
"less_encoding");
527 names.push_back(
"max_lp");
528 names.push_back(
"quick_restart");
531 names.push_back(
"default_lp");
532 if (use_fixed_strategy) {
533 names.push_back(
"fixed");
534 if (num_workers > 8) names.push_back(
"reduced_costs");
536 names.push_back(
"reduced_costs");
538 names.push_back(
"pseudo_costs");
539 names.push_back(
"no_lp");
540 names.push_back(
"max_lp");
547 names.push_back(
"quick_restart");
549 if (num_workers > 10) {
550 names.push_back(
"quick_restart_no_lp");
553 if (num_workers > 12) {
554 names.push_back(
"lb_tree_search");
557 names.push_back(
"default_lp");
558 if (use_fixed_strategy) names.push_back(
"fixed");
559 names.push_back(
"less_encoding");
560 names.push_back(
"no_lp");
561 names.push_back(
"max_lp");
562 names.push_back(
"quick_restart");
563 if (num_workers > 10) {
564 names.push_back(
"quick_restart_no_lp");
567 if (num_workers > 12) {
568 names.push_back(
"probing");
573 std::vector<SatParameters> result;
574 for (
const std::string&
name : names) {
578 result.push_back(new_params);
584 int target = num_workers;
591 target =
std::max(1, num_workers - 1);
595 while (result.size() < target) {
603 result.push_back(new_params);
613 result.resize(num_workers);
#define CHECK_NE(val1, val2)
#define DCHECK(condition)
An Assignment is a variable -> domains mapping, used to report solutions to the user.
bool IsBoolean(int ref) const
bool IsInteger(int ref) const
IntegerVariable Integer(int ref) const
sat::Literal Literal(int ref) const
int NumProtoVariables() const
const ::operations_research::sat::CpObjectiveProto & objective() const
const ::operations_research::sat::IntegerVariableProto & variables(int index) const
const ::operations_research::sat::DecisionStrategyProto & search_strategy(int index) const
bool has_objective() const
int variables_size() const
const ::operations_research::sat::ConstraintProto & constraints(int index) const
bool IsFixed(int var) const
BooleanOrIntegerLiteral GreaterOrEqual(int var, int64_t value) const
bool IsCurrentlyFree(int var) const
BooleanOrIntegerLiteral MedianValue(int var) const
CpModelView(Model *model)
int64_t Max(int var) const
BooleanOrIntegerLiteral LowerOrEqual(int var, int64_t value) const
int64_t Min(int var) const
static constexpr DomainReductionStrategy SELECT_MIN_VALUE
static constexpr DomainReductionStrategy SELECT_MAX_VALUE
static constexpr VariableSelectionStrategy CHOOSE_MAX_DOMAIN_SIZE
static constexpr VariableSelectionStrategy CHOOSE_LOWEST_MIN
static constexpr DomainReductionStrategy SELECT_MEDIAN_VALUE
static constexpr DomainReductionStrategy SELECT_LOWER_HALF
static constexpr VariableSelectionStrategy CHOOSE_MIN_DOMAIN_SIZE
static constexpr VariableSelectionStrategy CHOOSE_HIGHEST_MAX
static constexpr VariableSelectionStrategy CHOOSE_FIRST
static constexpr DomainReductionStrategy SELECT_UPPER_HALF
const InlinedIntegerLiteralVector & GetAllIntegerLiterals(Literal lit) const
bool VariableIsFullyEncoded(IntegerVariable var) const
std::vector< ValueLiteralPair > RawDomainEncoding(IntegerVariable var) const
bool IsCurrentlyIgnored(IntegerVariable i) const
bool IsFixed(IntegerVariable i) const
IntegerValue UpperBound(IntegerVariable i) const
IntegerValue LowerBound(IntegerVariable i) const
const std::string & name() const
LiteralIndex NegatedIndex() const
LiteralIndex Index() const
BooleanVariable Variable() const
Class that owns everything related to a particular optimization model.
bool interleave_search() const
void set_search_branching(::operations_research::sat::SatParameters_SearchBranching value)
static constexpr SearchBranching PSEUDO_COST_SEARCH
void set_search_randomization_tolerance(int64_t value)
bool use_feasibility_pump() const
void set_add_lp_constraints_lazily(bool value)
void set_optimize_with_core(bool value)
bool use_relaxation_lns() const
bool use_rins_lns() const
void set_linearization_level(int32_t value)
static constexpr SearchBranching PORTFOLIO_WITH_QUICK_RESTART_SEARCH
bool reduce_memory_usage_in_interleave_mode() const
void set_name(ArgT0 &&arg0, ArgT... args)
void set_randomize_search(bool value)
void set_random_seed(int32_t value)
static constexpr SearchBranching LP_SEARCH
int64_t search_randomization_tolerance() const
bool instantiate_all_variables() const
void set_exploit_best_solution(bool value)
static constexpr SearchBranching AUTOMATIC_SEARCH
void set_use_probing_search(bool value)
bool randomize_search() const
void set_optimize_with_lb_tree_search(bool value)
void set_boolean_encoding_level(int32_t value)
void set_share_objective_bounds(bool value)
static constexpr SearchBranching FIXED_SEARCH
bool LiteralIsAssigned(Literal literal) const
bool VariableIsAssigned(BooleanVariable var) const
bool LiteralIsTrue(Literal literal) const
bool LiteralIsFalse(Literal literal) const
const std::function< BooleanOrIntegerLiteral()> ConstructSearchStrategyInternal(const std::vector< DecisionStrategyProto > &strategies, Model *model)
DecisionStrategyProto_DomainReductionStrategy
std::function< BooleanOrIntegerLiteral()> FirstUnassignedVarAtItsMinHeuristic(const std::vector< IntegerVariable > &vars, Model *model)
bool RefIsPositive(int ref)
std::function< BooleanOrIntegerLiteral()> SequentialSearch(std::vector< std::function< BooleanOrIntegerLiteral()> > heuristics)
const LiteralIndex kNoLiteralIndex(-1)
const IntegerVariable kNoIntegerVariable(-1)
std::function< BooleanOrIntegerLiteral()> SchedulingSearchHeuristic(Model *model)
std::vector< IntegerVariable > NegationOf(const std::vector< IntegerVariable > &vars)
std::vector< SatParameters > GetDiverseSetOfParameters(const SatParameters &base_params, const CpModelProto &cp_model, const int num_workers)
std::function< BooleanOrIntegerLiteral()> ConstructSearchStrategy(const CpModelProto &cp_model_proto, const std::vector< IntegerVariable > &variable_mapping, IntegerVariable objective_var, Model *model)
std::function< BooleanOrIntegerLiteral()> InstrumentSearchStrategy(const CpModelProto &cp_model_proto, const std::vector< IntegerVariable > &variable_mapping, const std::function< BooleanOrIntegerLiteral()> &instrumented_strategy, Model *model)
Collection of objects used to extend the Constraint Solver library.
LiteralIndex boolean_literal_index
IntegerLiteral integer_literal
static IntegerLiteral LowerOrEqual(IntegerVariable i, IntegerValue bound)
static IntegerLiteral GreaterOrEqual(IntegerVariable i, IntegerValue bound)