diff --git a/examples/python/code_samples_sat.py b/examples/python/code_samples_sat.py index 9edf42ac5a..abda2f86ed 100644 --- a/examples/python/code_samples_sat.py +++ b/examples/python/code_samples_sat.py @@ -56,8 +56,6 @@ class VarArraySolutionPrinter(cp_model.CpSolverSolutionCallback): return self.__solution_count - - def MinimalCpSatAllSolutions(): # Creates the model. model = cp_model.CpModel() diff --git a/ortools/algorithms/dynamic_partition.cc b/ortools/algorithms/dynamic_partition.cc index aaba19416c..3ddf87259a 100644 --- a/ortools/algorithms/dynamic_partition.cc +++ b/ortools/algorithms/dynamic_partition.cc @@ -17,6 +17,7 @@ #include "ortools/base/stringprintf.h" #include "ortools/base/join.h" +#include "ortools/base/join.h" #include "ortools/base/murmur.h" namespace operations_research { diff --git a/ortools/glop/lp_solver.cc b/ortools/glop/lp_solver.cc index 4df7833969..6039acaa54 100644 --- a/ortools/glop/lp_solver.cc +++ b/ortools/glop/lp_solver.cc @@ -169,9 +169,9 @@ ProblemStatus LPSolver::SolveWithTimeLimit(const LinearProgram& lp, // Preprocess. MainLpPreprocessor preprocessor; preprocessor.SetParameters(parameters_); + preprocessor.SetTimeLimit(time_limit); - const bool postsolve_is_needed = preprocessor.Run(¤t_linear_program_, - time_limit); + const bool postsolve_is_needed = preprocessor.Run(¤t_linear_program_); // At this point, we need to initialize a ProblemSolution with the correct // size and status. diff --git a/ortools/glop/preprocessor.cc b/ortools/glop/preprocessor.cc index 74b631b510..94beb879fa 100644 --- a/ortools/glop/preprocessor.cc +++ b/ortools/glop/preprocessor.cc @@ -40,7 +40,10 @@ double trunc(double d) { return d > 0 ? floor(d) : ceil(d); } // Preprocessor // -------------------------------------------------------- Preprocessor::Preprocessor() - : status_(ProblemStatus::INIT), parameters_(), in_mip_context_(false) {} + : status_(ProblemStatus::INIT), + parameters_(), + in_mip_context_(false), + time_limit_(TimeLimit::Infinite().get()) {} Preprocessor::~Preprocessor() {} // -------------------------------------------------------- @@ -49,9 +52,9 @@ Preprocessor::~Preprocessor() {} #define RUN_PREPROCESSOR(name) \ RunAndPushIfRelevant(std::unique_ptr(new name()), #name, \ - time_limit, lp) + time_limit_, lp) -bool MainLpPreprocessor::Run(LinearProgram* lp, TimeLimit* time_limit) { +bool MainLpPreprocessor::Run(LinearProgram* lp) { RETURN_VALUE_IF_NULL(lp, false); initial_num_rows_ = lp->num_constraints(); initial_num_cols_ = lp->num_variables(); @@ -129,6 +132,7 @@ void MainLpPreprocessor::RunAndPushIfRelevant( const double start_time = time_limit->GetElapsedTime(); preprocessor->SetParameters(parameters_); + preprocessor->SetTimeLimit(time_limit); // No need to run the preprocessor if the lp is empty. // TODO(user): without this test, the code is failing as of 2013-03-18. @@ -137,7 +141,7 @@ void MainLpPreprocessor::RunAndPushIfRelevant( return; } - if (preprocessor->Run(lp, time_limit)) { + if (preprocessor->Run(lp)) { const EntryIndex new_num_entries = lp->num_entries(); const double preprocess_time = time_limit->GetElapsedTime() - start_time; VLOG(1) << StringPrintf( @@ -334,20 +338,17 @@ Fractional ComputeMaxVariableBoundsMagnitude(const LinearProgram& lp) { } // namespace -bool EmptyColumnPreprocessor::Run(LinearProgram* linear_program, - TimeLimit* time_limit) { +bool EmptyColumnPreprocessor::Run(LinearProgram* lp) { SCOPED_INSTRUCTION_COUNT; - RETURN_VALUE_IF_NULL(linear_program, false); + RETURN_VALUE_IF_NULL(lp, false); column_deletion_helper_.Clear(); - const ColIndex num_cols = linear_program->num_variables(); + const ColIndex num_cols = lp->num_variables(); for (ColIndex col(0); col < num_cols; ++col) { - if (linear_program->GetSparseColumn(col).IsEmpty()) { - const Fractional lower_bound = - linear_program->variable_lower_bounds()[col]; - const Fractional upper_bound = - linear_program->variable_upper_bounds()[col]; + if (lp->GetSparseColumn(col).IsEmpty()) { + const Fractional lower_bound = lp->variable_lower_bounds()[col]; + const Fractional upper_bound = lp->variable_upper_bounds()[col]; const Fractional objective_coefficient = - linear_program->GetObjectiveCoefficientForMinimizationVersion(col); + lp->GetObjectiveCoefficientForMinimizationVersion(col); Fractional value; if (objective_coefficient == 0) { // Any feasible value will do. @@ -370,15 +371,14 @@ bool EmptyColumnPreprocessor::Run(LinearProgram* linear_program, status_ = ProblemStatus::INFEASIBLE_OR_UNBOUNDED; return false; } - linear_program->SetObjectiveOffset( - linear_program->objective_offset() + - value * linear_program->objective_coefficients()[col]); + lp->SetObjectiveOffset(lp->objective_offset() + + value * lp->objective_coefficients()[col]); } column_deletion_helper_.MarkColumnForDeletionWithState( col, value, ComputeVariableStatus(value, lower_bound, upper_bound)); } } - linear_program->DeleteColumns(column_deletion_helper_.GetMarkedColumns()); + lp->DeleteColumns(column_deletion_helper_.GetMarkedColumns()); return !column_deletion_helper_.IsEmpty(); } @@ -436,8 +436,7 @@ struct ColumnWithRepresentativeAndScaledCost { } // namespace -bool ProportionalColumnPreprocessor::Run(LinearProgram* lp, - TimeLimit* time_limit) { +bool ProportionalColumnPreprocessor::Run(LinearProgram* lp) { SCOPED_INSTRUCTION_COUNT; RETURN_VALUE_IF_NULL(lp, false); ColMapping mapping = FindProportionalColumns( @@ -781,8 +780,7 @@ void ProportionalColumnPreprocessor::RecoverSolution( // ProportionalRowPreprocessor // -------------------------------------------------------- -bool ProportionalRowPreprocessor::Run(LinearProgram* lp, - TimeLimit* time_limit) { +bool ProportionalRowPreprocessor::Run(LinearProgram* lp) { SCOPED_INSTRUCTION_COUNT; RETURN_VALUE_IF_NULL(lp, false); const RowIndex num_rows = lp->num_constraints(); @@ -805,7 +803,7 @@ bool ProportionalRowPreprocessor::Run(LinearProgram* lp, DenseColumn upper_bounds(num_rows, +kInfinity); // Where the new bounds are coming from. Only for the constraints that stay - // in the linear_program and are modified, kInvalidRow otherwise. + // in the lp and are modified, kInvalidRow otherwise. upper_bound_sources_.assign(num_rows, kInvalidRow); lower_bound_sources_.assign(num_rows, kInvalidRow); @@ -1031,7 +1029,7 @@ void ProportionalRowPreprocessor::RecoverSolution( // FixedVariablePreprocessor // -------------------------------------------------------- -bool FixedVariablePreprocessor::Run(LinearProgram* lp, TimeLimit* time_limit) { +bool FixedVariablePreprocessor::Run(LinearProgram* lp) { SCOPED_INSTRUCTION_COUNT; RETURN_VALUE_IF_NULL(lp, false); const ColIndex num_cols = lp->num_variables(); @@ -1064,8 +1062,7 @@ void FixedVariablePreprocessor::RecoverSolution( // ForcingAndImpliedFreeConstraintPreprocessor // -------------------------------------------------------- -bool ForcingAndImpliedFreeConstraintPreprocessor::Run(LinearProgram* lp, - TimeLimit* time_limit) { +bool ForcingAndImpliedFreeConstraintPreprocessor::Run(LinearProgram* lp) { SCOPED_INSTRUCTION_COUNT; RETURN_VALUE_IF_NULL(lp, false); const RowIndex num_rows = lp->num_constraints(); @@ -1298,7 +1295,7 @@ struct ColWithDegree { }; } // namespace -bool ImpliedFreePreprocessor::Run(LinearProgram* lp, TimeLimit* time_limit) { +bool ImpliedFreePreprocessor::Run(LinearProgram* lp) { SCOPED_INSTRUCTION_COUNT; RETURN_VALUE_IF_NULL(lp, false); const RowIndex num_rows = lp->num_constraints(); @@ -1509,13 +1506,12 @@ void ImpliedFreePreprocessor::RecoverSolution(ProblemSolution* solution) const { // DoubletonFreeColumnPreprocessor // -------------------------------------------------------- -bool DoubletonFreeColumnPreprocessor::Run(LinearProgram* lp, - TimeLimit* time_limit) { +bool DoubletonFreeColumnPreprocessor::Run(LinearProgram* lp) { SCOPED_INSTRUCTION_COUNT; RETURN_VALUE_IF_NULL(lp, false); // We will modify the matrix transpose and then push the change to the linear - // program by calling lp->UseTransposeMatrixAsReference(). Note that - // original_matrix will not change during this preprocessor run. + // program by calling lp->UseTransposeMatrixAsReference(). Note + // that original_matrix will not change during this preprocessor run. const SparseMatrix& original_matrix = lp->GetSparseMatrix(); SparseMatrix* transpose = lp->GetMutableTransposeSparseMatrix(); @@ -1689,11 +1685,10 @@ namespace { // Does the constraint block the variable to go to infinity in the given // direction? direction is either positive or negative and row is the index of // the constraint. -bool IsConstraintBlockingVariable(const LinearProgram& linear_program, - Fractional direction, RowIndex row) { - return direction > 0.0 - ? linear_program.constraint_upper_bounds()[row] != kInfinity - : linear_program.constraint_lower_bounds()[row] != -kInfinity; +bool IsConstraintBlockingVariable(const LinearProgram& lp, Fractional direction, + RowIndex row) { + return direction > 0.0 ? lp.constraint_upper_bounds()[row] != kInfinity + : lp.constraint_lower_bounds()[row] != -kInfinity; } } // namespace @@ -1745,8 +1740,7 @@ void UnconstrainedVariablePreprocessor::RemoveZeroCostUnconstrainedVariable( lp->variable_upper_bounds()[col])); } -bool UnconstrainedVariablePreprocessor::Run(LinearProgram* lp, - TimeLimit* time_limit) { +bool UnconstrainedVariablePreprocessor::Run(LinearProgram* lp) { SCOPED_INSTRUCTION_COUNT; RETURN_VALUE_IF_NULL(lp, false); const Fractional tolerance = parameters_.preprocessor_zero_tolerance(); @@ -2033,21 +2027,18 @@ void UnconstrainedVariablePreprocessor::RecoverSolution( // FreeConstraintPreprocessor // -------------------------------------------------------- -bool FreeConstraintPreprocessor::Run(LinearProgram* linear_program, - TimeLimit* time_limit) { +bool FreeConstraintPreprocessor::Run(LinearProgram* lp) { SCOPED_INSTRUCTION_COUNT; - RETURN_VALUE_IF_NULL(linear_program, false); - const RowIndex num_rows = linear_program->num_constraints(); + RETURN_VALUE_IF_NULL(lp, false); + const RowIndex num_rows = lp->num_constraints(); for (RowIndex row(0); row < num_rows; ++row) { - const Fractional lower_bound = - linear_program->constraint_lower_bounds()[row]; - const Fractional upper_bound = - linear_program->constraint_upper_bounds()[row]; + const Fractional lower_bound = lp->constraint_lower_bounds()[row]; + const Fractional upper_bound = lp->constraint_upper_bounds()[row]; if (lower_bound == -kInfinity && upper_bound == kInfinity) { row_deletion_helper_.MarkRowForDeletion(row); } } - linear_program->DeleteRows(row_deletion_helper_.GetMarkedRows()); + lp->DeleteRows(row_deletion_helper_.GetMarkedRows()); return !row_deletion_helper_.IsEmpty(); } @@ -2062,8 +2053,7 @@ void FreeConstraintPreprocessor::RecoverSolution( // EmptyConstraintPreprocessor // -------------------------------------------------------- -bool EmptyConstraintPreprocessor::Run(LinearProgram* lp, - TimeLimit* time_limit) { +bool EmptyConstraintPreprocessor::Run(LinearProgram* lp) { SCOPED_INSTRUCTION_COUNT; RETURN_VALUE_IF_NULL(lp, false); const RowIndex num_rows(lp->num_constraints()); @@ -2623,7 +2613,7 @@ bool SingletonPreprocessor::MakeConstraintAnEqualityIfPossible( return false; } -bool SingletonPreprocessor::Run(LinearProgram* lp, TimeLimit* time_limit) { +bool SingletonPreprocessor::Run(LinearProgram* lp) { SCOPED_INSTRUCTION_COUNT; RETURN_VALUE_IF_NULL(lp, false); const SparseMatrix& matrix = lp->GetSparseMatrix(); @@ -2749,8 +2739,7 @@ MatrixEntry SingletonPreprocessor::GetSingletonRowMatrixEntry( // RemoveNearZeroEntriesPreprocessor // -------------------------------------------------------- -bool RemoveNearZeroEntriesPreprocessor::Run(LinearProgram* lp, - TimeLimit* time_limit) { +bool RemoveNearZeroEntriesPreprocessor::Run(LinearProgram* lp) { SCOPED_INSTRUCTION_COUNT; RETURN_VALUE_IF_NULL(lp, false); const ColIndex num_cols = lp->num_variables(); @@ -2824,28 +2813,26 @@ void RemoveNearZeroEntriesPreprocessor::RecoverSolution( // SingletonColumnSignPreprocessor // -------------------------------------------------------- -bool SingletonColumnSignPreprocessor::Run(LinearProgram* linear_program, - TimeLimit* time_limit) { +bool SingletonColumnSignPreprocessor::Run(LinearProgram* lp) { SCOPED_INSTRUCTION_COUNT; - RETURN_VALUE_IF_NULL(linear_program, false); - const ColIndex num_cols = linear_program->num_variables(); + RETURN_VALUE_IF_NULL(lp, false); + const ColIndex num_cols = lp->num_variables(); if (num_cols == 0) return false; changed_columns_.clear(); int num_singletons = 0; for (ColIndex col(0); col < num_cols; ++col) { - SparseColumn* sparse_column = linear_program->GetMutableSparseColumn(col); - const Fractional cost = linear_program->objective_coefficients()[col]; + SparseColumn* sparse_column = lp->GetMutableSparseColumn(col); + const Fractional cost = lp->objective_coefficients()[col]; if (sparse_column->num_entries() == 1) { ++num_singletons; } if (sparse_column->num_entries() == 1 && sparse_column->GetFirstCoefficient() < 0) { sparse_column->MultiplyByConstant(-1.0); - linear_program->SetVariableBounds( - col, -linear_program->variable_upper_bounds()[col], - -linear_program->variable_lower_bounds()[col]); - linear_program->SetObjectiveCoefficient(col, -cost); + lp->SetVariableBounds(col, -lp->variable_upper_bounds()[col], + -lp->variable_lower_bounds()[col]); + lp->SetObjectiveCoefficient(col, -cost); changed_columns_.push_back(col); } } @@ -2874,8 +2861,7 @@ void SingletonColumnSignPreprocessor::RecoverSolution( // DoubletonEqualityRowPreprocessor // -------------------------------------------------------- -bool DoubletonEqualityRowPreprocessor::Run(LinearProgram* lp, - TimeLimit* time_limit) { +bool DoubletonEqualityRowPreprocessor::Run(LinearProgram* lp) { SCOPED_INSTRUCTION_COUNT; RETURN_VALUE_IF_NULL(lp, false); // Note that we don't update the transpose during this preprocessor run. @@ -3131,7 +3117,7 @@ void DoubletonEqualityRowPreprocessor:: // DualizerPreprocessor // -------------------------------------------------------- -bool DualizerPreprocessor::Run(LinearProgram* lp, TimeLimit* time_limit) { +bool DualizerPreprocessor::Run(LinearProgram* lp) { SCOPED_INSTRUCTION_COUNT; RETURN_VALUE_IF_NULL(lp, false); if (parameters_.solve_dual_problem() == GlopParameters::NEVER_DO) { @@ -3381,8 +3367,7 @@ ProblemStatus DualizerPreprocessor::ChangeStatusToDualStatus( // ShiftVariableBoundsPreprocessor // -------------------------------------------------------- -bool ShiftVariableBoundsPreprocessor::Run(LinearProgram* lp, - TimeLimit* time_limit) { +bool ShiftVariableBoundsPreprocessor::Run(LinearProgram* lp) { SCOPED_INSTRUCTION_COUNT; RETURN_VALUE_IF_NULL(lp, false); @@ -3482,7 +3467,7 @@ void ShiftVariableBoundsPreprocessor::RecoverSolution( // ScalingPreprocessor // -------------------------------------------------------- -bool ScalingPreprocessor::Run(LinearProgram* lp, TimeLimit* time_limit) { +bool ScalingPreprocessor::Run(LinearProgram* lp) { SCOPED_INSTRUCTION_COUNT; RETURN_VALUE_IF_NULL(lp, false); if (!parameters_.use_scaling()) return false; @@ -3546,7 +3531,7 @@ void ScalingPreprocessor::RecoverSolution(ProblemSolution* solution) const { // ToMinimizationPreprocessor // -------------------------------------------------------- -bool ToMinimizationPreprocessor::Run(LinearProgram* lp, TimeLimit* time_limit) { +bool ToMinimizationPreprocessor::Run(LinearProgram* lp) { SCOPED_INSTRUCTION_COUNT; RETURN_VALUE_IF_NULL(lp, false); if (lp->IsMaximizationProblem()) { @@ -3570,11 +3555,11 @@ void ToMinimizationPreprocessor::RecoverSolution( // AddSlackVariablesPreprocessor // -------------------------------------------------------- -bool AddSlackVariablesPreprocessor::Run(LinearProgram* lp, - TimeLimit* time_limit) { +bool AddSlackVariablesPreprocessor::Run(LinearProgram* lp) { SCOPED_INSTRUCTION_COUNT; RETURN_VALUE_IF_NULL(lp, false); - lp->AddSlackVariablesWhereNecessary(/*detect_integer_constraints=*/true); + lp->AddSlackVariablesWhereNecessary( + /*detect_integer_constraints=*/true); first_slack_col_ = lp->GetFirstSlackVariable(); return true; } @@ -3615,7 +3600,7 @@ void AddSlackVariablesPreprocessor::RecoverSolution( // -------------------------------------------------------- // SolowHalimPreprocessor // -------------------------------------------------------- -bool SolowHalimPreprocessor::Run(LinearProgram* lp, TimeLimit* time_limit) { +bool SolowHalimPreprocessor::Run(LinearProgram* lp) { RETURN_VALUE_IF_NULL(lp, false); if (!parameters_.use_solowhalim()){ return false; diff --git a/ortools/glop/preprocessor.h b/ortools/glop/preprocessor.h index 6684333716..66d8c79fcd 100644 --- a/ortools/glop/preprocessor.h +++ b/ortools/glop/preprocessor.h @@ -49,7 +49,7 @@ class Preprocessor { // identity function). Also updates status_ to something different from // ProblemStatus::INIT if the problem was solved (including bad statuses // like ProblemStatus::ABNORMAL, ProblemStatus::INFEASIBLE, etc.). - virtual bool Run(LinearProgram* linear_program, TimeLimit* time_limit) = 0; + virtual bool Run(LinearProgram* lp) = 0; // Stores the optimal solution of the linear program that was passed to // Run(). The given solution needs to be set to the optimal solution of the @@ -74,6 +74,8 @@ class Preprocessor { // function on them will cause a LOG(FATAL). virtual void UseInMipContext() { in_mip_context_ = true; } + void SetTimeLimit(TimeLimit* time_limit) { time_limit_ = time_limit; } + protected: // Returns true if a is less than b (or slighlty greater than b with a given // tolerance). @@ -91,6 +93,7 @@ class Preprocessor { ProblemStatus status_; GlopParameters parameters_; bool in_mip_context_; + TimeLimit* time_limit_; private: DISALLOW_COPY_AND_ASSIGN(Preprocessor); @@ -106,7 +109,7 @@ class MainLpPreprocessor : public Preprocessor { MainLpPreprocessor() {} ~MainLpPreprocessor() override {} - bool Run(LinearProgram* linear_program, TimeLimit* time_limit) final; + bool Run(LinearProgram* lp) final; void RecoverSolution(ProblemSolution* solution) const override; private: @@ -233,7 +236,7 @@ class EmptyColumnPreprocessor : public Preprocessor { public: EmptyColumnPreprocessor() {} ~EmptyColumnPreprocessor() final {} - bool Run(LinearProgram* linear_program, TimeLimit* time_limit) final; + bool Run(LinearProgram* lp) final; void RecoverSolution(ProblemSolution* solution) const final; private: @@ -258,7 +261,7 @@ class ProportionalColumnPreprocessor : public Preprocessor { public: ProportionalColumnPreprocessor() {} ~ProportionalColumnPreprocessor() final {} - bool Run(LinearProgram* linear_program, TimeLimit* time_limit) final; + bool Run(LinearProgram* lp) final; void RecoverSolution(ProblemSolution* solution) const final; void UseInMipContext() final { LOG(FATAL) << "Not implemented."; } @@ -296,7 +299,7 @@ class ProportionalRowPreprocessor : public Preprocessor { public: ProportionalRowPreprocessor() {} ~ProportionalRowPreprocessor() final {} - bool Run(LinearProgram* linear_program, TimeLimit* time_limit) final; + bool Run(LinearProgram* lp) final; void RecoverSolution(ProblemSolution* solution) const final; private: @@ -345,8 +348,8 @@ class SingletonUndo { // deleted_rows_ of SingletonPreprocessor, are needed to undo an operation // with the given type. Note that all the arguments must refer to the linear // program BEFORE the operation is applied. - SingletonUndo(OperationType type, const LinearProgram& linear_program, - MatrixEntry e, ConstraintStatus status); + SingletonUndo(OperationType type, const LinearProgram& lp, MatrixEntry e, + ConstraintStatus status); // Undo the operation saved in this class, taking into account the deleted // columns and rows passed by the calling instance of SingletonPreprocessor. @@ -392,7 +395,7 @@ class SingletonPreprocessor : public Preprocessor { public: SingletonPreprocessor() {} ~SingletonPreprocessor() final {} - bool Run(LinearProgram* linear_program, TimeLimit* time_limit) final; + bool Run(LinearProgram* lp) final; void RecoverSolution(ProblemSolution* solution) const final; private: @@ -473,7 +476,7 @@ class FixedVariablePreprocessor : public Preprocessor { public: FixedVariablePreprocessor() {} ~FixedVariablePreprocessor() final {} - bool Run(LinearProgram* linear_program, TimeLimit* time_limit) final; + bool Run(LinearProgram* lp) final; void RecoverSolution(ProblemSolution* solution) const final; private: @@ -505,7 +508,7 @@ class ForcingAndImpliedFreeConstraintPreprocessor : public Preprocessor { public: ForcingAndImpliedFreeConstraintPreprocessor() {} ~ForcingAndImpliedFreeConstraintPreprocessor() final {} - bool Run(LinearProgram* linear_program, TimeLimit* time_limit) final; + bool Run(LinearProgram* lp) final; void RecoverSolution(ProblemSolution* solution) const final; private: @@ -547,7 +550,7 @@ class ImpliedFreePreprocessor : public Preprocessor { public: ImpliedFreePreprocessor() {} ~ImpliedFreePreprocessor() final {} - bool Run(LinearProgram* linear_program, TimeLimit* time_limit) final; + bool Run(LinearProgram* lp) final; void RecoverSolution(ProblemSolution* solution) const final; private: @@ -592,7 +595,7 @@ class DoubletonFreeColumnPreprocessor : public Preprocessor { public: DoubletonFreeColumnPreprocessor() {} ~DoubletonFreeColumnPreprocessor() final {} - bool Run(LinearProgram* linear_program, TimeLimit* time_limit) final; + bool Run(LinearProgram* lp) final; void RecoverSolution(ProblemSolution* solution) const final; private: @@ -640,7 +643,7 @@ class UnconstrainedVariablePreprocessor : public Preprocessor { public: UnconstrainedVariablePreprocessor() {} ~UnconstrainedVariablePreprocessor() final {} - bool Run(LinearProgram* linear_program, TimeLimit* time_limit) final; + bool Run(LinearProgram* lp) final; void RecoverSolution(ProblemSolution* solution) const final; // Removes the given variable and all the rows in which it appears: If a @@ -691,7 +694,7 @@ class FreeConstraintPreprocessor : public Preprocessor { public: FreeConstraintPreprocessor() {} ~FreeConstraintPreprocessor() final {} - bool Run(LinearProgram* linear_program, TimeLimit* time_limit) final; + bool Run(LinearProgram* lp) final; void RecoverSolution(ProblemSolution* solution) const final; private: @@ -707,7 +710,7 @@ class EmptyConstraintPreprocessor : public Preprocessor { public: EmptyConstraintPreprocessor() {} ~EmptyConstraintPreprocessor() final {} - bool Run(LinearProgram* linear_program, TimeLimit* time_limit) final; + bool Run(LinearProgram* lp) final; void RecoverSolution(ProblemSolution* solution) const final; private: @@ -729,7 +732,7 @@ class RemoveNearZeroEntriesPreprocessor : public Preprocessor { public: RemoveNearZeroEntriesPreprocessor() {} ~RemoveNearZeroEntriesPreprocessor() final {} - bool Run(LinearProgram* linear_program, TimeLimit* time_limit) final; + bool Run(LinearProgram* lp) final; void RecoverSolution(ProblemSolution* solution) const final; private: @@ -747,7 +750,7 @@ class SingletonColumnSignPreprocessor : public Preprocessor { public: SingletonColumnSignPreprocessor() {} ~SingletonColumnSignPreprocessor() final {} - bool Run(LinearProgram* linear_program, TimeLimit* time_limit) final; + bool Run(LinearProgram* lp) final; void RecoverSolution(ProblemSolution* solution) const final; private: @@ -765,7 +768,7 @@ class DoubletonEqualityRowPreprocessor : public Preprocessor { public: DoubletonEqualityRowPreprocessor() {} ~DoubletonEqualityRowPreprocessor() final {} - bool Run(LinearProgram* linear_program, TimeLimit* time_limit) final; + bool Run(LinearProgram* lp) final; void RecoverSolution(ProblemSolution* solution) const final; private: @@ -831,7 +834,7 @@ class DualizerPreprocessor : public Preprocessor { public: DualizerPreprocessor() {} ~DualizerPreprocessor() final {} - bool Run(LinearProgram* linear_program, TimeLimit* time_limit) final; + bool Run(LinearProgram* lp) final; void RecoverSolution(ProblemSolution* solution) const final; void UseInMipContext() final { LOG(FATAL) << "In the presence of integer variables, " @@ -888,7 +891,7 @@ class ShiftVariableBoundsPreprocessor : public Preprocessor { public: ShiftVariableBoundsPreprocessor() {} ~ShiftVariableBoundsPreprocessor() final {} - bool Run(LinearProgram* linear_program, TimeLimit* time_limit) final; + bool Run(LinearProgram* lp) final; void RecoverSolution(ProblemSolution* solution) const final; private: @@ -912,7 +915,7 @@ class ScalingPreprocessor : public Preprocessor { public: ScalingPreprocessor() {} ~ScalingPreprocessor() final {} - bool Run(LinearProgram* linear_program, TimeLimit* time_limit) final; + bool Run(LinearProgram* lp) final; void RecoverSolution(ProblemSolution* solution) const final; void UseInMipContext() final { LOG(FATAL) << "Not implemented."; } @@ -936,7 +939,7 @@ class ToMinimizationPreprocessor : public Preprocessor { public: ToMinimizationPreprocessor() {} ~ToMinimizationPreprocessor() final {} - bool Run(LinearProgram* linear_program, TimeLimit* time_limit) final; + bool Run(LinearProgram* lp) final; void RecoverSolution(ProblemSolution* solution) const final; private: @@ -960,7 +963,7 @@ class AddSlackVariablesPreprocessor : public Preprocessor { public: AddSlackVariablesPreprocessor() {} ~AddSlackVariablesPreprocessor() final {} - bool Run(LinearProgram* linear_program, TimeLimit* time_limit) final; + bool Run(LinearProgram* lp) final; void RecoverSolution(ProblemSolution* solution) const final; private: @@ -989,7 +992,7 @@ class SolowHalimPreprocessor : public Preprocessor { public: SolowHalimPreprocessor() {} ~SolowHalimPreprocessor() final {} - bool Run(LinearProgram* linear_program, TimeLimit* time_limit) final; + bool Run(LinearProgram* lp) final; void RecoverSolution(ProblemSolution* solution) const final; private: diff --git a/ortools/linear_solver/linear_solver.cc b/ortools/linear_solver/linear_solver.cc index e409526bfa..7c8c930400 100644 --- a/ortools/linear_solver/linear_solver.cc +++ b/ortools/linear_solver/linear_solver.cc @@ -1677,3 +1677,4 @@ int MPSolverParameters::GetIntegerParam(MPSolverParameters::IntegerParam param) } // namespace operations_research + diff --git a/ortools/lp_data/sparse.h b/ortools/lp_data/sparse.h index e801366491..fc93ac0f45 100644 --- a/ortools/lp_data/sparse.h +++ b/ortools/lp_data/sparse.h @@ -268,6 +268,15 @@ class MatrixView { StrictITIVector columns_; }; +extern template void SparseMatrix::PopulateFromTranspose( + const SparseMatrix& input); +extern template void SparseMatrix::PopulateFromPermutedMatrix( + const SparseMatrix& a, const RowPermutation& row_perm, + const ColumnPermutation& inverse_col_perm); +extern template void SparseMatrix::PopulateFromPermutedMatrix( + const MatrixView& a, const RowPermutation& row_perm, + const ColumnPermutation& inverse_col_perm); + // Another matrix representation which is more efficient than a SparseMatrix but // doesn't allow matrix modification. It is faster to construct, uses less // memory and provides a better cache locality when iterating over the non-zeros diff --git a/ortools/sat/python/cp_model.py b/ortools/sat/python/cp_model.py index f3b816ddb4..284e6ee636 100644 --- a/ortools/sat/python/cp_model.py +++ b/ortools/sat/python/cp_model.py @@ -1011,7 +1011,7 @@ class CpSolver(object): def Solve(self, model): """Solves the given model and returns the solve status.""" self.__solution = pywrapsat.SatHelper.SolveWithParameters( - model.ModelProto(), self.parameters) + model.ModelProto(), self.parameters) return self.__solution.status def SolveWithSolutionObserver(self, model, callback):