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  // 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  gtl::ITIVector<RowIndex, bool> row_sum_is_cached_;
470 
471  // The columns that are deleted by this preprocessor.
472  SparseMatrix deleted_columns_;
473  // The transpose of the rows that are deleted by this preprocessor.
474  // TODO(user): implement a RowMajorSparseMatrix class to simplify the code.
475  SparseMatrix deleted_rows_;
476 };
477 
478 // --------------------------------------------------------
479 // FixedVariablePreprocessor
480 // --------------------------------------------------------
481 // Removes the fixed variables from the problem.
483  public:
484  explicit FixedVariablePreprocessor(const GlopParameters* parameters)
488  delete;
490  bool Run(LinearProgram* lp) final;
491  void RecoverSolution(ProblemSolution* solution) const final;
492 
493  private:
494  ColumnDeletionHelper column_deletion_helper_;
495 };
496 
497 // --------------------------------------------------------
498 // ForcingAndImpliedFreeConstraintPreprocessor
499 // --------------------------------------------------------
500 // This preprocessor computes for each constraint row the bounds that are
501 // implied by the variable bounds and applies one of the following reductions:
502 //
503 // * If the intersection of the implied bounds and the current constraint bounds
504 // is empty (modulo some tolerance), the problem is INFEASIBLE.
505 //
506 // * If the intersection of the implied bounds and the current constraint bounds
507 // is a singleton (modulo some tolerance), then the constraint is said to be
508 // forcing and all the variables that appear in it can be fixed to one of their
509 // bounds. All these columns and the constraint row is removed.
510 //
511 // * If the implied bounds are included inside the current constraint bounds
512 // (modulo some tolerance) then the constraint is said to be redundant or
513 // implied free. Its bounds are relaxed and the constraint will be removed
514 // later by the FreeConstraintPreprocessor.
515 //
516 // * Otherwise, wo do nothing.
518  public:
520  const GlopParameters* parameters)
527  bool Run(LinearProgram* lp) final;
528  void RecoverSolution(ProblemSolution* solution) const final;
529 
530  private:
531  bool lp_is_maximization_problem_;
532  SparseMatrix deleted_columns_;
533  DenseRow costs_;
534  DenseBooleanColumn is_forcing_up_;
535  ColumnDeletionHelper column_deletion_helper_;
536  RowDeletionHelper row_deletion_helper_;
537 };
538 
539 // --------------------------------------------------------
540 // ImpliedFreePreprocessor
541 // --------------------------------------------------------
542 // It is possible to compute "implied" bounds on a variable from the bounds of
543 // all the other variables and the constraints in which this variable take
544 // place. If such "implied" bounds are inside the variable bounds, then the
545 // variable bounds can be relaxed and the variable is said to be "implied free".
546 //
547 // This preprocessor detects the implied free variables and make as many as
548 // possible free with a priority towards low-degree columns. This transformation
549 // will make the simplex algorithm more efficient later, but will also make it
550 // possible to reduce the problem by applying subsequent transformations:
551 //
552 // * The SingletonPreprocessor already deals with implied free singleton
553 // variables and removes the columns and the rows in which they appear.
554 //
555 // * Any multiple of the column of a free variable can be added to any other
556 // column without changing the linear program solution. This is the dual
557 // counterpart of the fact that any multiple of an equality row can be added to
558 // any row.
559 //
560 // TODO(user): Only process doubleton columns so we have more chance in the
561 // later passes to create more doubleton columns? Such columns lead to a smaller
562 // problem thanks to the DoubletonFreeColumnPreprocessor.
564  public:
565  explicit ImpliedFreePreprocessor(const GlopParameters* parameters)
570  bool Run(LinearProgram* lp) final;
571  void RecoverSolution(ProblemSolution* solution) const final;
572 
573  private:
574  // This preprocessor adds fixed offsets to some variables. We remember those
575  // here to un-offset them in RecoverSolution().
576  DenseRow variable_offsets_;
577 
578  // This preprocessor causes some variables who would normally be
579  // AT_{LOWER,UPPER}_BOUND to be VariableStatus::FREE. We store the restore
580  // value of these variables; which will only be used (eg. restored) if the
581  // variable actually turns out to be VariableStatus::FREE.
582  VariableStatusRow postsolve_status_of_free_variables_;
583 };
584 
585 // --------------------------------------------------------
586 // DoubletonFreeColumnPreprocessor
587 // --------------------------------------------------------
588 // This preprocessor removes one of the two rows in which a doubleton column of
589 // a free variable appears. Since we can add any multiple of such a column to
590 // any other column, the way this works is that we can always remove all the
591 // entries on one row.
592 //
593 // Actually, we can remove all the entries except the one of the free column.
594 // But we will be left with a singleton row that we can delete in the same way
595 // as what is done in SingletonPreprocessor. That is by reporting the constraint
596 // bounds into the one of the originally free variable. After this operation,
597 // the doubleton free column will become a singleton and may or may not be
598 // removed later by the SingletonPreprocessor.
599 //
600 // Note that this preprocessor can be seen as the dual of the
601 // DoubletonEqualityRowPreprocessor since when taking the dual, an equality row
602 // becomes a free variable and vice versa.
603 //
604 // Note(user): As far as I know, this doubleton free column procedure is more
605 // general than what can be found in the research papers or in any of the linear
606 // solver open source codes as of July 2013. All of them only process such
607 // columns if one of the two rows is also an equality which is not actually
608 // required. Most probably, commercial solvers do use it though.
610  public:
611  explicit DoubletonFreeColumnPreprocessor(const GlopParameters* parameters)
614  delete;
616  const DoubletonFreeColumnPreprocessor&) = delete;
618  bool Run(LinearProgram* lp) final;
619  void RecoverSolution(ProblemSolution* solution) const final;
620 
621  private:
622  enum RowChoice {
623  DELETED = 0,
624  MODIFIED = 1,
625  // This is just a constant for the number of rows in a doubleton column.
626  // That is 2, one will be DELETED, the other MODIFIED.
627  NUM_ROWS = 2,
628  };
629  struct RestoreInfo {
630  // The index of the original free doubleton column and its objective.
631  ColIndex col;
632  Fractional objective_coefficient;
633 
634  // The row indices of the two involved rows and their coefficients on
635  // column col.
636  RowIndex row[NUM_ROWS];
637  Fractional coeff[NUM_ROWS];
638 
639  // The deleted row as a column.
640  SparseColumn deleted_row_as_column;
641  };
642 
643  std::vector<RestoreInfo> restore_stack_;
644  RowDeletionHelper row_deletion_helper_;
645 };
646 
647 // --------------------------------------------------------
648 // UnconstrainedVariablePreprocessor
649 // --------------------------------------------------------
650 // If for a given variable, none of the constraints block it in one direction
651 // and this direction improves the objective, then this variable can be fixed to
652 // its bound in this direction. If this bound is infinite and the variable cost
653 // is non-zero, then the problem is unbounded.
654 //
655 // More generally, by using the constraints and the variables that are unbounded
656 // on one side, one can derive bounds on the dual values. These can be
657 // translated into bounds on the reduced costs or the columns, which may force
658 // variables to their bounds. This is called forcing and dominated columns in
659 // the Andersen & Andersen paper.
661  public:
662  explicit UnconstrainedVariablePreprocessor(const GlopParameters* parameters)
665  delete;
667  const UnconstrainedVariablePreprocessor&) = delete;
669  bool Run(LinearProgram* lp) final;
670  void RecoverSolution(ProblemSolution* solution) const final;
671 
672  // Removes the given variable and all the rows in which it appears: If a
673  // variable is unconstrained with a zero cost, then all the constraints in
674  // which it appears can be made free! More precisely, during postsolve, if
675  // such a variable is unconstrained towards +kInfinity, for any activity value
676  // of the involved constraints, an M exists such that for each value of the
677  // variable >= M the problem will be feasible.
678  //
679  // The algorithm during postsolve is to find a feasible value for all such
680  // variables while trying to keep their magnitudes small (for better numerical
681  // behavior). target_bound should take only two possible values: +/-kInfinity.
684  LinearProgram* lp);
685 
686  private:
687  // Lower/upper bounds on the feasible dual value. We use constraints and
688  // variables unbounded in one direction to derive these bounds. We use these
689  // bounds to compute bounds on the reduced costs of the problem variables.
690  // Note that any finite bounds on a reduced cost means that the variable
691  // (ignoring its domain) can move freely in one direction.
692  DenseColumn dual_lb_;
693  DenseColumn dual_ub_;
694 
695  // Indicates if a given column may have participated in the current lb/ub
696  // on the reduced cost of the same column.
697  DenseBooleanRow may_have_participated_ub_;
698  DenseBooleanRow may_have_participated_lb_;
699 
700  ColumnDeletionHelper column_deletion_helper_;
701  RowDeletionHelper row_deletion_helper_;
702  DenseColumn rhs_;
703  DenseColumn activity_sign_correction_;
704  DenseBooleanRow is_unbounded_;
705 
706  SparseMatrix deleted_columns_;
707  SparseMatrix deleted_rows_as_column_;
708 };
709 
710 // --------------------------------------------------------
711 // FreeConstraintPreprocessor
712 // --------------------------------------------------------
713 // Removes the constraints with no bounds from the problem.
715  public:
716  explicit FreeConstraintPreprocessor(const GlopParameters* parameters)
720  delete;
722  bool Run(LinearProgram* lp) final;
723  void RecoverSolution(ProblemSolution* solution) const final;
724 
725  private:
726  RowDeletionHelper row_deletion_helper_;
727 };
728 
729 // --------------------------------------------------------
730 // EmptyConstraintPreprocessor
731 // --------------------------------------------------------
732 // Removes the constraints with no coefficients from the problem.
734  public:
735  explicit EmptyConstraintPreprocessor(const GlopParameters* parameters)
739  delete;
741  bool Run(LinearProgram* lp) final;
742  void RecoverSolution(ProblemSolution* solution) const final;
743 
744  private:
745  RowDeletionHelper row_deletion_helper_;
746 };
747 
748 // --------------------------------------------------------
749 // RemoveNearZeroEntriesPreprocessor
750 // --------------------------------------------------------
751 // Removes matrix entries that have only a negligible impact on the solution.
752 // Using the variable bounds, we derive a maximum possible impact, and remove
753 // the entries whose impact is under a given tolerance.
754 //
755 // TODO(user): This preprocessor doesn't work well on badly scaled problems. In
756 // particular, it will set the objective to zero if all the objective
757 // coefficients are small! Run it after ScalingPreprocessor or fix the code.
759  public:
760  explicit RemoveNearZeroEntriesPreprocessor(const GlopParameters* parameters)
763  delete;
765  const RemoveNearZeroEntriesPreprocessor&) = delete;
767  bool Run(LinearProgram* lp) final;
768  void RecoverSolution(ProblemSolution* solution) const final;
769 
770  private:
771 };
772 
773 // --------------------------------------------------------
774 // SingletonColumnSignPreprocessor
775 // --------------------------------------------------------
776 // Make sure that the only coefficient of all singleton columns (i.e. column
777 // with only one entry) is positive. This is because this way the column will
778 // be transformed in an identity column by the scaling. This will lead to more
779 // efficient solve when this column is involved.
781  public:
782  explicit SingletonColumnSignPreprocessor(const GlopParameters* parameters)
785  delete;
787  const SingletonColumnSignPreprocessor&) = delete;
789  bool Run(LinearProgram* lp) final;
790  void RecoverSolution(ProblemSolution* solution) const final;
791 
792  private:
793  std::vector<ColIndex> changed_columns_;
794 };
795 
796 // --------------------------------------------------------
797 // DoubletonEqualityRowPreprocessor
798 // --------------------------------------------------------
799 // Reduce equality constraints involving two variables (i.e. aX + bY = c),
800 // by substitution (and thus removal) of one of the variables by the other
801 // in all the constraints that it is involved in.
803  public:
804  explicit DoubletonEqualityRowPreprocessor(const GlopParameters* parameters)
807  delete;
809  const DoubletonEqualityRowPreprocessor&) = delete;
811  bool Run(LinearProgram* lp) final;
812  void RecoverSolution(ProblemSolution* solution) const final;
813 
814  private:
815  enum ColChoice {
816  DELETED = 0,
817  MODIFIED = 1,
818  // For for() loops iterating over the ColChoice values, and/or arrays.
819  NUM_DOUBLETON_COLS = 2,
820  };
821  static ColChoice OtherColChoice(ColChoice x) {
822  return x == DELETED ? MODIFIED : DELETED;
823  }
824 
825  ColumnDeletionHelper column_deletion_helper_;
826  RowDeletionHelper row_deletion_helper_;
827 
828  struct RestoreInfo {
829  // The row index of the doubleton equality constraint, and its constant.
830  RowIndex row;
831  Fractional rhs; // The constant c in the equality aX + bY = c.
832 
833  // The indices and the data of the two columns that we touched, exactly
834  // as they were beforehand.
835  ColIndex col[NUM_DOUBLETON_COLS];
836  Fractional coeff[NUM_DOUBLETON_COLS];
837  Fractional lb[NUM_DOUBLETON_COLS];
838  Fractional ub[NUM_DOUBLETON_COLS];
839  SparseColumn column[NUM_DOUBLETON_COLS];
840  Fractional objective_coefficient[NUM_DOUBLETON_COLS];
841 
842  // If the modified variable has status AT_[LOWER,UPPER]_BOUND, then we'll
843  // set one of the two original variables to one of its bounds, and set the
844  // other to VariableStatus::BASIC. We store this information (which variable
845  // will be set to one of its bounds, and which bound) for each possible
846  // outcome.
848  ColChoice col_choice;
853  : col_choice(c), status(s), value(v) {}
854  };
855  ColChoiceAndStatus bound_backtracking_at_lower_bound;
856  ColChoiceAndStatus bound_backtracking_at_upper_bound;
857  };
858  void SwapDeletedAndModifiedVariableRestoreInfo(RestoreInfo* r);
859 
860  std::vector<RestoreInfo> restore_stack_;
861  DenseColumn saved_row_lower_bounds_;
862  DenseColumn saved_row_upper_bounds_;
863 };
864 
865 // Because of numerical imprecision, a preprocessor like
866 // DoubletonEqualityRowPreprocessor can transform a constraint/variable domain
867 // like [1, 1+1e-7] to a fixed domain (for ex by multiplying the above domain by
868 // 1e9). This causes an issue because at postsolve, a FIXED_VALUE status now
869 // needs to be transformed to a AT_LOWER_BOUND/AT_UPPER_BOUND status. This is
870 // what this function is doing for the constraint statuses only.
871 //
872 // TODO(user): A better solution would simply be to get rid of the FIXED status
873 // altogether, it is better to simply use AT_LOWER_BOUND/AT_UPPER_BOUND
874 // depending on the constraining bound in the optimal solution. Note that we can
875 // always at the end transform any variable/constraint with a fixed domain to
876 // FIXED_VALUE if needed to keep the same external API.
877 void FixConstraintWithFixedStatuses(const DenseColumn& row_lower_bounds,
878  const DenseColumn& row_upper_bounds,
879  ProblemSolution* solution);
880 
881 // --------------------------------------------------------
882 // DualizerPreprocessor
883 // --------------------------------------------------------
884 // DualizerPreprocessor may change the given program to its dual depending
885 // on the value of the parameter solve_dual_problem.
886 //
887 // IMPORTANT: FreeConstraintPreprocessor() must be called first since this
888 // preprocessor does not deal correctly with free constraints.
890  public:
891  explicit DualizerPreprocessor(const GlopParameters* parameters)
896  bool Run(LinearProgram* lp) final;
897  void RecoverSolution(ProblemSolution* solution) const final;
898  void UseInMipContext() final {
899  LOG(FATAL) << "In the presence of integer variables, "
900  << "there is no notion of a dual problem.";
901  }
902 
903  // Convert the given problem status to the one of its dual.
905 
906  private:
907  DenseRow variable_lower_bounds_;
908  DenseRow variable_upper_bounds_;
909 
910  RowIndex primal_num_rows_;
911  ColIndex primal_num_cols_;
912  bool primal_is_maximization_problem_;
913  RowToColMapping duplicated_rows_;
914 
915  // For postsolving the variable/constraint statuses.
916  VariableStatusRow dual_status_correspondence_;
917  ColMapping slack_or_surplus_mapping_;
918 };
919 
920 // --------------------------------------------------------
921 // ShiftVariableBoundsPreprocessor
922 // --------------------------------------------------------
923 // For each variable, inspects its bounds and "shift" them if necessary, so that
924 // its domain contains zero. A variable that was shifted will always have at
925 // least one of its bounds to zero. Doing it all at once allows to have a better
926 // precision when modifying the constraint bounds by using an accurate summation
927 // algorithm.
928 //
929 // Example:
930 // - A variable with bound [1e10, infinity] will be shifted to [0, infinity].
931 // - A variable with domain [-1e10, 1e10] will not be shifted. Note that
932 // compared to the first case, doing so here may introduce unecessary
933 // numerical errors if the variable value in the final solution is close to
934 // zero.
935 //
936 // The expected impact of this is:
937 // - Better behavior of the scaling.
938 // - Better precision and numerical accuracy of the simplex method.
939 // - Slightly improved speed (because adding a column with a variable value of
940 // zero takes no work later).
941 //
942 // TODO(user): Having for each variable one of their bounds at zero is a
943 // requirement for the DualizerPreprocessor and for the implied free column in
944 // the ImpliedFreePreprocessor. However, shifting a variable with a domain like
945 // [-1e10, 1e10] may introduce numerical issues. Relax the definition of
946 // a free variable so that only having a domain containing 0.0 is enough?
948  public:
949  explicit ShiftVariableBoundsPreprocessor(const GlopParameters* parameters)
952  delete;
954  const ShiftVariableBoundsPreprocessor&) = delete;
956  bool Run(LinearProgram* lp) final;
957  void RecoverSolution(ProblemSolution* solution) const final;
958 
959  const DenseRow& offsets() const { return offsets_; }
960 
961  private:
962  // Contains for each variable by how much its bounds where shifted during
963  // presolve. Note that the shift was negative (new bound = initial bound -
964  // offset).
965  DenseRow offsets_;
966  // Contains the initial problem bounds. They are needed to get the perfect
967  // numerical accuracy for variables at their bound after postsolve.
968  DenseRow variable_initial_lbs_;
969  DenseRow variable_initial_ubs_;
970 };
971 
972 // --------------------------------------------------------
973 // ScalingPreprocessor
974 // --------------------------------------------------------
975 // Scales the SparseMatrix of the linear program using a SparseMatrixScaler.
976 // This is only applied if the parameter use_scaling is true.
978  public:
979  explicit ScalingPreprocessor(const GlopParameters* parameters)
984  bool Run(LinearProgram* lp) final;
985  void RecoverSolution(ProblemSolution* solution) const final;
986  void UseInMipContext() final { LOG(FATAL) << "Not implemented."; }
987 
988  private:
989  DenseRow variable_lower_bounds_;
990  DenseRow variable_upper_bounds_;
991  Fractional cost_scaling_factor_;
992  Fractional bound_scaling_factor_;
993  SparseMatrixScaler scaler_;
994 };
995 
996 // --------------------------------------------------------
997 // ToMinimizationPreprocessor
998 // --------------------------------------------------------
999 // Changes the problem from maximization to minimization (if applicable).
1001  public:
1002  explicit ToMinimizationPreprocessor(const GlopParameters* parameters)
1003  : Preprocessor(parameters) {}
1006  delete;
1008  bool Run(LinearProgram* lp) final;
1009  void RecoverSolution(ProblemSolution* solution) const final;
1010 };
1011 
1012 // --------------------------------------------------------
1013 // AddSlackVariablesPreprocessor
1014 // --------------------------------------------------------
1015 // Transforms the linear program to the equation form
1016 // min c.x, s.t. A.x = 0. This is done by:
1017 // 1. Introducing slack variables for all constraints; all these variables are
1018 // introduced with coefficient 1.0, and their bounds are set to be negative
1019 // bounds of the corresponding constraint.
1020 // 2. Changing the bounds of all constraints to (0, 0) to make them an equality.
1021 //
1022 // As a consequence, the matrix of the linear program always has full row rank
1023 // after this preprocessor. Note that the slack variables are always added last,
1024 // so that the rightmost square sub-matrix is always the identity matrix.
1026  public:
1027  explicit AddSlackVariablesPreprocessor(const GlopParameters* parameters)
1028  : Preprocessor(parameters) {}
1031  const AddSlackVariablesPreprocessor&) = delete;
1033  bool Run(LinearProgram* lp) final;
1034  void RecoverSolution(ProblemSolution* solution) const final;
1035 
1036  private:
1037  ColIndex first_slack_col_;
1038 };
1039 
1040 } // namespace glop
1041 } // namespace operations_research
1042 
1043 #endif // OR_TOOLS_GLOP_PREPROCESSOR_H_
operations_research::glop::ImpliedFreePreprocessor
Definition: preprocessor.h:563
operations_research::glop::ToMinimizationPreprocessor::ToMinimizationPreprocessor
ToMinimizationPreprocessor(const GlopParameters *parameters)
Definition: preprocessor.h:1002
operations_research::glop::FixedVariablePreprocessor::~FixedVariablePreprocessor
~FixedVariablePreprocessor() final
Definition: preprocessor.h:489
operations_research::glop::FreeConstraintPreprocessor::Run
bool Run(LinearProgram *lp) final
Definition: preprocessor.cc:2055
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:3479
operations_research::glop::RowDeletionHelper::operator=
RowDeletionHelper & operator=(const RowDeletionHelper &)=delete
operations_research::glop::DoubletonFreeColumnPreprocessor::RecoverSolution
void RecoverSolution(ProblemSolution *solution) const final
Definition: preprocessor.cc:1634
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:3547
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:517
operations_research::glop::RowDeletionHelper::Clear
void Clear()
Definition: preprocessor.cc:238
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:766
operations_research::glop::FreeConstraintPreprocessor::~FreeConstraintPreprocessor
~FreeConstraintPreprocessor() final
Definition: preprocessor.h:721
operations_research::glop::DoubletonEqualityRowPreprocessor::DoubletonEqualityRowPreprocessor
DoubletonEqualityRowPreprocessor(const DoubletonEqualityRowPreprocessor &)=delete
operations_research::glop::DoubletonFreeColumnPreprocessor::operator=
DoubletonFreeColumnPreprocessor & operator=(const DoubletonFreeColumnPreprocessor &)=delete
operations_research::glop::ShiftVariableBoundsPreprocessor::offsets
const DenseRow & offsets() const
Definition: preprocessor.h:959
operations_research::glop::AddSlackVariablesPreprocessor::~AddSlackVariablesPreprocessor
~AddSlackVariablesPreprocessor() final
Definition: preprocessor.h:1032
operations_research::glop::MainLpPreprocessor::operator=
MainLpPreprocessor & operator=(const MainLpPreprocessor &)=delete
operations_research::glop::AddSlackVariablesPreprocessor::RecoverSolution
void RecoverSolution(ProblemSolution *solution) const final
Definition: preprocessor.cc:3675
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:1025
operations_research::glop::Preprocessor::operator=
Preprocessor & operator=(const Preprocessor &)=delete
gtl::ITIVector< RowIndex, bool >
operations_research::glop::ForcingAndImpliedFreeConstraintPreprocessor::~ForcingAndImpliedFreeConstraintPreprocessor
~ForcingAndImpliedFreeConstraintPreprocessor() final
Definition: preprocessor.h:526
operations_research::glop::FixedVariablePreprocessor::operator=
FixedVariablePreprocessor & operator=(const FixedVariablePreprocessor &)=delete
operations_research::glop::DualizerPreprocessor::~DualizerPreprocessor
~DualizerPreprocessor() final
Definition: preprocessor.h:895
operations_research::glop::ScalingPreprocessor::ScalingPreprocessor
ScalingPreprocessor(const ScalingPreprocessor &)=delete
operations_research::glop::DualizerPreprocessor::UseInMipContext
void UseInMipContext() final
Definition: preprocessor.h:898
operations_research::glop::ImpliedFreePreprocessor::ImpliedFreePreprocessor
ImpliedFreePreprocessor(const GlopParameters *parameters)
Definition: preprocessor.h:565
operations_research::glop::EmptyConstraintPreprocessor::~EmptyConstraintPreprocessor
~EmptyConstraintPreprocessor() final
Definition: preprocessor.h:740
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:849
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:3602
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:569
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:733
operations_research::glop::DoubletonFreeColumnPreprocessor
Definition: preprocessor.h:609
matrix_scaler.h
operations_research::glop::AddSlackVariablesPreprocessor::Run
bool Run(LinearProgram *lp) final
Definition: preprocessor.cc:3666
operations_research::glop::FreeConstraintPreprocessor::RecoverSolution
void RecoverSolution(ProblemSolution *solution) const final
Definition: preprocessor.cc:2070
operations_research::glop::DoubletonFreeColumnPreprocessor::~DoubletonFreeColumnPreprocessor
~DoubletonFreeColumnPreprocessor() final
Definition: preprocessor.h:617
operations_research::glop::MatrixEntry::coeff
Fractional coeff
Definition: preprocessor.h:335
operations_research::glop::SingletonColumnSignPreprocessor
Definition: preprocessor.h:780
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:735
operations_research::glop::SingletonUndo::SingletonUndo
SingletonUndo(OperationType type, const LinearProgram &lp, MatrixEntry e, ConstraintStatus status)
Definition: preprocessor.cc:2129
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:852
revised_simplex.h
gtl::ITIVector::empty
bool empty() const
Definition: int_type_indexed_vector.h:155
operations_research::glop::Fractional
double Fractional
Definition: lp_types.h:77
operations_research::glop::SingletonColumnSignPreprocessor::Run
bool Run(LinearProgram *lp) final
Definition: preprocessor.cc:2885
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:2680
operations_research::glop::ImpliedFreePreprocessor::operator=
ImpliedFreePreprocessor & operator=(const ImpliedFreePreprocessor &)=delete
operations_research::glop::UnconstrainedVariablePreprocessor
Definition: preprocessor.h:660
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:3579
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:986
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:1795
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:2063
operations_research::glop::DoubletonFreeColumnPreprocessor::Run
bool Run(LinearProgram *lp) final
Definition: preprocessor.cc:1528
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:2081
operations_research::glop::ImpliedFreePreprocessor::Run
bool Run(LinearProgram *lp) final
Definition: preprocessor.cc:1317
operations_research::glop::RemoveNearZeroEntriesPreprocessor
Definition: preprocessor.h:758
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:979
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:2913
operations_research::glop::ColumnDeletionHelper
Definition: preprocessor.h:137
operations_research::glop::DualizerPreprocessor::Run
bool Run(LinearProgram *lp) final
Definition: preprocessor.cc:3230
operations_research::glop::ToMinimizationPreprocessor::Run
bool Run(LinearProgram *lp) final
Definition: preprocessor.cc:3642
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:889
operations_research::glop::MatrixEntry::col
ColIndex col
Definition: preprocessor.h:334
operations_research::glop::DoubletonEqualityRowPreprocessor::RestoreInfo::ColChoiceAndStatus::value
Fractional value
Definition: preprocessor.h:850
operations_research::glop::FixedVariablePreprocessor::FixedVariablePreprocessor
FixedVariablePreprocessor(const GlopParameters *parameters)
Definition: preprocessor.h:484
operations_research::glop::RemoveNearZeroEntriesPreprocessor::Run
bool Run(LinearProgram *lp) final
Definition: preprocessor.cc:2811
operations_research::glop::RemoveNearZeroEntriesPreprocessor::RemoveNearZeroEntriesPreprocessor
RemoveNearZeroEntriesPreprocessor(const RemoveNearZeroEntriesPreprocessor &)=delete
operations_research::glop::DualizerPreprocessor::DualizerPreprocessor
DualizerPreprocessor(const GlopParameters *parameters)
Definition: preprocessor.h:891
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:3346
operations_research::glop::SparseMatrixScaler
Definition: matrix_scaler.h:79
operations_research::glop::UnconstrainedVariablePreprocessor::RecoverSolution
void RecoverSolution(ProblemSolution *solution) const final
Definition: preprocessor.cc:1987
operations_research::glop::SingletonPreprocessor::operator=
SingletonPreprocessor & operator=(const SingletonPreprocessor &)=delete
operations_research::glop::ShiftVariableBoundsPreprocessor
Definition: preprocessor.h:947
operations_research::glop::UnconstrainedVariablePreprocessor::RemoveZeroCostUnconstrainedVariable
void RemoveZeroCostUnconstrainedVariable(ColIndex col, Fractional target_bound, LinearProgram *lp)
Definition: preprocessor.cc:1712
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:3659
operations_research::glop::EmptyColumnPreprocessor::~EmptyColumnPreprocessor
~EmptyColumnPreprocessor() final
Definition: preprocessor.h:238
operations_research::glop::DoubletonEqualityRowPreprocessor::DoubletonEqualityRowPreprocessor
DoubletonEqualityRowPreprocessor(const GlopParameters *parameters)
Definition: preprocessor.h:804
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:1027
operations_research::glop::ToMinimizationPreprocessor
Definition: preprocessor.h:1000
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:482
operations_research::glop::UnconstrainedVariablePreprocessor::UnconstrainedVariablePreprocessor
UnconstrainedVariablePreprocessor(const GlopParameters *parameters)
Definition: preprocessor.h:662
operations_research::glop::Preprocessor::IsSmallerWithinFeasibilityTolerance
bool IsSmallerWithinFeasibilityTolerance(Fractional a, Fractional b) const
Definition: preprocessor.h:79
operations_research::glop::DualizerPreprocessor::DualizerPreprocessor
DualizerPreprocessor(const DualizerPreprocessor &)=delete
operations_research::glop::DoubletonEqualityRowPreprocessor::~DoubletonEqualityRowPreprocessor
~DoubletonEqualityRowPreprocessor() final
Definition: preprocessor.h:810
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:611
operations_research::glop::ScalingPreprocessor
Definition: preprocessor.h:977
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:2933
operations_research::glop::LinearProgram
Definition: lp_data.h:55
operations_research::glop::DoubletonEqualityRowPreprocessor
Definition: preprocessor.h:802
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:714
operations_research::glop::ProportionalRowPreprocessor::operator=
ProportionalRowPreprocessor & operator=(const ProportionalRowPreprocessor &)=delete
operations_research::glop::UnconstrainedVariablePreprocessor::~UnconstrainedVariablePreprocessor
~UnconstrainedVariablePreprocessor() final
Definition: preprocessor.h:668
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:847
operations_research::glop::ScalingPreprocessor::~ScalingPreprocessor
~ScalingPreprocessor() final
Definition: preprocessor.h:983
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:2141
operations_research::glop::ShiftVariableBoundsPreprocessor::ShiftVariableBoundsPreprocessor
ShiftVariableBoundsPreprocessor(const GlopParameters *parameters)
Definition: preprocessor.h:949
operations_research::glop::DoubletonEqualityRowPreprocessor::RestoreInfo::ColChoiceAndStatus::ColChoiceAndStatus
ColChoiceAndStatus()
Definition: preprocessor.h:851
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:1759
operations_research::glop::ToMinimizationPreprocessor::~ToMinimizationPreprocessor
~ToMinimizationPreprocessor() final
Definition: preprocessor.h:1007
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:788
operations_research::glop::RemoveNearZeroEntriesPreprocessor::RemoveNearZeroEntriesPreprocessor
RemoveNearZeroEntriesPreprocessor(const GlopParameters *parameters)
Definition: preprocessor.h:760
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:3193
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:848
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:782
operations_research::glop::DualizerPreprocessor::ChangeStatusToDualStatus
ProblemStatus ChangeStatusToDualStatus(ProblemStatus status) const
Definition: preprocessor.cc:3455
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:3113
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:1504
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:716
parameters
SatParameters parameters
Definition: cp_model_fz_solver.cc:107
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:955
name
const std::string name
Definition: default_search.cc:807
parameters.pb.h
operations_research::glop::SingletonPreprocessor::RecoverSolution
void RecoverSolution(ProblemSolution *solution) const final
Definition: preprocessor.cc:2758
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:519
operations_research::glop::RemoveNearZeroEntriesPreprocessor::RecoverSolution
void RecoverSolution(ProblemSolution *solution) const final
Definition: preprocessor.cc:2878
operations_research::glop::EmptyConstraintPreprocessor::RecoverSolution
void RecoverSolution(ProblemSolution *solution) const final
Definition: preprocessor.cc:2118
operations_research::glop::ProportionalColumnPreprocessor::operator=
ProportionalColumnPreprocessor & operator=(const ProportionalColumnPreprocessor &)=delete