21#ifndef OR_TOOLS_GLOP_PREPROCESSOR_H_
22#define OR_TOOLS_GLOP_PREPROCESSOR_H_
29#include "absl/strings/string_view.h"
31#include "ortools/glop/parameters.pb.h"
85 return ::operations_research::IsSmallerWithinTolerance(
91 return ::operations_research::IsSmallerWithinTolerance(
128 void RunAndPushIfRelevant(std::unique_ptr<Preprocessor>
preprocessor,
133 std::vector<std::unique_ptr<Preprocessor>> preprocessors_;
140 EntryIndex initial_num_entries_;
141 RowIndex initial_num_rows_;
142 ColIndex initial_num_cols_;
168 absl::flat_hash_map<ColIndex, int> saved_columns_index_;
172 std::deque<SparseColumn> saved_columns_;
200 return col < is_column_deleted_.
size() && is_column_deleted_[
col];
207 bool IsEmpty()
const {
return is_column_deleted_.empty(); }
239 bool IsEmpty()
const {
return is_row_deleted_.empty(); }
255 return row < is_row_deleted_.
size() && is_row_deleted_[
row];
278 bool Run(LinearProgram* lp) final;
340 ProportionalRowPreprocessor(
const ProportionalRowPreprocessor&) =
delete;
341 ProportionalRowPreprocessor& operator=(
const ProportionalRowPreprocessor&) =
343 ~ProportionalRowPreprocessor() final = default;
344 bool Run(LinearProgram* lp) final;
345 void RecoverSolution(ProblemSolution*
solution) const final;
349 DenseColumn row_factors_;
353 bool lp_is_maximization_problem_;
370 MatrixEntry(RowIndex _row, ColIndex _col,
Fractional _coeff)
371 :
row(_row),
col(_col), coeff(_coeff) {}
382 ZERO_COST_SINGLETON_COLUMN,
384 SINGLETON_COLUMN_IN_EQUALITY,
385 MAKE_CONSTRAINT_AN_EQUALITY,
402 const MatrixEntry& Entry()
const {
return e_; }
409 void ZeroCostSingletonColumnUndo(
const GlopParameters&
parameters,
412 void SingletonColumnInEqualityUndo(
const GlopParameters&
parameters,
419 bool is_maximization_;
440 SingletonPreprocessor(
const SingletonPreprocessor&) =
delete;
441 SingletonPreprocessor& operator=(
const SingletonPreprocessor&) =
delete;
442 ~SingletonPreprocessor() final = default;
443 bool Run(LinearProgram* lp) final;
444 void RecoverSolution(ProblemSolution*
solution) const final;
449 MatrixEntry GetSingletonColumnMatrixEntry(ColIndex
col,
450 const SparseMatrix& matrix);
451 MatrixEntry GetSingletonRowMatrixEntry(RowIndex
row,
461 void UpdateConstraintBoundsWithVariableBounds(MatrixEntry e,
466 bool IntegerSingletonColumnIsRemovable(const MatrixEntry& matrix_entry,
472 void DeleteZeroCostSingletonColumn(const
SparseMatrix& matrix_transpose,
492 bool MakeConstraintAnEqualityIfPossible(const
SparseMatrix& matrix_transpose,
498 void DeleteSingletonColumnInEquality(const
SparseMatrix& matrix_transpose,
507 util_intops::StrongVector<RowIndex,
bool> row_sum_is_cached_;
574 bool lp_is_maximization_problem_;
679 RowIndex
row[NUM_ROWS];
686 std::vector<RestoreInfo> restore_stack_;
703class UnconstrainedVariablePreprocessor final :
public Preprocessor {
705 explicit UnconstrainedVariablePreprocessor(
const GlopParameters*
parameters)
707 UnconstrainedVariablePreprocessor(
const UnconstrainedVariablePreprocessor&) =
709 UnconstrainedVariablePreprocessor& operator=(
710 const UnconstrainedVariablePreprocessor&) =
delete;
711 ~UnconstrainedVariablePreprocessor() final = default;
712 bool Run(LinearProgram* lp) final;
713 void RecoverSolution(ProblemSolution*
solution) const final;
725 void RemoveZeroCostUnconstrainedVariable(ColIndex
col,
778 EmptyConstraintPreprocessor(
const EmptyConstraintPreprocessor&) =
delete;
779 EmptyConstraintPreprocessor& operator=(
const EmptyConstraintPreprocessor&) =
781 ~EmptyConstraintPreprocessor() final = default;
782 bool Run(LinearProgram* lp) final;
809 std::vector<ColIndex> changed_columns_;
835 NUM_DOUBLETON_COLS = 2,
837 static ColChoice OtherColChoice(ColChoice
x) {
838 return x == DELETED ? MODIFIED : DELETED;
841 ColumnDeletionHelper column_deletion_helper_;
842 RowDeletionHelper row_deletion_helper_;
851 ColIndex
col[NUM_DOUBLETON_COLS];
855 Fractional objective_coefficient[NUM_DOUBLETON_COLS];
862 struct ColChoiceAndStatus {
863 ColChoice col_choice;
866 ColChoiceAndStatus() : col_choice(),
status(),
value(0.0) {}
870 ColChoiceAndStatus bound_backtracking_at_lower_bound;
871 ColChoiceAndStatus bound_backtracking_at_upper_bound;
873 void SwapDeletedAndModifiedVariableRestoreInfo(RestoreInfo* r);
875 std::vector<RestoreInfo> restore_stack_;
876 DenseColumn saved_row_lower_bounds_;
877 DenseColumn saved_row_upper_bounds_;
879 ColumnsSaver columns_saver_;
880 DenseRow saved_objective_;
895void FixConstraintWithFixedStatuses(
const DenseColumn& row_lower_bounds,
916 void UseInMipContext()
final {
917 LOG(FATAL) <<
"In the presence of integer variables, "
918 <<
"there is no notion of a dual problem.";
928 RowIndex primal_num_rows_;
929 ColIndex primal_num_cols_;
930 bool primal_is_maximization_problem_;
977 const DenseRow& offsets()
const {
return offsets_; }
999 ScalingPreprocessor(
const ScalingPreprocessor&) =
delete;
1000 ScalingPreprocessor& operator=(
const ScalingPreprocessor&) =
delete;
1001 ~ScalingPreprocessor() final = default;
1002 bool Run(LinearProgram* lp) final;
1004 void UseInMipContext() final { LOG(FATAL) <<
"Not implemented."; }
1061 ColIndex first_slack_col_;
Help preprocessors deal with column deletion.
const DenseRow & GetStoredValue() const
void Clear()
Restores the class to its initial state.
ColumnDeletionHelper & operator=(const ColumnDeletionHelper &)=delete
const DenseBooleanRow & GetMarkedColumns() const
Returns a Boolean vector of the column to be deleted.
void RestoreDeletedColumns(ProblemSolution *solution) const
bool IsEmpty() const
Returns true if no columns have been marked for deletion.
bool IsColumnMarked(ColIndex col) const
Returns whether or not the given column is marked for deletion.
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)
Saves a column. The first version CHECKs that it is not already done.
const SparseColumn & SavedColumn(ColIndex col) const
Returns the saved column. The first version CHECKs that it was saved.
void SaveColumnIfNotAlreadyDone(ColIndex col, const SparseColumn &column)
Removes the empty columns from the problem.
EmptyColumnPreprocessor & operator=(const EmptyColumnPreprocessor &)=delete
EmptyColumnPreprocessor(const GlopParameters *parameters)
void RecoverSolution(ProblemSolution *solution) const final
bool Run(LinearProgram *lp) final
~EmptyColumnPreprocessor() final=default
Removes the constraints with no coefficients from the problem.
Removes the fixed variables from the problem.
Removes the constraints with no bounds from the problem.
MainLpPreprocessor & operator=(const MainLpPreprocessor &)=delete
bool Run(LinearProgram *lp) final
~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_
virtual bool Run(LinearProgram *lp)=0
void SetTimeLimit(TimeLimit *time_limit)
bool IsSmallerWithinPreprocessorZeroTolerance(Fractional a, Fractional b) const
Preprocessor & operator=(const Preprocessor &)=delete
Help preprocessors deal with row deletion.
bool IsEmpty() const
Returns true if no rows have been marked for deletion.
void Clear()
Restores the class to its initial state.
void MarkRowForDeletion(RowIndex row)
Adds a deleted row to the helper.
bool IsRowMarked(RowIndex row) const
Returns whether or not the given row is marked for deletion.
RowDeletionHelper & operator=(const RowDeletionHelper &)=delete
const DenseBooleanColumn & GetMarkedRows() const
Returns a Boolean vector of the row to be deleted.
RowDeletionHelper()=default
void RestoreDeletedRows(ProblemSolution *solution) const
void UnmarkRow(RowIndex row)
If the given row was marked for deletion, unmark it.
Stores the information needed to undo a singleton row/column deletion.
OperationType
The type of a given operation.
Changes the problem from maximization to minimization (if applicable).
const std::string name
A name for logging purposes.
ProblemStatus
Different statuses for a given problem.
In SWIG mode, we don't want anything besides these top-level includes.
glop::MainLpPreprocessor preprocessor
Contains the solution of a LinearProgram as returned by a preprocessor.