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