OR-Tools  8.0
cuts.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_SAT_CUTS_H_
15 #define OR_TOOLS_SAT_CUTS_H_
16 
17 #include <utility>
18 #include <vector>
19 
20 #include "ortools/base/int_type.h"
22 #include "ortools/sat/integer.h"
23 #include "ortools/sat/intervals.h"
26 #include "ortools/sat/model.h"
28 
29 namespace operations_research {
30 namespace sat {
31 
32 // A "cut" generator on a set of IntegerVariable.
33 //
34 // The generate_cuts() function will usually be called with the current LP
35 // optimal solution (but should work for any lp_values). Note that a
36 // CutGenerator should:
37 // - Only look at the lp_values positions that corresponds to its 'vars' or
38 // their negation.
39 // - Only add cuts in term of the same variables or their negation.
40 struct CutGenerator {
41  std::vector<IntegerVariable> vars;
42  std::function<void(const gtl::ITIVector<IntegerVariable, double>& lp_values,
43  LinearConstraintManager* manager)>
45 };
46 
47 // Given an upper-bounded linear relation (sum terms <= ub), this algorithm
48 // inspects the integer variable appearing in the sum and try to replace each of
49 // them by a tight lower bound (>= coeff * binary + lb) using the implied bound
50 // repository. By tight, we mean that it will take the same value under the
51 // current LP solution.
52 //
53 // We use a class to reuse memory of the tmp terms.
55  public:
56  // We will only replace IntegerVariable appearing in lp_vars_.
57  ImpliedBoundsProcessor(absl::Span<const IntegerVariable> lp_vars_,
58  IntegerTrail* integer_trail,
59  ImpliedBounds* implied_bounds)
60  : lp_vars_(lp_vars_.begin(), lp_vars_.end()),
61  integer_trail_(integer_trail),
62  implied_bounds_(implied_bounds) {}
63 
64  // Processes and updates the given cut.
67  LinearConstraint* cut) const;
68 
69  // Same as ProcessUpperBoundedConstraint() but instead of just using
70  // var >= coeff * binary + lb we use var == slack + coeff * binary + lb where
71  // slack is a new temporary variable that we create.
72  //
73  // The new slack will be such that slack_infos[(slack - first_slack) / 2]
74  // contains its definition so that we can properly handle it in the cut
75  // generation and substitute it back later.
76  struct SlackInfo {
77  // This slack is equal to sum of terms + offset.
78  std::vector<std::pair<IntegerVariable, IntegerValue>> terms;
79  IntegerValue offset;
80 
81  // The slack bounds and current lp_value.
82  IntegerValue lb = IntegerValue(0);
83  IntegerValue ub = IntegerValue(0);
84  double lp_value = 0.0;
85  };
87  bool substitute_only_inner_variables, IntegerVariable first_slack,
89  LinearConstraint* cut, std::vector<SlackInfo>* slack_infos,
90  std::vector<LinearConstraint>* implied_bound_cuts) const;
91 
92  // Only used for debugging.
93  //
94  // Substituting back the slack created by the function above should give
95  // exactly the same cut as the original one.
96  bool DebugSlack(IntegerVariable first_slack,
97  const LinearConstraint& initial_cut,
98  const LinearConstraint& cut,
99  const std::vector<SlackInfo>& info);
100 
101  // Add a new variable that could be used in the new cuts.
102  void AddLpVariable(IntegerVariable var) { lp_vars_.insert(var); }
103 
104  // Must be called before we process any constraints with a different
105  // lp_values or level zero bounds.
106  void ClearCache() const { cache_.clear(); }
107 
109  double bool_lp_value = 0.0;
110  double slack_lp_value = std::numeric_limits<double>::infinity();
112  IntegerValue bound_diff;
113  IntegerVariable bool_var = kNoIntegerVariable;
114  };
116 
117  private:
118  BestImpliedBoundInfo ComputeBestImpliedBound(
119  IntegerVariable var,
121  std::vector<LinearConstraint>* implied_bound_cuts) const;
122 
123  absl::flat_hash_set<IntegerVariable> lp_vars_;
124  mutable absl::flat_hash_map<IntegerVariable, BestImpliedBoundInfo> cache_;
125 
126  // Data from the constructor.
127  IntegerTrail* integer_trail_;
128  ImpliedBounds* implied_bounds_;
129 
130  // Temporary memory used by ProcessUpperBoundedConstraint().
131  mutable std::vector<std::pair<IntegerVariable, IntegerValue>> tmp_terms_;
132 };
133 
134 // Visible for testing. Returns a function f on integers such that:
135 // - f is non-decreasing.
136 // - f is super-additive: f(a) + f(b) <= f(a + b)
137 // - 1 <= f(divisor) <= max_scaling
138 // - For all x, f(x * divisor) = x * f(divisor)
139 // - For all x, f(x * divisor + remainder) = x * f(divisor)
140 //
141 // Preconditions:
142 // - 0 <= remainder < divisor.
143 // - 1 <= max_scaling.
144 //
145 // This is used in IntegerRoundingCut() and is responsible for "strengthening"
146 // the cut. Just taking f(x) = x / divisor result in the non-strengthened cut
147 // and using any function that stricly dominate this one is better.
148 //
149 // Algorithm:
150 // - We first scale by a factor t so that rhs_remainder >= divisor / 2.
151 // - Then, if max_scaling == 2, we use the function described
152 // in "Strenghtening Chvatal-Gomory cuts and Gomory fractional cuts", Adam N.
153 // Letchfrod, Andrea Lodi.
154 // - Otherwise, we use a generalization of this which is a discretized version
155 // of the classical MIR rounding function that only take the value of the
156 // form "an_integer / max_scaling". As max_scaling goes to infinity, this
157 // converge to the real-valued MIR function.
158 //
159 // Note that for each value of max_scaling we will get a different function.
160 // And that there is no dominance relation between any of these functions. So
161 // it could be nice to try to generate a cut using different values of
162 // max_scaling.
163 IntegerValue GetFactorT(IntegerValue rhs_remainder, IntegerValue divisor,
164  IntegerValue max_t);
165 std::function<IntegerValue(IntegerValue)> GetSuperAdditiveRoundingFunction(
166  IntegerValue rhs_remainder, IntegerValue divisor, IntegerValue t,
167  IntegerValue max_scaling);
168 
169 // Given an upper bounded linear constraint, this function tries to transform it
170 // to a valid cut that violate the given LP solution using integer rounding.
171 // Note that the returned cut might not always violate the LP solution, in which
172 // case it can be discarded.
173 //
174 // What this does is basically take the integer division of the constraint by an
175 // integer. If the coefficients where doubles, this would be the same as scaling
176 // the constraint and then rounding. We choose the coefficient of the most
177 // fractional variable (rescaled by its coefficient) as the divisor, but there
178 // are other possible alternatives.
179 //
180 // Note that if the constraint is tight under the given lp solution, and if
181 // there is a unique variable not at one of its bounds and fractional, then we
182 // are guaranteed to generate a cut that violate the current LP solution. This
183 // should be the case for Chvatal-Gomory base constraints modulo our loss of
184 // precision while doing exact integer computations.
185 //
186 // Precondition:
187 // - We assumes that the given initial constraint is tight using the given lp
188 // values. This could be relaxed, but for now it should always be the case, so
189 // we log a message and abort if not, to ease debugging.
190 // - The IntegerVariable of the cuts are not used here. We assumes that the
191 // first three vectors are in one to one correspondence with the initial order
192 // of the variable in the cut.
193 //
194 // TODO(user): There is a bunch of heuristic involved here, and we could spend
195 // more effort tunning them. In particular, one can try many heuristics and keep
196 // the best looking cut (or more than one). This is not on the critical code
197 // path, so we can spend more effort in finding good cuts.
199  IntegerValue max_scaling = IntegerValue(60);
200 };
202  public:
203  void ComputeCut(RoundingOptions options, const std::vector<double>& lp_values,
204  const std::vector<IntegerValue>& lower_bounds,
205  const std::vector<IntegerValue>& upper_bounds,
206  ImpliedBoundsProcessor* ib_processor, LinearConstraint* cut);
207 
208  // Returns the number of implied bound lifted Booleans in the last
209  // ComputeCut() call. Useful for investigation.
210  int NumLiftedBooleans() const { return num_lifted_booleans_; }
211 
212  private:
213  // The helper is just here to reuse the memory for these vectors.
214  std::vector<int> relevant_indices_;
215  std::vector<double> relevant_lp_values_;
216  std::vector<IntegerValue> relevant_coeffs_;
217  std::vector<IntegerValue> relevant_bound_diffs_;
218  std::vector<IntegerValue> divisors_;
219  std::vector<std::pair<int, IntegerValue>> adjusted_coeffs_;
220  std::vector<IntegerValue> remainders_;
221  std::vector<bool> change_sign_at_postprocessing_;
222  std::vector<IntegerValue> rs_;
223  std::vector<IntegerValue> best_rs_;
224 
225  int num_lifted_booleans_ = 0;
226  std::vector<std::pair<IntegerVariable, IntegerValue>> tmp_terms_;
227 };
228 
229 // If a variable is away from its upper bound by more than value 1.0, then it
230 // cannot be part of a cover that will violate the lp solution. This method
231 // returns a reduced constraint by removing such variables from the given
232 // constraint.
233 LinearConstraint GetPreprocessedLinearConstraint(
234  const LinearConstraint& constraint,
236  const IntegerTrail& integer_trail);
237 
238 // Returns true if sum of all the variables in the given constraint is less than
239 // or equal to constraint upper bound. This method assumes that all the
240 // coefficients are non negative.
241 bool ConstraintIsTriviallyTrue(const LinearConstraint& constraint,
242  const IntegerTrail& integer_trail);
243 
244 // If the left variables in lp solution satisfies following inequality, we prove
245 // that there does not exist any knapsack cut which is violated by the solution.
246 // Let |Cmin| = smallest possible cover size.
247 // Let S = smallest (var_ub - lp_values[var]) first |Cmin| variables.
248 // Let cut lower bound = sum_(var in S)(var_ub - lp_values[var])
249 // For any cover,
250 // If cut lower bound >= 1
251 // ==> sum_(var in S)(var_ub - lp_values[var]) >= 1
252 // ==> sum_(var in cover)(var_ub - lp_values[var]) >= 1
253 // ==> The solution already satisfies cover. Since this is true for all covers,
254 // this method returns false in such cases.
255 // This method assumes that the constraint is preprocessed and has only non
256 // negative coefficients.
258  const LinearConstraint& preprocessed_constraint,
260  const IntegerTrail& integer_trail);
261 
262 // Struct to help compute upper bound for knapsack instance.
263 struct KnapsackItem {
264  double profit;
265  double weight;
266  bool operator>(const KnapsackItem& other) const {
267  return profit * other.weight > other.profit * weight;
268  }
269 };
270 
271 // Gets upper bound on profit for knapsack instance by solving the linear
272 // relaxation.
273 double GetKnapsackUpperBound(std::vector<KnapsackItem> items, double capacity);
274 
275 // Returns true if the linear relaxation upper bound for the knapsack instance
276 // shows that this constraint cannot be used to form a cut. This method assumes
277 // that all the coefficients are non negative.
279  const LinearConstraint& constraint,
281  const IntegerTrail& integer_trail);
282 
283 // Returns true if the given constraint passes all the filters described above.
284 // This method assumes that the constraint is preprocessed and has only non
285 // negative coefficients.
287  const LinearConstraint& preprocessed_constraint,
289  const IntegerTrail& integer_trail);
290 
291 // Converts the given constraint into canonical knapsack form (described
292 // below) and adds it to 'knapsack_constraints'.
293 // Canonical knapsack form:
294 // - Constraint has finite upper bound.
295 // - All coefficients are positive.
296 // For constraint with finite lower bound, this method also adds the negation of
297 // the given constraint after converting it to canonical knapsack form.
298 void ConvertToKnapsackForm(const LinearConstraint& constraint,
299  std::vector<LinearConstraint>* knapsack_constraints,
300  IntegerTrail* integer_trail);
301 
302 // Returns true if the cut is lifted. Lifting procedure is described below.
303 //
304 // First we decide a lifting sequence for the binary variables which are not
305 // already in cut. We lift the cut for each lifting candidate one by one.
306 //
307 // Given the original constraint where the lifting candidate is fixed to one, we
308 // compute the maximum value the cut can take and still be feasible using a
309 // knapsack problem. We can then lift the variable in the cut using the
310 // difference between the cut upper bound and this maximum value.
311 bool LiftKnapsackCut(
312  const LinearConstraint& constraint,
314  const std::vector<IntegerValue>& cut_vars_original_coefficients,
315  const IntegerTrail& integer_trail, TimeLimit* time_limit,
316  LinearConstraint* cut);
317 
318 // A cut generator that creates knpasack cover cuts.
319 //
320 // For a constraint of type
321 // \sum_{i=1..n}(a_i * x_i) <= b
322 // where x_i are integer variables with upper bound u_i, a cover of size k is a
323 // subset C of {1 , .. , n} such that \sum_{c \in C}(a_c * u_c) > b.
324 //
325 // A knapsack cover cut is a constraint of the form
326 // \sum_{c \in C}(u_c - x_c) >= 1
327 // which is equivalent to \sum_{c \in C}(x_c) <= \sum_{c \in C}(u_c) - 1.
328 // In other words, in a feasible solution, at least some of the variables do
329 // not take their maximum value.
330 //
331 // If all x_i are binary variables then the cover cut becomes
332 // \sum_{c \in C}(x_c) <= |C| - 1.
333 //
334 // The major difficulty for generating Knapsack cover cuts is finding a minimal
335 // cover set C that cut a given floating point solution. There are many ways to
336 // heuristically generate the cover but the following method that uses a
337 // solution of the LP relaxation of the constraint works the best.
338 //
339 // Look at a given linear relaxation solution for the integer problem x'
340 // and try to solve the following knapsack problem:
341 // Minimize \sum_{i=1..n}(z_i * (u_i - x_i')),
342 // such that \sum_{i=1..n}(a_i * u_i * z_i) > b,
343 // where z_i is a binary decision variable and x_i' are values of the variables
344 // in the given relaxation solution x'. If the objective of the optimal solution
345 // of this problem is less than 1, this algorithm does not generate any cuts.
346 // Otherwise, it adds a knapsack cover cut in the form
347 // \sum_{i=1..n}(z_i' * x_i) <= cb,
348 // where z_i' is the value of z_i in the optimal solution of the above
349 // problem and cb is the upper bound for the cut constraint. Note that the above
350 // problem can be converted into a standard kanpsack form by replacing z_i by 1
351 // - y_i. In that case the problem becomes
352 // Maximize \sum_{i=1..n}((u_i - x_i') * (y_i - 1)),
353 // such that
354 // \sum_{i=1..n}(a_i * u_i * y_i) <= \sum_{i=1..n}(a_i * u_i) - b - 1.
355 //
356 // Solving this knapsack instance would help us find the smallest cover with
357 // maximum LP violation.
358 //
359 // Cut strengthning:
360 // Let lambda = \sum_{c \in C}(a_c * u_c) - b and max_coeff = \max_{c
361 // \in C}(a_c), then cut can be strengthened as
362 // \sum_{c \in C}(u_c - x_c) >= ceil(lambda / max_coeff)
363 //
364 // For further information about knapsack cover cuts see
365 // A. Atamtürk, Cover and Pack Inequalities for (Mixed) Integer Programming
366 // Annals of Operations Research Volume 139, Issue 1 , pp 21-38, 2005.
367 // TODO(user): Implement cut lifting.
369  const std::vector<LinearConstraint>& base_constraints,
370  const std::vector<IntegerVariable>& vars, Model* model);
371 
372 // A cut generator for z = x * y (x and y >= 0).
373 CutGenerator CreatePositiveMultiplicationCutGenerator(IntegerVariable z,
374  IntegerVariable x,
375  IntegerVariable y,
376  Model* model);
377 
378 // A cut generator for y = x ^ 2 (x >= 0).
379 // It will dynamically add a linear inequality to push y closer to the parabola.
380 CutGenerator CreateSquareCutGenerator(IntegerVariable y, IntegerVariable x,
381  Model* model);
382 
383 // A cut generator for all_diff(xi). Let the united domain of all xi be D. Sum
384 // of any k-sized subset of xi need to be greater or equal to the sum of
385 // smallest k values in D and lesser or equal to the sum of largest k values in
386 // D. The cut generator first sorts the variables based on LP values and adds
387 // cuts of the form described above if they are violated by lp solution. Note
388 // that all the fixed variables are ignored while generating cuts.
389 CutGenerator CreateAllDifferentCutGenerator(
390  const std::vector<IntegerVariable>& vars, Model* model);
391 
392 // Consider the Lin Max constraint with d expressions and n variables in the
393 // form: target = max {exprs[k] = Sum (wki * xi + bk)}. k in {1,..,d}.
394 // Li = lower bound of xi
395 // Ui = upper bound of xi.
396 // Let zk be in {0,1} for all k in {1,..,d}.
397 // The target = exprs[k] when zk = 1.
398 //
399 // The following is a valid linearization for Lin Max.
400 // target >= exprs[k], for all k in {1,..,d}
401 // target <= Sum (wli * xi) + Sum((Nlk + bk) * zk), for all l in {1,..,d}
402 // Where Nlk is a large number defined as:
403 // Nlk = Sum (max((wki - wli)*Li, (wki - wli)*Ui))
404 // = Sum (max corner difference for variable i, target expr l, max expr k)
405 //
406 // Consider a partition of variables xi into set {1,..,d} as I.
407 // i.e. I(i) = j means xi is mapped to jth index.
408 // The following inequality is valid and sharp cut for the lin max constraint
409 // described above.
410 //
411 // target <= Sum(i=1..n)(wI(i)i * xi + Sum(k=1..d)(MPlusCoefficient_ki * zk))
412 // + Sum(k=1..d)(bk * zk) ,
413 // Where MPlusCoefficient_ki = max((wki - wI(i)i) * Li,
414 // (wki - wI(i)i) * Ui)
415 // = max corner difference for variable i,
416 // target expr I(i), max expr k.
417 //
418 // For detailed proof of validity, refer
419 // Reference: "Strong mixed-integer programming formulations for trained neural
420 // networks" by Ross Anderson et. (https://arxiv.org/pdf/1811.01988.pdf).
421 //
422 // In the cut generator, we compute the most violated partition I by computing
423 // the rhs value (wI(i)i * lp_value(xi) + Sum(k=1..d)(MPlusCoefficient_ki * zk))
424 // for each variable for each partition index. We choose the partition index
425 // that gives lowest rhs value for a given variable.
426 //
427 // Note: This cut generator requires all expressions to contain only positive
428 // vars.
429 CutGenerator CreateLinMaxCutGenerator(
430  const IntegerVariable target, const std::vector<LinearExpression>& exprs,
431  const std::vector<IntegerVariable>& z_vars, Model* model);
432 
433 // Creates a cut generator for an optional interval.
434 CutGenerator CreateOptionalIntervalCutGenerator(IntegerVariable start,
435  IntegerVariable size,
436  IntegerVariable end,
437  Literal presence, Model* model);
438 
439 // For a given set of intervals and demands, we first compute the mandatory part
440 // of the interval as [start_max , end_min]. We use this to calculate mandatory
441 // demands for each start_max time points for eligible intervals.
442 // Since the sum of these mandatory demands must be smaller or equal to the
443 // capacity, we create a cut representing that.
444 //
445 // If an interval is optional, it contributes min_demand * presence_literal
446 // amount of demand to the mandatory demands sum. So the final cut is generated
447 // as follows:
448 // sum(demands of always present intervals)
449 // + sum(presence_literal * min_of_demand) <= capacity.
450 CutGenerator CreateCumulativeCutGenerator(
451  const std::vector<IntervalVariable>& intervals,
452  const IntegerVariable capacity, const std::vector<IntegerVariable>& demands,
453  Model* model);
454 
455 } // namespace sat
456 } // namespace operations_research
457 
458 #endif // OR_TOOLS_SAT_CUTS_H_
operations_research::sat::ImpliedBoundsProcessor::ClearCache
void ClearCache() const
Definition: cuts.h:106
var
IntVar * var
Definition: expr_array.cc:1858
operations_research::sat::CutGenerator::vars
std::vector< IntegerVariable > vars
Definition: cuts.h:41
operations_research::sat::KnapsackItem::profit
double profit
Definition: cuts.h:264
operations_research::sat::kNoIntegerVariable
const IntegerVariable kNoIntegerVariable(-1)
operations_research::sat::CreateAllDifferentCutGenerator
CutGenerator CreateAllDifferentCutGenerator(const std::vector< IntegerVariable > &vars, Model *model)
Definition: cuts.cc:1627
operations_research::sat::IntegerRoundingCutHelper
Definition: cuts.h:201
operations_research::sat::CanBeFilteredUsingCutLowerBound
bool CanBeFilteredUsingCutLowerBound(const LinearConstraint &preprocessed_constraint, const gtl::ITIVector< IntegerVariable, double > &lp_values, const IntegerTrail &integer_trail)
Definition: cuts.cc:275
operations_research::sat::ImpliedBoundsProcessor::SlackInfo
Definition: cuts.h:76
time_limit.h
operations_research::sat::GetFactorT
IntegerValue GetFactorT(IntegerValue rhs_remainder, IntegerValue divisor, IntegerValue max_t)
Definition: cuts.cc:601
operations_research::sat::RoundingOptions
Definition: cuts.h:198
operations_research::sat::ImpliedBounds
Definition: implied_bounds.h:77
operations_research::sat::ImpliedBoundsProcessor::BestImpliedBoundInfo::slack_lp_value
double slack_lp_value
Definition: cuts.h:110
operations_research::sat::ImpliedBoundsProcessor::AddLpVariable
void AddLpVariable(IntegerVariable var)
Definition: cuts.h:102
linear_constraint.h
operations_research::sat::KnapsackItem::operator>
bool operator>(const KnapsackItem &other) const
Definition: cuts.h:266
operations_research::sat::KnapsackItem
Definition: cuts.h:263
model.h
operations_research::sat::ImpliedBoundsProcessor::BestImpliedBoundInfo::bool_lp_value
double bool_lp_value
Definition: cuts.h:109
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::ImpliedBoundsProcessor::BestImpliedBoundInfo::bool_var
IntegerVariable bool_var
Definition: cuts.h:113
operations_research::sat::ImpliedBoundsProcessor
Definition: cuts.h:54
operations_research::sat::IntegerTrail
Definition: integer.h:534
operations_research::sat::ImpliedBoundsProcessor::SlackInfo::lb
IntegerValue lb
Definition: cuts.h:82
operations_research::sat::ConvertToKnapsackForm
void ConvertToKnapsackForm(const LinearConstraint &constraint, std::vector< LinearConstraint > *knapsack_constraints, IntegerTrail *integer_trail)
Definition: cuts.cc:373
operations_research::sat::LiftKnapsackCut
bool LiftKnapsackCut(const LinearConstraint &constraint, const gtl::ITIVector< IntegerVariable, double > &lp_values, const std::vector< IntegerValue > &cut_vars_original_coefficients, const IntegerTrail &integer_trail, TimeLimit *time_limit, LinearConstraint *cut)
Definition: cuts.cc:157
operations_research::sat::ImpliedBoundsProcessor::ImpliedBoundsProcessor
ImpliedBoundsProcessor(absl::Span< const IntegerVariable > lp_vars_, IntegerTrail *integer_trail, ImpliedBounds *implied_bounds)
Definition: cuts.h:57
operations_research::sat::CreateSquareCutGenerator
CutGenerator CreateSquareCutGenerator(IntegerVariable y, IntegerVariable x, Model *model)
Definition: cuts.cc:1236
operations_research::sat::KnapsackItem::weight
double weight
Definition: cuts.h:265
operations_research::sat::ImpliedBoundsProcessor::SlackInfo::terms
std::vector< std::pair< IntegerVariable, IntegerValue > > terms
Definition: cuts.h:78
operations_research::sat::LinearConstraint
Definition: linear_constraint.h:39
operations_research::sat::ImpliedBoundsProcessor::DebugSlack
bool DebugSlack(IntegerVariable first_slack, const LinearConstraint &initial_cut, const LinearConstraint &cut, const std::vector< SlackInfo > &info)
Definition: cuts.cc:1534
operations_research::sat::GetPreprocessedLinearConstraint
LinearConstraint GetPreprocessedLinearConstraint(const LinearConstraint &constraint, const gtl::ITIVector< IntegerVariable, double > &lp_values, const IntegerTrail &integer_trail)
Definition: cuts.cc:235
time_limit
SharedTimeLimit * time_limit
Definition: cp_model_solver.cc:2025
operations_research::sat::ImpliedBoundsProcessor::SlackInfo::ub
IntegerValue ub
Definition: cuts.h:83
int_type.h
intervals.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::sat::RoundingOptions::max_scaling
IntegerValue max_scaling
Definition: cuts.h:199
operations_research::sat::ImpliedBoundsProcessor::SlackInfo::offset
IntegerValue offset
Definition: cuts.h:79
operations_research::sat::IntegerRoundingCutHelper::NumLiftedBooleans
int NumLiftedBooleans() const
Definition: cuts.h:210
operations_research::sat::CreateLinMaxCutGenerator
CutGenerator CreateLinMaxCutGenerator(const IntegerVariable target, const std::vector< LinearExpression > &exprs, const std::vector< IntegerVariable > &z_vars, Model *model)
Definition: cuts.cc:1724
operations_research::sat::LinearConstraintManager
Definition: linear_constraint_manager.h:40
operations_research::sat::CanBeFilteredUsingKnapsackUpperBound
bool CanBeFilteredUsingKnapsackUpperBound(const LinearConstraint &constraint, const gtl::ITIVector< IntegerVariable, double > &lp_values, const IntegerTrail &integer_trail)
Definition: cuts.cc:321
operations_research::sat::CreatePositiveMultiplicationCutGenerator
CutGenerator CreatePositiveMultiplicationCutGenerator(IntegerVariable z, IntegerVariable x, IntegerVariable y, Model *model)
Definition: cuts.cc:1140
implied_bounds.h
operations_research::sat::ImpliedBoundsProcessor::BestImpliedBoundInfo::is_positive
bool is_positive
Definition: cuts.h:111
model
GRBmodel * model
Definition: gurobi_interface.cc:195
operations_research::sat::CanFormValidKnapsackCover
bool CanFormValidKnapsackCover(const LinearConstraint &preprocessed_constraint, const gtl::ITIVector< IntegerVariable, double > &lp_values, const IntegerTrail &integer_trail)
Definition: cuts.cc:355
operations_research::sat::CreateOptionalIntervalCutGenerator
CutGenerator CreateOptionalIntervalCutGenerator(IntegerVariable start, IntegerVariable size, IntegerVariable end, Literal presence, Model *model)
Definition: cuts.cc:1793
operations_research::sat::ImpliedBoundsProcessor::BestImpliedBoundInfo
Definition: cuts.h:108
operations_research::sat::GetSuperAdditiveRoundingFunction
std::function< IntegerValue(IntegerValue)> GetSuperAdditiveRoundingFunction(IntegerValue rhs_remainder, IntegerValue divisor, IntegerValue t, IntegerValue max_scaling)
Definition: cuts.cc:609
operations_research::sat::ImpliedBoundsProcessor::BestImpliedBoundInfo::bound_diff
IntegerValue bound_diff
Definition: cuts.h:112
linear_constraint_manager.h
operations_research::sat::ImpliedBoundsProcessor::ProcessUpperBoundedConstraintWithSlackCreation
void ProcessUpperBoundedConstraintWithSlackCreation(bool substitute_only_inner_variables, IntegerVariable first_slack, const gtl::ITIVector< IntegerVariable, double > &lp_values, LinearConstraint *cut, std::vector< SlackInfo > *slack_infos, std::vector< LinearConstraint > *implied_bound_cuts) const
Definition: cuts.cc:1391
lower_bounds
std::vector< double > lower_bounds
Definition: sat/lp_utils.cc:288
operations_research::sat::GetKnapsackUpperBound
double GetKnapsackUpperBound(std::vector< KnapsackItem > items, const double capacity)
Definition: cuts.cc:303
operations_research::sat::CreateCumulativeCutGenerator
CutGenerator CreateCumulativeCutGenerator(const std::vector< IntervalVariable > &intervals, const IntegerVariable capacity, const std::vector< IntegerVariable > &demands, Model *model)
Definition: cuts.cc:1823
operations_research::sat::IntegerRoundingCutHelper::ComputeCut
void ComputeCut(RoundingOptions options, const std::vector< double > &lp_values, const std::vector< IntegerValue > &lower_bounds, const std::vector< IntegerValue > &upper_bounds, ImpliedBoundsProcessor *ib_processor, LinearConstraint *cut)
Definition: cuts.cc:692
operations_research::sat::CutGenerator::generate_cuts
std::function< void(const gtl::ITIVector< IntegerVariable, double > &lp_values, LinearConstraintManager *manager)> generate_cuts
Definition: cuts.h:44
gtl::ITIVector< IntegerVariable, double >
capacity
int64 capacity
Definition: routing_flow.cc:129
operations_research::sat::CutGenerator
Definition: cuts.h:40
operations_research::sat::ImpliedBoundsProcessor::SlackInfo::lp_value
double lp_value
Definition: cuts.h:84
upper_bounds
std::vector< double > upper_bounds
Definition: sat/lp_utils.cc:289
operations_research::sat::CreateKnapsackCoverCutGenerator
CutGenerator CreateKnapsackCoverCutGenerator(const std::vector< LinearConstraint > &base_constraints, const std::vector< IntegerVariable > &vars, Model *model)
Definition: cuts.cc:422
operations_research::sat::ImpliedBoundsProcessor::ProcessUpperBoundedConstraint
void ProcessUpperBoundedConstraint(const gtl::ITIVector< IntegerVariable, double > &lp_values, LinearConstraint *cut) const
Definition: cuts.cc:1303
operations_research::sat::ConstraintIsTriviallyTrue
bool ConstraintIsTriviallyTrue(const LinearConstraint &constraint, const IntegerTrail &integer_trail)
Definition: cuts.cc:259
integer.h
operations_research::sat::ImpliedBoundsProcessor::GetCachedImpliedBoundInfo
BestImpliedBoundInfo GetCachedImpliedBoundInfo(IntegerVariable var)
Definition: cuts.cc:1312