OR-Tools  8.1
bop_portfolio.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 "absl/memory/memory.h"
17 #include "absl/strings/str_format.h"
18 #include "ortools/base/stl_util.h"
19 #include "ortools/bop/bop_fs.h"
20 #include "ortools/bop/bop_lns.h"
21 #include "ortools/bop/bop_ls.h"
22 #include "ortools/bop/bop_util.h"
26 #include "ortools/sat/symmetry.h"
27 
28 namespace operations_research {
29 namespace bop {
30 
31 using ::operations_research::sat::LinearBooleanProblem;
32 using ::operations_research::sat::LinearObjective;
33 
34 namespace {
35 void BuildObjectiveTerms(const LinearBooleanProblem& problem,
36  BopConstraintTerms* objective_terms) {
37  CHECK(objective_terms != nullptr);
38 
39  if (!objective_terms->empty()) return;
40 
41  const LinearObjective& objective = problem.objective();
42  const size_t num_objective_terms = objective.literals_size();
43  CHECK_EQ(num_objective_terms, objective.coefficients_size());
44  for (int i = 0; i < num_objective_terms; ++i) {
45  CHECK_GT(objective.literals(i), 0);
46  CHECK_NE(objective.coefficients(i), 0);
47 
48  const VariableIndex var_id(objective.literals(i) - 1);
49  const int64 weight = objective.coefficients(i);
50  objective_terms->push_back(BopConstraintTerm(var_id, weight));
51  }
52 }
53 } // anonymous namespace
54 
55 //------------------------------------------------------------------------------
56 // PortfolioOptimizer
57 //------------------------------------------------------------------------------
59  const ProblemState& problem_state, const BopParameters& parameters,
60  const BopSolverOptimizerSet& optimizer_set, const std::string& name)
62  random_(),
63  state_update_stamp_(ProblemState::kInitialStampValue),
64  objective_terms_(),
65  selector_(),
66  optimizers_(),
67  sat_propagator_(),
68  parameters_(parameters),
69  lower_bound_(-glop::kInfinity),
70  upper_bound_(glop::kInfinity),
71  number_of_consecutive_failing_optimizers_(0) {
72  CreateOptimizers(problem_state.original_problem(), parameters, optimizer_set);
73 }
74 
76  if (parameters_.log_search_progress() || VLOG_IS_ON(1)) {
77  std::string stats_string;
78  for (OptimizerIndex i(0); i < optimizers_.size(); ++i) {
79  if (selector_->NumCallsForOptimizer(i) > 0) {
80  stats_string += selector_->PrintStats(i);
81  }
82  }
83  if (!stats_string.empty()) {
84  LOG(INFO) << "Stats. #new_solutions/#calls by optimizer:\n" +
85  stats_string;
86  }
87  }
88 
89  // Note that unique pointers are not used due to unsupported emplace_back
90  // in ITIVectors.
91  gtl::STLDeleteElements(&optimizers_);
92 }
93 
94 BopOptimizerBase::Status PortfolioOptimizer::SynchronizeIfNeeded(
95  const ProblemState& problem_state) {
96  if (state_update_stamp_ == problem_state.update_stamp()) {
98  }
99  state_update_stamp_ = problem_state.update_stamp();
100 
101  // Load any new information into the sat_propagator_.
102  const bool first_time = (sat_propagator_.NumVariables() == 0);
103  const BopOptimizerBase::Status status =
104  LoadStateProblemToSatSolver(problem_state, &sat_propagator_);
105  if (status != BopOptimizerBase::CONTINUE) return status;
106  if (first_time) {
107  // We configure the sat_propagator_ to use the objective as an assignment
108  // preference
110  &sat_propagator_);
111  }
112 
113  lower_bound_ = problem_state.GetScaledLowerBound();
114  upper_bound_ = problem_state.solution().IsFeasible()
115  ? problem_state.solution().GetScaledCost()
116  : glop::kInfinity;
118 }
119 
121  const BopParameters& parameters, const ProblemState& problem_state,
122  LearnedInfo* learned_info, TimeLimit* time_limit) {
123  CHECK(learned_info != nullptr);
124  CHECK(time_limit != nullptr);
125  learned_info->Clear();
126 
127  const BopOptimizerBase::Status sync_status =
128  SynchronizeIfNeeded(problem_state);
129  if (sync_status != BopOptimizerBase::CONTINUE) {
130  return sync_status;
131  }
132 
133  for (OptimizerIndex i(0); i < optimizers_.size(); ++i) {
134  selector_->SetOptimizerRunnability(
135  i, optimizers_[i]->ShouldBeRun(problem_state));
136  }
137 
138  const int64 init_cost = problem_state.solution().IsFeasible()
139  ? problem_state.solution().GetCost()
140  : kint64max;
141  const double init_deterministic_time =
142  time_limit->GetElapsedDeterministicTime();
143 
144  const OptimizerIndex selected_optimizer_id = selector_->SelectOptimizer();
145  if (selected_optimizer_id == kInvalidOptimizerIndex) {
146  LOG(INFO) << "All the optimizers are done.";
148  }
149  BopOptimizerBase* const selected_optimizer =
150  optimizers_[selected_optimizer_id];
151  if (parameters.log_search_progress() || VLOG_IS_ON(1)) {
152  LOG(INFO) << " " << lower_bound_ << " .. " << upper_bound_ << " "
153  << name() << " - " << selected_optimizer->name()
154  << ". Time limit: " << time_limit->GetTimeLeft() << " -- "
155  << time_limit->GetDeterministicTimeLeft();
156  }
157  const BopOptimizerBase::Status optimization_status =
158  selected_optimizer->Optimize(parameters, problem_state, learned_info,
159  time_limit);
160 
161  // ABORT means that this optimizer can't be run until we found a new solution.
162  if (optimization_status == BopOptimizerBase::ABORT) {
163  selector_->TemporarilyMarkOptimizerAsUnselectable(selected_optimizer_id);
164  }
165 
166  // The gain is defined as 1 for the first solution.
167  // TODO(user): Is 1 the right value? It might be better to use a percentage
168  // of the gap, or use the same gain as for the second solution.
169  const int64 gain = optimization_status == BopOptimizerBase::SOLUTION_FOUND
170  ? (init_cost == kint64max
171  ? 1
172  : init_cost - learned_info->solution.GetCost())
173  : 0;
174  const double spent_deterministic_time =
175  time_limit->GetElapsedDeterministicTime() - init_deterministic_time;
176  selector_->UpdateScore(gain, spent_deterministic_time);
177 
178  if (optimization_status == BopOptimizerBase::INFEASIBLE ||
179  optimization_status == BopOptimizerBase::OPTIMAL_SOLUTION_FOUND) {
180  return optimization_status;
181  }
182 
183  // Stop the portfolio optimizer after too many unsuccessful calls.
184  if (parameters.has_max_number_of_consecutive_failing_optimizer_calls() &&
185  problem_state.solution().IsFeasible()) {
186  number_of_consecutive_failing_optimizers_ =
187  optimization_status == BopOptimizerBase::SOLUTION_FOUND
188  ? 0
189  : number_of_consecutive_failing_optimizers_ + 1;
190  if (number_of_consecutive_failing_optimizers_ >
191  parameters.max_number_of_consecutive_failing_optimizer_calls()) {
193  }
194  }
195 
196  // TODO(user): don't penalize the SatCoreBasedOptimizer or the
197  // LinearRelaxation when they improve the lower bound.
198  // TODO(user): Do we want to re-order the optimizers in the selector when
199  // the status is BopOptimizerBase::INFORMATION_FOUND?
201 }
202 
203 void PortfolioOptimizer::AddOptimizer(
204  const LinearBooleanProblem& problem, const BopParameters& parameters,
205  const BopOptimizerMethod& optimizer_method) {
206  switch (optimizer_method.type()) {
207  case BopOptimizerMethod::SAT_CORE_BASED:
208  optimizers_.push_back(new SatCoreBasedOptimizer("SatCoreBasedOptimizer"));
209  break;
210  case BopOptimizerMethod::SAT_LINEAR_SEARCH:
211  optimizers_.push_back(new GuidedSatFirstSolutionGenerator(
213  break;
214  case BopOptimizerMethod::LINEAR_RELAXATION:
215  optimizers_.push_back(
216  new LinearRelaxation(parameters, "LinearRelaxation"));
217  break;
218  case BopOptimizerMethod::LOCAL_SEARCH: {
219  for (int i = 1; i <= parameters.max_num_decisions_in_ls(); ++i) {
220  optimizers_.push_back(new LocalSearchOptimizer(
221  absl::StrFormat("LS_%d", i), i, &sat_propagator_));
222  }
223  } break;
224  case BopOptimizerMethod::RANDOM_FIRST_SOLUTION:
225  optimizers_.push_back(new BopRandomFirstSolutionGenerator(
226  "SATRandomFirstSolution", parameters, &sat_propagator_,
227  random_.get()));
228  break;
229  case BopOptimizerMethod::RANDOM_VARIABLE_LNS:
230  BuildObjectiveTerms(problem, &objective_terms_);
231  optimizers_.push_back(new BopAdaptiveLNSOptimizer(
232  "RandomVariableLns",
233  /*use_lp_to_guide_sat=*/false,
234  new ObjectiveBasedNeighborhood(&objective_terms_, random_.get()),
235  &sat_propagator_));
236  break;
237  case BopOptimizerMethod::RANDOM_VARIABLE_LNS_GUIDED_BY_LP:
238  BuildObjectiveTerms(problem, &objective_terms_);
239  optimizers_.push_back(new BopAdaptiveLNSOptimizer(
240  "RandomVariableLnsWithLp",
241  /*use_lp_to_guide_sat=*/true,
242  new ObjectiveBasedNeighborhood(&objective_terms_, random_.get()),
243  &sat_propagator_));
244  break;
245  case BopOptimizerMethod::RANDOM_CONSTRAINT_LNS:
246  BuildObjectiveTerms(problem, &objective_terms_);
247  optimizers_.push_back(new BopAdaptiveLNSOptimizer(
248  "RandomConstraintLns",
249  /*use_lp_to_guide_sat=*/false,
250  new ConstraintBasedNeighborhood(&objective_terms_, random_.get()),
251  &sat_propagator_));
252  break;
253  case BopOptimizerMethod::RANDOM_CONSTRAINT_LNS_GUIDED_BY_LP:
254  BuildObjectiveTerms(problem, &objective_terms_);
255  optimizers_.push_back(new BopAdaptiveLNSOptimizer(
256  "RandomConstraintLnsWithLp",
257  /*use_lp_to_guide_sat=*/true,
258  new ConstraintBasedNeighborhood(&objective_terms_, random_.get()),
259  &sat_propagator_));
260  break;
261  case BopOptimizerMethod::RELATION_GRAPH_LNS:
262  BuildObjectiveTerms(problem, &objective_terms_);
263  optimizers_.push_back(new BopAdaptiveLNSOptimizer(
264  "RelationGraphLns",
265  /*use_lp_to_guide_sat=*/false,
266  new RelationGraphBasedNeighborhood(problem, random_.get()),
267  &sat_propagator_));
268  break;
269  case BopOptimizerMethod::RELATION_GRAPH_LNS_GUIDED_BY_LP:
270  BuildObjectiveTerms(problem, &objective_terms_);
271  optimizers_.push_back(new BopAdaptiveLNSOptimizer(
272  "RelationGraphLnsWithLp",
273  /*use_lp_to_guide_sat=*/true,
274  new RelationGraphBasedNeighborhood(problem, random_.get()),
275  &sat_propagator_));
276  break;
277  case BopOptimizerMethod::COMPLETE_LNS:
278  BuildObjectiveTerms(problem, &objective_terms_);
279  optimizers_.push_back(
280  new BopCompleteLNSOptimizer("LNS", objective_terms_));
281  break;
282  case BopOptimizerMethod::USER_GUIDED_FIRST_SOLUTION:
283  optimizers_.push_back(new GuidedSatFirstSolutionGenerator(
284  "SATUserGuidedFirstSolution",
286  break;
287  case BopOptimizerMethod::LP_FIRST_SOLUTION:
288  optimizers_.push_back(new GuidedSatFirstSolutionGenerator(
289  "SATLPFirstSolution",
291  break;
292  case BopOptimizerMethod::OBJECTIVE_FIRST_SOLUTION:
293  optimizers_.push_back(new GuidedSatFirstSolutionGenerator(
294  "SATObjectiveFirstSolution",
296  break;
297  default:
298  LOG(FATAL) << "Unknown optimizer type.";
299  }
300 }
301 
302 void PortfolioOptimizer::CreateOptimizers(
303  const LinearBooleanProblem& problem, const BopParameters& parameters,
304  const BopSolverOptimizerSet& optimizer_set) {
305  random_ = absl::make_unique<MTRandom>(parameters.random_seed());
306 
307  if (parameters.use_symmetry()) {
308  VLOG(1) << "Finding symmetries of the problem.";
309  std::vector<std::unique_ptr<SparsePermutation>> generators;
310  sat::FindLinearBooleanProblemSymmetries(problem, &generators);
311  std::unique_ptr<sat::SymmetryPropagator> propagator(
312  new sat::SymmetryPropagator);
313  for (int i = 0; i < generators.size(); ++i) {
314  propagator->AddSymmetry(std::move(generators[i]));
315  }
316  sat_propagator_.AddPropagator(propagator.get());
317  sat_propagator_.TakePropagatorOwnership(std::move(propagator));
318  }
319 
320  const int max_num_optimizers =
321  optimizer_set.methods_size() + parameters.max_num_decisions_in_ls() - 1;
322  optimizers_.reserve(max_num_optimizers);
323  for (const BopOptimizerMethod& optimizer_method : optimizer_set.methods()) {
324  const OptimizerIndex old_size(optimizers_.size());
325  AddOptimizer(problem, parameters, optimizer_method);
326  }
327 
328  selector_ = absl::make_unique<OptimizerSelector>(optimizers_);
329 }
330 
331 //------------------------------------------------------------------------------
332 // OptimizerSelector
333 //------------------------------------------------------------------------------
336  : run_infos_(), selected_index_(optimizers.size()) {
337  for (OptimizerIndex i(0); i < optimizers.size(); ++i) {
338  info_positions_.push_back(run_infos_.size());
339  run_infos_.push_back(RunInfo(i, optimizers[i]->name()));
340  }
341 }
342 
344  CHECK_GE(selected_index_, 0);
345 
346  do {
347  ++selected_index_;
348  } while (selected_index_ < run_infos_.size() &&
349  !run_infos_[selected_index_].RunnableAndSelectable());
350 
351  if (selected_index_ >= run_infos_.size()) {
352  // Select the first possible optimizer.
353  selected_index_ = -1;
354  for (int i = 0; i < run_infos_.size(); ++i) {
355  if (run_infos_[i].RunnableAndSelectable()) {
356  selected_index_ = i;
357  break;
358  }
359  }
360  if (selected_index_ == -1) return kInvalidOptimizerIndex;
361  } else {
362  // Select the next possible optimizer. If none, select the first one.
363  // Check that the time is smaller than all previous optimizers which are
364  // runnable.
365  bool too_much_time_spent = false;
366  const double time_spent =
367  run_infos_[selected_index_].time_spent_since_last_solution;
368  for (int i = 0; i < selected_index_; ++i) {
369  const RunInfo& info = run_infos_[i];
370  if (info.RunnableAndSelectable() &&
371  info.time_spent_since_last_solution < time_spent) {
372  too_much_time_spent = true;
373  break;
374  }
375  }
376  if (too_much_time_spent) {
377  // TODO(user): Remove this recursive call, even if in practice it's
378  // safe because the max depth is the number of optimizers.
379  return SelectOptimizer();
380  }
381  }
382 
383  // Select the optimizer.
384  ++run_infos_[selected_index_].num_calls;
385  return run_infos_[selected_index_].optimizer_index;
386 }
387 
388 void OptimizerSelector::UpdateScore(int64 gain, double time_spent) {
389  const bool new_solution_found = gain != 0;
390  if (new_solution_found) NewSolutionFound(gain);
391  UpdateDeterministicTime(time_spent);
392 
393  const double new_score = time_spent == 0.0 ? 0.0 : gain / time_spent;
394  const double kErosion = 0.2;
395  const double kMinScore = 1E-6;
396 
397  RunInfo& info = run_infos_[selected_index_];
398  const double old_score = info.score;
399  info.score =
400  std::max(kMinScore, old_score * (1 - kErosion) + kErosion * new_score);
401 
402  if (new_solution_found) { // Solution found
403  UpdateOrder();
404  selected_index_ = run_infos_.size();
405  }
406 }
407 
409  OptimizerIndex optimizer_index) {
410  run_infos_[info_positions_[optimizer_index]].selectable = false;
411 }
412 
413 void OptimizerSelector::SetOptimizerRunnability(OptimizerIndex optimizer_index,
414  bool runnable) {
415  run_infos_[info_positions_[optimizer_index]].runnable = runnable;
416 }
417 
419  OptimizerIndex optimizer_index) const {
420  const RunInfo& info = run_infos_[info_positions_[optimizer_index]];
421  return absl::StrFormat(
422  " %40s : %3d/%-3d (%6.2f%%) Total gain: %6d Total Dtime: %0.3f "
423  "score: %f\n",
424  info.name, info.num_successes, info.num_calls,
425  100.0 * info.num_successes / info.num_calls, info.total_gain,
426  info.time_spent, info.score);
427 }
428 
430  OptimizerIndex optimizer_index) const {
431  const RunInfo& info = run_infos_[info_positions_[optimizer_index]];
432  return info.num_calls;
433 }
434 
436  std::string str;
437  for (int i = 0; i < run_infos_.size(); ++i) {
438  const RunInfo& info = run_infos_[i];
439  LOG(INFO) << " " << info.name << " " << info.total_gain
440  << " / " << info.time_spent << " = " << info.score << " "
441  << info.selectable << " " << info.time_spent_since_last_solution;
442  }
443 }
444 
445 void OptimizerSelector::NewSolutionFound(int64 gain) {
446  run_infos_[selected_index_].num_successes++;
447  run_infos_[selected_index_].total_gain += gain;
448 
449  for (int i = 0; i < run_infos_.size(); ++i) {
450  run_infos_[i].time_spent_since_last_solution = 0;
451  run_infos_[i].selectable = true;
452  }
453 }
454 
455 void OptimizerSelector::UpdateDeterministicTime(double time_spent) {
456  run_infos_[selected_index_].time_spent += time_spent;
457  run_infos_[selected_index_].time_spent_since_last_solution += time_spent;
458 }
459 
460 void OptimizerSelector::UpdateOrder() {
461  // Re-sort optimizers.
462  std::stable_sort(run_infos_.begin(), run_infos_.end(),
463  [](const RunInfo& a, const RunInfo& b) -> bool {
464  if (a.total_gain == 0 && b.total_gain == 0)
465  return a.time_spent < b.time_spent;
466  return a.score > b.score;
467  });
468 
469  // Update the positions.
470  for (int i = 0; i < run_infos_.size(); ++i) {
471  info_positions_[run_infos_[i].optimizer_index] = i;
472  }
473 }
474 
475 } // namespace bop
476 } // namespace operations_research
operations_research::bop::OptimizerSelector::DebugPrint
void DebugPrint() const
Definition: bop_portfolio.cc:435
bop_fs.h
INFO
const int INFO
Definition: log_severity.h:31
VLOG
#define VLOG(verboselevel)
Definition: base/logging.h:978
operations_research::bop::BopOptimizerBase::SOLUTION_FOUND
@ SOLUTION_FOUND
Definition: bop_base.h:63
absl::StrongVector::push_back
void push_back(const value_type &x)
Definition: strong_vector.h:158
max
int64 max
Definition: alldiff_cst.cc:139
complete_optimizer.h
operations_research::bop::ProblemState::solution
const BopSolution & solution() const
Definition: bop_base.h:193
operations_research::bop::BopOptimizerBase::name
const std::string & name() const
Definition: bop_base.h:46
operations_research::bop::OptimizerSelector::TemporarilyMarkOptimizerAsUnselectable
void TemporarilyMarkOptimizerAsUnselectable(OptimizerIndex optimizer_index)
Definition: bop_portfolio.cc:408
LOG
#define LOG(severity)
Definition: base/logging.h:420
absl::StrongVector::size
size_type size() const
Definition: strong_vector.h:147
operations_research::bop::GuidedSatFirstSolutionGenerator::Policy::kUserGuided
@ kUserGuided
operations_research::bop::LearnedInfo::Clear
void Clear()
Definition: bop_base.h:255
FATAL
const int FATAL
Definition: log_severity.h:32
CHECK_GE
#define CHECK_GE(val1, val2)
Definition: base/logging.h:701
operations_research::bop::OptimizerSelector::OptimizerSelector
OptimizerSelector(const absl::StrongVector< OptimizerIndex, BopOptimizerBase * > &optimizers)
Definition: bop_portfolio.cc:334
operations_research::bop::GuidedSatFirstSolutionGenerator::Policy::kLpGuided
@ kLpGuided
symmetry.h
operations_research::bop::LinearRelaxation
Definition: bop_fs.h:109
CHECK_GT
#define CHECK_GT(val1, val2)
Definition: base/logging.h:702
weight
int64 weight
Definition: pack.cc:509
operations_research::bop::LearnedInfo::solution
BopSolution solution
Definition: bop_base.h:266
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::bop::LoadStateProblemToSatSolver
BopOptimizerBase::Status LoadStateProblemToSatSolver(const ProblemState &problem_state, sat::SatSolver *sat_solver)
Definition: bop_util.cc:87
bop_portfolio.h
operations_research::bop::OptimizerSelector::SelectOptimizer
OptimizerIndex SelectOptimizer()
Definition: bop_portfolio.cc:343
operations_research::sat::FindLinearBooleanProblemSymmetries
void FindLinearBooleanProblemSymmetries(const LinearBooleanProblem &problem, std::vector< std::unique_ptr< SparsePermutation >> *generators)
Definition: boolean_problem.cc:670
operations_research::bop::BopOptimizerBase
Definition: bop_base.h:40
int64
int64_t int64
Definition: integral_types.h:34
operations_research::bop::PortfolioOptimizer::PortfolioOptimizer
PortfolioOptimizer(const ProblemState &problem_state, const BopParameters &parameters, const BopSolverOptimizerSet &optimizer_set, const std::string &name)
Definition: bop_portfolio.cc:58
operations_research::TimeLimit
A simple class to enforce both an elapsed time limit and a deterministic time limit in the same threa...
Definition: time_limit.h:105
operations_research::sat::SatSolver::TakePropagatorOwnership
void TakePropagatorOwnership(std::unique_ptr< SatPropagator > propagator)
Definition: sat_solver.h:143
operations_research::bop::kInvalidOptimizerIndex
const OptimizerIndex kInvalidOptimizerIndex(-1)
operations_research::glop::kInfinity
const double kInfinity
Definition: lp_types.h:83
operations_research::sat::UseObjectiveForSatAssignmentPreference
void UseObjectiveForSatAssignmentPreference(const LinearBooleanProblem &problem, SatSolver *solver)
Definition: boolean_problem.cc:307
operations_research::bop::OptimizerSelector::SetOptimizerRunnability
void SetOptimizerRunnability(OptimizerIndex optimizer_index, bool runnable)
Definition: bop_portfolio.cc:413
a
int64 a
Definition: constraint_solver/table.cc:42
operations_research::bop::BopOptimizerBase::INFEASIBLE
@ INFEASIBLE
Definition: bop_base.h:64
time_limit
SharedTimeLimit * time_limit
Definition: cp_model_solver.cc:2103
operations_research::bop::LearnedInfo
Definition: bop_base.h:245
operations_research::bop::PortfolioOptimizer::~PortfolioOptimizer
~PortfolioOptimizer() override
Definition: bop_portfolio.cc:75
operations_research::bop::ProblemState::GetScaledLowerBound
double GetScaledLowerBound() const
Definition: bop_base.h:210
operations_research::bop::ProblemState
Definition: bop_base.h:111
boolean_problem.pb.h
operations_research::bop::GuidedSatFirstSolutionGenerator
Definition: bop_fs.h:42
CHECK_EQ
#define CHECK_EQ(val1, val2)
Definition: base/logging.h:697
operations_research::bop::OptimizerSelector::NumCallsForOptimizer
int NumCallsForOptimizer(OptimizerIndex optimizer_index) const
Definition: bop_portfolio.cc:429
operations_research::bop::BopSolution::GetScaledCost
double GetScaledCost() const
Definition: bop_solution.h:61
operations_research::bop::OptimizerSelector::UpdateScore
void UpdateScore(int64 gain, double time_spent)
Definition: bop_portfolio.cc:388
operations_research::bop::ProblemState::original_problem
const sat::LinearBooleanProblem & original_problem() const
Definition: bop_base.h:198
bop_util.h
operations_research::bop::BopConstraintTerms
absl::StrongVector< SparseIndex, BopConstraintTerm > BopConstraintTerms
Definition: bop_types.h:85
operations_research::bop::GuidedSatFirstSolutionGenerator::Policy::kObjectiveGuided
@ kObjectiveGuided
operations_research::bop::PortfolioOptimizer::Optimize
Status Optimize(const BopParameters &parameters, const ProblemState &problem_state, LearnedInfo *learned_info, TimeLimit *time_limit) override
Definition: bop_portfolio.cc:120
operations_research::bop::BopOptimizerBase::OPTIMAL_SOLUTION_FOUND
@ OPTIMAL_SOLUTION_FOUND
Definition: bop_base.h:62
operations_research::bop::BopOptimizerBase::Optimize
virtual Status Optimize(const BopParameters &parameters, const ProblemState &problem_state, LearnedInfo *learned_info, TimeLimit *time_limit)=0
operations_research::bop::GuidedSatFirstSolutionGenerator::Policy::kNotGuided
@ kNotGuided
absl::StrongVector
Definition: strong_vector.h:76
operations_research::bop::BopSolution::IsFeasible
bool IsFeasible() const
Definition: bop_solution.h:69
bop_ls.h
stl_util.h
b
int64 b
Definition: constraint_solver/table.cc:43
VLOG_IS_ON
#define VLOG_IS_ON(verboselevel)
Definition: vlog_is_on.h:41
boolean_problem.h
operations_research::sat::SatSolver::AddPropagator
void AddPropagator(SatPropagator *propagator)
Definition: sat_solver.cc:405
selector_
BaseVariableAssignmentSelector *const selector_
Definition: search.cc:1856
gtl::STLDeleteElements
void STLDeleteElements(T *container)
Definition: stl_util.h:372
CHECK_NE
#define CHECK_NE(val1, val2)
Definition: base/logging.h:698
operations_research::bop::LocalSearchOptimizer
Definition: bop_ls.h:114
operations_research::bop::BopOptimizerBase::CONTINUE
@ CONTINUE
Definition: bop_base.h:76
operations_research::bop::BopSolution::GetCost
int64 GetCost() const
Definition: bop_solution.h:50
operations_research::bop::PortfolioOptimizer::ShouldBeRun
bool ShouldBeRun(const ProblemState &problem_state) const override
Definition: bop_portfolio.h:68
bop_lns.h
operations_research::bop::BopOptimizerBase::Status
Status
Definition: bop_base.h:61
CHECK
#define CHECK(condition)
Definition: base/logging.h:495
operations_research::sat::SatSolver::NumVariables
int NumVariables() const
Definition: sat_solver.h:83
parameters
SatParameters parameters
Definition: cp_model_fz_solver.cc:108
operations_research::bop::SatCoreBasedOptimizer
Definition: complete_optimizer.h:43
name
const std::string name
Definition: default_search.cc:808
operations_research::bop::BopOptimizerBase::ABORT
@ ABORT
Definition: bop_base.h:79
kint64max
static const int64 kint64max
Definition: integral_types.h:62
operations_research::bop::ProblemState::update_stamp
int64 update_stamp() const
Definition: bop_base.h:153
operations_research::bop::OptimizerSelector::PrintStats
std::string PrintStats(OptimizerIndex optimizer_index) const
Definition: bop_portfolio.cc:418