20#ifndef ORTOOLS_GLOP_PREPROCESSOR_H_
21#define ORTOOLS_GLOP_PREPROCESSOR_H_
28#include "absl/strings/string_view.h"
84 return ::operations_research::IsSmallerWithinTolerance(
90 return ::operations_research::IsSmallerWithinTolerance(
127 void RunAndPushIfRelevant(std::unique_ptr<Preprocessor> preprocessor,
128 absl::string_view name,
TimeLimit* time_limit,
132 std::vector<std::unique_ptr<Preprocessor>> preprocessors_;
139 EntryIndex initial_num_entries_;
140 RowIndex initial_num_rows_;
141 ColIndex initial_num_cols_;
167 absl::flat_hash_map<ColIndex, int> saved_columns_index_;
171 std::deque<SparseColumn> saved_columns_;
199 return col < is_column_deleted_.size() && is_column_deleted_[col];
206 bool IsEmpty()
const {
return is_column_deleted_.empty(); }
238 bool IsEmpty()
const {
return is_row_deleted_.empty(); }
254 return row < is_row_deleted_.size() && is_row_deleted_[row];
339 ProportionalRowPreprocessor(
const ProportionalRowPreprocessor&) =
delete;
340 ProportionalRowPreprocessor& operator=(
const ProportionalRowPreprocessor&) =
342 ~ProportionalRowPreprocessor() final = default;
344 void RecoverSolution(ProblemSolution*
solution) const final;
348 DenseColumn row_factors_;
352 bool lp_is_maximization_problem_;
370 : row(_row), col(_col), coeff(_coeff) {}
380 typedef enum : uint8_t {
381 ZERO_COST_SINGLETON_COLUMN,
383 SINGLETON_COLUMN_IN_EQUALITY,
384 MAKE_CONSTRAINT_AN_EQUALITY,
408 void ZeroCostSingletonColumnUndo(
const GlopParameters& parameters,
411 void SingletonColumnInEqualityUndo(
const GlopParameters& parameters,
418 bool is_maximization_;
439 SingletonPreprocessor(
const SingletonPreprocessor&) =
delete;
440 SingletonPreprocessor& operator=(
const SingletonPreprocessor&) =
delete;
441 ~SingletonPreprocessor() final = default;
443 void RecoverSolution(ProblemSolution*
solution) const final;
448 MatrixEntry GetSingletonColumnMatrixEntry(ColIndex col,
450 MatrixEntry GetSingletonRowMatrixEntry(RowIndex row,
460 void UpdateConstraintBoundsWithVariableBounds(
MatrixEntry e,
465 bool IntegerSingletonColumnIsRemovable(const
MatrixEntry& matrix_entry,
471 void DeleteZeroCostSingletonColumn(const
SparseMatrix& matrix_transpose,
491 bool MakeConstraintAnEqualityIfPossible(const
SparseMatrix& matrix_transpose,
497 void DeleteSingletonColumnInEquality(const
SparseMatrix& matrix_transpose,
506 util_intops::StrongVector<RowIndex,
bool> row_sum_is_cached_;
573 bool lp_is_maximization_problem_;
664 enum RowChoice :
int {
678 RowIndex row[NUM_ROWS];
685 std::vector<RestoreInfo> restore_stack_;
702class UnconstrainedVariablePreprocessor final :
public Preprocessor {
704 explicit UnconstrainedVariablePreprocessor(
const GlopParameters* parameters)
705 : Preprocessor(parameters) {}
706 UnconstrainedVariablePreprocessor(
const UnconstrainedVariablePreprocessor&) =
708 UnconstrainedVariablePreprocessor& operator=(
709 const UnconstrainedVariablePreprocessor&) =
delete;
710 ~UnconstrainedVariablePreprocessor() final = default;
712 void RecoverSolution(ProblemSolution* solution) const final;
724 void RemoveZeroCostUnconstrainedVariable(ColIndex col,
777 EmptyConstraintPreprocessor(
const EmptyConstraintPreprocessor&) =
delete;
778 EmptyConstraintPreprocessor& operator=(
const EmptyConstraintPreprocessor&) =
780 ~EmptyConstraintPreprocessor() final = default;
808 std::vector<ColIndex> changed_columns_;
830 enum ColChoice :
int {
834 NUM_DOUBLETON_COLS = 2,
836 static ColChoice OtherColChoice(ColChoice x) {
837 return x == DELETED ? MODIFIED : DELETED;
840 ColumnDeletionHelper column_deletion_helper_;
841 RowDeletionHelper row_deletion_helper_;
850 ColIndex col[NUM_DOUBLETON_COLS];
854 Fractional objective_coefficient[NUM_DOUBLETON_COLS];
861 struct ColChoiceAndStatus {
862 ColChoice col_choice;
865 ColChoiceAndStatus() : col_choice(),
status(), value(0.0) {}
867 : col_choice(c),
status(s), value(v) {}
869 ColChoiceAndStatus bound_backtracking_at_lower_bound;
870 ColChoiceAndStatus bound_backtracking_at_upper_bound;
872 void SwapDeletedAndModifiedVariableRestoreInfo(RestoreInfo* r);
874 std::vector<RestoreInfo> restore_stack_;
875 DenseColumn saved_row_lower_bounds_;
876 DenseColumn saved_row_upper_bounds_;
878 ColumnsSaver columns_saver_;
879 DenseRow saved_objective_;
894void FixConstraintWithFixedStatuses(
const DenseColumn& row_lower_bounds,
916 LOG(FATAL) <<
"In the presence of integer variables, "
917 <<
"there is no notion of a dual problem.";
927 RowIndex primal_num_rows_;
928 ColIndex primal_num_cols_;
929 bool primal_is_maximization_problem_;
976 const DenseRow& offsets()
const {
return offsets_; }
998 ScalingPreprocessor(
const ScalingPreprocessor&) =
delete;
999 ScalingPreprocessor& operator=(
const ScalingPreprocessor&) =
delete;
1000 ~ScalingPreprocessor() final = default;
1060 ColIndex first_slack_col_;
const DenseRow & GetStoredValue() const
ColumnDeletionHelper & operator=(const ColumnDeletionHelper &)=delete
const DenseBooleanRow & GetMarkedColumns() const
void RestoreDeletedColumns(ProblemSolution *solution) const
bool IsColumnMarked(ColIndex col) const
void MarkColumnForDeletion(ColIndex col)
void MarkColumnForDeletionWithState(ColIndex col, Fractional value, VariableStatus status)
ColumnDeletionHelper()=default
const SparseColumn & SavedOrEmptyColumn(ColIndex col) const
void SaveColumn(ColIndex col, const SparseColumn &column)
const SparseColumn & SavedColumn(ColIndex col) const
void SaveColumnIfNotAlreadyDone(ColIndex col, const SparseColumn &column)
void RecoverSolution(ProblemSolution *solution) const final
DoubletonEqualityRowPreprocessor & operator=(const DoubletonEqualityRowPreprocessor &)=delete
bool Run(LinearProgram *lp) final
DualizerPreprocessor & operator=(const DualizerPreprocessor &)=delete
void RecoverSolution(ProblemSolution *solution) const final
bool Run(LinearProgram *lp) final
EmptyColumnPreprocessor & operator=(const EmptyColumnPreprocessor &)=delete
EmptyColumnPreprocessor(const GlopParameters *parameters)
void RecoverSolution(ProblemSolution *solution) const final
~EmptyColumnPreprocessor() final=default
void RecoverSolution(ProblemSolution *solution) const final
EmptyConstraintPreprocessor & operator=(const EmptyConstraintPreprocessor &)=delete
bool Run(LinearProgram *lp) final
bool Run(LinearProgram *lp) final
FixedVariablePreprocessor & operator=(const FixedVariablePreprocessor &)=delete
void RecoverSolution(ProblemSolution *solution) const final
ForcingAndImpliedFreeConstraintPreprocessor & operator=(const ForcingAndImpliedFreeConstraintPreprocessor &)=delete
void RecoverSolution(ProblemSolution *solution) const final
bool Run(LinearProgram *lp) final
FreeConstraintPreprocessor & operator=(const FreeConstraintPreprocessor &)=delete
void RecoverSolution(ProblemSolution *solution) const final
bool Run(LinearProgram *lp) final
void RecoverSolution(ProblemSolution *solution) const final
ImpliedFreePreprocessor & operator=(const ImpliedFreePreprocessor &)=delete
MainLpPreprocessor & operator=(const MainLpPreprocessor &)=delete
~MainLpPreprocessor() override=default
void SetLogger(SolverLogger *logger)
void DestructiveRecoverSolution(ProblemSolution *solution)
void RecoverSolution(ProblemSolution *solution) const override
MainLpPreprocessor(const GlopParameters *parameters)
ProblemStatus status() const
bool IsSmallerWithinFeasibilityTolerance(Fractional a, Fractional b) const
virtual void UseInMipContext()
virtual void RecoverSolution(ProblemSolution *solution) const =0
Preprocessor(const GlopParameters *parameters)
std::unique_ptr< TimeLimit > infinite_time_limit_
const GlopParameters & parameters_
void SetTimeLimit(TimeLimit *time_limit)
bool IsSmallerWithinPreprocessorZeroTolerance(Fractional a, Fractional b) const
Preprocessor & operator=(const Preprocessor &)=delete
void MarkRowForDeletion(RowIndex row)
bool IsRowMarked(RowIndex row) const
RowDeletionHelper & operator=(const RowDeletionHelper &)=delete
const DenseBooleanColumn & GetMarkedRows() const
RowDeletionHelper()=default
void RestoreDeletedRows(ProblemSolution *solution) const
void UnmarkRow(RowIndex row)
ScalingPreprocessor & operator=(const ScalingPreprocessor &)=delete
bool Run(LinearProgram *lp) final
void RecoverSolution(ProblemSolution *solution) const final
ShiftVariableBoundsPreprocessor & operator=(const ShiftVariableBoundsPreprocessor &)=delete
void RecoverSolution(ProblemSolution *solution) const final
bool Run(LinearProgram *lp) final
void RecoverSolution(ProblemSolution *solution) const final
SingletonPreprocessor & operator=(const SingletonPreprocessor &)=delete
void RecoverSolution(ProblemSolution *solution) const final
bool Run(LinearProgram *lp) final
void Undo(const GlopParameters ¶meters, const SparseColumn &saved_column, const SparseColumn &saved_row, ProblemSolution *solution) const
const MatrixEntry & Entry() const
UnconstrainedVariablePreprocessor & operator=(const UnconstrainedVariablePreprocessor &)=delete
bool Run(LinearProgram *lp) final
void RecoverSolution(ProblemSolution *solution) const final
StrictITIVector< RowIndex, ColIndex > RowToColMapping
StrictITIVector< RowIndex, bool > DenseBooleanColumn
StrictITIVector< ColIndex, ColIndex > ColMapping
SumWithOneMissing< true > SumWithPositiveInfiniteAndOneMissing
StrictITIVector< RowIndex, RowIndex > RowMapping
StrictITIVector< ColIndex, VariableStatus > VariableStatusRow
StrictITIVector< RowIndex, Fractional > DenseColumn
StrictITIVector< ColIndex, Fractional > DenseRow
StrictITIVector< ColIndex, bool > DenseBooleanRow
SumWithOneMissing< false > SumWithNegativeInfiniteAndOneMissing
Select next search node to expand Select next item_i to add this new search node to the search Generate a new search node where item_i is not in the knapsack Check validity of this new partial solution(using propagators) - If valid
MatrixEntry(RowIndex _row, ColIndex _col, Fractional _coeff)