OR-Tools  8.1
preprocessor.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 //
15 // This file contains the presolving code for a LinearProgram.
16 //
17 // A classical reference is:
18 // E. D. Andersen, K. D. Andersen, "Presolving in linear programming.",
19 // Mathematical Programming 71 (1995) 221-245.
20 
21 #ifndef OR_TOOLS_GLOP_PREPROCESSOR_H_
22 #define OR_TOOLS_GLOP_PREPROCESSOR_H_
23 
24 #include <memory>
25 
31 
32 namespace operations_research {
33 namespace glop {
34 
35 // --------------------------------------------------------
36 // Preprocessor
37 // --------------------------------------------------------
38 // This is the base class for preprocessors.
39 //
40 // TODO(user): On most preprocessors, calling Run() more than once will not work
41 // as expected. Fix? or document and crash in debug if this happens.
42 class Preprocessor {
43  public:
44  explicit Preprocessor(const GlopParameters* parameters);
45  Preprocessor(const Preprocessor&) = delete;
46  Preprocessor& operator=(const Preprocessor&) = delete;
47  virtual ~Preprocessor();
48 
49  // Runs the preprocessor by modifying the given linear program. Returns true
50  // if a postsolve step will be needed (i.e. RecoverSolution() is not the
51  // identity function). Also updates status_ to something different from
52  // ProblemStatus::INIT if the problem was solved (including bad statuses
53  // like ProblemStatus::ABNORMAL, ProblemStatus::INFEASIBLE, etc.).
54  virtual bool Run(LinearProgram* lp) = 0;
55 
56  // Stores the optimal solution of the linear program that was passed to
57  // Run(). The given solution needs to be set to the optimal solution of the
58  // linear program "modified" by Run().
59  virtual void RecoverSolution(ProblemSolution* solution) const = 0;
60 
61  // Returns the status of the preprocessor.
62  // A status different from ProblemStatus::INIT means that the problem is
63  // solved and there is not need to call subsequent preprocessors.
64  ProblemStatus status() const { return status_; }
65 
66  // Some preprocessors only need minimal changes when used with integer
67  // variables in a MIP context. Setting this to true allows to consider integer
68  // variables as integer in these preprocessors.
69  //
70  // Not all preprocessors handle integer variables correctly, calling this
71  // function on them will cause a LOG(FATAL).
72  virtual void UseInMipContext() { in_mip_context_ = true; }
73 
75 
76  protected:
77  // Returns true if a is less than b (or slighlty greater than b with a given
78  // tolerance).
81  a, b, parameters_.solution_feasibility_tolerance());
82  }
84  Fractional b) const {
85  // TODO(user): use an absolute tolerance here to be even more defensive?
87  a, b, parameters_.preprocessor_zero_tolerance());
88  }
89 
91  const GlopParameters& parameters_;
93  std::unique_ptr<TimeLimit> infinite_time_limit_;
95 };
96 
97 // --------------------------------------------------------
98 // MainLpPreprocessor
99 // --------------------------------------------------------
100 // This is the main LP preprocessor responsible for calling all the other
101 // preprocessors in this file, possibly more than once.
103  public:
104  explicit MainLpPreprocessor(const GlopParameters* parameters)
108  ~MainLpPreprocessor() override {}
109 
110  bool Run(LinearProgram* lp) final;
111  void RecoverSolution(ProblemSolution* solution) const override;
112 
113  private:
114  // Runs the given preprocessor and push it on preprocessors_ for the postsolve
115  // step when needed.
116  void RunAndPushIfRelevant(std::unique_ptr<Preprocessor> preprocessor,
117  const std::string& name, TimeLimit* time_limit,
118  LinearProgram* lp);
119 
120  // Stack of preprocessors currently applied to the lp that needs postsolve.
121  //
122  // TODO(user): This is mutable so that the preprocessor can be freed as soon
123  // as their RecoverSolution() is called. Make RecoverSolution() non-const or
124  // remove this optimization?
125  mutable std::vector<std::unique_ptr<Preprocessor>> preprocessors_;
126 
127  // Initial dimension of the lp given to Run(), for displaying purpose.
128  EntryIndex initial_num_entries_;
129  RowIndex initial_num_rows_;
130  ColIndex initial_num_cols_;
131 };
132 
133 // --------------------------------------------------------
134 // ColumnDeletionHelper
135 // --------------------------------------------------------
136 // Help preprocessors deal with column deletion.
138  public:
142 
143  // Remember the given column as "deleted" so that it can later be restored
144  // by RestoreDeletedColumns(). Optionally, the caller may indicate the
145  // value and status of the corresponding variable so that it is automatically
146  // restored; if they don't then the restored value and status will be junk
147  // and must be set by the caller.
148  //
149  // The actual deletion is done by LinearProgram::DeleteColumns().
150  void MarkColumnForDeletion(ColIndex col);
152  VariableStatus status);
153 
154  // From a solution omitting the deleted column, expands it and inserts the
155  // deleted columns. If values and statuses for the corresponding variables
156  // were saved, they'll be restored.
157  void RestoreDeletedColumns(ProblemSolution* solution) const;
158 
159  // Returns whether or not the given column is marked for deletion.
160  bool IsColumnMarked(ColIndex col) const {
161  return col < is_column_deleted_.size() && is_column_deleted_[col];
162  }
163 
164  // Returns a Boolean vector of the column to be deleted.
165  const DenseBooleanRow& GetMarkedColumns() const { return is_column_deleted_; }
166 
167  // Returns true if no columns have been marked for deletion.
168  bool IsEmpty() const { return is_column_deleted_.empty(); }
169 
170  // Restores the class to its initial state.
171  void Clear();
172 
173  // Returns the value that will be restored by
174  // RestoreDeletedColumnInSolution(). Note that only the marked position value
175  // make sense.
176  const DenseRow& GetStoredValue() const { return stored_value_; }
177 
178  private:
179  DenseBooleanRow is_column_deleted_;
180 
181  // Note that this vector has the same size as is_column_deleted_ and that
182  // the value of the variable corresponding to a deleted column col is stored
183  // at position col. Values of columns not deleted are not used. We use this
184  // data structure so columns can be deleted in any order if needed.
185  DenseRow stored_value_;
186  VariableStatusRow stored_status_;
187 };
188 
189 // --------------------------------------------------------
190 // RowDeletionHelper
191 // --------------------------------------------------------
192 // Help preprocessors deal with row deletion.
194  public:
198 
199  // Returns true if no rows have been marked for deletion.
200  bool IsEmpty() const { return is_row_deleted_.empty(); }
201 
202  // Restores the class to its initial state.
203  void Clear();
204 
205  // Adds a deleted row to the helper.
206  void MarkRowForDeletion(RowIndex row);
207 
208  // If the given row was marked for deletion, unmark it.
209  void UnmarkRow(RowIndex row);
210 
211  // Returns a Boolean vector of the row to be deleted.
212  const DenseBooleanColumn& GetMarkedRows() const;
213 
214  // Returns whether or not the given row is marked for deletion.
215  bool IsRowMarked(RowIndex row) const {
216  return row < is_row_deleted_.size() && is_row_deleted_[row];
217  }
218 
219  // From a solution without the deleted rows, expand it by restoring
220  // the deleted rows to a VariableStatus::BASIC status with 0.0 value.
221  // This latter value is important, many preprocessors rely on it.
222  void RestoreDeletedRows(ProblemSolution* solution) const;
223 
224  private:
225  DenseBooleanColumn is_row_deleted_;
226 };
227 
228 // --------------------------------------------------------
229 // EmptyColumnPreprocessor
230 // --------------------------------------------------------
231 // Removes the empty columns from the problem.
233  public:
234  explicit EmptyColumnPreprocessor(const GlopParameters* parameters)
239  bool Run(LinearProgram* lp) final;
240  void RecoverSolution(ProblemSolution* solution) const final;
241 
242  private:
243  ColumnDeletionHelper column_deletion_helper_;
244 };
245 
246 // --------------------------------------------------------
247 // ProportionalColumnPreprocessor
248 // --------------------------------------------------------
249 // Removes the proportional columns from the problem when possible. Two columns
250 // are proportional if one is a non-zero scalar multiple of the other.
251 //
252 // Note that in the linear programming literature, two proportional columns are
253 // usually called duplicates. The notion is the same once the problem has been
254 // scaled. However, during presolve the columns can't be assumed to be scaled,
255 // so it makes sense to use the more general notion of proportional columns.
257  public:
258  explicit ProportionalColumnPreprocessor(const GlopParameters* parameters)
261  delete;
263  const ProportionalColumnPreprocessor&) = delete;
265  bool Run(LinearProgram* lp) final;
266  void RecoverSolution(ProblemSolution* solution) const final;
267  void UseInMipContext() final { LOG(FATAL) << "Not implemented."; }
268 
269  private:
270  // Postsolve information about proportional columns with the same scaled cost
271  // that were merged during presolve.
272 
273  // The proportionality factor of each column. If two columns are proportional
274  // with factor p1 and p2 then p1 times the first column is the same as p2
275  // times the second column.
276  DenseRow column_factors_;
277 
278  // If merged_columns_[col] != kInvalidCol, then column col has been merged
279  // into the column merged_columns_[col].
280  ColMapping merged_columns_;
281 
282  // The old and new variable bounds.
283  DenseRow lower_bounds_;
284  DenseRow upper_bounds_;
285  DenseRow new_lower_bounds_;
286  DenseRow new_upper_bounds_;
287 
288  ColumnDeletionHelper column_deletion_helper_;
289 };
290 
291 // --------------------------------------------------------
292 // ProportionalRowPreprocessor
293 // --------------------------------------------------------
294 // Removes the proportional rows from the problem.
295 // The linear programming literature also calls such rows duplicates, see the
296 // same remark above for columns in ProportionalColumnPreprocessor.
298  public:
299  explicit ProportionalRowPreprocessor(const GlopParameters* parameters)
303  delete;
305  bool Run(LinearProgram* lp) final;
306  void RecoverSolution(ProblemSolution* solution) const final;
307 
308  private:
309  // Informations about proportional rows, only filled for such rows.
310  DenseColumn row_factors_;
311  RowMapping upper_bound_sources_;
312  RowMapping lower_bound_sources_;
313 
314  bool lp_is_maximization_problem_;
315  RowDeletionHelper row_deletion_helper_;
316 };
317 
318 // --------------------------------------------------------
319 // SingletonPreprocessor
320 // --------------------------------------------------------
321 // Removes as many singleton rows and singleton columns as possible from the
322 // problem. Note that not all types of singleton columns can be removed. See the
323 // comments below on the SingletonPreprocessor functions for more details.
324 //
325 // TODO(user): Generalize the design used in this preprocessor to a general
326 // "propagation" framework in order to apply as many reductions as possible in
327 // an efficient manner.
328 
329 // Holds a triplet (row, col, coefficient).
330 struct MatrixEntry {
331  MatrixEntry(RowIndex _row, ColIndex _col, Fractional _coeff)
332  : row(_row), col(_col), coeff(_coeff) {}
333  RowIndex row;
334  ColIndex col;
336 };
337 
338 // Stores the information needed to undo a singleton row/column deletion.
340  public:
341  // The type of a given operation.
342  typedef enum {
347  } OperationType;
348 
349  // Stores the information, which together with the field deleted_columns_ and
350  // deleted_rows_ of SingletonPreprocessor, are needed to undo an operation
351  // with the given type. Note that all the arguments must refer to the linear
352  // program BEFORE the operation is applied.
353  SingletonUndo(OperationType type, const LinearProgram& lp, MatrixEntry e,
354  ConstraintStatus status);
355 
356  // Undo the operation saved in this class, taking into account the deleted
357  // columns and rows passed by the calling instance of SingletonPreprocessor.
358  // Note that the operations must be undone in the reverse order of the one
359  // in which they were applied.
360  void Undo(const GlopParameters& parameters,
361  const SparseMatrix& deleted_columns,
362  const SparseMatrix& deleted_rows, ProblemSolution* solution) const;
363 
364  private:
365  // Actual undo functions for each OperationType.
366  // Undo() just calls the correct one.
367  void SingletonRowUndo(const SparseMatrix& deleted_columns,
368  ProblemSolution* solution) const;
369  void ZeroCostSingletonColumnUndo(const GlopParameters& parameters,
370  const SparseMatrix& deleted_rows,
371  ProblemSolution* solution) const;
372  void SingletonColumnInEqualityUndo(const GlopParameters& parameters,
373  const SparseMatrix& deleted_rows,
374  ProblemSolution* solution) const;
375  void MakeConstraintAnEqualityUndo(ProblemSolution* solution) const;
376 
377  // All the information needed during undo.
378  OperationType type_;
379  bool is_maximization_;
380  MatrixEntry e_;
381  Fractional cost_;
382 
383  // TODO(user): regroup the pair (lower bound, upper bound) in a bound class?
384  Fractional variable_lower_bound_;
385  Fractional variable_upper_bound_;
386  Fractional constraint_lower_bound_;
387  Fractional constraint_upper_bound_;
388 
389  // This in only used with MAKE_CONSTRAINT_AN_EQUALITY undo.
390  // TODO(user): Clean that up using many Undo classes and virtual functions.
391  ConstraintStatus constraint_status_;
392 };
393 
394 // Deletes as many singleton rows or singleton columns as possible. Note that
395 // each time we delete a row or a column, new singletons may be created.
397  public:
398  explicit SingletonPreprocessor(const GlopParameters* parameters)
403  bool Run(LinearProgram* lp) final;
404  void RecoverSolution(ProblemSolution* solution) const final;
405 
406  private:
407  // Returns the MatrixEntry of the given singleton row or column, taking into
408  // account the rows and columns that were already deleted.
409  MatrixEntry GetSingletonColumnMatrixEntry(ColIndex col,
410  const SparseMatrix& matrix);
411  MatrixEntry GetSingletonRowMatrixEntry(RowIndex row,
412  const SparseMatrix& matrix_transpose);
413 
414  // A singleton row can always be removed by changing the corresponding
415  // variable bounds to take into account the bounds on this singleton row.
416  void DeleteSingletonRow(MatrixEntry e, LinearProgram* lp);
417 
418  // Internal operation when removing a zero-cost singleton column corresponding
419  // to the given entry. This modifies the constraint bounds to take into acount
420  // the bounds of the corresponding variable.
421  void UpdateConstraintBoundsWithVariableBounds(MatrixEntry e,
422  LinearProgram* lp);
423 
424  // Checks if all other variables in the constraint are integer and the
425  // coefficients are divisible by the coefficient of the singleton variable.
426  bool IntegerSingletonColumnIsRemovable(const MatrixEntry& matrix_entry,
427  const LinearProgram& lp) const;
428 
429  // A singleton column with a cost of zero can always be removed by changing
430  // the corresponding constraint bounds to take into acount the bound of this
431  // singleton column.
432  void DeleteZeroCostSingletonColumn(const SparseMatrix& matrix_transpose,
433  MatrixEntry e, LinearProgram* lp);
434 
435  // Returns true if the constraint associated to the given singleton column was
436  // an equality or could be made one:
437  // If a singleton variable is free in a direction that improves the cost, then
438  // we can always move it as much as possible in this direction. Only the
439  // constraint will stop us, making it an equality. If the constraint doesn't
440  // stop us, then the program is unbounded (provided that there is a feasible
441  // solution).
442  //
443  // Note that this operation does not need any "undo" during the post-solve. At
444  // optimality, the dual value on the constraint row will be of the correct
445  // sign, and relaxing the constraint bound will not impact the dual
446  // feasibility of the solution.
447  //
448  // TODO(user): this operation can be generalized to columns with just one
449  // blocking constraint. Investigate how to use this. The 'reverse' can
450  // probably also be done, relaxing a constraint that is blocking a
451  // unconstrained variable.
452  bool MakeConstraintAnEqualityIfPossible(const SparseMatrix& matrix_transpose,
453  MatrixEntry e, LinearProgram* lp);
454 
455  // If a singleton column appears in an equality, we can remove its cost by
456  // changing the other variables cost using the constraint. We can then delete
457  // the column like in DeleteZeroCostSingletonColumn().
458  void DeleteSingletonColumnInEquality(const SparseMatrix& matrix_transpose,
459  MatrixEntry e, LinearProgram* lp);
460 
461  ColumnDeletionHelper column_deletion_helper_;
462  RowDeletionHelper row_deletion_helper_;
463  std::vector<SingletonUndo> undo_stack_;
464 
465  // This is used as a "cache" by MakeConstraintAnEqualityIfPossible() to avoid
466  // scanning more than once each row. See the code to see how this is used.
467  absl::StrongVector<RowIndex, bool> row_sum_is_cached_;
469  row_lb_sum_;
471  row_ub_sum_;
472 
473  // The columns that are deleted by this preprocessor.
474  SparseMatrix deleted_columns_;
475  // The transpose of the rows that are deleted by this preprocessor.
476  // TODO(user): implement a RowMajorSparseMatrix class to simplify the code.
477  SparseMatrix deleted_rows_;
478 };
479 
480 // --------------------------------------------------------
481 // FixedVariablePreprocessor
482 // --------------------------------------------------------
483 // Removes the fixed variables from the problem.
485  public:
486  explicit FixedVariablePreprocessor(const GlopParameters* parameters)
490  delete;
492  bool Run(LinearProgram* lp) final;
493  void RecoverSolution(ProblemSolution* solution) const final;
494 
495  private:
496  ColumnDeletionHelper column_deletion_helper_;
497 };
498 
499 // --------------------------------------------------------
500 // ForcingAndImpliedFreeConstraintPreprocessor
501 // --------------------------------------------------------
502 // This preprocessor computes for each constraint row the bounds that are
503 // implied by the variable bounds and applies one of the following reductions:
504 //
505 // * If the intersection of the implied bounds and the current constraint bounds
506 // is empty (modulo some tolerance), the problem is INFEASIBLE.
507 //
508 // * If the intersection of the implied bounds and the current constraint bounds
509 // is a singleton (modulo some tolerance), then the constraint is said to be
510 // forcing and all the variables that appear in it can be fixed to one of their
511 // bounds. All these columns and the constraint row is removed.
512 //
513 // * If the implied bounds are included inside the current constraint bounds
514 // (modulo some tolerance) then the constraint is said to be redundant or
515 // implied free. Its bounds are relaxed and the constraint will be removed
516 // later by the FreeConstraintPreprocessor.
517 //
518 // * Otherwise, wo do nothing.
520  public:
522  const GlopParameters* parameters)
529  bool Run(LinearProgram* lp) final;
530  void RecoverSolution(ProblemSolution* solution) const final;
531 
532  private:
533  bool lp_is_maximization_problem_;
534  SparseMatrix deleted_columns_;
535  DenseRow costs_;
536  DenseBooleanColumn is_forcing_up_;
537  ColumnDeletionHelper column_deletion_helper_;
538  RowDeletionHelper row_deletion_helper_;
539 };
540 
541 // --------------------------------------------------------
542 // ImpliedFreePreprocessor
543 // --------------------------------------------------------
544 // It is possible to compute "implied" bounds on a variable from the bounds of
545 // all the other variables and the constraints in which this variable take
546 // place. If such "implied" bounds are inside the variable bounds, then the
547 // variable bounds can be relaxed and the variable is said to be "implied free".
548 //
549 // This preprocessor detects the implied free variables and make as many as
550 // possible free with a priority towards low-degree columns. This transformation
551 // will make the simplex algorithm more efficient later, but will also make it
552 // possible to reduce the problem by applying subsequent transformations:
553 //
554 // * The SingletonPreprocessor already deals with implied free singleton
555 // variables and removes the columns and the rows in which they appear.
556 //
557 // * Any multiple of the column of a free variable can be added to any other
558 // column without changing the linear program solution. This is the dual
559 // counterpart of the fact that any multiple of an equality row can be added to
560 // any row.
561 //
562 // TODO(user): Only process doubleton columns so we have more chance in the
563 // later passes to create more doubleton columns? Such columns lead to a smaller
564 // problem thanks to the DoubletonFreeColumnPreprocessor.
566  public:
567  explicit ImpliedFreePreprocessor(const GlopParameters* parameters)
572  bool Run(LinearProgram* lp) final;
573  void RecoverSolution(ProblemSolution* solution) const final;
574 
575  private:
576  // This preprocessor adds fixed offsets to some variables. We remember those
577  // here to un-offset them in RecoverSolution().
578  DenseRow variable_offsets_;
579 
580  // This preprocessor causes some variables who would normally be
581  // AT_{LOWER,UPPER}_BOUND to be VariableStatus::FREE. We store the restore
582  // value of these variables; which will only be used (eg. restored) if the
583  // variable actually turns out to be VariableStatus::FREE.
584  VariableStatusRow postsolve_status_of_free_variables_;
585 };
586 
587 // --------------------------------------------------------
588 // DoubletonFreeColumnPreprocessor
589 // --------------------------------------------------------
590 // This preprocessor removes one of the two rows in which a doubleton column of
591 // a free variable appears. Since we can add any multiple of such a column to
592 // any other column, the way this works is that we can always remove all the
593 // entries on one row.
594 //
595 // Actually, we can remove all the entries except the one of the free column.
596 // But we will be left with a singleton row that we can delete in the same way
597 // as what is done in SingletonPreprocessor. That is by reporting the constraint
598 // bounds into the one of the originally free variable. After this operation,
599 // the doubleton free column will become a singleton and may or may not be
600 // removed later by the SingletonPreprocessor.
601 //
602 // Note that this preprocessor can be seen as the dual of the
603 // DoubletonEqualityRowPreprocessor since when taking the dual, an equality row
604 // becomes a free variable and vice versa.
605 //
606 // Note(user): As far as I know, this doubleton free column procedure is more
607 // general than what can be found in the research papers or in any of the linear
608 // solver open source codes as of July 2013. All of them only process such
609 // columns if one of the two rows is also an equality which is not actually
610 // required. Most probably, commercial solvers do use it though.
612  public:
613  explicit DoubletonFreeColumnPreprocessor(const GlopParameters* parameters)
616  delete;
618  const DoubletonFreeColumnPreprocessor&) = delete;
620  bool Run(LinearProgram* lp) final;
621  void RecoverSolution(ProblemSolution* solution) const final;
622 
623  private:
624  enum RowChoice {
625  DELETED = 0,
626  MODIFIED = 1,
627  // This is just a constant for the number of rows in a doubleton column.
628  // That is 2, one will be DELETED, the other MODIFIED.
629  NUM_ROWS = 2,
630  };
631  struct RestoreInfo {
632  // The index of the original free doubleton column and its objective.
633  ColIndex col;
634  Fractional objective_coefficient;
635 
636  // The row indices of the two involved rows and their coefficients on
637  // column col.
638  RowIndex row[NUM_ROWS];
639  Fractional coeff[NUM_ROWS];
640 
641  // The deleted row as a column.
642  SparseColumn deleted_row_as_column;
643  };
644 
645  std::vector<RestoreInfo> restore_stack_;
646  RowDeletionHelper row_deletion_helper_;
647 };
648 
649 // --------------------------------------------------------
650 // UnconstrainedVariablePreprocessor
651 // --------------------------------------------------------
652 // If for a given variable, none of the constraints block it in one direction
653 // and this direction improves the objective, then this variable can be fixed to
654 // its bound in this direction. If this bound is infinite and the variable cost
655 // is non-zero, then the problem is unbounded.
656 //
657 // More generally, by using the constraints and the variables that are unbounded
658 // on one side, one can derive bounds on the dual values. These can be
659 // translated into bounds on the reduced costs or the columns, which may force
660 // variables to their bounds. This is called forcing and dominated columns in
661 // the Andersen & Andersen paper.
663  public:
664  explicit UnconstrainedVariablePreprocessor(const GlopParameters* parameters)
667  delete;
669  const UnconstrainedVariablePreprocessor&) = delete;
671  bool Run(LinearProgram* lp) final;
672  void RecoverSolution(ProblemSolution* solution) const final;
673 
674  // Removes the given variable and all the rows in which it appears: If a
675  // variable is unconstrained with a zero cost, then all the constraints in
676  // which it appears can be made free! More precisely, during postsolve, if
677  // such a variable is unconstrained towards +kInfinity, for any activity value
678  // of the involved constraints, an M exists such that for each value of the
679  // variable >= M the problem will be feasible.
680  //
681  // The algorithm during postsolve is to find a feasible value for all such
682  // variables while trying to keep their magnitudes small (for better numerical
683  // behavior). target_bound should take only two possible values: +/-kInfinity.
686  LinearProgram* lp);
687 
688  private:
689  // Lower/upper bounds on the feasible dual value. We use constraints and
690  // variables unbounded in one direction to derive these bounds. We use these
691  // bounds to compute bounds on the reduced costs of the problem variables.
692  // Note that any finite bounds on a reduced cost means that the variable
693  // (ignoring its domain) can move freely in one direction.
694  DenseColumn dual_lb_;
695  DenseColumn dual_ub_;
696 
697  // Indicates if a given column may have participated in the current lb/ub
698  // on the reduced cost of the same column.
699  DenseBooleanRow may_have_participated_ub_;
700  DenseBooleanRow may_have_participated_lb_;
701 
702  ColumnDeletionHelper column_deletion_helper_;
703  RowDeletionHelper row_deletion_helper_;
704  DenseColumn rhs_;
705  DenseColumn activity_sign_correction_;
706  DenseBooleanRow is_unbounded_;
707 
708  SparseMatrix deleted_columns_;
709  SparseMatrix deleted_rows_as_column_;
710 };
711 
712 // --------------------------------------------------------
713 // FreeConstraintPreprocessor
714 // --------------------------------------------------------
715 // Removes the constraints with no bounds from the problem.
717  public:
718  explicit FreeConstraintPreprocessor(const GlopParameters* parameters)
722  delete;
724  bool Run(LinearProgram* lp) final;
725  void RecoverSolution(ProblemSolution* solution) const final;
726 
727  private:
728  RowDeletionHelper row_deletion_helper_;
729 };
730 
731 // --------------------------------------------------------
732 // EmptyConstraintPreprocessor
733 // --------------------------------------------------------
734 // Removes the constraints with no coefficients from the problem.
736  public:
737  explicit EmptyConstraintPreprocessor(const GlopParameters* parameters)
741  delete;
743  bool Run(LinearProgram* lp) final;
744  void RecoverSolution(ProblemSolution* solution) const final;
745 
746  private:
747  RowDeletionHelper row_deletion_helper_;
748 };
749 
750 // --------------------------------------------------------
751 // RemoveNearZeroEntriesPreprocessor
752 // --------------------------------------------------------
753 // Removes matrix entries that have only a negligible impact on the solution.
754 // Using the variable bounds, we derive a maximum possible impact, and remove
755 // the entries whose impact is under a given tolerance.
756 //
757 // TODO(user): This preprocessor doesn't work well on badly scaled problems. In
758 // particular, it will set the objective to zero if all the objective
759 // coefficients are small! Run it after ScalingPreprocessor or fix the code.
761  public:
762  explicit RemoveNearZeroEntriesPreprocessor(const GlopParameters* parameters)
765  delete;
767  const RemoveNearZeroEntriesPreprocessor&) = delete;
769  bool Run(LinearProgram* lp) final;
770  void RecoverSolution(ProblemSolution* solution) const final;
771 
772  private:
773 };
774 
775 // --------------------------------------------------------
776 // SingletonColumnSignPreprocessor
777 // --------------------------------------------------------
778 // Make sure that the only coefficient of all singleton columns (i.e. column
779 // with only one entry) is positive. This is because this way the column will
780 // be transformed in an identity column by the scaling. This will lead to more
781 // efficient solve when this column is involved.
783  public:
784  explicit SingletonColumnSignPreprocessor(const GlopParameters* parameters)
787  delete;
789  const SingletonColumnSignPreprocessor&) = delete;
791  bool Run(LinearProgram* lp) final;
792  void RecoverSolution(ProblemSolution* solution) const final;
793 
794  private:
795  std::vector<ColIndex> changed_columns_;
796 };
797 
798 // --------------------------------------------------------
799 // DoubletonEqualityRowPreprocessor
800 // --------------------------------------------------------
801 // Reduce equality constraints involving two variables (i.e. aX + bY = c),
802 // by substitution (and thus removal) of one of the variables by the other
803 // in all the constraints that it is involved in.
805  public:
806  explicit DoubletonEqualityRowPreprocessor(const GlopParameters* parameters)
809  delete;
811  const DoubletonEqualityRowPreprocessor&) = delete;
813  bool Run(LinearProgram* lp) final;
814  void RecoverSolution(ProblemSolution* solution) const final;
815 
816  private:
817  enum ColChoice {
818  DELETED = 0,
819  MODIFIED = 1,
820  // For for() loops iterating over the ColChoice values, and/or arrays.
821  NUM_DOUBLETON_COLS = 2,
822  };
823  static ColChoice OtherColChoice(ColChoice x) {
824  return x == DELETED ? MODIFIED : DELETED;
825  }
826 
827  ColumnDeletionHelper column_deletion_helper_;
828  RowDeletionHelper row_deletion_helper_;
829 
830  struct RestoreInfo {
831  // The row index of the doubleton equality constraint, and its constant.
832  RowIndex row;
833  Fractional rhs; // The constant c in the equality aX + bY = c.
834 
835  // The indices and the data of the two columns that we touched, exactly
836  // as they were beforehand.
837  ColIndex col[NUM_DOUBLETON_COLS];
838  Fractional coeff[NUM_DOUBLETON_COLS];
839  Fractional lb[NUM_DOUBLETON_COLS];
840  Fractional ub[NUM_DOUBLETON_COLS];
841  SparseColumn column[NUM_DOUBLETON_COLS];
842  Fractional objective_coefficient[NUM_DOUBLETON_COLS];
843 
844  // If the modified variable has status AT_[LOWER,UPPER]_BOUND, then we'll
845  // set one of the two original variables to one of its bounds, and set the
846  // other to VariableStatus::BASIC. We store this information (which variable
847  // will be set to one of its bounds, and which bound) for each possible
848  // outcome.
850  ColChoice col_choice;
855  : col_choice(c), status(s), value(v) {}
856  };
857  ColChoiceAndStatus bound_backtracking_at_lower_bound;
858  ColChoiceAndStatus bound_backtracking_at_upper_bound;
859  };
860  void SwapDeletedAndModifiedVariableRestoreInfo(RestoreInfo* r);
861 
862  std::vector<RestoreInfo> restore_stack_;
863  DenseColumn saved_row_lower_bounds_;
864  DenseColumn saved_row_upper_bounds_;
865 };
866 
867 // Because of numerical imprecision, a preprocessor like
868 // DoubletonEqualityRowPreprocessor can transform a constraint/variable domain
869 // like [1, 1+1e-7] to a fixed domain (for ex by multiplying the above domain by
870 // 1e9). This causes an issue because at postsolve, a FIXED_VALUE status now
871 // needs to be transformed to a AT_LOWER_BOUND/AT_UPPER_BOUND status. This is
872 // what this function is doing for the constraint statuses only.
873 //
874 // TODO(user): A better solution would simply be to get rid of the FIXED status
875 // altogether, it is better to simply use AT_LOWER_BOUND/AT_UPPER_BOUND
876 // depending on the constraining bound in the optimal solution. Note that we can
877 // always at the end transform any variable/constraint with a fixed domain to
878 // FIXED_VALUE if needed to keep the same external API.
879 void FixConstraintWithFixedStatuses(const DenseColumn& row_lower_bounds,
880  const DenseColumn& row_upper_bounds,
881  ProblemSolution* solution);
882 
883 // --------------------------------------------------------
884 // DualizerPreprocessor
885 // --------------------------------------------------------
886 // DualizerPreprocessor may change the given program to its dual depending
887 // on the value of the parameter solve_dual_problem.
888 //
889 // IMPORTANT: FreeConstraintPreprocessor() must be called first since this
890 // preprocessor does not deal correctly with free constraints.
892  public:
893  explicit DualizerPreprocessor(const GlopParameters* parameters)
898  bool Run(LinearProgram* lp) final;
899  void RecoverSolution(ProblemSolution* solution) const final;
900  void UseInMipContext() final {
901  LOG(FATAL) << "In the presence of integer variables, "
902  << "there is no notion of a dual problem.";
903  }
904 
905  // Convert the given problem status to the one of its dual.
907 
908  private:
909  DenseRow variable_lower_bounds_;
910  DenseRow variable_upper_bounds_;
911 
912  RowIndex primal_num_rows_;
913  ColIndex primal_num_cols_;
914  bool primal_is_maximization_problem_;
915  RowToColMapping duplicated_rows_;
916 
917  // For postsolving the variable/constraint statuses.
918  VariableStatusRow dual_status_correspondence_;
919  ColMapping slack_or_surplus_mapping_;
920 };
921 
922 // --------------------------------------------------------
923 // ShiftVariableBoundsPreprocessor
924 // --------------------------------------------------------
925 // For each variable, inspects its bounds and "shift" them if necessary, so that
926 // its domain contains zero. A variable that was shifted will always have at
927 // least one of its bounds to zero. Doing it all at once allows to have a better
928 // precision when modifying the constraint bounds by using an accurate summation
929 // algorithm.
930 //
931 // Example:
932 // - A variable with bound [1e10, infinity] will be shifted to [0, infinity].
933 // - A variable with domain [-1e10, 1e10] will not be shifted. Note that
934 // compared to the first case, doing so here may introduce unecessary
935 // numerical errors if the variable value in the final solution is close to
936 // zero.
937 //
938 // The expected impact of this is:
939 // - Better behavior of the scaling.
940 // - Better precision and numerical accuracy of the simplex method.
941 // - Slightly improved speed (because adding a column with a variable value of
942 // zero takes no work later).
943 //
944 // TODO(user): Having for each variable one of their bounds at zero is a
945 // requirement for the DualizerPreprocessor and for the implied free column in
946 // the ImpliedFreePreprocessor. However, shifting a variable with a domain like
947 // [-1e10, 1e10] may introduce numerical issues. Relax the definition of
948 // a free variable so that only having a domain containing 0.0 is enough?
950  public:
951  explicit ShiftVariableBoundsPreprocessor(const GlopParameters* parameters)
954  delete;
956  const ShiftVariableBoundsPreprocessor&) = delete;
958  bool Run(LinearProgram* lp) final;
959  void RecoverSolution(ProblemSolution* solution) const final;
960 
961  const DenseRow& offsets() const { return offsets_; }
962 
963  private:
964  // Contains for each variable by how much its bounds where shifted during
965  // presolve. Note that the shift was negative (new bound = initial bound -
966  // offset).
967  DenseRow offsets_;
968  // Contains the initial problem bounds. They are needed to get the perfect
969  // numerical accuracy for variables at their bound after postsolve.
970  DenseRow variable_initial_lbs_;
971  DenseRow variable_initial_ubs_;
972 };
973 
974 // --------------------------------------------------------
975 // ScalingPreprocessor
976 // --------------------------------------------------------
977 // Scales the SparseMatrix of the linear program using a SparseMatrixScaler.
978 // This is only applied if the parameter use_scaling is true.
980  public:
981  explicit ScalingPreprocessor(const GlopParameters* parameters)
986  bool Run(LinearProgram* lp) final;
987  void RecoverSolution(ProblemSolution* solution) const final;
988  void UseInMipContext() final { LOG(FATAL) << "Not implemented."; }
989 
990  private:
991  DenseRow variable_lower_bounds_;
992  DenseRow variable_upper_bounds_;
993  Fractional cost_scaling_factor_;
994  Fractional bound_scaling_factor_;
995  SparseMatrixScaler scaler_;
996 };
997 
998 // --------------------------------------------------------
999 // ToMinimizationPreprocessor
1000 // --------------------------------------------------------
1001 // Changes the problem from maximization to minimization (if applicable).
1003  public:
1004  explicit ToMinimizationPreprocessor(const GlopParameters* parameters)
1005  : Preprocessor(parameters) {}
1008  delete;
1010  bool Run(LinearProgram* lp) final;
1011  void RecoverSolution(ProblemSolution* solution) const final;
1012 };
1013 
1014 // --------------------------------------------------------
1015 // AddSlackVariablesPreprocessor
1016 // --------------------------------------------------------
1017 // Transforms the linear program to the equation form
1018 // min c.x, s.t. A.x = 0. This is done by:
1019 // 1. Introducing slack variables for all constraints; all these variables are
1020 // introduced with coefficient 1.0, and their bounds are set to be negative
1021 // bounds of the corresponding constraint.
1022 // 2. Changing the bounds of all constraints to (0, 0) to make them an equality.
1023 //
1024 // As a consequence, the matrix of the linear program always has full row rank
1025 // after this preprocessor. Note that the slack variables are always added last,
1026 // so that the rightmost square sub-matrix is always the identity matrix.
1028  public:
1029  explicit AddSlackVariablesPreprocessor(const GlopParameters* parameters)
1030  : Preprocessor(parameters) {}
1033  const AddSlackVariablesPreprocessor&) = delete;
1035  bool Run(LinearProgram* lp) final;
1036  void RecoverSolution(ProblemSolution* solution) const final;
1037 
1038  private:
1039  ColIndex first_slack_col_;
1040 };
1041 
1042 } // namespace glop
1043 } // namespace operations_research
1044 
1045 #endif // OR_TOOLS_GLOP_PREPROCESSOR_H_
operations_research::glop::ImpliedFreePreprocessor
Definition: preprocessor.h:565
operations_research::glop::ToMinimizationPreprocessor::ToMinimizationPreprocessor
ToMinimizationPreprocessor(const GlopParameters *parameters)
Definition: preprocessor.h:1004
operations_research::glop::FixedVariablePreprocessor::~FixedVariablePreprocessor
~FixedVariablePreprocessor() final
Definition: preprocessor.h:491
operations_research::glop::FreeConstraintPreprocessor::Run
bool Run(LinearProgram *lp) final
Definition: preprocessor.cc:2057
operations_research::glop::RowDeletionHelper::IsRowMarked
bool IsRowMarked(RowIndex row) const
Definition: preprocessor.h:215
operations_research::glop::SingletonColumnSignPreprocessor::SingletonColumnSignPreprocessor
SingletonColumnSignPreprocessor(const SingletonColumnSignPreprocessor &)=delete
operations_research::glop::ShiftVariableBoundsPreprocessor::Run
bool Run(LinearProgram *lp) final
Definition: preprocessor.cc:3481
operations_research::glop::RowDeletionHelper::operator=
RowDeletionHelper & operator=(const RowDeletionHelper &)=delete
operations_research::glop::DoubletonFreeColumnPreprocessor::RecoverSolution
void RecoverSolution(ProblemSolution *solution) const final
Definition: preprocessor.cc:1636
operations_research::glop::RowDeletionHelper::RowDeletionHelper
RowDeletionHelper()
Definition: preprocessor.h:195
operations_research::glop::ColumnDeletionHelper::MarkColumnForDeletionWithState
void MarkColumnForDeletionWithState(ColIndex col, Fractional value, VariableStatus status)
Definition: preprocessor.cc:194
operations_research::glop::MainLpPreprocessor::MainLpPreprocessor
MainLpPreprocessor(const MainLpPreprocessor &)=delete
operations_research::glop::ShiftVariableBoundsPreprocessor::RecoverSolution
void RecoverSolution(ProblemSolution *solution) const final
Definition: preprocessor.cc:3549
operations_research::glop::SingletonPreprocessor::SingletonPreprocessor
SingletonPreprocessor(const GlopParameters *parameters)
Definition: preprocessor.h:398
operations_research::glop::ColumnDeletionHelper::ColumnDeletionHelper
ColumnDeletionHelper(const ColumnDeletionHelper &)=delete
operations_research::glop::ShiftVariableBoundsPreprocessor::operator=
ShiftVariableBoundsPreprocessor & operator=(const ShiftVariableBoundsPreprocessor &)=delete
operations_research::glop::FixedVariablePreprocessor::RecoverSolution
void RecoverSolution(ProblemSolution *solution) const final
Definition: preprocessor.cc:1055
operations_research::glop::ForcingAndImpliedFreeConstraintPreprocessor::RecoverSolution
void RecoverSolution(ProblemSolution *solution) const final
Definition: preprocessor.cc:1232
operations_research::glop::ForcingAndImpliedFreeConstraintPreprocessor
Definition: preprocessor.h:519
operations_research::glop::RowDeletionHelper::Clear
void Clear()
Definition: preprocessor.cc:238
LOG
#define LOG(severity)
Definition: base/logging.h:420
operations_research::glop::Preprocessor::parameters_
const GlopParameters & parameters_
Definition: preprocessor.h:91
lp_data.h
operations_research::glop::SingletonUndo::OperationType
OperationType
Definition: preprocessor.h:342
operations_research::glop::ColumnDeletionHelper::operator=
ColumnDeletionHelper & operator=(const ColumnDeletionHelper &)=delete
operations_research::glop::RemoveNearZeroEntriesPreprocessor::~RemoveNearZeroEntriesPreprocessor
~RemoveNearZeroEntriesPreprocessor() final
Definition: preprocessor.h:768
operations_research::glop::FreeConstraintPreprocessor::~FreeConstraintPreprocessor
~FreeConstraintPreprocessor() final
Definition: preprocessor.h:723
operations_research::glop::DoubletonEqualityRowPreprocessor::DoubletonEqualityRowPreprocessor
DoubletonEqualityRowPreprocessor(const DoubletonEqualityRowPreprocessor &)=delete
operations_research::glop::DoubletonFreeColumnPreprocessor::operator=
DoubletonFreeColumnPreprocessor & operator=(const DoubletonFreeColumnPreprocessor &)=delete
FATAL
const int FATAL
Definition: log_severity.h:32
operations_research::glop::ShiftVariableBoundsPreprocessor::offsets
const DenseRow & offsets() const
Definition: preprocessor.h:961
operations_research::glop::AddSlackVariablesPreprocessor::~AddSlackVariablesPreprocessor
~AddSlackVariablesPreprocessor() final
Definition: preprocessor.h:1034
operations_research::glop::MainLpPreprocessor::operator=
MainLpPreprocessor & operator=(const MainLpPreprocessor &)=delete
operations_research::glop::AddSlackVariablesPreprocessor::RecoverSolution
void RecoverSolution(ProblemSolution *solution) const final
Definition: preprocessor.cc:3677
operations_research::glop::EmptyColumnPreprocessor
Definition: preprocessor.h:232
operations_research::glop::RowDeletionHelper::RestoreDeletedRows
void RestoreDeletedRows(ProblemSolution *solution) const
Definition: preprocessor.cc:257
operations_research::glop::AddSlackVariablesPreprocessor
Definition: preprocessor.h:1027
operations_research::glop::Preprocessor::operator=
Preprocessor & operator=(const Preprocessor &)=delete
operations_research::glop::ForcingAndImpliedFreeConstraintPreprocessor::~ForcingAndImpliedFreeConstraintPreprocessor
~ForcingAndImpliedFreeConstraintPreprocessor() final
Definition: preprocessor.h:528
operations_research::glop::FixedVariablePreprocessor::operator=
FixedVariablePreprocessor & operator=(const FixedVariablePreprocessor &)=delete
operations_research::glop::DualizerPreprocessor::~DualizerPreprocessor
~DualizerPreprocessor() final
Definition: preprocessor.h:897
operations_research::glop::ScalingPreprocessor::ScalingPreprocessor
ScalingPreprocessor(const ScalingPreprocessor &)=delete
operations_research::glop::DualizerPreprocessor::UseInMipContext
void UseInMipContext() final
Definition: preprocessor.h:900
operations_research::glop::ImpliedFreePreprocessor::ImpliedFreePreprocessor
ImpliedFreePreprocessor(const GlopParameters *parameters)
Definition: preprocessor.h:567
operations_research::glop::EmptyConstraintPreprocessor::~EmptyConstraintPreprocessor
~EmptyConstraintPreprocessor() final
Definition: preprocessor.h:742
operations_research::glop::ToMinimizationPreprocessor::ToMinimizationPreprocessor
ToMinimizationPreprocessor(const ToMinimizationPreprocessor &)=delete
operations_research::glop::ForcingAndImpliedFreeConstraintPreprocessor::operator=
ForcingAndImpliedFreeConstraintPreprocessor & operator=(const ForcingAndImpliedFreeConstraintPreprocessor &)=delete
operations_research::glop::ProportionalColumnPreprocessor
Definition: preprocessor.h:256
operations_research::glop::FreeConstraintPreprocessor::FreeConstraintPreprocessor
FreeConstraintPreprocessor(const FreeConstraintPreprocessor &)=delete
value
int64 value
Definition: demon_profiler.cc:43
operations_research::glop::DoubletonEqualityRowPreprocessor::RestoreInfo::ColChoiceAndStatus::status
VariableStatus status
Definition: preprocessor.h:851
operations_research::glop::ProportionalRowPreprocessor::Run
bool Run(LinearProgram *lp) final
Definition: preprocessor.cc:784
operations_research::glop::ScalingPreprocessor::RecoverSolution
void RecoverSolution(ProblemSolution *solution) const final
Definition: preprocessor.cc:3604
operations_research::glop::RowDeletionHelper::RowDeletionHelper
RowDeletionHelper(const RowDeletionHelper &)=delete
operations_research::glop::RowDeletionHelper::GetMarkedRows
const DenseBooleanColumn & GetMarkedRows() const
Definition: preprocessor.cc:253
operations_research::glop::MainLpPreprocessor::~MainLpPreprocessor
~MainLpPreprocessor() override
Definition: preprocessor.h:108
operations_research::glop::ImpliedFreePreprocessor::~ImpliedFreePreprocessor
~ImpliedFreePreprocessor() final
Definition: preprocessor.h:571
operations_research::glop::ScalingPreprocessor::operator=
ScalingPreprocessor & operator=(const ScalingPreprocessor &)=delete
operations_research::glop::ProportionalRowPreprocessor
Definition: preprocessor.h:297
operations_research::glop::StrictITIVector::size
IntType size() const
Definition: lp_types.h:276
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::glop::ConstraintStatus
ConstraintStatus
Definition: lp_types.h:227
operations_research::glop::MatrixEntry::row
RowIndex row
Definition: preprocessor.h:333
operations_research::glop::ForcingAndImpliedFreeConstraintPreprocessor::ForcingAndImpliedFreeConstraintPreprocessor
ForcingAndImpliedFreeConstraintPreprocessor(const ForcingAndImpliedFreeConstraintPreprocessor &)=delete
operations_research::glop::EmptyConstraintPreprocessor
Definition: preprocessor.h:735
operations_research::glop::DoubletonFreeColumnPreprocessor
Definition: preprocessor.h:611
matrix_scaler.h
operations_research::glop::AddSlackVariablesPreprocessor::Run
bool Run(LinearProgram *lp) final
Definition: preprocessor.cc:3668
operations_research::glop::FreeConstraintPreprocessor::RecoverSolution
void RecoverSolution(ProblemSolution *solution) const final
Definition: preprocessor.cc:2072
operations_research::glop::DoubletonFreeColumnPreprocessor::~DoubletonFreeColumnPreprocessor
~DoubletonFreeColumnPreprocessor() final
Definition: preprocessor.h:619
operations_research::glop::MatrixEntry::coeff
Fractional coeff
Definition: preprocessor.h:335
operations_research::glop::SingletonColumnSignPreprocessor
Definition: preprocessor.h:782
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::glop::Preprocessor::UseInMipContext
virtual void UseInMipContext()
Definition: preprocessor.h:72
operations_research::glop::SingletonPreprocessor::SingletonPreprocessor
SingletonPreprocessor(const SingletonPreprocessor &)=delete
operations_research::glop::RowDeletionHelper::IsEmpty
bool IsEmpty() const
Definition: preprocessor.h:200
operations_research::glop::Preprocessor::status
ProblemStatus status() const
Definition: preprocessor.h:64
operations_research::glop::ForcingAndImpliedFreeConstraintPreprocessor::Run
bool Run(LinearProgram *lp) final
Definition: preprocessor.cc:1066
operations_research::glop::EmptyConstraintPreprocessor::EmptyConstraintPreprocessor
EmptyConstraintPreprocessor(const GlopParameters *parameters)
Definition: preprocessor.h:737
operations_research::glop::SingletonUndo::SingletonUndo
SingletonUndo(OperationType type, const LinearProgram &lp, MatrixEntry e, ConstraintStatus status)
Definition: preprocessor.cc:2131
operations_research::glop::SingletonUndo::MAKE_CONSTRAINT_AN_EQUALITY
@ MAKE_CONSTRAINT_AN_EQUALITY
Definition: preprocessor.h:346
operations_research::glop::DoubletonEqualityRowPreprocessor::RestoreInfo::ColChoiceAndStatus::ColChoiceAndStatus
ColChoiceAndStatus(ColChoice c, VariableStatus s, Fractional v)
Definition: preprocessor.h:854
revised_simplex.h
operations_research::glop::Fractional
double Fractional
Definition: lp_types.h:77
operations_research::glop::SingletonColumnSignPreprocessor::Run
bool Run(LinearProgram *lp) final
Definition: preprocessor.cc:2887
operations_research::glop::Preprocessor
Definition: preprocessor.h:42
operations_research::glop::Preprocessor::Preprocessor
Preprocessor(const Preprocessor &)=delete
operations_research::glop::ProportionalColumnPreprocessor::Run
bool Run(LinearProgram *lp) final
Definition: preprocessor.cc:440
operations_research::glop::SingletonPreprocessor::Run
bool Run(LinearProgram *lp) final
Definition: preprocessor.cc:2682
operations_research::glop::ImpliedFreePreprocessor::operator=
ImpliedFreePreprocessor & operator=(const ImpliedFreePreprocessor &)=delete
operations_research::glop::UnconstrainedVariablePreprocessor
Definition: preprocessor.h:662
operations_research::glop::Preprocessor::SetTimeLimit
void SetTimeLimit(TimeLimit *time_limit)
Definition: preprocessor.h:74
operations_research::glop::ScalingPreprocessor::Run
bool Run(LinearProgram *lp) final
Definition: preprocessor.cc:3581
a
int64 a
Definition: constraint_solver/table.cc:42
operations_research::glop::Preprocessor::status_
ProblemStatus status_
Definition: preprocessor.h:90
operations_research::glop::ScalingPreprocessor::UseInMipContext
void UseInMipContext() final
Definition: preprocessor.h:988
operations_research::glop::MatrixEntry::MatrixEntry
MatrixEntry(RowIndex _row, ColIndex _col, Fractional _coeff)
Definition: preprocessor.h:331
operations_research::glop::ProportionalColumnPreprocessor::RecoverSolution
void RecoverSolution(ProblemSolution *solution) const final
Definition: preprocessor.cc:669
operations_research::glop::ProportionalRowPreprocessor::ProportionalRowPreprocessor
ProportionalRowPreprocessor(const ProportionalRowPreprocessor &)=delete
target_bound
Fractional target_bound
Definition: revised_simplex.cc:1804
operations_research::glop::EmptyColumnPreprocessor::RecoverSolution
void RecoverSolution(ProblemSolution *solution) const final
Definition: preprocessor.cc:386
time_limit
SharedTimeLimit * time_limit
Definition: cp_model_solver.cc:2103
operations_research::glop::DoubletonFreeColumnPreprocessor::Run
bool Run(LinearProgram *lp) final
Definition: preprocessor.cc:1530
operations_research::glop::SparseMatrix
Definition: sparse.h:61
operations_research::glop::ColumnDeletionHelper::GetMarkedColumns
const DenseBooleanRow & GetMarkedColumns() const
Definition: preprocessor.h:165
operations_research::glop::UnconstrainedVariablePreprocessor::UnconstrainedVariablePreprocessor
UnconstrainedVariablePreprocessor(const UnconstrainedVariablePreprocessor &)=delete
operations_research::glop::EmptyColumnPreprocessor::Run
bool Run(LinearProgram *lp) final
Definition: preprocessor.cc:342
operations_research::glop::Preprocessor::IsSmallerWithinPreprocessorZeroTolerance
bool IsSmallerWithinPreprocessorZeroTolerance(Fractional a, Fractional b) const
Definition: preprocessor.h:83
operations_research::glop::SingletonColumnSignPreprocessor::operator=
SingletonColumnSignPreprocessor & operator=(const SingletonColumnSignPreprocessor &)=delete
operations_research::glop::RowDeletionHelper::MarkRowForDeletion
void MarkRowForDeletion(RowIndex row)
Definition: preprocessor.cc:240
operations_research::glop::EmptyConstraintPreprocessor::Run
bool Run(LinearProgram *lp) final
Definition: preprocessor.cc:2083
operations_research::glop::ImpliedFreePreprocessor::Run
bool Run(LinearProgram *lp) final
Definition: preprocessor.cc:1317
operations_research::glop::RemoveNearZeroEntriesPreprocessor
Definition: preprocessor.h:760
operations_research::glop::ProblemSolution
Definition: lp_data.h:647
operations_research::glop::Preprocessor::Run
virtual bool Run(LinearProgram *lp)=0
operations_research::glop::RowDeletionHelper
Definition: preprocessor.h:193
operations_research::glop::StrictITIVector< ColIndex, bool >
operations_research::glop::ScalingPreprocessor::ScalingPreprocessor
ScalingPreprocessor(const GlopParameters *parameters)
Definition: preprocessor.h:981
operations_research::glop::DoubletonEqualityRowPreprocessor::operator=
DoubletonEqualityRowPreprocessor & operator=(const DoubletonEqualityRowPreprocessor &)=delete
operations_research::glop::EmptyColumnPreprocessor::EmptyColumnPreprocessor
EmptyColumnPreprocessor(const GlopParameters *parameters)
Definition: preprocessor.h:234
operations_research::glop::EmptyConstraintPreprocessor::EmptyConstraintPreprocessor
EmptyConstraintPreprocessor(const EmptyConstraintPreprocessor &)=delete
operations_research::glop::DualizerPreprocessor::operator=
DualizerPreprocessor & operator=(const DualizerPreprocessor &)=delete
operations_research::glop::SingletonColumnSignPreprocessor::RecoverSolution
void RecoverSolution(ProblemSolution *solution) const final
Definition: preprocessor.cc:2915
operations_research::glop::ColumnDeletionHelper
Definition: preprocessor.h:137
operations_research::glop::DualizerPreprocessor::Run
bool Run(LinearProgram *lp) final
Definition: preprocessor.cc:3232
operations_research::glop::ToMinimizationPreprocessor::Run
bool Run(LinearProgram *lp) final
Definition: preprocessor.cc:3644
operations_research::glop::ColumnDeletionHelper::MarkColumnForDeletion
void MarkColumnForDeletion(ColIndex col)
Definition: preprocessor.cc:190
operations_research::glop::ProportionalColumnPreprocessor::ProportionalColumnPreprocessor
ProportionalColumnPreprocessor(const GlopParameters *parameters)
Definition: preprocessor.h:258
operations_research::glop::AddSlackVariablesPreprocessor::AddSlackVariablesPreprocessor
AddSlackVariablesPreprocessor(const AddSlackVariablesPreprocessor &)=delete
operations_research::glop::ProportionalRowPreprocessor::~ProportionalRowPreprocessor
~ProportionalRowPreprocessor() final
Definition: preprocessor.h:304
operations_research::glop::SingletonPreprocessor::~SingletonPreprocessor
~SingletonPreprocessor() final
Definition: preprocessor.h:402
operations_research::glop::ImpliedFreePreprocessor::ImpliedFreePreprocessor
ImpliedFreePreprocessor(const ImpliedFreePreprocessor &)=delete
operations_research::glop::ColumnDeletionHelper::GetStoredValue
const DenseRow & GetStoredValue() const
Definition: preprocessor.h:176
operations_research::glop::DualizerPreprocessor
Definition: preprocessor.h:891
operations_research::glop::MatrixEntry::col
ColIndex col
Definition: preprocessor.h:334
operations_research::glop::DoubletonEqualityRowPreprocessor::RestoreInfo::ColChoiceAndStatus::value
Fractional value
Definition: preprocessor.h:852
operations_research::glop::FixedVariablePreprocessor::FixedVariablePreprocessor
FixedVariablePreprocessor(const GlopParameters *parameters)
Definition: preprocessor.h:486
operations_research::glop::RemoveNearZeroEntriesPreprocessor::Run
bool Run(LinearProgram *lp) final
Definition: preprocessor.cc:2813
operations_research::glop::RemoveNearZeroEntriesPreprocessor::RemoveNearZeroEntriesPreprocessor
RemoveNearZeroEntriesPreprocessor(const RemoveNearZeroEntriesPreprocessor &)=delete
operations_research::glop::DualizerPreprocessor::DualizerPreprocessor
DualizerPreprocessor(const GlopParameters *parameters)
Definition: preprocessor.h:893
operations_research::glop::Preprocessor::RecoverSolution
virtual void RecoverSolution(ProblemSolution *solution) const =0
operations_research::glop::DualizerPreprocessor::RecoverSolution
void RecoverSolution(ProblemSolution *solution) const final
Definition: preprocessor.cc:3348
operations_research::glop::SparseMatrixScaler
Definition: matrix_scaler.h:79
operations_research::glop::UnconstrainedVariablePreprocessor::RecoverSolution
void RecoverSolution(ProblemSolution *solution) const final
Definition: preprocessor.cc:1989
operations_research::glop::SingletonPreprocessor::operator=
SingletonPreprocessor & operator=(const SingletonPreprocessor &)=delete
operations_research::glop::ShiftVariableBoundsPreprocessor
Definition: preprocessor.h:949
operations_research::glop::UnconstrainedVariablePreprocessor::RemoveZeroCostUnconstrainedVariable
void RemoveZeroCostUnconstrainedVariable(ColIndex col, Fractional target_bound, LinearProgram *lp)
Definition: preprocessor.cc:1714
operations_research::glop::Preprocessor::Preprocessor
Preprocessor(const GlopParameters *parameters)
Definition: preprocessor.cc:45
operations_research::glop::ToMinimizationPreprocessor::RecoverSolution
void RecoverSolution(ProblemSolution *solution) const final
Definition: preprocessor.cc:3661
operations_research::glop::EmptyColumnPreprocessor::~EmptyColumnPreprocessor
~EmptyColumnPreprocessor() final
Definition: preprocessor.h:238
operations_research::glop::DoubletonEqualityRowPreprocessor::DoubletonEqualityRowPreprocessor
DoubletonEqualityRowPreprocessor(const GlopParameters *parameters)
Definition: preprocessor.h:806
operations_research::glop::FixedVariablePreprocessor::Run
bool Run(LinearProgram *lp) final
Definition: preprocessor.cc:1033
operations_research::glop::AddSlackVariablesPreprocessor::AddSlackVariablesPreprocessor
AddSlackVariablesPreprocessor(const GlopParameters *parameters)
Definition: preprocessor.h:1029
operations_research::glop::ToMinimizationPreprocessor
Definition: preprocessor.h:1002
operations_research::glop::ColumnDeletionHelper::IsColumnMarked
bool IsColumnMarked(ColIndex col) const
Definition: preprocessor.h:160
operations_research::glop::UnconstrainedVariablePreprocessor::operator=
UnconstrainedVariablePreprocessor & operator=(const UnconstrainedVariablePreprocessor &)=delete
operations_research::glop::FreeConstraintPreprocessor::operator=
FreeConstraintPreprocessor & operator=(const FreeConstraintPreprocessor &)=delete
operations_research::glop::ProportionalColumnPreprocessor::ProportionalColumnPreprocessor
ProportionalColumnPreprocessor(const ProportionalColumnPreprocessor &)=delete
operations_research::glop::FixedVariablePreprocessor
Definition: preprocessor.h:484
operations_research::glop::UnconstrainedVariablePreprocessor::UnconstrainedVariablePreprocessor
UnconstrainedVariablePreprocessor(const GlopParameters *parameters)
Definition: preprocessor.h:664
operations_research::glop::Preprocessor::IsSmallerWithinFeasibilityTolerance
bool IsSmallerWithinFeasibilityTolerance(Fractional a, Fractional b) const
Definition: preprocessor.h:79
absl::StrongVector< RowIndex, bool >
operations_research::glop::DualizerPreprocessor::DualizerPreprocessor
DualizerPreprocessor(const DualizerPreprocessor &)=delete
operations_research::glop::DoubletonEqualityRowPreprocessor::~DoubletonEqualityRowPreprocessor
~DoubletonEqualityRowPreprocessor() final
Definition: preprocessor.h:812
col
ColIndex col
Definition: markowitz.cc:176
operations_research::glop::ProportionalColumnPreprocessor::~ProportionalColumnPreprocessor
~ProportionalColumnPreprocessor() final
Definition: preprocessor.h:264
operations_research::glop::ColumnDeletionHelper::Clear
void Clear()
Definition: preprocessor.cc:185
operations_research::glop::DoubletonFreeColumnPreprocessor::DoubletonFreeColumnPreprocessor
DoubletonFreeColumnPreprocessor(const GlopParameters *parameters)
Definition: preprocessor.h:613
operations_research::glop::ScalingPreprocessor
Definition: preprocessor.h:979
operations_research::glop::SingletonUndo::SINGLETON_ROW
@ SINGLETON_ROW
Definition: preprocessor.h:344
operations_research::glop::FixedVariablePreprocessor::FixedVariablePreprocessor
FixedVariablePreprocessor(const FixedVariablePreprocessor &)=delete
operations_research::glop::ProblemStatus
ProblemStatus
Definition: lp_types.h:101
operations_research::glop::ToMinimizationPreprocessor::operator=
ToMinimizationPreprocessor & operator=(const ToMinimizationPreprocessor &)=delete
operations_research::glop::MainLpPreprocessor::Run
bool Run(LinearProgram *lp) final
Definition: preprocessor.cc:61
row
RowIndex row
Definition: markowitz.cc:175
operations_research::glop::DoubletonEqualityRowPreprocessor::Run
bool Run(LinearProgram *lp) final
Definition: preprocessor.cc:2935
operations_research::glop::LinearProgram
Definition: lp_data.h:55
operations_research::glop::DoubletonEqualityRowPreprocessor
Definition: preprocessor.h:804
operations_research::glop::EmptyColumnPreprocessor::EmptyColumnPreprocessor
EmptyColumnPreprocessor(const EmptyColumnPreprocessor &)=delete
operations_research::glop::DenseColumn
StrictITIVector< RowIndex, Fractional > DenseColumn
Definition: lp_types.h:328
operations_research::glop::EmptyConstraintPreprocessor::operator=
EmptyConstraintPreprocessor & operator=(const EmptyConstraintPreprocessor &)=delete
operations_research::glop::FreeConstraintPreprocessor
Definition: preprocessor.h:716
operations_research::glop::ProportionalRowPreprocessor::operator=
ProportionalRowPreprocessor & operator=(const ProportionalRowPreprocessor &)=delete
operations_research::glop::UnconstrainedVariablePreprocessor::~UnconstrainedVariablePreprocessor
~UnconstrainedVariablePreprocessor() final
Definition: preprocessor.h:670
operations_research::glop::ProportionalRowPreprocessor::ProportionalRowPreprocessor
ProportionalRowPreprocessor(const GlopParameters *parameters)
Definition: preprocessor.h:299
operations_research::glop::MainLpPreprocessor
Definition: preprocessor.h:102
operations_research::glop::DoubletonEqualityRowPreprocessor::RestoreInfo::ColChoiceAndStatus
Definition: preprocessor.h:849
operations_research::glop::ScalingPreprocessor::~ScalingPreprocessor
~ScalingPreprocessor() final
Definition: preprocessor.h:985
operations_research::glop::Preprocessor::~Preprocessor
virtual ~Preprocessor()
Definition: preprocessor.cc:51
operations_research::glop::SingletonUndo::Undo
void Undo(const GlopParameters &parameters, const SparseMatrix &deleted_columns, const SparseMatrix &deleted_rows, ProblemSolution *solution) const
Definition: preprocessor.cc:2143
operations_research::glop::ShiftVariableBoundsPreprocessor::ShiftVariableBoundsPreprocessor
ShiftVariableBoundsPreprocessor(const GlopParameters *parameters)
Definition: preprocessor.h:951
operations_research::glop::DoubletonEqualityRowPreprocessor::RestoreInfo::ColChoiceAndStatus::ColChoiceAndStatus
ColChoiceAndStatus()
Definition: preprocessor.h:853
operations_research::glop::ProportionalRowPreprocessor::RecoverSolution
void RecoverSolution(ProblemSolution *solution) const final
Definition: preprocessor.cc:959
operations_research::glop::ColumnDeletionHelper::IsEmpty
bool IsEmpty() const
Definition: preprocessor.h:168
operations_research::glop::RemoveNearZeroEntriesPreprocessor::operator=
RemoveNearZeroEntriesPreprocessor & operator=(const RemoveNearZeroEntriesPreprocessor &)=delete
b
int64 b
Definition: constraint_solver/table.cc:43
operations_research::glop::UnconstrainedVariablePreprocessor::Run
bool Run(LinearProgram *lp) final
Definition: preprocessor.cc:1761
operations_research::glop::ToMinimizationPreprocessor::~ToMinimizationPreprocessor
~ToMinimizationPreprocessor() final
Definition: preprocessor.h:1009
operations_research::glop::ColumnDeletionHelper::ColumnDeletionHelper
ColumnDeletionHelper()
Definition: preprocessor.h:139
operations_research::glop::Preprocessor::in_mip_context_
bool in_mip_context_
Definition: preprocessor.h:92
operations_research::glop::SingletonColumnSignPreprocessor::~SingletonColumnSignPreprocessor
~SingletonColumnSignPreprocessor() final
Definition: preprocessor.h:790
operations_research::glop::RemoveNearZeroEntriesPreprocessor::RemoveNearZeroEntriesPreprocessor
RemoveNearZeroEntriesPreprocessor(const GlopParameters *parameters)
Definition: preprocessor.h:762
operations_research::glop::SingletonUndo
Definition: preprocessor.h:339
operations_research::glop::ProportionalColumnPreprocessor::UseInMipContext
void UseInMipContext() final
Definition: preprocessor.h:267
operations_research::glop::FixConstraintWithFixedStatuses
void FixConstraintWithFixedStatuses(const DenseColumn &row_lower_bounds, const DenseColumn &row_upper_bounds, ProblemSolution *solution)
Definition: preprocessor.cc:3195
operations_research::glop::ShiftVariableBoundsPreprocessor::ShiftVariableBoundsPreprocessor
ShiftVariableBoundsPreprocessor(const ShiftVariableBoundsPreprocessor &)=delete
operations_research::glop::SingletonUndo::SINGLETON_COLUMN_IN_EQUALITY
@ SINGLETON_COLUMN_IN_EQUALITY
Definition: preprocessor.h:345
operations_research::glop::VariableStatus
VariableStatus
Definition: lp_types.h:196
operations_research::glop::MainLpPreprocessor::RecoverSolution
void RecoverSolution(ProblemSolution *solution) const override
Definition: preprocessor.cc:173
operations_research::glop::Preprocessor::time_limit_
TimeLimit * time_limit_
Definition: preprocessor.h:94
operations_research::glop::DoubletonEqualityRowPreprocessor::RestoreInfo::ColChoiceAndStatus::col_choice
ColChoice col_choice
Definition: preprocessor.h:850
lp_types.h
operations_research::IsSmallerWithinTolerance
bool IsSmallerWithinTolerance(FloatType x, FloatType y, FloatType tolerance)
Definition: fp_utils.h:153
operations_research::glop::DoubletonFreeColumnPreprocessor::DoubletonFreeColumnPreprocessor
DoubletonFreeColumnPreprocessor(const DoubletonFreeColumnPreprocessor &)=delete
operations_research::glop::SingletonColumnSignPreprocessor::SingletonColumnSignPreprocessor
SingletonColumnSignPreprocessor(const GlopParameters *parameters)
Definition: preprocessor.h:784
operations_research::glop::DualizerPreprocessor::ChangeStatusToDualStatus
ProblemStatus ChangeStatusToDualStatus(ProblemStatus status) const
Definition: preprocessor.cc:3457
absl::StrongVector::empty
bool empty() const
Definition: strong_vector.h:156
operations_research::glop::AddSlackVariablesPreprocessor::operator=
AddSlackVariablesPreprocessor & operator=(const AddSlackVariablesPreprocessor &)=delete
operations_research::glop::RowDeletionHelper::UnmarkRow
void UnmarkRow(RowIndex row)
Definition: preprocessor.cc:248
operations_research::glop::DoubletonEqualityRowPreprocessor::RecoverSolution
void RecoverSolution(ProblemSolution *solution) const final
Definition: preprocessor.cc:3115
operations_research::glop::ColumnDeletionHelper::RestoreDeletedColumns
void RestoreDeletedColumns(ProblemSolution *solution) const
Definition: preprocessor.cc:207
operations_research::glop::MainLpPreprocessor::MainLpPreprocessor
MainLpPreprocessor(const GlopParameters *parameters)
Definition: preprocessor.h:104
operations_research::glop::ImpliedFreePreprocessor::RecoverSolution
void RecoverSolution(ProblemSolution *solution) const final
Definition: preprocessor.cc:1506
operations_research::glop::EmptyColumnPreprocessor::operator=
EmptyColumnPreprocessor & operator=(const EmptyColumnPreprocessor &)=delete
operations_research::glop::SingletonPreprocessor
Definition: preprocessor.h:396
operations_research::glop::FreeConstraintPreprocessor::FreeConstraintPreprocessor
FreeConstraintPreprocessor(const GlopParameters *parameters)
Definition: preprocessor.h:718
parameters
SatParameters parameters
Definition: cp_model_fz_solver.cc:108
operations_research::glop::SingletonUndo::ZERO_COST_SINGLETON_COLUMN
@ ZERO_COST_SINGLETON_COLUMN
Definition: preprocessor.h:343
operations_research::glop::ShiftVariableBoundsPreprocessor::~ShiftVariableBoundsPreprocessor
~ShiftVariableBoundsPreprocessor() final
Definition: preprocessor.h:957
name
const std::string name
Definition: default_search.cc:808
parameters.pb.h
operations_research::glop::SingletonPreprocessor::RecoverSolution
void RecoverSolution(ProblemSolution *solution) const final
Definition: preprocessor.cc:2760
operations_research::glop::Preprocessor::infinite_time_limit_
std::unique_ptr< TimeLimit > infinite_time_limit_
Definition: preprocessor.h:93
operations_research::glop::ForcingAndImpliedFreeConstraintPreprocessor::ForcingAndImpliedFreeConstraintPreprocessor
ForcingAndImpliedFreeConstraintPreprocessor(const GlopParameters *parameters)
Definition: preprocessor.h:521
operations_research::glop::RemoveNearZeroEntriesPreprocessor::RecoverSolution
void RecoverSolution(ProblemSolution *solution) const final
Definition: preprocessor.cc:2880
operations_research::glop::EmptyConstraintPreprocessor::RecoverSolution
void RecoverSolution(ProblemSolution *solution) const final
Definition: preprocessor.cc:2120
operations_research::glop::ProportionalColumnPreprocessor::operator=
ProportionalColumnPreprocessor & operator=(const ProportionalColumnPreprocessor &)=delete