OR-Tools  8.0
cp_model_search.cc
Go to the documentation of this file.
1 // Copyright 2010-2018 Google LLC
2 // Licensed under the Apache License, Version 2.0 (the "License");
3 // you may not use this file except in compliance with the License.
4 // You may obtain a copy of the License at
5 //
6 // http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13 
15 
16 #include <random>
17 
18 #include "absl/container/flat_hash_map.h"
19 #include "absl/strings/str_format.h"
21 #include "ortools/sat/util.h"
22 
23 namespace operations_research {
24 namespace sat {
25 
26 // The function responsible for implementing the chosen search strategy.
27 //
28 // TODO(user): expose and unit-test, it seems easy to get the order wrong, and
29 // that would not change the correctness.
30 struct Strategy {
31  std::vector<IntegerVariable> variables;
32  DecisionStrategyProto::VariableSelectionStrategy var_strategy;
33  DecisionStrategyProto::DomainReductionStrategy domain_strategy;
34 };
35 
36 // Stores one variable and its strategy value.
37 struct VarValue {
38  IntegerVariable var;
39  IntegerValue value;
40 };
41 
42 const std::function<LiteralIndex()> ConstructSearchStrategyInternal(
43  const absl::flat_hash_map<int, std::pair<int64, int64>>&
44  var_to_coeff_offset_pair,
45  const std::vector<Strategy>& strategies, Model* model) {
46  IntegerEncoder* const integer_encoder = model->GetOrCreate<IntegerEncoder>();
47  IntegerTrail* const integer_trail = model->GetOrCreate<IntegerTrail>();
48 
49  // Note that we copy strategies to keep the return function validity
50  // independently of the life of the passed vector.
51  return [integer_encoder, integer_trail, strategies, var_to_coeff_offset_pair,
52  model]() {
53  const SatParameters* const parameters = model->GetOrCreate<SatParameters>();
54 
55  for (const Strategy& strategy : strategies) {
56  IntegerVariable candidate = kNoIntegerVariable;
57  IntegerValue candidate_value = kMaxIntegerValue;
58  IntegerValue candidate_lb;
59  IntegerValue candidate_ub;
60 
61  // TODO(user): Improve the complexity if this becomes an issue which
62  // may be the case if we do a fixed_search.
63 
64  // To store equivalent variables in randomized search.
65  std::vector<VarValue> active_vars;
66 
67  for (const IntegerVariable var : strategy.variables) {
68  if (integer_trail->IsCurrentlyIgnored(var)) continue;
69  const IntegerValue lb = integer_trail->LowerBound(var);
70  const IntegerValue ub = integer_trail->UpperBound(var);
71  if (lb == ub) continue;
72  IntegerValue value(0);
73  IntegerValue coeff(1);
74  IntegerValue offset(0);
75  if (gtl::ContainsKey(var_to_coeff_offset_pair, var.value())) {
76  const auto coeff_offset =
77  gtl::FindOrDie(var_to_coeff_offset_pair, var.value());
78  coeff = coeff_offset.first;
79  offset = coeff_offset.second;
80  }
81  DCHECK_GT(coeff, 0);
82 
83  // TODO(user): deal with integer overflow in case of wrongly specified
84  // coeff.
85  switch (strategy.var_strategy) {
86  case DecisionStrategyProto::CHOOSE_FIRST:
87  break;
88  case DecisionStrategyProto::CHOOSE_LOWEST_MIN:
89  value = coeff * lb + offset;
90  break;
91  case DecisionStrategyProto::CHOOSE_HIGHEST_MAX:
92  value = -(coeff * ub + offset);
93  break;
94  case DecisionStrategyProto::CHOOSE_MIN_DOMAIN_SIZE:
95  // TODO(user): Evaluate an exact domain computation.
96  value = coeff * (ub - lb + 1);
97  break;
98  case DecisionStrategyProto::CHOOSE_MAX_DOMAIN_SIZE:
99  // TODO(user): Evaluate an exact domain computation.
100  value = -coeff * (ub - lb + 1);
101  break;
102  default:
103  LOG(FATAL) << "Unknown VariableSelectionStrategy "
104  << strategy.var_strategy;
105  }
106  if (value < candidate_value) {
107  candidate = var;
108  candidate_lb = lb;
109  candidate_ub = ub;
110  candidate_value = value;
111  }
112  if (strategy.var_strategy == DecisionStrategyProto::CHOOSE_FIRST &&
113  !parameters->randomize_search()) {
114  break;
115  } else if (parameters->randomize_search()) {
116  if (active_vars.empty() ||
117  value <= candidate_value +
118  parameters->search_randomization_tolerance()) {
119  active_vars.push_back({var, value});
120  }
121  }
122  }
123  if (candidate == kNoIntegerVariable) continue;
124  if (parameters->randomize_search()) {
125  CHECK(!active_vars.empty());
126  const IntegerValue threshold(
127  candidate_value + parameters->search_randomization_tolerance());
128  auto is_above_tolerance = [threshold](const VarValue& entry) {
129  return entry.value > threshold;
130  };
131  // Remove all values above tolerance.
132  active_vars.erase(std::remove_if(active_vars.begin(), active_vars.end(),
133  is_above_tolerance),
134  active_vars.end());
135  const int winner =
136  std::uniform_int_distribution<int>(0, active_vars.size() - 1)(
137  *model->GetOrCreate<ModelRandomGenerator>());
138  candidate = active_vars[winner].var;
139  candidate_lb = integer_trail->LowerBound(candidate);
140  candidate_ub = integer_trail->UpperBound(candidate);
141  }
142 
144  switch (strategy.domain_strategy) {
145  case DecisionStrategyProto::SELECT_MIN_VALUE:
146  literal = IntegerLiteral::LowerOrEqual(candidate, candidate_lb);
147  break;
148  case DecisionStrategyProto::SELECT_MAX_VALUE:
149  literal = IntegerLiteral::GreaterOrEqual(candidate, candidate_ub);
150  break;
151  case DecisionStrategyProto::SELECT_LOWER_HALF:
153  candidate, candidate_lb + (candidate_ub - candidate_lb) / 2);
154  break;
155  case DecisionStrategyProto::SELECT_UPPER_HALF:
157  candidate, candidate_ub - (candidate_ub - candidate_lb) / 2);
158  break;
159  case DecisionStrategyProto::SELECT_MEDIAN_VALUE:
160  // TODO(user): Implement the correct method.
161  literal = IntegerLiteral::LowerOrEqual(candidate, candidate_lb);
162  break;
163  default:
164  LOG(FATAL) << "Unknown DomainReductionStrategy "
165  << strategy.domain_strategy;
166  }
167  return integer_encoder->GetOrCreateAssociatedLiteral(literal).Index();
168  }
169  return kNoLiteralIndex;
170  };
171 }
172 
173 std::function<LiteralIndex()> ConstructSearchStrategy(
174  const CpModelProto& cp_model_proto,
175  const std::vector<IntegerVariable>& variable_mapping,
176  IntegerVariable objective_var, Model* model) {
177  // Default strategy is to instantiate the IntegerVariable in order.
178  std::function<LiteralIndex()> default_search_strategy = nullptr;
179  const bool instantiate_all_variables =
180  model->GetOrCreate<SatParameters>()->instantiate_all_variables();
181 
182  if (instantiate_all_variables) {
183  std::vector<IntegerVariable> decisions;
184  for (const IntegerVariable var : variable_mapping) {
185  if (var == kNoIntegerVariable) continue;
186 
187  // Make sure we try to fix the objective to its lowest value first.
188  if (var == NegationOf(objective_var)) {
189  decisions.push_back(objective_var);
190  } else {
191  decisions.push_back(var);
192  }
193  }
194  default_search_strategy =
196  }
197 
198  std::vector<Strategy> strategies;
199  absl::flat_hash_map<int, std::pair<int64, int64>> var_to_coeff_offset_pair;
200  for (const DecisionStrategyProto& proto : cp_model_proto.search_strategy()) {
201  strategies.push_back(Strategy());
202  Strategy& strategy = strategies.back();
203  for (const int ref : proto.variables()) {
204  strategy.variables.push_back(
205  RefIsPositive(ref) ? variable_mapping[ref]
206  : NegationOf(variable_mapping[PositiveRef(ref)]));
207  }
208  strategy.var_strategy = proto.variable_selection_strategy();
209  strategy.domain_strategy = proto.domain_reduction_strategy();
210  for (const auto& transform : proto.transformations()) {
211  const int ref = transform.var();
212  const IntegerVariable var =
213  RefIsPositive(ref) ? variable_mapping[ref]
214  : NegationOf(variable_mapping[PositiveRef(ref)]);
215  if (!gtl::ContainsKey(var_to_coeff_offset_pair, var.value())) {
216  var_to_coeff_offset_pair[var.value()] = {transform.positive_coeff(),
217  transform.offset()};
218  }
219  }
220  }
221  if (instantiate_all_variables) {
223  var_to_coeff_offset_pair, strategies, model),
224  default_search_strategy});
225  } else {
226  return ConstructSearchStrategyInternal(var_to_coeff_offset_pair, strategies,
227  model);
228  }
229 }
230 
231 std::function<LiteralIndex()> InstrumentSearchStrategy(
232  const CpModelProto& cp_model_proto,
233  const std::vector<IntegerVariable>& variable_mapping,
234  const std::function<LiteralIndex()>& instrumented_strategy, Model* model) {
235  std::vector<int> ref_to_display;
236  for (int i = 0; i < cp_model_proto.variables_size(); ++i) {
237  if (variable_mapping[i] == kNoIntegerVariable) continue;
238  if (cp_model_proto.variables(i).name().empty()) continue;
239  ref_to_display.push_back(i);
240  }
241  std::sort(ref_to_display.begin(), ref_to_display.end(), [&](int i, int j) {
242  return cp_model_proto.variables(i).name() <
243  cp_model_proto.variables(j).name();
244  });
245 
246  std::vector<std::pair<int64, int64>> old_domains(variable_mapping.size());
247  return [instrumented_strategy, model, variable_mapping, cp_model_proto,
248  old_domains, ref_to_display]() mutable {
249  const LiteralIndex decision = instrumented_strategy();
250  if (decision == kNoLiteralIndex) return decision;
251 
252  for (const IntegerLiteral i_lit :
254  Literal(decision))) {
255  LOG(INFO) << "decision " << i_lit;
256  }
257  const int level = model->Get<Trail>()->CurrentDecisionLevel();
258  std::string to_display =
259  absl::StrCat("Diff since last call, level=", level, "\n");
260  IntegerTrail* integer_trail = model->GetOrCreate<IntegerTrail>();
261  for (const int ref : ref_to_display) {
262  const IntegerVariable var = variable_mapping[ref];
263  const std::pair<int64, int64> new_domain(
264  integer_trail->LowerBound(var).value(),
265  integer_trail->UpperBound(var).value());
266  if (new_domain != old_domains[ref]) {
267  absl::StrAppend(&to_display, cp_model_proto.variables(ref).name(), " [",
268  old_domains[ref].first, ",", old_domains[ref].second,
269  "] -> [", new_domain.first, ",", new_domain.second,
270  "]\n");
271  old_domains[ref] = new_domain;
272  }
273  }
274  LOG(INFO) << to_display;
275  return decision;
276  };
277 }
278 
279 SatParameters DiversifySearchParameters(const SatParameters& params,
280  const CpModelProto& cp_model,
281  const int worker_id,
282  std::string* name) {
283  // Note: in the flatzinc setting, we know we always have a fixed search
284  // defined.
285  // Things to try:
286  // - Specialize for purely boolean problems
287  // - Disable linearization_level options for non linear problems
288  // - Fast restart in randomized search
289  // - Different propatation levels for scheduling constraints
290  SatParameters new_params = params;
291  new_params.set_random_seed(params.random_seed() + worker_id);
292  new_params.set_use_lns_only(false);
293  int index = worker_id;
294 
295  if (params.reduce_memory_usage_in_interleave_mode() &&
296  params.interleave_search()) {
297  // Low memory mode for interleaved search in single thread (5 workers).
298  CHECK_LE(index, 4);
299  if (cp_model.has_objective()) { // Reduced memory, objective.
300  // First strategy (default).
301  if (index == 0) { // Use default parameters and automatic search.
302  new_params.set_search_branching(SatParameters::AUTOMATIC_SEARCH);
303  *name = "auto";
304  return new_params;
305  }
306 
307  // Second strategy (fixed or pseudo costs).
308  if (cp_model.search_strategy_size() > 0) {
309  if (--index == 0) { // Use default parameters and fixed search.
310  new_params.set_search_branching(SatParameters::FIXED_SEARCH);
311  *name = "fixed";
312  return new_params;
313  }
314  } else {
315  if (--index == 0) {
316  new_params.set_search_branching(SatParameters::PSEUDO_COST_SEARCH);
317  new_params.set_exploit_best_solution(true);
318  *name = "pseudo_cost";
319  return new_params;
320  }
321  }
322 
323  // Third strategy (core or no lp).
324  if (cp_model.objective().vars_size() > 1) {
325  if (--index == 0) { // Core based approach.
326  new_params.set_search_branching(SatParameters::AUTOMATIC_SEARCH);
327  new_params.set_optimize_with_core(true);
328  new_params.set_linearization_level(0);
329  *name = "core";
330  return new_params;
331  }
332  } else {
333  if (--index == 0) { // Remove LP relaxation.
334  new_params.set_search_branching(SatParameters::AUTOMATIC_SEARCH);
335  new_params.set_linearization_level(0);
336  *name = "no_lp";
337  return new_params;
338  }
339  }
340 
341  // Fourth strategy: max_lp.
342  if (--index == 0) { // Reinforce LP relaxation.
343  new_params.set_search_branching(SatParameters::AUTOMATIC_SEARCH);
344  new_params.set_linearization_level(2);
345  new_params.set_use_branching_in_lp(true);
346  *name = "max_lp";
347  return new_params;
348  }
349 
350  // Fifth strategy using LNS.
351  new_params.set_search_branching(SatParameters::AUTOMATIC_SEARCH);
352  new_params.set_use_lns_only(true);
353  *name = "lns";
354  return new_params;
355  } else { // Reduced memory, no objective.
356  // First strategy (default).
357  if (index == 0) { // Use default parameters and automatic search.
358  new_params.set_search_branching(SatParameters::AUTOMATIC_SEARCH);
359  *name = "auto";
360  return new_params;
361  }
362  // Second strategy (fixed or no_lp).
363  if (cp_model.search_strategy_size() > 0) {
364  if (--index == 0) { // Use default parameters and fixed search.
365  new_params.set_search_branching(SatParameters::FIXED_SEARCH);
366  *name = "fixed";
367  return new_params;
368  }
369  } else {
370  // TODO(user): Disable lp_br if linear part is small or empty.
371  if (--index == 0) {
372  new_params.set_search_branching(SatParameters::AUTOMATIC_SEARCH);
373  new_params.set_linearization_level(0);
374  *name = "no_lp";
375  return new_params;
376  }
377  }
378 
379  // Third strategy: reduce boolean encoding.
380  if (--index == 0) {
381  new_params.set_search_branching(SatParameters::AUTOMATIC_SEARCH);
382  new_params.set_boolean_encoding_level(0);
383  *name = "less encoding";
384  return new_params;
385  }
386 
387  // Fourth strategy: max_lp.
388  if (--index == 0) { // Reinforce LP relaxation.
389  new_params.set_search_branching(SatParameters::AUTOMATIC_SEARCH);
390  new_params.set_linearization_level(2);
391  *name = "max_lp";
392  return new_params;
393  }
394 
395  // Fifth strategy: quick restart.
396  new_params.set_search_branching(
397  SatParameters::PORTFOLIO_WITH_QUICK_RESTART_SEARCH);
398  *name = "random";
399  return new_params;
400  }
401  } else if (cp_model.has_objective()) { // Normal memory, objective.
402  if (index == 0) { // Use default parameters and automatic search.
403  new_params.set_search_branching(SatParameters::AUTOMATIC_SEARCH);
404  new_params.set_linearization_level(1);
405  *name = "auto";
406  return new_params;
407  }
408 
409  if (cp_model.search_strategy_size() > 0) {
410  if (--index == 0) { // Use default parameters and fixed search.
411  new_params.set_search_branching(SatParameters::FIXED_SEARCH);
412  *name = "fixed";
413  return new_params;
414  }
415  } else {
416  // TODO(user): Disable lp_br if linear part is small or empty.
417  if (--index == 0) {
418  new_params.set_search_branching(SatParameters::LP_SEARCH);
419  *name = "lp_br";
420  return new_params;
421  }
422  }
423 
424  if (--index == 0) {
425  new_params.set_search_branching(SatParameters::PSEUDO_COST_SEARCH);
426  new_params.set_exploit_best_solution(true);
427  *name = "pseudo_cost";
428  return new_params;
429  }
430 
431  // TODO(user): Disable no_lp if linear part is small.
432  if (--index == 0) { // Remove LP relaxation.
433  new_params.set_search_branching(SatParameters::AUTOMATIC_SEARCH);
434  new_params.set_linearization_level(0);
435  *name = "no_lp";
436  return new_params;
437  }
438 
439  // TODO(user): Disable max_lp if no change in linearization against auto.
440  if (--index == 0) { // Reinforce LP relaxation.
441  new_params.set_search_branching(SatParameters::AUTOMATIC_SEARCH);
442  new_params.set_linearization_level(2);
443  new_params.set_use_branching_in_lp(true);
444  *name = "max_lp";
445  return new_params;
446  }
447 
448  // Only add this strategy if we have enough worker left for LNS.
449  if (params.num_search_workers() > 8 && --index == 0) {
450  new_params.set_search_branching(
451  SatParameters::PORTFOLIO_WITH_QUICK_RESTART_SEARCH);
452  *name = "quick_restart";
453  return new_params;
454  }
455 
456  if (cp_model.objective().vars_size() > 1) {
457  if (--index == 0) { // Core based approach.
458  new_params.set_search_branching(SatParameters::AUTOMATIC_SEARCH);
459  new_params.set_optimize_with_core(true);
460  new_params.set_linearization_level(0);
461  *name = "core";
462  return new_params;
463  }
464  }
465 
466  // Use LNS for the remaining workers.
467  new_params.set_search_branching(SatParameters::AUTOMATIC_SEARCH);
468  new_params.set_use_lns_only(true);
469  *name = absl::StrFormat("lns_%i", index);
470  return new_params;
471  } else { // Normal memory, no objective.
472  // The goal here is to try fixed and free search on the first two threads.
473  // Then maximize diversity on the extra threads.
474  int index = worker_id;
475 
476  if (index == 0) { // Default automatic search.
477  new_params.set_search_branching(SatParameters::AUTOMATIC_SEARCH);
478  *name = "auto";
479  return new_params;
480  }
481 
482  if (cp_model.search_strategy_size() > 0) { // Use predefined search.
483  if (--index == 0) {
484  new_params.set_search_branching(SatParameters::FIXED_SEARCH);
485  *name = "fixed";
486  return new_params;
487  }
488  }
489 
490  if (--index == 0) { // Reduce boolean encoding.
491  new_params.set_search_branching(SatParameters::AUTOMATIC_SEARCH);
492  new_params.set_boolean_encoding_level(0);
493  *name = "less encoding";
494  return new_params;
495  }
496 
497  // TODO(user): Disable no_lp if linear part is small.
498  if (--index == 0) { // Remove LP relaxation.
499  new_params.set_search_branching(SatParameters::AUTOMATIC_SEARCH);
500  new_params.set_linearization_level(0);
501  *name = "no_lp";
502  return new_params;
503  }
504 
505  // TODO(user): Disable max_lp if no change in linearization against auto.
506  if (--index == 0) { // Reinforce LP relaxation.
507  new_params.set_search_branching(SatParameters::AUTOMATIC_SEARCH);
508  new_params.set_linearization_level(2);
509  *name = "max_lp";
510  return new_params;
511  }
512 
513  if (--index == 0) {
514  new_params.set_search_branching(
515  SatParameters::PORTFOLIO_WITH_QUICK_RESTART_SEARCH);
516  *name = "random";
517  return new_params;
518  }
519 
520  // Randomized fixed search.
521  new_params.set_search_branching(SatParameters::FIXED_SEARCH);
522  new_params.set_randomize_search(true);
523  new_params.set_search_randomization_tolerance(index);
524  *name = absl::StrFormat("random_%i", index);
525  return new_params;
526  }
527 }
528 
529 } // namespace sat
530 } // namespace operations_research
operations_research::sat::Trail
Definition: sat_base.h:233
var
IntVar * var
Definition: expr_array.cc:1858
operations_research::sat::VarValue::var
IntegerVariable var
Definition: cp_model_search.cc:38
operations_research::sat::IntegerLiteral
Definition: integer.h:164
operations_research::sat::IntegerTrail::Index
int Index() const
Definition: integer.h:811
operations_research::sat::IntegerLiteral::GreaterOrEqual
static IntegerLiteral GreaterOrEqual(IntegerVariable i, IntegerValue bound)
Definition: integer.h:1197
operations_research::sat::kNoIntegerVariable
const IntegerVariable kNoIntegerVariable(-1)
operations_research::sat::kNoLiteralIndex
const LiteralIndex kNoLiteralIndex(-1)
operations_research::sat::IntegerTrail::UpperBound
IntegerValue UpperBound(IntegerVariable i) const
Definition: integer.h:1221
operations_research::sat::Strategy::domain_strategy
DecisionStrategyProto::DomainReductionStrategy domain_strategy
Definition: cp_model_search.cc:33
operations_research::sat::ConstructSearchStrategyInternal
const std::function< LiteralIndex()> ConstructSearchStrategyInternal(const absl::flat_hash_map< int, std::pair< int64, int64 >> &var_to_coeff_offset_pair, const std::vector< Strategy > &strategies, Model *model)
Definition: cp_model_search.cc:42
value
int64 value
Definition: demon_profiler.cc:43
operations_research
The vehicle routing library lets one model and solve generic vehicle routing problems ranging from th...
Definition: dense_doubly_linked_list.h:21
operations_research::sat::NegationOf
std::vector< IntegerVariable > NegationOf(const std::vector< IntegerVariable > &vars)
Definition: integer.cc:42
operations_research::sat::IntegerTrail::IsCurrentlyIgnored
bool IsCurrentlyIgnored(IntegerVariable i) const
Definition: integer.h:612
operations_research::sat::FirstUnassignedVarAtItsMinHeuristic
std::function< LiteralIndex()> FirstUnassignedVarAtItsMinHeuristic(const std::vector< IntegerVariable > &vars, Model *model)
Definition: integer_search.cc:161
operations_research::sat::IntegerTrail
Definition: integer.h:534
operations_research::sat::Strategy::var_strategy
DecisionStrategyProto::VariableSelectionStrategy var_strategy
Definition: cp_model_search.cc:32
operations_research::sat::Model
Class that owns everything related to a particular optimization model.
Definition: sat/model.h:38
index
int index
Definition: pack.cc:508
operations_research::sat::VarValue
Definition: cp_model_search.cc:37
gtl::FindOrDie
const Collection::value_type::second_type & FindOrDie(const Collection &collection, const typename Collection::value_type::first_type &key)
Definition: map_util.h:176
operations_research::sat::Literal
Definition: sat_base.h:64
operations_research::sat::PositiveRef
int PositiveRef(int ref)
Definition: cp_model_utils.h:33
operations_research::sat::Strategy
Definition: cp_model_search.cc:30
operations_research::sat::IntegerEncoder
Definition: integer.h:278
operations_research::sat::InstrumentSearchStrategy
std::function< LiteralIndex()> InstrumentSearchStrategy(const CpModelProto &cp_model_proto, const std::vector< IntegerVariable > &variable_mapping, const std::function< LiteralIndex()> &instrumented_strategy, Model *model)
Definition: cp_model_search.cc:231
operations_research::sat::kMaxIntegerValue
constexpr IntegerValue kMaxIntegerValue(std::numeric_limits< IntegerValue::ValueType >::max() - 1)
operations_research::sat::ModelRandomGenerator
Definition: sat/util.h:33
operations_research::sat::DiversifySearchParameters
SatParameters DiversifySearchParameters(const SatParameters &params, const CpModelProto &cp_model, const int worker_id, std::string *name)
Definition: cp_model_search.cc:279
operations_research::sat::SequentialSearch
std::function< LiteralIndex()> SequentialSearch(std::vector< std::function< LiteralIndex()>> heuristics)
Definition: integer_search.cc:198
model
GRBmodel * model
Definition: gurobi_interface.cc:195
operations_research::sat::RefIsPositive
bool RefIsPositive(int ref)
Definition: cp_model_utils.h:34
operations_research::sat::IntegerTrail::LowerBound
IntegerValue LowerBound(IntegerVariable i) const
Definition: integer.h:1217
util.h
cp_model_search.h
operations_research::sat::IntegerLiteral::LowerOrEqual
static IntegerLiteral LowerOrEqual(IntegerVariable i, IntegerValue bound)
Definition: integer.h:1203
proto
CpModelProto proto
Definition: cp_model_fz_solver.cc:106
operations_research::sat::IntegerEncoder::GetAllIntegerLiterals
const InlinedIntegerLiteralVector & GetAllIntegerLiterals(Literal lit) const
Definition: integer.h:402
literal
Literal literal
Definition: optimization.cc:84
operations_research::sat::VarValue::value
IntegerValue value
Definition: cp_model_search.cc:39
operations_research::sat::ConstructSearchStrategy
std::function< LiteralIndex()> ConstructSearchStrategy(const CpModelProto &cp_model_proto, const std::vector< IntegerVariable > &variable_mapping, IntegerVariable objective_var, Model *model)
Definition: cp_model_search.cc:173
parameters
SatParameters parameters
Definition: cp_model_fz_solver.cc:107
name
const std::string name
Definition: default_search.cc:807
cp_model_utils.h
gtl::ContainsKey
bool ContainsKey(const Collection &collection, const Key &key)
Definition: map_util.h:170
operations_research::sat::Strategy::variables
std::vector< IntegerVariable > variables
Definition: cp_model_search.cc:31