OR-Tools  8.0
bop_portfolio.h
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 
14 #ifndef OR_TOOLS_BOP_BOP_PORTFOLIO_H_
15 #define OR_TOOLS_BOP_BOP_PORTFOLIO_H_
16 
17 #include "ortools/bop/bop_base.h"
18 #include "ortools/bop/bop_lns.h"
21 #include "ortools/bop/bop_types.h"
22 #include "ortools/glop/lp_solver.h"
24 #include "ortools/sat/sat_solver.h"
25 #include "ortools/util/stats.h"
27 
28 namespace operations_research {
29 namespace bop {
30 
31 DEFINE_INT_TYPE(OptimizerIndex, int);
32 const OptimizerIndex kInvalidOptimizerIndex(-1);
33 
34 // Forward declaration.
35 class OptimizerSelector;
36 
37 // This class implements a portfolio optimizer.
38 // The portfolio currently includes all the following optimizers:
39 // - SAT_CORE_BASED
40 // - SAT_LINEAR_SEARCH
41 // - LINEAR_RELAXATION
42 // - LOCAL_SEARCH
43 // - RANDOM_FIRST_SOLUTION
44 // - RANDOM_CONSTRAINT_LNS
45 // - RANDOM_VARIABLE_LNS
46 // - COMPLETE_LNS
47 // - LP_FIRST_SOLUTION
48 // - OBJECTIVE_FIRST_SOLUTION
49 // - USER_GUIDED_FIRST_SOLUTION
50 // - FEASIBILITY_PUMP_FIRST_SOLUTION
51 // - RANDOM_CONSTRAINT_LNS_GUIDED_BY_LP
52 // - RANDOM_VARIABLE_LNS_GUIDED_BY_LP
53 // - RELATION_GRAPH_LNS
54 // - RELATION_GRAPH_LNS_GUIDED_BY_LP
55 //
56 // At each call of Optimize(), the portfolio optimizer selects the next
57 // optimizer to run and runs it. The selection is auto-adaptative, meaning that
58 // optimizers that succeeded more in the previous calls to Optimizer() are more
59 // likely to be selected.
61  public:
62  PortfolioOptimizer(const ProblemState& problem_state,
63  const BopParameters& parameters,
64  const BopSolverOptimizerSet& optimizer_set,
65  const std::string& name);
66  ~PortfolioOptimizer() override;
67 
68  bool ShouldBeRun(const ProblemState& problem_state) const override {
69  return true;
70  }
71  Status Optimize(const BopParameters& parameters,
72  const ProblemState& problem_state, LearnedInfo* learned_info,
73  TimeLimit* time_limit) override;
74 
75  private:
76  BopOptimizerBase::Status SynchronizeIfNeeded(
77  const ProblemState& problem_state);
78  void AddOptimizer(const sat::LinearBooleanProblem& problem,
79  const BopParameters& parameters,
80  const BopOptimizerMethod& optimizer_method);
81  void CreateOptimizers(const sat::LinearBooleanProblem& problem,
82  const BopParameters& parameters,
83  const BopSolverOptimizerSet& optimizer_set);
84 
85  std::unique_ptr<MTRandom> random_;
86  int64 state_update_stamp_;
87  BopConstraintTerms objective_terms_;
88  std::unique_ptr<OptimizerSelector> selector_;
90  sat::SatSolver sat_propagator_;
91  BopParameters parameters_;
92  double lower_bound_;
93  double upper_bound_;
94  int number_of_consecutive_failing_optimizers_;
95 };
96 
97 // This class is providing an adaptative selector for optimizers based on
98 // their past successes and deterministic time spent.
100  public:
101  // Note that the list of optimizers is only used to get the names for
102  // debug purposes, the ownership of the optimizers is not transferred.
103  explicit OptimizerSelector(
105 
106  // Selects the next optimizer to run based on the user defined order and
107  // history of success. Returns kInvalidOptimizerIndex if no optimizer is
108  // selectable and runnable (see the functions below).
109  //
110  // The optimizer is selected using the following algorithm (L being the
111  // sorted list of optimizers, and l the position of the last selected
112  // optimizer):
113  // a- If a new solution has been found by optimizer l, select the first
114  // optimizer l' in L, l' >= 0, that can run.
115  // b- If optimizer l didn't find a new solution, select the first
116  // optimizer l', with l' > l, such that its deterministic time spent
117  // since last solution is smaller than the deterministic time spent
118  // by any runnable optimizer in 1..l since last solution.
119  // If no such optimizer is available, go to option a.
120  OptimizerIndex SelectOptimizer();
121 
122  // Updates the internal metrics to decide which optimizer to select.
123  // This method should be called each time the selected optimizer is run.
124  //
125  // The gain corresponds to the reward to assign to the solver; It could for
126  // instance be the difference in cost between the last and the current
127  // solution.
128  //
129  // The time spent corresponds to the time the optimizer spent; To make the
130  // behavior deterministic, it is recommanded to use the deterministic time
131  // instead of the elapsed time.
132  //
133  // The optimizers are sorted based on their score each time a new solution is
134  // found.
135  void UpdateScore(int64 gain, double time_spent);
136 
137  // Marks the given optimizer as not selectable until UpdateScore() is called
138  // with a positive gain. In which case, all optimizer will become selectable
139  // again.
140  void TemporarilyMarkOptimizerAsUnselectable(OptimizerIndex optimizer_index);
141 
142  // Sets whether or not an optimizer is "runnable". Like a non-selectable one,
143  // a non-runnable optimizer will never be returned by SelectOptimizer().
144  //
145  // TODO(user): Maybe we should simply have the notion of selectability here
146  // and let the client handle the logic to decide what optimizer are selectable
147  // or not.
148  void SetOptimizerRunnability(OptimizerIndex optimizer_index, bool runnable);
149 
150  // Returns statistics about the given optimizer.
151  std::string PrintStats(OptimizerIndex optimizer_index) const;
152  int NumCallsForOptimizer(OptimizerIndex optimizer_index) const;
153 
154  // Prints some debug information. Should not be used in production.
155  void DebugPrint() const;
156 
157  private:
158  // Updates internals when a solution has been found using the selected
159  // optimizer.
160  void NewSolutionFound(int64 gain);
161 
162  // Updates the deterministic time spent by the selected optimizer.
163  void UpdateDeterministicTime(double time_spent);
164 
165  // Sorts optimizers based on their scores.
166  void UpdateOrder();
167 
168  struct RunInfo {
169  RunInfo(OptimizerIndex i, const std::string& n)
170  : optimizer_index(i),
171  name(n),
172  num_successes(0),
173  num_calls(0),
174  total_gain(0),
175  time_spent(0.0),
176  time_spent_since_last_solution(0),
177  runnable(true),
178  selectable(true),
179  score(0.0) {}
180 
181  bool RunnableAndSelectable() const { return runnable && selectable; }
182 
183  OptimizerIndex optimizer_index;
184  std::string name;
185  int num_successes;
186  int num_calls;
187  int64 total_gain;
188  double time_spent;
189  double time_spent_since_last_solution;
190  bool runnable;
191  bool selectable;
192  double score;
193  };
194 
195  std::vector<RunInfo> run_infos_;
196  gtl::ITIVector<OptimizerIndex, int> info_positions_;
197  int selected_index_;
198 };
199 
200 } // namespace bop
201 } // namespace operations_research
202 #endif // OR_TOOLS_BOP_BOP_PORTFOLIO_H_
operations_research::bop::OptimizerSelector::PrintStats
std::string PrintStats(OptimizerIndex optimizer_index) const
Definition: bop_portfolio.cc:417
time_limit.h
operations_research::bop::OptimizerSelector::DebugPrint
void DebugPrint() const
Definition: bop_portfolio.cc:434
operations_research::bop::ProblemState
Definition: bop_base.h:111
operations_research::bop::PortfolioOptimizer::~PortfolioOptimizer
~PortfolioOptimizer() override
Definition: bop_portfolio.cc:74
operations_research::bop::OptimizerSelector::SelectOptimizer
OptimizerIndex SelectOptimizer()
Definition: bop_portfolio.cc:342
operations_research::bop::OptimizerSelector
Definition: bop_portfolio.h:99
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
bop_solution.h
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
sat_solver.h
operations_research::bop::LearnedInfo
Definition: bop_base.h:245
operations_research::bop::kInvalidOptimizerIndex
const OptimizerIndex kInvalidOptimizerIndex(-1)
operations_research::sat::SatSolver
Definition: sat_solver.h:58
stats.h
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
bop_types.h
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
boolean_problem.pb.h
operations_research::bop::DEFINE_INT_TYPE
DEFINE_INT_TYPE(OptimizerIndex, int)
operations_research::bop::OptimizerSelector::OptimizerSelector
OptimizerSelector(const gtl::ITIVector< OptimizerIndex, BopOptimizerBase * > &optimizers)
Definition: bop_portfolio.cc:333
operations_research::bop::BopOptimizerBase::name
const std::string & name() const
Definition: bop_base.h:46
bop_parameters.pb.h
operations_research::bop::PortfolioOptimizer
Definition: bop_portfolio.h:60
operations_research::bop::OptimizerSelector::NumCallsForOptimizer
int NumCallsForOptimizer(OptimizerIndex optimizer_index) const
Definition: bop_portfolio.cc:428
gtl::ITIVector< SparseIndex, BopConstraintTerm >
operations_research::bop::OptimizerSelector::UpdateScore
void UpdateScore(int64 gain, double time_spent)
Definition: bop_portfolio.cc:387
bop_base.h
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
lp_solver.h