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