diff --git a/ortools/glop/revised_simplex.cc b/ortools/glop/revised_simplex.cc index 71b29b440f..a21e888cec 100644 --- a/ortools/glop/revised_simplex.cc +++ b/ortools/glop/revised_simplex.cc @@ -269,12 +269,7 @@ Status RevisedSimplex::Solve(const LinearProgram& lp, TimeLimit* time_limit) { // // Note(user): Currently, we never do both at the same time, so we could // be a bit faster here, but then this is quick anyway. - const VariableStatusRow& statuses = variables_info_.GetStatusRow(); - for (ColIndex col(0); col < num_cols_; ++col) { - if (statuses[col] != VariableStatus::BASIC) { - SetNonBasicVariableStatusAndDeriveValue(col, statuses[col]); - } - } + variable_values_.ResetAllNonBasicVariableValues(); GLOP_RETURN_IF_ERROR(basis_factorization_.Refactorize()); PermuteBasis(); variable_values_.RecomputeBasicVariableValues(); @@ -895,7 +890,7 @@ void RevisedSimplex::InitializeVariableStatusesForWarmStart( if (num_basic_variables == num_rows_) { VLOG(1) << "Too many basic variables in the warm-start basis." << "Only keeping the first ones as VariableStatus::BASIC."; - SetNonBasicVariableStatusAndDeriveValue(col, default_status); + variables_info_.UpdateToNonBasicStatus(col, default_status); } else { ++num_basic_variables; variables_info_.UpdateToBasicStatus(col); @@ -914,9 +909,12 @@ void RevisedSimplex::InitializeVariableStatusesForWarmStart( upper_bound_[col] == kInfinity))) { status = default_status; } - SetNonBasicVariableStatusAndDeriveValue(col, status); + variables_info_.UpdateToNonBasicStatus(col, status); } } + + // Initialize the values. + variable_values_.ResetAllNonBasicVariableValues(); } // This implementation starts with an initial matrix B equal to the identity diff --git a/ortools/glop/variable_values.cc b/ortools/glop/variable_values.cc index f62cee9531..18ffc2fa2e 100644 --- a/ortools/glop/variable_values.cc +++ b/ortools/glop/variable_values.cc @@ -62,6 +62,31 @@ void VariableValues::SetNonBasicVariableValueFromStatus(ColIndex col) { // get a compile-time error if a value is missing. } +void VariableValues::ResetAllNonBasicVariableValues() { + const DenseRow& lower_bounds = variables_info_.GetVariableLowerBounds(); + const DenseRow& upper_bounds = variables_info_.GetVariableUpperBounds(); + const VariableStatusRow& statuses = variables_info_.GetStatusRow(); + const ColIndex num_cols = matrix_.num_cols(); + variable_values_.resize(num_cols, 0.0); + for (ColIndex col(0); col < num_cols; ++col) { + switch (statuses[col]) { + case VariableStatus::FIXED_VALUE: + ABSL_FALLTHROUGH_INTENDED; + case VariableStatus::AT_LOWER_BOUND: + variable_values_[col] = lower_bounds[col]; + break; + case VariableStatus::AT_UPPER_BOUND: + variable_values_[col] = upper_bounds[col]; + break; + case VariableStatus::FREE: + variable_values_[col] = 0.0; + break; + case VariableStatus::BASIC: + break; + } + } +} + void VariableValues::RecomputeBasicVariableValues() { SCOPED_TIME_STAT(&stats_); DCHECK(basis_factorization_.IsRefactorized()); diff --git a/ortools/glop/variable_values.h b/ortools/glop/variable_values.h index 27b515fe83..3e6add76ec 100644 --- a/ortools/glop/variable_values.h +++ b/ortools/glop/variable_values.h @@ -52,6 +52,9 @@ class VariableValues { // function and it is up to the client to call RecomputeBasicVariableValues(). void SetNonBasicVariableValueFromStatus(ColIndex col); + // Calls SetNonBasicVariableValueFromStatus() on all non-basic variables. + void ResetAllNonBasicVariableValues(); + // Recomputes the value of the basic variables from the non-basic ones knowing // that the linear program matrix A times the variable values vector must be // zero. It is better to call this when the basis is refactorized. This