OR-Tools  8.0
integer_search.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 // This file contains all the top-level logic responsible for driving the search
15 // of a satisfiability integer problem. What decision we take next, which new
16 // Literal associated to an IntegerLiteral we create and when we restart.
17 //
18 // For an optimization problem, our algorithm solves a sequence of decision
19 // problem using this file as an entry point. Note that some heuristics here
20 // still use the objective if there is one in order to orient the search towards
21 // good feasible solution though.
22 
23 #ifndef OR_TOOLS_SAT_INTEGER_SEARCH_H_
24 #define OR_TOOLS_SAT_INTEGER_SEARCH_H_
25 
26 #include <vector>
27 
28 #include "ortools/sat/integer.h"
29 #include "ortools/sat/sat_base.h"
30 #include "ortools/sat/sat_solver.h"
31 
32 namespace operations_research {
33 namespace sat {
34 
35 // Model struct that contains the search heuristics used to find a feasible
36 // solution to an integer problem.
37 //
38 // This is reset by ConfigureSearchHeuristics() and used by
39 // SolveIntegerProblem(), see below.
41  // Decision and restart heuristics. The two vectors must be of the same size
42  // and restart_policies[i] will always be used in conjunction with
43  // decision_policies[i].
44  std::vector<std::function<LiteralIndex()>> decision_policies;
45  std::vector<std::function<bool()>> restart_policies;
46 
47  // Index in the vector above that indicate the current configuration.
49 
50  // Two special decision functions that are constructed at loading time.
51  // These are used by ConfigureSearchHeuristics() to fill the policies above.
52  std::function<LiteralIndex()> fixed_search = nullptr;
53  std::function<LiteralIndex()> hint_search = nullptr;
54 };
55 
56 // Given a base "fixed_search" function that should mainly control in which
57 // order integer variables are lazily instantiated (and at what value), this
58 // uses the current solver parameters to set the SearchHeuristics class in the
59 // given model.
61 
62 // Callbacks that will be called when the search goes back to level 0.
63 // Callbacks should return false if the propagation fails.
65  std::vector<std::function<bool()>> callbacks;
66 };
67 
68 // Tries to find a feasible solution to the current model.
69 //
70 // This function continues from the current state of the solver and loop until
71 // all variables are instantiated (i.e. the next decision is kNoLiteralIndex) or
72 // a search limit is reached. It uses the heuristic from the SearchHeuristics
73 // class in the model to decide when to restart and what next decision to take.
74 //
75 // Each time a restart happen, this increment the policy index modulo the number
76 // of heuristics to act as a portfolio search.
78 
79 // Resets the solver to the given assumptions before calling
80 // SolveIntegerProblem().
82  const std::vector<Literal>& assumptions, Model* model);
83 
84 // Only used in tests. Move to a test utility file.
85 //
86 // This configures the model SearchHeuristics with a simple default heuristic
87 // and then call ResetAndSolveIntegerProblem() without any assumptions.
89 
90 // Helper methods to return up (>=) and down (<=) branching decisions.
91 LiteralIndex BranchDown(IntegerVariable var, IntegerValue value, Model* model);
92 LiteralIndex BranchUp(IntegerVariable var, IntegerValue value, Model* model);
93 
94 // Returns decision corresponding to var at its lower bound. Returns
95 // kNoLiteralIndex if the variable is fixed.
96 LiteralIndex AtMinValue(IntegerVariable var, IntegerTrail* integer_trail,
97  IntegerEncoder* integer_encoder);
98 
99 // Returns decision corresponding to var >= lb + max(1, (ub - lb) / 2). It also
100 // CHECKs that the variable is not fixed.
101 LiteralIndex GreaterOrEqualToMiddleValue(IntegerVariable var, Model* model);
102 
103 // This method first tries var <= value. If this does not reduce the domain it
104 // tries var >= value. If that also does not reduce the domain then returns
105 // kNoLiteralIndex.
106 LiteralIndex SplitAroundGivenValue(IntegerVariable positive_var,
107  IntegerValue value, Model* model);
108 
109 // Returns decision corresponding to var <= round(lp_value). If the variable
110 // does not appear in the LP, this method returns kNoLiteralIndex.
111 LiteralIndex SplitAroundLpValue(IntegerVariable var, Model* model);
112 
113 // Returns decision corresponding to var <= best_solution[var]. If no solution
114 // has been found, this method returns kNoLiteralIndex. This was suggested in
115 // paper: "Solution-Based Phase Saving for CP" (2018) by Emir Demirovic,
116 // Geoffrey Chu, and Peter J. Stuckey
117 LiteralIndex SplitDomainUsingBestSolutionValue(IntegerVariable var,
118  Model* model);
119 
120 // Decision heuristic for SolveIntegerProblemWithLazyEncoding(). Returns a
121 // function that will return the literal corresponding to the fact that the
122 // first currently non-fixed variable value is <= its min. The function will
123 // return kNoLiteralIndex if all the given variables are fixed.
124 //
125 // Note that this function will create the associated literal if needed.
126 std::function<LiteralIndex()> FirstUnassignedVarAtItsMinHeuristic(
127  const std::vector<IntegerVariable>& vars, Model* model);
128 
129 // Decision heuristic for SolveIntegerProblemWithLazyEncoding(). Like
130 // FirstUnassignedVarAtItsMinHeuristic() but the function will return the
131 // literal corresponding to the fact that the currently non-assigned variable
132 // with the lowest min has a value <= this min.
133 std::function<LiteralIndex()> UnassignedVarWithLowestMinAtItsMinHeuristic(
134  const std::vector<IntegerVariable>& vars, Model* model);
135 
136 // Set the first unassigned Literal/Variable to its value.
137 //
138 // TODO(user): This is currently quadratic as we scan all variables to find the
139 // first unassigned one. Fix. Note that this is also the case in many other
140 // heuristics and should be fixed.
142  BooleanVariable bool_var = kNoBooleanVariable;
143  IntegerVariable int_var = kNoIntegerVariable;
144 };
145 std::function<LiteralIndex()> FollowHint(
146  const std::vector<BooleanOrIntegerVariable>& vars,
147  const std::vector<IntegerValue>& values, Model* model);
148 
149 // Combines search heuristics in order: if the i-th one returns kNoLiteralIndex,
150 // ask the (i+1)-th. If every heuristic returned kNoLiteralIndex,
151 // returns kNoLiteralIndex.
152 std::function<LiteralIndex()> SequentialSearch(
153  std::vector<std::function<LiteralIndex()>> heuristics);
154 
155 // Changes the value of the given decision by 'var_selection_heuristic'. We try
156 // to see if the decision is "associated" with an IntegerVariable, and if it is
157 // the case, we choose the new value by the first 'value_selection_heuristics'
158 // that is applicable (return value != kNoLiteralIndex). If none of the
159 // heuristics are applicable then the given decision by
160 // 'var_selection_heuristic' is returned.
161 std::function<LiteralIndex()> SequentialValueSelection(
162  std::vector<std::function<LiteralIndex(IntegerVariable)>>
163  value_selection_heuristics,
164  std::function<LiteralIndex()> var_selection_heuristic, Model* model);
165 
166 // Changes the value of the given decision by 'var_selection_heuristic'
167 // according to various value selection heuristics. Looks at the code to know
168 // exactly what heuristic we use.
169 std::function<LiteralIndex()> IntegerValueSelectionHeuristic(
170  std::function<LiteralIndex()> var_selection_heuristic, Model* model);
171 
172 // Returns the LiteralIndex advised by the underliying SAT solver.
173 std::function<LiteralIndex()> SatSolverHeuristic(Model* model);
174 
175 // Gets the branching variable using pseudo costs and combines it with a value
176 // for branching.
177 std::function<LiteralIndex()> PseudoCost(Model* model);
178 
179 // Returns true if the number of variables in the linearized part represent
180 // a large enough proportion of all the problem variables.
182 
183 // A restart policy that restarts every k failures.
184 std::function<bool()> RestartEveryKFailures(int k, SatSolver* solver);
185 
186 // A restart policy that uses the underlying sat solver's policy.
187 std::function<bool()> SatSolverRestartPolicy(Model* model);
188 
189 // Appends model-owned automatic heuristics to input_heuristics in a new vector.
190 std::vector<std::function<LiteralIndex()>> AddModelHeuristics(
191  const std::vector<std::function<LiteralIndex()>>& input_heuristics,
192  Model* model);
193 
194 // Concatenates each input_heuristic with a default heuristic that instantiate
195 // all the problem's Boolean variables, into a new vector.
196 std::vector<std::function<LiteralIndex()>> CompleteHeuristics(
197  const std::vector<std::function<LiteralIndex()>>& incomplete_heuristics,
198  const std::function<LiteralIndex()>& completion_heuristic);
199 
200 } // namespace sat
201 } // namespace operations_research
202 
203 #endif // OR_TOOLS_SAT_INTEGER_SEARCH_H_
operations_research::sat::LevelZeroCallbackHelper::callbacks
std::vector< std::function< bool()> > callbacks
Definition: integer_search.h:65
var
IntVar * var
Definition: expr_array.cc:1858
operations_research::sat::IntegerValueSelectionHeuristic
std::function< LiteralIndex()> IntegerValueSelectionHeuristic(std::function< LiteralIndex()> var_selection_heuristic, Model *model)
Definition: integer_search.cc:254
operations_research::sat::SatSolver::Status
Status
Definition: sat_solver.h:181
operations_research::sat::RestartEveryKFailures
std::function< bool()> RestartEveryKFailures(int k, SatSolver *solver)
Definition: integer_search.cc:514
operations_research::sat::IntegerTrail
Definition: integer.h:523
operations_research::sat::FollowHint
std::function< LiteralIndex()> FollowHint(const std::vector< BooleanOrIntegerVariable > &vars, const std::vector< IntegerValue > &values, Model *model)
Definition: integer_search.cc:455
operations_research::sat::kNoIntegerVariable
const IntegerVariable kNoIntegerVariable(-1)
operations_research::sat::BranchDown
LiteralIndex BranchDown(IntegerVariable var, IntegerValue value, Model *model)
Definition: integer_search.cc:37
operations_research::sat::SearchHeuristics::policy_index
int policy_index
Definition: integer_search.h:48
operations_research::sat::SplitAroundLpValue
LiteralIndex SplitAroundLpValue(IntegerVariable var, Model *model)
Definition: integer_search.cc:109
operations_research::sat::SatSolver
Definition: sat_solver.h:58
value
int64 value
Definition: demon_profiler.cc:43
operations_research::sat::SolveIntegerProblem
SatSolver::Status SolveIntegerProblem(Model *model)
Definition: integer_search.cc:655
operations_research::sat::AtMinValue
LiteralIndex AtMinValue(IntegerVariable var, IntegerTrail *integer_trail, IntegerEncoder *integer_encoder)
Definition: integer_search.cc:55
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::FirstUnassignedVarAtItsMinHeuristic
std::function< LiteralIndex()> FirstUnassignedVarAtItsMinHeuristic(const std::vector< IntegerVariable > &vars, Model *model)
Definition: integer_search.cc:161
operations_research::sat::CompleteHeuristics
std::vector< std::function< LiteralIndex()> > CompleteHeuristics(const std::vector< std::function< LiteralIndex()>> &incomplete_heuristics, const std::function< LiteralIndex()> &completion_heuristic)
Definition: integer_search.cc:643
operations_research::sat::SearchHeuristics::restart_policies
std::vector< std::function< bool()> > restart_policies
Definition: integer_search.h:45
sat_solver.h
operations_research::sat::SearchHeuristics::decision_policies
std::vector< std::function< LiteralIndex()> > decision_policies
Definition: integer_search.h:44
sat_base.h
operations_research::sat::GreaterOrEqualToMiddleValue
LiteralIndex GreaterOrEqualToMiddleValue(IntegerVariable var, Model *model)
Definition: integer_search.cc:67
operations_research::sat::SplitDomainUsingBestSolutionValue
LiteralIndex SplitDomainUsingBestSolutionValue(IntegerVariable var, Model *model)
operations_research::sat::ResetAndSolveIntegerProblem
SatSolver::Status ResetAndSolveIntegerProblem(const std::vector< Literal > &assumptions, Model *model)
Definition: integer_search.cc:857
operations_research::sat::BranchUp
LiteralIndex BranchUp(IntegerVariable var, IntegerValue value, Model *model)
Definition: integer_search.cc:46
operations_research::sat::SatSolverRestartPolicy
std::function< bool()> SatSolverRestartPolicy(Model *model)
Definition: integer_search.cc:528
operations_research::sat::BooleanOrIntegerVariable::bool_var
BooleanVariable bool_var
Definition: integer_search.h:142
operations_research::sat::Model
Class that owns everything related to a particular optimization model.
Definition: sat/model.h:38
operations_research::sat::AddModelHeuristics
std::vector< std::function< LiteralIndex()> > AddModelHeuristics(const std::vector< std::function< LiteralIndex()>> &input_heuristics, Model *model)
Definition: integer_search.cc:633
operations_research::sat::kNoBooleanVariable
const BooleanVariable kNoBooleanVariable(-1)
operations_research::sat::SequentialValueSelection
std::function< LiteralIndex()> SequentialValueSelection(std::vector< std::function< LiteralIndex(IntegerVariable)>> value_selection_heuristics, std::function< LiteralIndex()> var_selection_heuristic, Model *model)
Definition: integer_search.cc:209
operations_research::sat::SearchHeuristics::hint_search
std::function< LiteralIndex()> hint_search
Definition: integer_search.h:53
operations_research::sat::BooleanOrIntegerVariable::int_var
IntegerVariable int_var
Definition: integer_search.h:143
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::SearchHeuristics
Definition: integer_search.h:40
operations_research::sat::LevelZeroCallbackHelper
Definition: integer_search.h:64
operations_research::sat::PseudoCost
std::function< LiteralIndex()> PseudoCost(Model *model)
Definition: integer_search.cc:325
operations_research::sat::BooleanOrIntegerVariable
Definition: integer_search.h:141
operations_research::sat::LinearizedPartIsLarge
bool LinearizedPartIsLarge(Model *model)
Definition: integer_search.cc:501
operations_research::sat::SatSolverHeuristic
std::function< LiteralIndex()> SatSolverHeuristic(Model *model)
Definition: integer_search.cc:312
operations_research::sat::SplitAroundGivenValue
LiteralIndex SplitAroundGivenValue(IntegerVariable positive_var, IntegerValue value, Model *model)
Definition: integer_search.cc:78
operations_research::sat::ConfigureSearchHeuristics
void ConfigureSearchHeuristics(Model *model)
Definition: integer_search.cc:533
operations_research::sat::UnassignedVarWithLowestMinAtItsMinHeuristic
std::function< LiteralIndex()> UnassignedVarWithLowestMinAtItsMinHeuristic(const std::vector< IntegerVariable > &vars, Model *model)
Definition: integer_search.cc:177
operations_research::sat::SearchHeuristics::fixed_search
std::function< LiteralIndex()> fixed_search
Definition: integer_search.h:52
operations_research::sat::IntegerEncoder
Definition: integer.h:267
integer.h
operations_research::sat::SolveIntegerProblemWithLazyEncoding
SatSolver::Status SolveIntegerProblemWithLazyEncoding(Model *model)
Definition: integer_search.cc:875