OR-Tools  9.6
linear_programming_constraint.h
Go to the documentation of this file.
1 // Copyright 2010-2022 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_LINEAR_PROGRAMMING_CONSTRAINT_H_
15 #define OR_TOOLS_SAT_LINEAR_PROGRAMMING_CONSTRAINT_H_
16 
17 #include <cstdint>
18 #include <functional>
19 #include <limits>
20 #include <memory>
21 #include <string>
22 #include <utility>
23 #include <vector>
24 
25 #include "absl/container/flat_hash_map.h"
31 #include "ortools/sat/cuts.h"
33 #include "ortools/sat/integer.h"
37 #include "ortools/sat/model.h"
38 #include "ortools/sat/sat_base.h"
39 #include "ortools/sat/sat_parameters.pb.h"
41 #include "ortools/sat/util.h"
43 #include "ortools/util/rev.h"
46 
47 namespace operations_research {
48 namespace sat {
49 
50 // Stores for each IntegerVariable its temporary LP solution.
51 //
52 // This is shared between all LinearProgrammingConstraint because in the corner
53 // case where we have many different LinearProgrammingConstraint and a lot of
54 // variable, we could theoretically use up a quadratic amount of memory
55 // otherwise.
56 //
57 // TODO(user): find a better way?
59  : public absl::StrongVector<IntegerVariable, double> {
61 };
62 
63 // Helper struct to combine info generated from solving LP.
64 struct LPSolveInfo {
66  double lp_objective = -std::numeric_limits<double>::infinity();
68 };
69 
70 // Simple class to combine linear expression efficiently. First in a sparse
71 // way that switch to dense when the number of non-zeros grows.
73  public:
74  // This must be called with the correct size before any other functions are
75  // used.
76  void ClearAndResize(int size);
77 
78  // Does vector[col] += value and return false in case of overflow.
79  bool Add(glop::ColIndex col, IntegerValue value);
80 
81  // Similar to Add() but for multiplier * terms.
82  // Returns false in case of overflow.
84  IntegerValue multiplier,
85  const std::vector<std::pair<glop::ColIndex, IntegerValue>>& terms);
86 
87  // This is not const only because non_zeros is sorted. Note that sorting the
88  // non-zeros make the result deterministic whether or not we were in sparse
89  // mode.
90  //
91  // TODO(user): Ideally we should convert to IntegerVariable as late as
92  // possible. Prefer to use GetTerms().
94  const std::vector<IntegerVariable>& integer_variables,
95  IntegerValue upper_bound, LinearConstraint* result);
96 
97  // Similar to ConvertToLinearConstraint().
98  std::vector<std::pair<glop::ColIndex, IntegerValue>> GetTerms();
99 
100  // We only provide the const [].
101  IntegerValue operator[](glop::ColIndex col) const {
102  return dense_vector_[col];
103  }
104 
105  bool IsSparse() const { return is_sparse_; }
106 
107  private:
108  // If is_sparse is true we maintain the non_zeros positions and bool vector
109  // of dense_vector_. Otherwise we don't. Note that we automatically switch
110  // from sparse to dense as needed.
111  bool is_sparse_ = true;
112  std::vector<glop::ColIndex> non_zeros_;
114 
115  // The dense representation of the vector.
117 };
118 
119 // A SAT constraint that enforces a set of linear inequality constraints on
120 // integer variables using an LP solver.
121 //
122 // The propagator uses glop's revised simplex for feasibility and propagation.
123 // It uses the Reduced Cost Strengthening technique, a classic in mixed integer
124 // programming, for instance see the thesis of Tobias Achterberg,
125 // "Constraint Integer Programming", sections 7.7 and 8.8, algorithm 7.11.
126 // http://nbn-resolving.de/urn:nbn:de:0297-zib-11129
127 //
128 // Per-constraint bounds propagation is NOT done by this constraint,
129 // it should be done by redundant constraints, as reduced cost propagation
130 // may miss some filtering.
131 //
132 // Note that this constraint works with double floating-point numbers, so one
133 // could be worried that it may filter too much in case of precision issues.
134 // However, by default, we interpret the LP result by recomputing everything
135 // in integer arithmetic, so we are exact.
136 class LinearProgrammingDispatcher;
137 
140  public:
141  typedef glop::RowIndex ConstraintIndex;
142 
143  // Each linear programming constraint works on a fixed set of variables.
144  // We expect the set of variable to be sorted in increasing order.
146  absl::Span<const IntegerVariable> vars);
147 
148  // Add a new linear constraint to this LP.
150 
151  // Set the coefficient of the variable in the objective. Calling it twice will
152  // overwrite the previous value.
153  void SetObjectiveCoefficient(IntegerVariable ivar, IntegerValue coeff);
154 
155  // The main objective variable should be equal to the linear sum of
156  // the arguments passed to SetObjectiveCoefficient().
157  void SetMainObjectiveVariable(IntegerVariable ivar) { objective_cp_ = ivar; }
158  IntegerVariable ObjectiveVariable() const { return objective_cp_; }
159 
160  // Register a new cut generator with this constraint.
161  void AddCutGenerator(CutGenerator generator);
162 
163  // Returns the LP value and reduced cost of a variable in the current
164  // solution. These functions should only be called when HasSolution() is true.
165  //
166  // Note that this solution is always an OPTIMAL solution of an LP above or
167  // at the current decision level. We "erase" it when we backtrack over it.
168  bool HasSolution() const { return lp_solution_is_set_; }
169  double SolutionObjectiveValue() const { return lp_objective_; }
170  double GetSolutionValue(IntegerVariable variable) const;
171  double GetSolutionReducedCost(IntegerVariable variable) const;
172  bool SolutionIsInteger() const { return lp_solution_is_integer_; }
173 
174  // PropagatorInterface API.
175  bool Propagate() override;
176  bool IncrementalPropagate(const std::vector<int>& watch_indices) override;
177  void RegisterWith(Model* model);
178 
179  // ReversibleInterface API.
180  void SetLevel(int level) override;
181 
182  int NumVariables() const {
183  return static_cast<int>(integer_variables_.size());
184  }
185  const std::vector<IntegerVariable>& integer_variables() const {
186  return integer_variables_;
187  }
188  std::string DimensionString() const { return lp_data_.GetDimensionString(); }
189 
190  // Returns a IntegerLiteral guided by the underlying LP constraints.
191  //
192  // This looks at all unassigned 0-1 variables, takes the one with
193  // a support value closest to 0.5, and tries to assign it to 1.
194  // If all 0-1 variables have an integer support, returns kNoLiteralIndex.
195  // Tie-breaking is done using the variable natural order.
196  //
197  // TODO(user): This fixes to 1, but for some problems fixing to 0
198  // or to the std::round(support value) might work better. When this is the
199  // case, change behaviour automatically?
201 
202  // Returns a IntegerLiteral guided by the underlying LP constraints.
203  //
204  // This computes the mean of reduced costs over successive calls,
205  // and tries to fix the variable which has the highest reduced cost.
206  // Tie-breaking is done using the variable natural order.
207  // Only works for 0/1 variables.
208  //
209  // TODO(user): Try to get better pseudocosts than averaging every time
210  // the heuristic is called. MIP solvers initialize this with strong branching,
211  // then keep track of the pseudocosts when doing tree search. Also, this
212  // version only branches on var >= 1 and keeps track of reduced costs from var
213  // = 1 to var = 0. This works better than the conventional MIP where the
214  // chosen variable will be argmax_var min(pseudocost_var(0->1),
215  // pseudocost_var(1->0)), probably because we are doing DFS search where MIP
216  // does BFS. This might depend on the model, more trials are necessary. We
217  // could also do exponential smoothing instead of decaying every N calls, i.e.
218  // pseudo = a * pseudo + (1-a) reduced.
220 
221  // Returns a IntegerLiteral guided by the underlying LP constraints.
222  //
223  // This computes the mean of reduced costs over successive calls,
224  // and tries to fix the variable which has the highest reduced cost.
225  // Tie-breaking is done using the variable natural order.
227 
228  // Average number of nonbasic variables with zero reduced costs.
229  double average_degeneracy() const {
230  return average_degeneracy_.CurrentAverage();
231  }
232 
234  return total_num_simplex_iterations_;
235  }
236 
237  // Returns some statistics about this LP.
238  std::string Statistics() const;
239 
240  // Important: this is only temporarily valid.
242  if (optimal_constraints_.empty()) return nullptr;
243  return optimal_constraints_.back().get();
244  }
245 
246  const std::vector<std::unique_ptr<IntegerSumLE>>& OptimalConstraints() const {
247  return optimal_constraints_;
248  }
249 
250  private:
251  // Helper methods for branching. Returns true if branching on the given
252  // variable helps with more propagation or finds a conflict.
253  bool BranchOnVar(IntegerVariable var);
254  LPSolveInfo SolveLpForBranching();
255 
256  // Helper method to fill reduced cost / dual ray reason in 'integer_reason'.
257  // Generates a set of IntegerLiterals explaining why the best solution can not
258  // be improved using reduced costs. This is used to generate explanations for
259  // both infeasibility and bounds deductions.
260  void FillReducedCostReasonIn(const glop::DenseRow& reduced_costs,
261  std::vector<IntegerLiteral>* integer_reason);
262 
263  // Reinitialize the LP from a potentially new set of constraints.
264  // This fills all data structure and properly rescale the underlying LP.
265  //
266  // Returns false if the problem is UNSAT (it can happen when presolve is off
267  // and some LP constraint are trivially false).
268  bool CreateLpFromConstraintManager();
269 
270  // Solve the LP, returns false if something went wrong in the LP solver.
271  bool SolveLp();
272 
273  // Analyzes the result of an LP Solution. Returns false on conflict.
274  bool AnalyzeLp();
275 
276  // Returns false if some terms cannot be removed because of overflow. If this
277  // happends the cut is left in a non-usable state and we should abort its
278  // processing.
279  bool RemoveFixedTerms(LinearConstraint* cut);
280 
281  // Does some basic preprocessing of a cut candidate. Returns false if we
282  // should abort processing this candidate.
283  bool PreprocessCut(LinearConstraint* cut);
284 
285  // Add a "MIR" cut obtained by first taking the linear combination of the
286  // row of the matrix according to "integer_multipliers" and then trying
287  // some integer rounding heuristic.
288  //
289  // Return true if a new cut was added to the cut manager.
290  bool AddCutFromConstraints(
291  const std::string& name,
292  const std::vector<std::pair<glop::RowIndex, IntegerValue>>&
293  integer_multipliers);
294 
295  // Second half of AddCutFromConstraints().
296  bool PostprocessAndAddCut(const std::string& name, const std::string& info,
297  IntegerVariable first_slack,
298  const LinearConstraint& cut);
299 
300  // Computes and adds the corresponding type of cuts.
301  // This can currently only be called at the root node.
302  void AddObjectiveCut();
303  void AddCGCuts();
304  void AddMirCuts();
305  void AddZeroHalfCuts();
306 
307  // Updates the bounds of the LP variables from the CP bounds.
308  void UpdateBoundsOfLpVariables();
309 
310  // Use the dual optimal lp values to compute an EXACT lower bound on the
311  // objective. Fills its reason and perform reduced cost strenghtening.
312  // Returns false in case of conflict.
313  bool ExactLpReasonning();
314 
315  // Same as FillDualRayReason() but perform the computation EXACTLY. Returns
316  // false in the case that the problem is not provably infeasible with exact
317  // computations, true otherwise.
318  bool FillExactDualRayReason();
319 
320  // Returns number of non basic variables with zero reduced costs.
321  int64_t CalculateDegeneracy();
322 
323  // From a set of row multipliers (at LP scale), scale them back to the CP
324  // world and then make them integer (eventually multiplying them by a new
325  // scaling factor returned in *scaling).
326  //
327  // Note that this will loose some precision, but our subsequent computation
328  // will still be exact as it will work for any set of multiplier.
329  std::vector<std::pair<glop::RowIndex, IntegerValue>> ScaleLpMultiplier(
330  bool take_objective_into_account,
331  const std::vector<std::pair<glop::RowIndex, double>>& lp_multipliers,
332  glop::Fractional* scaling, int max_pow = 62) const;
333 
334  // Computes from an integer linear combination of the integer rows of the LP a
335  // new constraint of the form "sum terms <= upper_bound". All computation are
336  // exact here.
337  //
338  // Returns false if we encountered any integer overflow.
339  bool ComputeNewLinearConstraint(
340  const std::vector<std::pair<glop::RowIndex, IntegerValue>>&
341  integer_multipliers,
342  ScatteredIntegerVector* scattered_vector,
343  IntegerValue* upper_bound) const;
344 
345  // Simple heuristic to try to minimize |upper_bound - ImpliedLB(terms)|. This
346  // should make the new constraint tighter and correct a bit the imprecision
347  // introduced by rounding the floating points values.
348  void AdjustNewLinearConstraint(
349  std::vector<std::pair<glop::RowIndex, IntegerValue>>* integer_multipliers,
350  ScatteredIntegerVector* scattered_vector,
351  IntegerValue* upper_bound) const;
352 
353  // Shortcut for an integer linear expression type.
354  using LinearExpression = std::vector<std::pair<glop::ColIndex, IntegerValue>>;
355 
356  // Converts a dense representation of a linear constraint to a sparse one
357  // expressed in terms of IntegerVariable.
358  void ConvertToLinearConstraint(
360  IntegerValue upper_bound, LinearConstraint* result);
361 
362  // Compute the implied lower bound of the given linear expression using the
363  // current variable bound. Return kMinIntegerValue in case of overflow.
364  IntegerValue GetImpliedLowerBound(const LinearConstraint& terms) const;
365 
366  // Fills integer_reason_ with the reason for the implied lower bound of the
367  // given linear expression. We relax the reason if we have some slack.
368  void SetImpliedLowerBoundReason(const LinearConstraint& terms,
369  IntegerValue slack);
370 
371  // Fills the deductions vector with reduced cost deductions that can be made
372  // from the current state of the LP solver. The given delta should be the
373  // difference between the cp objective upper bound and lower bound given by
374  // the lp.
375  void ReducedCostStrengtheningDeductions(double cp_objective_delta);
376 
377  // Returns the variable value on the same scale as the CP variable value.
378  glop::Fractional GetVariableValueAtCpScale(glop::ColIndex var);
379 
380  // Gets an LP variable that mirrors a CP variable.
381  // The variable should be a positive reference.
382  glop::ColIndex GetMirrorVariable(IntegerVariable positive_variable);
383 
384  // This must be called on an OPTIMAL LP and will update the data for
385  // LPReducedCostAverageDecision().
386  void UpdateAverageReducedCosts();
387 
388  // Callback underlying LPReducedCostAverageBranching().
389  IntegerLiteral LPReducedCostAverageDecision();
390 
391  // Updates the simplex iteration limit for the next visit.
392  // As per current algorithm, we use a limit which is dependent on size of the
393  // problem and drop it significantly if degeneracy is detected. We use
394  // DUAL_FEASIBLE status as a signal to correct the prediction. The next limit
395  // is capped by 'min_iter' and 'max_iter'. Note that this is enabled only for
396  // linearization level 2 and above.
397  void UpdateSimplexIterationLimit(int64_t min_iter, int64_t max_iter);
398 
399  // This epsilon is related to the precision of the value/reduced_cost returned
400  // by the LP once they have been scaled back into the CP domain. So for large
401  // domain or cost coefficient, we may have some issues.
402  static constexpr double kCpEpsilon = 1e-4;
403 
404  // Same but at the LP scale.
405  static constexpr double kLpEpsilon = 1e-6;
406 
407  // Anything coming from the LP with a magnitude below that will be assumed to
408  // be zero.
409  static constexpr double kZeroTolerance = 1e-12;
410 
411  // Class responsible for managing all possible constraints that may be part
412  // of the LP.
413  LinearConstraintManager constraint_manager_;
414 
415  // Initial problem in integer form.
416  // We always sort the inner vectors by increasing glop::ColIndex.
417  struct LinearConstraintInternal {
418  IntegerValue lb;
419  IntegerValue ub;
420  LinearExpression terms;
421  };
422  LinearExpression integer_objective_;
423  IntegerValue integer_objective_offset_ = IntegerValue(0);
424  IntegerValue objective_infinity_norm_ = IntegerValue(0);
427 
428  // Underlying LP solver API.
429  glop::GlopParameters simplex_params_;
430  glop::BasisState state_;
431  glop::LinearProgram lp_data_;
432  glop::RevisedSimplex simplex_;
433  int64_t next_simplex_iter_ = 500;
434 
435  // For the scaling.
436  glop::LpScalingHelper scaler_;
437 
438  // Temporary data for cuts.
439  ZeroHalfCutHelper zero_half_cut_helper_;
440  CoverCutHelper cover_cut_helper_;
441  FlowCoverCutHelper flow_cover_cut_helper_;
442  IntegerRoundingCutHelper integer_rounding_cut_helper_;
443 
444  CutData base_ct_;
445  LinearConstraint cut_;
446  LinearConstraint saved_cut_;
447  LinearConstraint tmp_constraint_;
448 
449  ScatteredIntegerVector tmp_scattered_vector_;
450 
451  std::vector<double> tmp_lp_values_;
452  std::vector<IntegerValue> tmp_var_lbs_;
453  std::vector<IntegerValue> tmp_var_ubs_;
454  std::vector<glop::RowIndex> tmp_slack_rows_;
455  std::vector<std::pair<glop::ColIndex, IntegerValue>> tmp_terms_;
456 
457  // Used by AddCGCuts().
458  std::vector<std::pair<glop::RowIndex, double>> tmp_lp_multipliers_;
459  std::vector<std::pair<glop::RowIndex, IntegerValue>> tmp_integer_multipliers_;
460 
461  // Used by ScaleLpMultiplier().
462  mutable std::vector<std::pair<glop::RowIndex, double>> tmp_cp_multipliers_;
463 
464  // Structures used for mirroring IntegerVariables inside the underlying LP
465  // solver: an integer variable var is mirrored by mirror_lp_variable_[var].
466  // Note that these indices are dense in [0, mirror_lp_variable_.size()] so
467  // they can be used as vector indices.
468  //
469  // TODO(user): This should be absl::StrongVector<glop::ColIndex,
470  // IntegerVariable> Except if we have too many LinearProgrammingConstraint.
471  std::vector<IntegerVariable> integer_variables_;
472  absl::flat_hash_map<IntegerVariable, glop::ColIndex> mirror_lp_variable_;
473 
474  // We need to remember what to optimize if an objective is given, because
475  // then we will switch the objective between feasibility and optimization.
476  bool objective_is_defined_ = false;
477  IntegerVariable objective_cp_;
478 
479  // Singletons from Model.
480  const SatParameters& parameters_;
481  Model* model_;
482  TimeLimit* time_limit_;
483  IntegerTrail* integer_trail_;
484  SatSolver* sat_solver_;
485  Trail* trail_;
486  IntegerEncoder* integer_encoder_;
487  ModelRandomGenerator* random_;
488 
489  // Used while deriving cuts.
490  ImpliedBoundsProcessor implied_bounds_processor_;
491 
492  // The dispatcher for all LP propagators of the model, allows to find which
493  // LinearProgrammingConstraint has a given IntegerVariable.
494  LinearProgrammingDispatcher* dispatcher_;
495 
496  std::vector<IntegerLiteral> integer_reason_;
497  std::vector<IntegerLiteral> deductions_;
498  std::vector<IntegerLiteral> deductions_reason_;
499 
500  // Repository of IntegerSumLE that needs to be kept around for the lazy
501  // reasons. Those are new integer constraint that are created each time we
502  // solve the LP to a dual-feasible solution. Propagating these constraints
503  // both improve the objective lower bound but also perform reduced cost
504  // fixing.
505  int rev_optimal_constraints_size_ = 0;
506  std::vector<std::unique_ptr<IntegerSumLE>> optimal_constraints_;
507 
508  // Last OPTIMAL solution found by a call to the underlying LP solver.
509  // On IncrementalPropagate(), if the bound updates do not invalidate this
510  // solution, Propagate() will not find domain reductions, no need to call it.
511  int lp_solution_level_ = 0;
512  bool lp_solution_is_set_ = false;
513  bool lp_solution_is_integer_ = false;
514  double lp_objective_;
515  std::vector<double> lp_solution_;
516  std::vector<double> lp_reduced_cost_;
517 
518  // If non-empty, this is the last known optimal lp solution at root-node. If
519  // the variable bounds changed, or cuts where added, it is possible that this
520  // solution is no longer optimal though.
521  std::vector<double> level_zero_lp_solution_;
522 
523  // True if the last time we solved the exact same LP at level zero, no cuts
524  // and no lazy constraints where added.
525  bool lp_at_level_zero_is_final_ = false;
526 
527  // Same as lp_solution_ but this vector is indexed differently.
528  LinearProgrammingConstraintLpSolution& expanded_lp_solution_;
529 
530  // Linear constraints cannot be created or modified after this is registered.
531  bool lp_constraint_is_registered_ = false;
532 
533  std::vector<CutGenerator> cut_generators_;
534 
535  // Store some statistics for HeuristicLPReducedCostAverage().
536  bool compute_reduced_cost_averages_ = false;
537  int num_calls_since_reduced_cost_averages_reset_ = 0;
538  std::vector<double> sum_cost_up_;
539  std::vector<double> sum_cost_down_;
540  std::vector<int> num_cost_up_;
541  std::vector<int> num_cost_down_;
542  std::vector<double> rc_scores_;
543 
544  // All the entries before rev_rc_start_ in the sorted positions correspond
545  // to fixed variables and can be ignored.
546  int rev_rc_start_ = 0;
547  RevRepository<int> rc_rev_int_repository_;
548  std::vector<std::pair<double, int>> positions_by_decreasing_rc_score_;
549 
550  // Defined as average number of nonbasic variables with zero reduced costs.
551  IncrementalAverage average_degeneracy_;
552  bool is_degenerate_ = false;
553 
554  // Used by the strong branching heuristic.
555  int branching_frequency_ = 1;
556  int64_t count_since_last_branching_ = 0;
557 
558  // Sum of all simplex iterations performed by this class. This is useful to
559  // test the incrementality and compare to other solvers.
560  int64_t total_num_simplex_iterations_ = 0;
561 
562  // As we form candidate form cuts, sometimes we can propagate level zero
563  // bounds with them.
564  int64_t total_num_cut_propagations_ = 0;
565 
566  // Some stats on the LP statuses encountered.
567  int64_t num_solves_ = 0;
568  std::vector<int64_t> num_solves_by_status_;
569 };
570 
571 // A class that stores which LP propagator is associated to each variable.
572 // We need to give the hash_map a name so it can be used as a singleton in our
573 // model.
574 //
575 // Important: only positive variable do appear here.
577  : public absl::flat_hash_map<IntegerVariable,
578  LinearProgrammingConstraint*> {};
579 
580 // A class that stores the collection of all LP constraints in a model.
582  : public std::vector<LinearProgrammingConstraint*> {
583  public:
585  : std::vector<LinearProgrammingConstraint*>() {
587  ->callbacks.push_back([this](CpSolverResponse* response) {
588  int64_t num_lp_iters = 0;
589  for (const LinearProgrammingConstraint* lp : *this) {
590  num_lp_iters += lp->total_num_simplex_iterations();
591  }
592  response->set_num_lp_iterations(num_lp_iters);
593  });
594  }
595 };
596 
597 // Tests for possible overflow in the propagation of the given linear
598 // constraint.
599 bool PossibleOverflow(const IntegerTrail& integer_trail,
600  const LinearConstraint& constraint);
601 
602 // Reduce the coefficient of the constraint so that we cannot have overflow
603 // in the propagation of the given linear constraint. Note that we may loose
604 // some strength by doing so.
605 void PreventOverflow(const IntegerTrail& integer_trail,
606  LinearConstraint* constraint);
607 
608 } // namespace sat
609 } // namespace operations_research
610 
611 #endif // OR_TOOLS_SAT_LINEAR_PROGRAMMING_CONSTRAINT_H_
A simple class to enforce both an elapsed time limit and a deterministic time limit in the same threa...
Definition: time_limit.h:106
std::string GetDimensionString() const
Definition: lp_data.cc:426
const std::vector< std::unique_ptr< IntegerSumLE > > & OptimalConstraints() const
LinearProgrammingConstraint(Model *model, absl::Span< const IntegerVariable > vars)
std::function< IntegerLiteral()> HeuristicLpReducedCostBinary(Model *model)
bool IncrementalPropagate(const std::vector< int > &watch_indices) override
std::function< IntegerLiteral()> HeuristicLpMostInfeasibleBinary(Model *model)
const std::vector< IntegerVariable > & integer_variables() const
void SetObjectiveCoefficient(IntegerVariable ivar, IntegerValue coeff)
Class that owns everything related to a particular optimization model.
Definition: sat/model.h:42
void ConvertToLinearConstraint(const std::vector< IntegerVariable > &integer_variables, IntegerValue upper_bound, LinearConstraint *result)
bool Add(glop::ColIndex col, IntegerValue value)
std::vector< std::pair< glop::ColIndex, IntegerValue > > GetTerms()
bool AddLinearExpressionMultiple(IntegerValue multiplier, const std::vector< std::pair< glop::ColIndex, IntegerValue >> &terms)
SharedResponseManager * response
const std::string name
const Constraint * ct
int64_t value
IntVar * var
Definition: expr_array.cc:1874
GRBmodel * model
ColIndex col
Definition: markowitz.cc:186
constexpr IntegerValue kMinIntegerValue(-kMaxIntegerValue.value())
bool PossibleOverflow(const IntegerTrail &integer_trail, const LinearConstraint &constraint)
void PreventOverflow(const IntegerTrail &integer_trail, LinearConstraint *constraint)
Collection of objects used to extend the Constraint Solver library.
IntVar * upper_bound
Definition: routing.cc:1087