OR-Tools  8.0
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  // A singleton column with a cost of zero can always be removed by changing
425  // the corresponding constraint bounds to take into acount the bound of this
426  // singleton column.
427  void DeleteZeroCostSingletonColumn(const SparseMatrix& matrix_transpose,
428  MatrixEntry e, LinearProgram* lp);
429 
430  // Returns true if the constraint associated to the given singleton column was
431  // an equality or could be made one:
432  // If a singleton variable is free in a direction that improves the cost, then
433  // we can always move it as much as possible in this direction. Only the
434  // constraint will stop us, making it an equality. If the constraint doesn't
435  // stop us, then the program is unbounded (provided that there is a feasible
436  // solution).
437  //
438  // Note that this operation does not need any "undo" during the post-solve. At
439  // optimality, the dual value on the constraint row will be of the correct
440  // sign, and relaxing the constraint bound will not impact the dual
441  // feasibility of the solution.
442  //
443  // TODO(user): this operation can be generalized to columns with just one
444  // blocking constraint. Investigate how to use this. The 'reverse' can
445  // probably also be done, relaxing a constraint that is blocking a
446  // unconstrained variable.
447  bool MakeConstraintAnEqualityIfPossible(const SparseMatrix& matrix_transpose,
448  MatrixEntry e, LinearProgram* lp);
449 
450  // If a singleton column appears in an equality, we can remove its cost by
451  // changing the other variables cost using the constraint. We can then delete
452  // the column like in DeleteZeroCostSingletonColumn().
453  void DeleteSingletonColumnInEquality(const SparseMatrix& matrix_transpose,
454  MatrixEntry e, LinearProgram* lp);
455 
456  ColumnDeletionHelper column_deletion_helper_;
457  RowDeletionHelper row_deletion_helper_;
458  std::vector<SingletonUndo> undo_stack_;
459 
460  // This is used as a "cache" by MakeConstraintAnEqualityIfPossible() to avoid
461  // scanning more than once each row. See the code to see how this is used.
462  gtl::ITIVector<RowIndex, bool> row_sum_is_cached_;
465 
466  // The columns that are deleted by this preprocessor.
467  SparseMatrix deleted_columns_;
468  // The transpose of the rows that are deleted by this preprocessor.
469  // TODO(user): implement a RowMajorSparseMatrix class to simplify the code.
470  SparseMatrix deleted_rows_;
471 };
472 
473 // --------------------------------------------------------
474 // FixedVariablePreprocessor
475 // --------------------------------------------------------
476 // Removes the fixed variables from the problem.
478  public:
479  explicit FixedVariablePreprocessor(const GlopParameters* parameters)
483  delete;
485  bool Run(LinearProgram* lp) final;
486  void RecoverSolution(ProblemSolution* solution) const final;
487 
488  private:
489  ColumnDeletionHelper column_deletion_helper_;
490 };
491 
492 // --------------------------------------------------------
493 // ForcingAndImpliedFreeConstraintPreprocessor
494 // --------------------------------------------------------
495 // This preprocessor computes for each constraint row the bounds that are
496 // implied by the variable bounds and applies one of the following reductions:
497 //
498 // * If the intersection of the implied bounds and the current constraint bounds
499 // is empty (modulo some tolerance), the problem is INFEASIBLE.
500 //
501 // * If the intersection of the implied bounds and the current constraint bounds
502 // is a singleton (modulo some tolerance), then the constraint is said to be
503 // forcing and all the variables that appear in it can be fixed to one of their
504 // bounds. All these columns and the constraint row is removed.
505 //
506 // * If the implied bounds are included inside the current constraint bounds
507 // (modulo some tolerance) then the constraint is said to be redundant or
508 // implied free. Its bounds are relaxed and the constraint will be removed
509 // later by the FreeConstraintPreprocessor.
510 //
511 // * Otherwise, wo do nothing.
513  public:
515  const GlopParameters* parameters)
522  bool Run(LinearProgram* lp) final;
523  void RecoverSolution(ProblemSolution* solution) const final;
524 
525  private:
526  bool lp_is_maximization_problem_;
527  SparseMatrix deleted_columns_;
528  DenseRow costs_;
529  DenseBooleanColumn is_forcing_up_;
530  ColumnDeletionHelper column_deletion_helper_;
531  RowDeletionHelper row_deletion_helper_;
532 };
533 
534 // --------------------------------------------------------
535 // ImpliedFreePreprocessor
536 // --------------------------------------------------------
537 // It is possible to compute "implied" bounds on a variable from the bounds of
538 // all the other variables and the constraints in which this variable take
539 // place. If such "implied" bounds are inside the variable bounds, then the
540 // variable bounds can be relaxed and the variable is said to be "implied free".
541 //
542 // This preprocessor detects the implied free variables and make as many as
543 // possible free with a priority towards low-degree columns. This transformation
544 // will make the simplex algorithm more efficient later, but will also make it
545 // possible to reduce the problem by applying subsequent transformations:
546 //
547 // * The SingletonPreprocessor already deals with implied free singleton
548 // variables and removes the columns and the rows in which they appear.
549 //
550 // * Any multiple of the column of a free variable can be added to any other
551 // column without changing the linear program solution. This is the dual
552 // counterpart of the fact that any multiple of an equality row can be added to
553 // any row.
554 //
555 // TODO(user): Only process doubleton columns so we have more chance in the
556 // later passes to create more doubleton columns? Such columns lead to a smaller
557 // problem thanks to the DoubletonFreeColumnPreprocessor.
559  public:
560  explicit ImpliedFreePreprocessor(const GlopParameters* parameters)
565  bool Run(LinearProgram* lp) final;
566  void RecoverSolution(ProblemSolution* solution) const final;
567 
568  private:
569  // This preprocessor adds fixed offsets to some variables. We remember those
570  // here to un-offset them in RecoverSolution().
571  DenseRow variable_offsets_;
572 
573  // This preprocessor causes some variables who would normally be
574  // AT_{LOWER,UPPER}_BOUND to be VariableStatus::FREE. We store the restore
575  // value of these variables; which will only be used (eg. restored) if the
576  // variable actually turns out to be VariableStatus::FREE.
577  VariableStatusRow postsolve_status_of_free_variables_;
578 };
579 
580 // --------------------------------------------------------
581 // DoubletonFreeColumnPreprocessor
582 // --------------------------------------------------------
583 // This preprocessor removes one of the two rows in which a doubleton column of
584 // a free variable appears. Since we can add any multiple of such a column to
585 // any other column, the way this works is that we can always remove all the
586 // entries on one row.
587 //
588 // Actually, we can remove all the entries except the one of the free column.
589 // But we will be left with a singleton row that we can delete in the same way
590 // as what is done in SingletonPreprocessor. That is by reporting the constraint
591 // bounds into the one of the originally free variable. After this operation,
592 // the doubleton free column will become a singleton and may or may not be
593 // removed later by the SingletonPreprocessor.
594 //
595 // Note that this preprocessor can be seen as the dual of the
596 // DoubletonEqualityRowPreprocessor since when taking the dual, an equality row
597 // becomes a free variable and vice versa.
598 //
599 // Note(user): As far as I know, this doubleton free column procedure is more
600 // general than what can be found in the research papers or in any of the linear
601 // solver open source codes as of July 2013. All of them only process such
602 // columns if one of the two rows is also an equality which is not actually
603 // required. Most probably, commercial solvers do use it though.
605  public:
606  explicit DoubletonFreeColumnPreprocessor(const GlopParameters* parameters)
609  delete;
611  const DoubletonFreeColumnPreprocessor&) = delete;
613  bool Run(LinearProgram* lp) final;
614  void RecoverSolution(ProblemSolution* solution) const final;
615 
616  private:
617  enum RowChoice {
618  DELETED = 0,
619  MODIFIED = 1,
620  // This is just a constant for the number of rows in a doubleton column.
621  // That is 2, one will be DELETED, the other MODIFIED.
622  NUM_ROWS = 2,
623  };
624  struct RestoreInfo {
625  // The index of the original free doubleton column and its objective.
626  ColIndex col;
627  Fractional objective_coefficient;
628 
629  // The row indices of the two involved rows and their coefficients on
630  // column col.
631  RowIndex row[NUM_ROWS];
632  Fractional coeff[NUM_ROWS];
633 
634  // The deleted row as a column.
635  SparseColumn deleted_row_as_column;
636  };
637 
638  std::vector<RestoreInfo> restore_stack_;
639  RowDeletionHelper row_deletion_helper_;
640 };
641 
642 // --------------------------------------------------------
643 // UnconstrainedVariablePreprocessor
644 // --------------------------------------------------------
645 // If for a given variable, none of the constraints block it in one direction
646 // and this direction improves the objective, then this variable can be fixed to
647 // its bound in this direction. If this bound is infinite and the variable cost
648 // is non-zero, then the problem is unbounded.
649 //
650 // More generally, by using the constraints and the variables that are unbounded
651 // on one side, one can derive bounds on the dual values. These can be
652 // translated into bounds on the reduced costs or the columns, which may force
653 // variables to their bounds. This is called forcing and dominated columns in
654 // the Andersen & Andersen paper.
656  public:
657  explicit UnconstrainedVariablePreprocessor(const GlopParameters* parameters)
660  delete;
662  const UnconstrainedVariablePreprocessor&) = delete;
664  bool Run(LinearProgram* lp) final;
665  void RecoverSolution(ProblemSolution* solution) const final;
666 
667  // Removes the given variable and all the rows in which it appears: If a
668  // variable is unconstrained with a zero cost, then all the constraints in
669  // which it appears can be made free! More precisely, during postsolve, if
670  // such a variable is unconstrained towards +kInfinity, for any activity value
671  // of the involved constraints, an M exists such that for each value of the
672  // variable >= M the problem will be feasible.
673  //
674  // The algorithm during postsolve is to find a feasible value for all such
675  // variables while trying to keep their magnitudes small (for better numerical
676  // behavior). target_bound should take only two possible values: +/-kInfinity.
679  LinearProgram* lp);
680 
681  private:
682  // Lower/upper bounds on the feasible dual value. We use constraints and
683  // variables unbounded in one direction to derive these bounds. We use these
684  // bounds to compute bounds on the reduced costs of the problem variables.
685  // Note that any finite bounds on a reduced cost means that the variable
686  // (ignoring its domain) can move freely in one direction.
687  DenseColumn dual_lb_;
688  DenseColumn dual_ub_;
689 
690  // Indicates if a given column may have participated in the current lb/ub
691  // on the reduced cost of the same column.
692  DenseBooleanRow may_have_participated_ub_;
693  DenseBooleanRow may_have_participated_lb_;
694 
695  ColumnDeletionHelper column_deletion_helper_;
696  RowDeletionHelper row_deletion_helper_;
697  DenseColumn rhs_;
698  DenseColumn activity_sign_correction_;
699  DenseBooleanRow is_unbounded_;
700 
701  SparseMatrix deleted_columns_;
702  SparseMatrix deleted_rows_as_column_;
703 };
704 
705 // --------------------------------------------------------
706 // FreeConstraintPreprocessor
707 // --------------------------------------------------------
708 // Removes the constraints with no bounds from the problem.
710  public:
711  explicit FreeConstraintPreprocessor(const GlopParameters* parameters)
715  delete;
717  bool Run(LinearProgram* lp) final;
718  void RecoverSolution(ProblemSolution* solution) const final;
719 
720  private:
721  RowDeletionHelper row_deletion_helper_;
722 };
723 
724 // --------------------------------------------------------
725 // EmptyConstraintPreprocessor
726 // --------------------------------------------------------
727 // Removes the constraints with no coefficients from the problem.
729  public:
730  explicit EmptyConstraintPreprocessor(const GlopParameters* parameters)
734  delete;
736  bool Run(LinearProgram* lp) final;
737  void RecoverSolution(ProblemSolution* solution) const final;
738 
739  private:
740  RowDeletionHelper row_deletion_helper_;
741 };
742 
743 // --------------------------------------------------------
744 // RemoveNearZeroEntriesPreprocessor
745 // --------------------------------------------------------
746 // Removes matrix entries that have only a negligible impact on the solution.
747 // Using the variable bounds, we derive a maximum possible impact, and remove
748 // the entries whose impact is under a given tolerance.
749 //
750 // TODO(user): This preprocessor doesn't work well on badly scaled problems. In
751 // particular, it will set the objective to zero if all the objective
752 // coefficients are small! Run it after ScalingPreprocessor or fix the code.
754  public:
755  explicit RemoveNearZeroEntriesPreprocessor(const GlopParameters* parameters)
758  delete;
760  const RemoveNearZeroEntriesPreprocessor&) = delete;
762  bool Run(LinearProgram* lp) final;
763  void RecoverSolution(ProblemSolution* solution) const final;
764 
765  private:
766 };
767 
768 // --------------------------------------------------------
769 // SingletonColumnSignPreprocessor
770 // --------------------------------------------------------
771 // Make sure that the only coefficient of all singleton columns (i.e. column
772 // with only one entry) is positive. This is because this way the column will
773 // be transformed in an identity column by the scaling. This will lead to more
774 // efficient solve when this column is involved.
776  public:
777  explicit SingletonColumnSignPreprocessor(const GlopParameters* parameters)
780  delete;
782  const SingletonColumnSignPreprocessor&) = delete;
784  bool Run(LinearProgram* lp) final;
785  void RecoverSolution(ProblemSolution* solution) const final;
786 
787  private:
788  std::vector<ColIndex> changed_columns_;
789 };
790 
791 // --------------------------------------------------------
792 // DoubletonEqualityRowPreprocessor
793 // --------------------------------------------------------
794 // Reduce equality constraints involving two variables (i.e. aX + bY = c),
795 // by substitution (and thus removal) of one of the variables by the other
796 // in all the constraints that it is involved in.
798  public:
799  explicit DoubletonEqualityRowPreprocessor(const GlopParameters* parameters)
802  delete;
804  const DoubletonEqualityRowPreprocessor&) = delete;
806  bool Run(LinearProgram* lp) final;
807  void RecoverSolution(ProblemSolution* solution) const final;
808 
809  private:
810  enum ColChoice {
811  DELETED = 0,
812  MODIFIED = 1,
813  // For for() loops iterating over the ColChoice values, and/or arrays.
814  NUM_DOUBLETON_COLS = 2,
815  };
816  static ColChoice OtherColChoice(ColChoice x) {
817  return x == DELETED ? MODIFIED : DELETED;
818  }
819 
820  ColumnDeletionHelper column_deletion_helper_;
821  RowDeletionHelper row_deletion_helper_;
822 
823  struct RestoreInfo {
824  // The row index of the doubleton equality constraint, and its constant.
825  RowIndex row;
826  Fractional rhs; // The constant c in the equality aX + bY = c.
827 
828  // The indices and the data of the two columns that we touched, exactly
829  // as they were beforehand.
830  ColIndex col[NUM_DOUBLETON_COLS];
831  Fractional coeff[NUM_DOUBLETON_COLS];
832  Fractional lb[NUM_DOUBLETON_COLS];
833  Fractional ub[NUM_DOUBLETON_COLS];
834  SparseColumn column[NUM_DOUBLETON_COLS];
835  Fractional objective_coefficient[NUM_DOUBLETON_COLS];
836 
837  // If the modified variable has status AT_[LOWER,UPPER]_BOUND, then we'll
838  // set one of the two original variables to one of its bounds, and set the
839  // other to VariableStatus::BASIC. We store this information (which variable
840  // will be set to one of its bounds, and which bound) for each possible
841  // outcome.
843  ColChoice col_choice;
848  : col_choice(c), status(s), value(v) {}
849  };
850  ColChoiceAndStatus bound_backtracking_at_lower_bound;
851  ColChoiceAndStatus bound_backtracking_at_upper_bound;
852  };
853  void SwapDeletedAndModifiedVariableRestoreInfo(RestoreInfo* r);
854 
855  std::vector<RestoreInfo> restore_stack_;
856  DenseColumn saved_row_lower_bounds_;
857  DenseColumn saved_row_upper_bounds_;
858 };
859 
860 // Because of numerical imprecision, a preprocessor like
861 // DoubletonEqualityRowPreprocessor can transform a constraint/variable domain
862 // like [1, 1+1e-7] to a fixed domain (for ex by multiplying the above domain by
863 // 1e9). This causes an issue because at postsolve, a FIXED_VALUE status now
864 // needs to be transformed to a AT_LOWER_BOUND/AT_UPPER_BOUND status. This is
865 // what this function is doing for the constraint statuses only.
866 //
867 // TODO(user): A better solution would simply be to get rid of the FIXED status
868 // altogether, it is better to simply use AT_LOWER_BOUND/AT_UPPER_BOUND
869 // depending on the constraining bound in the optimal solution. Note that we can
870 // always at the end transform any variable/constraint with a fixed domain to
871 // FIXED_VALUE if needed to keep the same external API.
872 void FixConstraintWithFixedStatuses(const DenseColumn& row_lower_bounds,
873  const DenseColumn& row_upper_bounds,
874  ProblemSolution* solution);
875 
876 // --------------------------------------------------------
877 // DualizerPreprocessor
878 // --------------------------------------------------------
879 // DualizerPreprocessor may change the given program to its dual depending
880 // on the value of the parameter solve_dual_problem.
881 //
882 // IMPORTANT: FreeConstraintPreprocessor() must be called first since this
883 // preprocessor does not deal correctly with free constraints.
885  public:
886  explicit DualizerPreprocessor(const GlopParameters* parameters)
891  bool Run(LinearProgram* lp) final;
892  void RecoverSolution(ProblemSolution* solution) const final;
893  void UseInMipContext() final {
894  LOG(FATAL) << "In the presence of integer variables, "
895  << "there is no notion of a dual problem.";
896  }
897 
898  // Convert the given problem status to the one of its dual.
900 
901  private:
902  DenseRow variable_lower_bounds_;
903  DenseRow variable_upper_bounds_;
904 
905  RowIndex primal_num_rows_;
906  ColIndex primal_num_cols_;
907  bool primal_is_maximization_problem_;
908  RowToColMapping duplicated_rows_;
909 
910  // For postsolving the variable/constraint statuses.
911  VariableStatusRow dual_status_correspondence_;
912  ColMapping slack_or_surplus_mapping_;
913 };
914 
915 // --------------------------------------------------------
916 // ShiftVariableBoundsPreprocessor
917 // --------------------------------------------------------
918 // For each variable, inspects its bounds and "shift" them if necessary, so that
919 // its domain contains zero. A variable that was shifted will always have at
920 // least one of its bounds to zero. Doing it all at once allows to have a better
921 // precision when modifying the constraint bounds by using an accurate summation
922 // algorithm.
923 //
924 // Example:
925 // - A variable with bound [1e10, infinity] will be shifted to [0, infinity].
926 // - A variable with domain [-1e10, 1e10] will not be shifted. Note that
927 // compared to the first case, doing so here may introduce unecessary
928 // numerical errors if the variable value in the final solution is close to
929 // zero.
930 //
931 // The expected impact of this is:
932 // - Better behavior of the scaling.
933 // - Better precision and numerical accuracy of the simplex method.
934 // - Slightly improved speed (because adding a column with a variable value of
935 // zero takes no work later).
936 //
937 // TODO(user): Having for each variable one of their bounds at zero is a
938 // requirement for the DualizerPreprocessor and for the implied free column in
939 // the ImpliedFreePreprocessor. However, shifting a variable with a domain like
940 // [-1e10, 1e10] may introduce numerical issues. Relax the definition of
941 // a free variable so that only having a domain containing 0.0 is enough?
943  public:
944  explicit ShiftVariableBoundsPreprocessor(const GlopParameters* parameters)
947  delete;
949  const ShiftVariableBoundsPreprocessor&) = delete;
951  bool Run(LinearProgram* lp) final;
952  void RecoverSolution(ProblemSolution* solution) const final;
953 
954  const DenseRow& offsets() const { return offsets_; }
955 
956  private:
957  // Contains for each variable by how much its bounds where shifted during
958  // presolve. Note that the shift was negative (new bound = initial bound -
959  // offset).
960  DenseRow offsets_;
961  // Contains the initial problem bounds. They are needed to get the perfect
962  // numerical accuracy for variables at their bound after postsolve.
963  DenseRow variable_initial_lbs_;
964  DenseRow variable_initial_ubs_;
965 };
966 
967 // --------------------------------------------------------
968 // ScalingPreprocessor
969 // --------------------------------------------------------
970 // Scales the SparseMatrix of the linear program using a SparseMatrixScaler.
971 // This is only applied if the parameter use_scaling is true.
973  public:
974  explicit ScalingPreprocessor(const GlopParameters* parameters)
979  bool Run(LinearProgram* lp) final;
980  void RecoverSolution(ProblemSolution* solution) const final;
981  void UseInMipContext() final { LOG(FATAL) << "Not implemented."; }
982 
983  private:
984  DenseRow variable_lower_bounds_;
985  DenseRow variable_upper_bounds_;
986  Fractional cost_scaling_factor_;
987  Fractional bound_scaling_factor_;
988  SparseMatrixScaler scaler_;
989 };
990 
991 // --------------------------------------------------------
992 // ToMinimizationPreprocessor
993 // --------------------------------------------------------
994 // Changes the problem from maximization to minimization (if applicable).
996  public:
997  explicit ToMinimizationPreprocessor(const GlopParameters* parameters)
1001  delete;
1003  bool Run(LinearProgram* lp) final;
1004  void RecoverSolution(ProblemSolution* solution) const final;
1005 };
1006 
1007 // --------------------------------------------------------
1008 // AddSlackVariablesPreprocessor
1009 // --------------------------------------------------------
1010 // Transforms the linear program to the equation form
1011 // min c.x, s.t. A.x = 0. This is done by:
1012 // 1. Introducing slack variables for all constraints; all these variables are
1013 // introduced with coefficient 1.0, and their bounds are set to be negative
1014 // bounds of the corresponding constraint.
1015 // 2. Changing the bounds of all constraints to (0, 0) to make them an equality.
1016 //
1017 // As a consequence, the matrix of the linear program always has full row rank
1018 // after this preprocessor. Note that the slack variables are always added last,
1019 // so that the rightmost square sub-matrix is always the identity matrix.
1021  public:
1022  explicit AddSlackVariablesPreprocessor(const GlopParameters* parameters)
1023  : Preprocessor(parameters) {}
1026  const AddSlackVariablesPreprocessor&) = delete;
1028  bool Run(LinearProgram* lp) final;
1029  void RecoverSolution(ProblemSolution* solution) const final;
1030 
1031  private:
1032  ColIndex first_slack_col_;
1033 };
1034 
1035 } // namespace glop
1036 } // namespace operations_research
1037 
1038 #endif // OR_TOOLS_GLOP_PREPROCESSOR_H_
operations_research::glop::RowDeletionHelper::operator=
RowDeletionHelper & operator=(const RowDeletionHelper &)=delete
operations_research::glop::DoubletonEqualityRowPreprocessor::RestoreInfo::ColChoiceAndStatus::ColChoiceAndStatus
ColChoiceAndStatus()
Definition: preprocessor.h:846
operations_research::glop::ToMinimizationPreprocessor
Definition: preprocessor.h:995
operations_research::glop::ImpliedFreePreprocessor::ImpliedFreePreprocessor
ImpliedFreePreprocessor(const ImpliedFreePreprocessor &)=delete
operations_research::glop::RowDeletionHelper::UnmarkRow
void UnmarkRow(RowIndex row)
Definition: preprocessor.cc:248
operations_research::glop::ToMinimizationPreprocessor::ToMinimizationPreprocessor
ToMinimizationPreprocessor(const ToMinimizationPreprocessor &)=delete
operations_research::glop::SingletonUndo::ZERO_COST_SINGLETON_COLUMN
@ ZERO_COST_SINGLETON_COLUMN
Definition: preprocessor.h:343
operations_research::glop::DoubletonFreeColumnPreprocessor::DoubletonFreeColumnPreprocessor
DoubletonFreeColumnPreprocessor(const DoubletonFreeColumnPreprocessor &)=delete
operations_research::glop::RemoveNearZeroEntriesPreprocessor::RemoveNearZeroEntriesPreprocessor
RemoveNearZeroEntriesPreprocessor(const RemoveNearZeroEntriesPreprocessor &)=delete
operations_research::glop::UnconstrainedVariablePreprocessor
Definition: preprocessor.h:655
operations_research::glop::ColumnDeletionHelper::RestoreDeletedColumns
void RestoreDeletedColumns(ProblemSolution *solution) const
Definition: preprocessor.cc:207
operations_research::glop::ProportionalColumnPreprocessor
Definition: preprocessor.h:256
operations_research::glop::DoubletonEqualityRowPreprocessor::Run
bool Run(LinearProgram *lp) final
Definition: preprocessor.cc:2887
operations_research::glop::SingletonPreprocessor
Definition: preprocessor.h:396
operations_research::glop::DualizerPreprocessor::RecoverSolution
void RecoverSolution(ProblemSolution *solution) const final
Definition: preprocessor.cc:3300
operations_research::glop::FixedVariablePreprocessor::Run
bool Run(LinearProgram *lp) final
Definition: preprocessor.cc:1033
operations_research::glop::ShiftVariableBoundsPreprocessor::Run
bool Run(LinearProgram *lp) final
Definition: preprocessor.cc:3433
operations_research::glop::EmptyColumnPreprocessor::EmptyColumnPreprocessor
EmptyColumnPreprocessor(const EmptyColumnPreprocessor &)=delete
operations_research::glop::Preprocessor::Run
virtual bool Run(LinearProgram *lp)=0
operations_research::glop::FreeConstraintPreprocessor::RecoverSolution
void RecoverSolution(ProblemSolution *solution) const final
Definition: preprocessor.cc:2070
operations_research::glop::EmptyConstraintPreprocessor::EmptyConstraintPreprocessor
EmptyConstraintPreprocessor(const GlopParameters *parameters)
Definition: preprocessor.h:730
operations_research::glop::Preprocessor::infinite_time_limit_
std::unique_ptr< TimeLimit > infinite_time_limit_
Definition: preprocessor.h:93
operations_research::glop::DoubletonFreeColumnPreprocessor::operator=
DoubletonFreeColumnPreprocessor & operator=(const DoubletonFreeColumnPreprocessor &)=delete
operations_research::glop::FixedVariablePreprocessor::~FixedVariablePreprocessor
~FixedVariablePreprocessor() final
Definition: preprocessor.h:484
operations_research::glop::DualizerPreprocessor::DualizerPreprocessor
DualizerPreprocessor(const GlopParameters *parameters)
Definition: preprocessor.h:886
operations_research::glop::SingletonUndo::SINGLETON_COLUMN_IN_EQUALITY
@ SINGLETON_COLUMN_IN_EQUALITY
Definition: preprocessor.h:345
operations_research::glop::AddSlackVariablesPreprocessor::operator=
AddSlackVariablesPreprocessor & operator=(const AddSlackVariablesPreprocessor &)=delete
operations_research::glop::StrictITIVector< ColIndex, bool >
operations_research::glop::ColumnDeletionHelper::GetStoredValue
const DenseRow & GetStoredValue() const
Definition: preprocessor.h:176
operations_research::glop::MainLpPreprocessor::~MainLpPreprocessor
~MainLpPreprocessor() override
Definition: preprocessor.h:108
lp_data.h
operations_research::glop::ProportionalColumnPreprocessor::RecoverSolution
void RecoverSolution(ProblemSolution *solution) const final
Definition: preprocessor.cc:669
operations_research::glop::ImpliedFreePreprocessor::RecoverSolution
void RecoverSolution(ProblemSolution *solution) const final
Definition: preprocessor.cc:1504
operations_research::glop::ProportionalColumnPreprocessor::ProportionalColumnPreprocessor
ProportionalColumnPreprocessor(const ProportionalColumnPreprocessor &)=delete
operations_research::glop::EmptyColumnPreprocessor::Run
bool Run(LinearProgram *lp) final
Definition: preprocessor.cc:342
operations_research::glop::ProportionalRowPreprocessor
Definition: preprocessor.h:297
operations_research::glop::SingletonColumnSignPreprocessor
Definition: preprocessor.h:775
operations_research::glop::Preprocessor::time_limit_
TimeLimit * time_limit_
Definition: preprocessor.h:94
operations_research::glop::ColumnDeletionHelper::ColumnDeletionHelper
ColumnDeletionHelper()
Definition: preprocessor.h:139
operations_research::glop::DoubletonEqualityRowPreprocessor::DoubletonEqualityRowPreprocessor
DoubletonEqualityRowPreprocessor(const DoubletonEqualityRowPreprocessor &)=delete
operations_research::glop::FreeConstraintPreprocessor::Run
bool Run(LinearProgram *lp) final
Definition: preprocessor.cc:2055
operations_research::glop::EmptyConstraintPreprocessor::operator=
EmptyConstraintPreprocessor & operator=(const EmptyConstraintPreprocessor &)=delete
operations_research::glop::ColumnDeletionHelper::MarkColumnForDeletion
void MarkColumnForDeletion(ColIndex col)
Definition: preprocessor.cc:190
operations_research::glop::SparseMatrix
Definition: sparse.h:61
operations_research::glop::DoubletonEqualityRowPreprocessor::RestoreInfo::ColChoiceAndStatus::col_choice
ColChoice col_choice
Definition: preprocessor.h:843
operations_research::glop::RowDeletionHelper::MarkRowForDeletion
void MarkRowForDeletion(RowIndex row)
Definition: preprocessor.cc:240
operations_research::glop::RemoveNearZeroEntriesPreprocessor::~RemoveNearZeroEntriesPreprocessor
~RemoveNearZeroEntriesPreprocessor() final
Definition: preprocessor.h:761
operations_research::glop::Preprocessor::IsSmallerWithinFeasibilityTolerance
bool IsSmallerWithinFeasibilityTolerance(Fractional a, Fractional b) const
Definition: preprocessor.h:79
operations_research::glop::SingletonPreprocessor::~SingletonPreprocessor
~SingletonPreprocessor() final
Definition: preprocessor.h:402
operations_research::glop::ImpliedFreePreprocessor::~ImpliedFreePreprocessor
~ImpliedFreePreprocessor() final
Definition: preprocessor.h:564
operations_research::glop::ProportionalRowPreprocessor::Run
bool Run(LinearProgram *lp) final
Definition: preprocessor.cc:784
value
int64 value
Definition: demon_profiler.cc:43
operations_research::glop::Preprocessor::parameters_
const GlopParameters & parameters_
Definition: preprocessor.h:91
operations_research::glop::ProblemSolution
Definition: lp_data.h:647
operations_research::glop::MainLpPreprocessor::operator=
MainLpPreprocessor & operator=(const MainLpPreprocessor &)=delete
operations_research::glop::ColumnDeletionHelper::IsColumnMarked
bool IsColumnMarked(ColIndex col) const
Definition: preprocessor.h:160
operations_research::glop::Preprocessor::SetTimeLimit
void SetTimeLimit(TimeLimit *time_limit)
Definition: preprocessor.h:74
operations_research::glop::ForcingAndImpliedFreeConstraintPreprocessor::ForcingAndImpliedFreeConstraintPreprocessor
ForcingAndImpliedFreeConstraintPreprocessor(const GlopParameters *parameters)
Definition: preprocessor.h:514
operations_research::glop::UnconstrainedVariablePreprocessor::~UnconstrainedVariablePreprocessor
~UnconstrainedVariablePreprocessor() final
Definition: preprocessor.h:663
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::SingletonColumnSignPreprocessor::SingletonColumnSignPreprocessor
SingletonColumnSignPreprocessor(const SingletonColumnSignPreprocessor &)=delete
operations_research::glop::EmptyColumnPreprocessor::operator=
EmptyColumnPreprocessor & operator=(const EmptyColumnPreprocessor &)=delete
operations_research::glop::ConstraintStatus
ConstraintStatus
Definition: lp_types.h:227
operations_research::glop::SingletonUndo::SINGLETON_ROW
@ SINGLETON_ROW
Definition: preprocessor.h:344
operations_research::glop::DoubletonFreeColumnPreprocessor::DoubletonFreeColumnPreprocessor
DoubletonFreeColumnPreprocessor(const GlopParameters *parameters)
Definition: preprocessor.h:606
operations_research::glop::Preprocessor::Preprocessor
Preprocessor(const Preprocessor &)=delete
operations_research::glop::ForcingAndImpliedFreeConstraintPreprocessor::~ForcingAndImpliedFreeConstraintPreprocessor
~ForcingAndImpliedFreeConstraintPreprocessor() final
Definition: preprocessor.h:521
operations_research::glop::EmptyColumnPreprocessor::~EmptyColumnPreprocessor
~EmptyColumnPreprocessor() final
Definition: preprocessor.h:238
operations_research::glop::LinearProgram
Definition: lp_data.h:55
operations_research::glop::DoubletonFreeColumnPreprocessor
Definition: preprocessor.h:604
operations_research::glop::RowDeletionHelper
Definition: preprocessor.h:193
operations_research::glop::Preprocessor::IsSmallerWithinPreprocessorZeroTolerance
bool IsSmallerWithinPreprocessorZeroTolerance(Fractional a, Fractional b) const
Definition: preprocessor.h:83
operations_research::glop::Preprocessor::UseInMipContext
virtual void UseInMipContext()
Definition: preprocessor.h:72
operations_research::glop::FreeConstraintPreprocessor
Definition: preprocessor.h:709
matrix_scaler.h
operations_research::glop::ScalingPreprocessor::operator=
ScalingPreprocessor & operator=(const ScalingPreprocessor &)=delete
operations_research::glop::RowDeletionHelper::RestoreDeletedRows
void RestoreDeletedRows(ProblemSolution *solution) const
Definition: preprocessor.cc:257
operations_research::glop::UnconstrainedVariablePreprocessor::Run
bool Run(LinearProgram *lp) final
Definition: preprocessor.cc:1759
gtl::ITIVector::empty
bool empty() const
Definition: int_type_indexed_vector.h:155
operations_research::glop::DoubletonEqualityRowPreprocessor::operator=
DoubletonEqualityRowPreprocessor & operator=(const DoubletonEqualityRowPreprocessor &)=delete
operations_research::glop::SingletonUndo::MAKE_CONSTRAINT_AN_EQUALITY
@ MAKE_CONSTRAINT_AN_EQUALITY
Definition: preprocessor.h:346
operations_research::glop::ColumnDeletionHelper::ColumnDeletionHelper
ColumnDeletionHelper(const ColumnDeletionHelper &)=delete
operations_research::glop::ToMinimizationPreprocessor::~ToMinimizationPreprocessor
~ToMinimizationPreprocessor() final
Definition: preprocessor.h:1002
operations_research::glop::ScalingPreprocessor::RecoverSolution
void RecoverSolution(ProblemSolution *solution) const final
Definition: preprocessor.cc:3556
operations_research::glop::RowDeletionHelper::GetMarkedRows
const DenseBooleanColumn & GetMarkedRows() const
Definition: preprocessor.cc:253
operations_research::glop::FreeConstraintPreprocessor::FreeConstraintPreprocessor
FreeConstraintPreprocessor(const FreeConstraintPreprocessor &)=delete
revised_simplex.h
operations_research::glop::ColumnDeletionHelper::Clear
void Clear()
Definition: preprocessor.cc:185
operations_research::glop::ProportionalColumnPreprocessor::operator=
ProportionalColumnPreprocessor & operator=(const ProportionalColumnPreprocessor &)=delete
operations_research::glop::Fractional
double Fractional
Definition: lp_types.h:77
operations_research::glop::MainLpPreprocessor::RecoverSolution
void RecoverSolution(ProblemSolution *solution) const override
Definition: preprocessor.cc:173
operations_research::glop::AddSlackVariablesPreprocessor::RecoverSolution
void RecoverSolution(ProblemSolution *solution) const final
Definition: preprocessor.cc:3629
operations_research::glop::ScalingPreprocessor::UseInMipContext
void UseInMipContext() final
Definition: preprocessor.h:981
operations_research::glop::ShiftVariableBoundsPreprocessor::ShiftVariableBoundsPreprocessor
ShiftVariableBoundsPreprocessor(const GlopParameters *parameters)
Definition: preprocessor.h:944
operations_research::glop::SingletonUndo
Definition: preprocessor.h:339
operations_research::glop::ShiftVariableBoundsPreprocessor::operator=
ShiftVariableBoundsPreprocessor & operator=(const ShiftVariableBoundsPreprocessor &)=delete
operations_research::glop::SingletonColumnSignPreprocessor::RecoverSolution
void RecoverSolution(ProblemSolution *solution) const final
Definition: preprocessor.cc:2867
a
int64 a
Definition: constraint_solver/table.cc:42
operations_research::glop::MainLpPreprocessor::Run
bool Run(LinearProgram *lp) final
Definition: preprocessor.cc:61
operations_research::glop::SingletonPreprocessor::operator=
SingletonPreprocessor & operator=(const SingletonPreprocessor &)=delete
operations_research::glop::ProportionalColumnPreprocessor::Run
bool Run(LinearProgram *lp) final
Definition: preprocessor.cc:440
operations_research::glop::EmptyConstraintPreprocessor::~EmptyConstraintPreprocessor
~EmptyConstraintPreprocessor() final
Definition: preprocessor.h:735
target_bound
Fractional target_bound
Definition: revised_simplex.cc:1795
operations_research::glop::RowDeletionHelper::IsEmpty
bool IsEmpty() const
Definition: preprocessor.h:200
operations_research::glop::SingletonColumnSignPreprocessor::Run
bool Run(LinearProgram *lp) final
Definition: preprocessor.cc:2839
operations_research::glop::Preprocessor::status
ProblemStatus status() const
Definition: preprocessor.h:64
time_limit
SharedTimeLimit * time_limit
Definition: cp_model_solver.cc:2025
operations_research::glop::UnconstrainedVariablePreprocessor::RemoveZeroCostUnconstrainedVariable
void RemoveZeroCostUnconstrainedVariable(ColIndex col, Fractional target_bound, LinearProgram *lp)
Definition: preprocessor.cc:1712
operations_research::glop::DoubletonFreeColumnPreprocessor::RecoverSolution
void RecoverSolution(ProblemSolution *solution) const final
Definition: preprocessor.cc:1634
operations_research::glop::ShiftVariableBoundsPreprocessor::~ShiftVariableBoundsPreprocessor
~ShiftVariableBoundsPreprocessor() final
Definition: preprocessor.h:950
operations_research::glop::ForcingAndImpliedFreeConstraintPreprocessor::ForcingAndImpliedFreeConstraintPreprocessor
ForcingAndImpliedFreeConstraintPreprocessor(const ForcingAndImpliedFreeConstraintPreprocessor &)=delete
operations_research::glop::Preprocessor::operator=
Preprocessor & operator=(const Preprocessor &)=delete
operations_research::glop::FixedVariablePreprocessor::RecoverSolution
void RecoverSolution(ProblemSolution *solution) const final
Definition: preprocessor.cc:1055
operations_research::glop::EmptyColumnPreprocessor::EmptyColumnPreprocessor
EmptyColumnPreprocessor(const GlopParameters *parameters)
Definition: preprocessor.h:234
operations_research::glop::ProportionalColumnPreprocessor::~ProportionalColumnPreprocessor
~ProportionalColumnPreprocessor() final
Definition: preprocessor.h:264
operations_research::glop::SingletonUndo::SingletonUndo
SingletonUndo(OperationType type, const LinearProgram &lp, MatrixEntry e, ConstraintStatus status)
Definition: preprocessor.cc:2129
operations_research::glop::MainLpPreprocessor::MainLpPreprocessor
MainLpPreprocessor(const GlopParameters *parameters)
Definition: preprocessor.h:104
operations_research::glop::EmptyConstraintPreprocessor::Run
bool Run(LinearProgram *lp) final
Definition: preprocessor.cc:2081
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::RemoveNearZeroEntriesPreprocessor::operator=
RemoveNearZeroEntriesPreprocessor & operator=(const RemoveNearZeroEntriesPreprocessor &)=delete
operations_research::glop::ForcingAndImpliedFreeConstraintPreprocessor
Definition: preprocessor.h:512
operations_research::glop::StrictITIVector::size
IntType size() const
Definition: lp_types.h:276
operations_research::glop::ToMinimizationPreprocessor::RecoverSolution
void RecoverSolution(ProblemSolution *solution) const final
Definition: preprocessor.cc:3613
operations_research::glop::SingletonPreprocessor::SingletonPreprocessor
SingletonPreprocessor(const GlopParameters *parameters)
Definition: preprocessor.h:398
operations_research::glop::ShiftVariableBoundsPreprocessor::ShiftVariableBoundsPreprocessor
ShiftVariableBoundsPreprocessor(const ShiftVariableBoundsPreprocessor &)=delete
operations_research::glop::MainLpPreprocessor
Definition: preprocessor.h:102
operations_research::glop::FreeConstraintPreprocessor::operator=
FreeConstraintPreprocessor & operator=(const FreeConstraintPreprocessor &)=delete
operations_research::glop::Preprocessor::~Preprocessor
virtual ~Preprocessor()
Definition: preprocessor.cc:51
operations_research::glop::DualizerPreprocessor::operator=
DualizerPreprocessor & operator=(const DualizerPreprocessor &)=delete
operations_research::glop::ImpliedFreePreprocessor
Definition: preprocessor.h:558
operations_research::glop::MatrixEntry::col
ColIndex col
Definition: preprocessor.h:334
operations_research::glop::FixedVariablePreprocessor::FixedVariablePreprocessor
FixedVariablePreprocessor(const FixedVariablePreprocessor &)=delete
operations_research::glop::ProportionalRowPreprocessor::operator=
ProportionalRowPreprocessor & operator=(const ProportionalRowPreprocessor &)=delete
operations_research::glop::ImpliedFreePreprocessor::Run
bool Run(LinearProgram *lp) final
Definition: preprocessor.cc:1317
operations_research::glop::ForcingAndImpliedFreeConstraintPreprocessor::Run
bool Run(LinearProgram *lp) final
Definition: preprocessor.cc:1066
operations_research::glop::UnconstrainedVariablePreprocessor::operator=
UnconstrainedVariablePreprocessor & operator=(const UnconstrainedVariablePreprocessor &)=delete
operations_research::glop::ScalingPreprocessor::Run
bool Run(LinearProgram *lp) final
Definition: preprocessor.cc:3533
operations_research::glop::RemoveNearZeroEntriesPreprocessor::RemoveNearZeroEntriesPreprocessor
RemoveNearZeroEntriesPreprocessor(const GlopParameters *parameters)
Definition: preprocessor.h:755
operations_research::glop::UnconstrainedVariablePreprocessor::UnconstrainedVariablePreprocessor
UnconstrainedVariablePreprocessor(const GlopParameters *parameters)
Definition: preprocessor.h:657
operations_research::glop::RowDeletionHelper::RowDeletionHelper
RowDeletionHelper()
Definition: preprocessor.h:195
operations_research::glop::ForcingAndImpliedFreeConstraintPreprocessor::operator=
ForcingAndImpliedFreeConstraintPreprocessor & operator=(const ForcingAndImpliedFreeConstraintPreprocessor &)=delete
operations_research::glop::ShiftVariableBoundsPreprocessor::RecoverSolution
void RecoverSolution(ProblemSolution *solution) const final
Definition: preprocessor.cc:3501
operations_research::glop::ToMinimizationPreprocessor::Run
bool Run(LinearProgram *lp) final
Definition: preprocessor.cc:3596
operations_research::glop::DoubletonEqualityRowPreprocessor::RecoverSolution
void RecoverSolution(ProblemSolution *solution) const final
Definition: preprocessor.cc:3067
operations_research::glop::DoubletonEqualityRowPreprocessor::RestoreInfo::ColChoiceAndStatus
Definition: preprocessor.h:842
operations_research::glop::ProportionalRowPreprocessor::~ProportionalRowPreprocessor
~ProportionalRowPreprocessor() final
Definition: preprocessor.h:304
operations_research::glop::RemoveNearZeroEntriesPreprocessor::RecoverSolution
void RecoverSolution(ProblemSolution *solution) const final
Definition: preprocessor.cc:2832
operations_research::glop::MatrixEntry::MatrixEntry
MatrixEntry(RowIndex _row, ColIndex _col, Fractional _coeff)
Definition: preprocessor.h:331
operations_research::glop::SingletonPreprocessor::SingletonPreprocessor
SingletonPreprocessor(const SingletonPreprocessor &)=delete
operations_research::glop::SingletonUndo::OperationType
OperationType
Definition: preprocessor.h:342
operations_research::glop::RowDeletionHelper::RowDeletionHelper
RowDeletionHelper(const RowDeletionHelper &)=delete
operations_research::glop::EmptyColumnPreprocessor::RecoverSolution
void RecoverSolution(ProblemSolution *solution) const final
Definition: preprocessor.cc:386
operations_research::glop::DoubletonFreeColumnPreprocessor::~DoubletonFreeColumnPreprocessor
~DoubletonFreeColumnPreprocessor() final
Definition: preprocessor.h:612
operations_research::glop::ColumnDeletionHelper::operator=
ColumnDeletionHelper & operator=(const ColumnDeletionHelper &)=delete
operations_research::glop::DualizerPreprocessor::Run
bool Run(LinearProgram *lp) final
Definition: preprocessor.cc:3184
operations_research::glop::ProportionalColumnPreprocessor::ProportionalColumnPreprocessor
ProportionalColumnPreprocessor(const GlopParameters *parameters)
Definition: preprocessor.h:258
operations_research::glop::Preprocessor::in_mip_context_
bool in_mip_context_
Definition: preprocessor.h:92
operations_research::glop::DoubletonEqualityRowPreprocessor::DoubletonEqualityRowPreprocessor
DoubletonEqualityRowPreprocessor(const GlopParameters *parameters)
Definition: preprocessor.h:799
operations_research::glop::DoubletonFreeColumnPreprocessor::Run
bool Run(LinearProgram *lp) final
Definition: preprocessor.cc:1528
operations_research::glop::UnconstrainedVariablePreprocessor::UnconstrainedVariablePreprocessor
UnconstrainedVariablePreprocessor(const UnconstrainedVariablePreprocessor &)=delete
operations_research::glop::RemoveNearZeroEntriesPreprocessor
Definition: preprocessor.h:753
operations_research::glop::ToMinimizationPreprocessor::operator=
ToMinimizationPreprocessor & operator=(const ToMinimizationPreprocessor &)=delete
operations_research::glop::SingletonUndo::Undo
void Undo(const GlopParameters &parameters, const SparseMatrix &deleted_columns, const SparseMatrix &deleted_rows, ProblemSolution *solution) const
Definition: preprocessor.cc:2141
operations_research::glop::ScalingPreprocessor
Definition: preprocessor.h:972
operations_research::glop::ScalingPreprocessor::ScalingPreprocessor
ScalingPreprocessor(const ScalingPreprocessor &)=delete
operations_research::glop::EmptyColumnPreprocessor
Definition: preprocessor.h:232
operations_research::glop::SingletonColumnSignPreprocessor::operator=
SingletonColumnSignPreprocessor & operator=(const SingletonColumnSignPreprocessor &)=delete
operations_research::glop::ProportionalRowPreprocessor::RecoverSolution
void RecoverSolution(ProblemSolution *solution) const final
Definition: preprocessor.cc:959
operations_research::glop::DoubletonEqualityRowPreprocessor::~DoubletonEqualityRowPreprocessor
~DoubletonEqualityRowPreprocessor() final
Definition: preprocessor.h:805
operations_research::glop::AddSlackVariablesPreprocessor::AddSlackVariablesPreprocessor
AddSlackVariablesPreprocessor(const GlopParameters *parameters)
Definition: preprocessor.h:1022
operations_research::glop::DoubletonEqualityRowPreprocessor::RestoreInfo::ColChoiceAndStatus::value
Fractional value
Definition: preprocessor.h:845
operations_research::glop::EmptyConstraintPreprocessor
Definition: preprocessor.h:728
operations_research::glop::ProportionalRowPreprocessor::ProportionalRowPreprocessor
ProportionalRowPreprocessor(const ProportionalRowPreprocessor &)=delete
operations_research::glop::AddSlackVariablesPreprocessor::~AddSlackVariablesPreprocessor
~AddSlackVariablesPreprocessor() final
Definition: preprocessor.h:1027
operations_research::glop::ImpliedFreePreprocessor::operator=
ImpliedFreePreprocessor & operator=(const ImpliedFreePreprocessor &)=delete
operations_research::glop::RowDeletionHelper::IsRowMarked
bool IsRowMarked(RowIndex row) const
Definition: preprocessor.h:215
col
ColIndex col
Definition: markowitz.cc:176
operations_research::glop::ColumnDeletionHelper::GetMarkedColumns
const DenseBooleanRow & GetMarkedColumns() const
Definition: preprocessor.h:165
operations_research::glop::ProblemStatus
ProblemStatus
Definition: lp_types.h:101
operations_research::glop::ProportionalColumnPreprocessor::UseInMipContext
void UseInMipContext() final
Definition: preprocessor.h:267
operations_research::glop::EmptyConstraintPreprocessor::RecoverSolution
void RecoverSolution(ProblemSolution *solution) const final
Definition: preprocessor.cc:2118
row
RowIndex row
Definition: markowitz.cc:175
operations_research::glop::AddSlackVariablesPreprocessor
Definition: preprocessor.h:1020
operations_research::glop::DenseColumn
StrictITIVector< RowIndex, Fractional > DenseColumn
Definition: lp_types.h:328
operations_research::glop::ColumnDeletionHelper::IsEmpty
bool IsEmpty() const
Definition: preprocessor.h:168
operations_research::glop::AddSlackVariablesPreprocessor::AddSlackVariablesPreprocessor
AddSlackVariablesPreprocessor(const AddSlackVariablesPreprocessor &)=delete
operations_research::glop::SingletonPreprocessor::Run
bool Run(LinearProgram *lp) final
Definition: preprocessor.cc:2639
operations_research::glop::FixedVariablePreprocessor::operator=
FixedVariablePreprocessor & operator=(const FixedVariablePreprocessor &)=delete
operations_research::glop::SingletonColumnSignPreprocessor::SingletonColumnSignPreprocessor
SingletonColumnSignPreprocessor(const GlopParameters *parameters)
Definition: preprocessor.h:777
operations_research::glop::RowDeletionHelper::Clear
void Clear()
Definition: preprocessor.cc:238
operations_research::glop::ForcingAndImpliedFreeConstraintPreprocessor::RecoverSolution
void RecoverSolution(ProblemSolution *solution) const final
Definition: preprocessor.cc:1232
operations_research::glop::SingletonColumnSignPreprocessor::~SingletonColumnSignPreprocessor
~SingletonColumnSignPreprocessor() final
Definition: preprocessor.h:783
operations_research::glop::UnconstrainedVariablePreprocessor::RecoverSolution
void RecoverSolution(ProblemSolution *solution) const final
Definition: preprocessor.cc:1987
operations_research::glop::ShiftVariableBoundsPreprocessor::offsets
const DenseRow & offsets() const
Definition: preprocessor.h:954
operations_research::glop::SparseMatrixScaler
Definition: matrix_scaler.h:79
operations_research::glop::DualizerPreprocessor::~DualizerPreprocessor
~DualizerPreprocessor() final
Definition: preprocessor.h:890
operations_research::glop::FixedVariablePreprocessor
Definition: preprocessor.h:477
b
int64 b
Definition: constraint_solver/table.cc:43
operations_research::glop::DualizerPreprocessor
Definition: preprocessor.h:884
operations_research::glop::ToMinimizationPreprocessor::ToMinimizationPreprocessor
ToMinimizationPreprocessor(const GlopParameters *parameters)
Definition: preprocessor.h:997
operations_research::glop::DualizerPreprocessor::UseInMipContext
void UseInMipContext() final
Definition: preprocessor.h:893
gtl::ITIVector< RowIndex, bool >
operations_research::glop::ShiftVariableBoundsPreprocessor
Definition: preprocessor.h:942
operations_research::glop::MatrixEntry::coeff
Fractional coeff
Definition: preprocessor.h:335
operations_research::glop::DoubletonEqualityRowPreprocessor
Definition: preprocessor.h:797
operations_research::glop::DualizerPreprocessor::DualizerPreprocessor
DualizerPreprocessor(const DualizerPreprocessor &)=delete
operations_research::glop::SingletonPreprocessor::RecoverSolution
void RecoverSolution(ProblemSolution *solution) const final
Definition: preprocessor.cc:2712
operations_research::glop::FixConstraintWithFixedStatuses
void FixConstraintWithFixedStatuses(const DenseColumn &row_lower_bounds, const DenseColumn &row_upper_bounds, ProblemSolution *solution)
Definition: preprocessor.cc:3147
operations_research::glop::ImpliedFreePreprocessor::ImpliedFreePreprocessor
ImpliedFreePreprocessor(const GlopParameters *parameters)
Definition: preprocessor.h:560
operations_research::glop::VariableStatus
VariableStatus
Definition: lp_types.h:196
operations_research::glop::DoubletonEqualityRowPreprocessor::RestoreInfo::ColChoiceAndStatus::status
VariableStatus status
Definition: preprocessor.h:844
operations_research::glop::Preprocessor::Preprocessor
Preprocessor(const GlopParameters *parameters)
Definition: preprocessor.cc:45
operations_research::glop::ScalingPreprocessor::ScalingPreprocessor
ScalingPreprocessor(const GlopParameters *parameters)
Definition: preprocessor.h:974
operations_research::glop::Preprocessor::RecoverSolution
virtual void RecoverSolution(ProblemSolution *solution) const =0
lp_types.h
operations_research::glop::DoubletonEqualityRowPreprocessor::RestoreInfo::ColChoiceAndStatus::ColChoiceAndStatus
ColChoiceAndStatus(ColChoice c, VariableStatus s, Fractional v)
Definition: preprocessor.h:847
operations_research::IsSmallerWithinTolerance
bool IsSmallerWithinTolerance(FloatType x, FloatType y, FloatType tolerance)
Definition: fp_utils.h:152
operations_research::glop::AddSlackVariablesPreprocessor::Run
bool Run(LinearProgram *lp) final
Definition: preprocessor.cc:3620
operations_research::glop::MatrixEntry::row
RowIndex row
Definition: preprocessor.h:333
operations_research::glop::ColumnDeletionHelper
Definition: preprocessor.h:137
operations_research::glop::Preprocessor
Definition: preprocessor.h:42
operations_research::glop::FreeConstraintPreprocessor::~FreeConstraintPreprocessor
~FreeConstraintPreprocessor() final
Definition: preprocessor.h:716
operations_research::glop::EmptyConstraintPreprocessor::EmptyConstraintPreprocessor
EmptyConstraintPreprocessor(const EmptyConstraintPreprocessor &)=delete
parameters
SatParameters parameters
Definition: cp_model_fz_solver.cc:107
operations_research::glop::RemoveNearZeroEntriesPreprocessor::Run
bool Run(LinearProgram *lp) final
Definition: preprocessor.cc:2765
operations_research::glop::MainLpPreprocessor::MainLpPreprocessor
MainLpPreprocessor(const MainLpPreprocessor &)=delete
name
const std::string name
Definition: default_search.cc:807
parameters.pb.h
operations_research::glop::FixedVariablePreprocessor::FixedVariablePreprocessor
FixedVariablePreprocessor(const GlopParameters *parameters)
Definition: preprocessor.h:479
operations_research::glop::ProportionalRowPreprocessor::ProportionalRowPreprocessor
ProportionalRowPreprocessor(const GlopParameters *parameters)
Definition: preprocessor.h:299
operations_research::glop::FreeConstraintPreprocessor::FreeConstraintPreprocessor
FreeConstraintPreprocessor(const GlopParameters *parameters)
Definition: preprocessor.h:711
operations_research::glop::ColumnDeletionHelper::MarkColumnForDeletionWithState
void MarkColumnForDeletionWithState(ColIndex col, Fractional value, VariableStatus status)
Definition: preprocessor.cc:194
operations_research::glop::DualizerPreprocessor::ChangeStatusToDualStatus
ProblemStatus ChangeStatusToDualStatus(ProblemStatus status) const
Definition: preprocessor.cc:3409
operations_research::glop::ScalingPreprocessor::~ScalingPreprocessor
~ScalingPreprocessor() final
Definition: preprocessor.h:978
operations_research::glop::Preprocessor::status_
ProblemStatus status_
Definition: preprocessor.h:90