minor sync with internal code
This commit is contained in:
@@ -40,7 +40,7 @@ void FapModelPrinter::PrintFapVariables() {
|
||||
for (const int value : it.second.domain) {
|
||||
StringAppendF(&domain, "%d ", value);
|
||||
}
|
||||
StringAppendF(&domain, "}");
|
||||
domain.append("}");
|
||||
|
||||
std::string hard = " ";
|
||||
if (it.second.hard) {
|
||||
|
||||
@@ -337,6 +337,9 @@ int Run() {
|
||||
printf("s UNSATISFIABLE\n");
|
||||
}
|
||||
|
||||
// Print status.
|
||||
printf("c status: %s\n", SatStatusString(result).c_str());
|
||||
|
||||
// Print objective value.
|
||||
if (solution.empty()) {
|
||||
printf("c objective: na\n");
|
||||
@@ -349,13 +352,13 @@ int Run() {
|
||||
}
|
||||
|
||||
// Print final statistics.
|
||||
printf("c status: %s\n", SatStatusString(result).c_str());
|
||||
printf("c booleans: %d\n", solver->NumVariables());
|
||||
printf("c conflicts: %lld\n", solver->num_failures());
|
||||
printf("c branches: %lld\n", solver->num_branches());
|
||||
printf("c propagations: %lld\n", solver->num_propagations());
|
||||
printf("c walltime: %f\n", wall_timer.Get());
|
||||
printf("c usertime: %f\n", user_timer.Get());
|
||||
printf("c deterministic time: %f\n", solver->deterministic_time());
|
||||
printf("c deterministic_time: %f\n", solver->deterministic_time());
|
||||
|
||||
// The SAT competition requires a particular exit code and since we don't
|
||||
// really use it for any other purpose, we comply.
|
||||
|
||||
@@ -194,6 +194,39 @@ void LPSolver::Clear() {
|
||||
revised_simplex_.reset(nullptr);
|
||||
}
|
||||
|
||||
void LPSolver::SetInitialBasis(
|
||||
const VariableStatusRow& variable_statuses,
|
||||
const ConstraintStatusColumn& constraint_statuses) {
|
||||
// Create the associated basis state.
|
||||
BasisState state;
|
||||
state.statuses = variable_statuses;
|
||||
for (const ConstraintStatus status : constraint_statuses) {
|
||||
// Note the change of upper/lower bound between the status of a constraint
|
||||
// and the status of its associated slack variable.
|
||||
switch (status) {
|
||||
case ConstraintStatus::FREE:
|
||||
state.statuses.push_back(VariableStatus::FREE);
|
||||
break;
|
||||
case ConstraintStatus::AT_LOWER_BOUND:
|
||||
state.statuses.push_back(VariableStatus::AT_UPPER_BOUND);
|
||||
break;
|
||||
case ConstraintStatus::AT_UPPER_BOUND:
|
||||
state.statuses.push_back(VariableStatus::AT_LOWER_BOUND);
|
||||
break;
|
||||
case ConstraintStatus::FIXED_VALUE:
|
||||
state.statuses.push_back(VariableStatus::FIXED_VALUE);
|
||||
break;
|
||||
case ConstraintStatus::BASIC:
|
||||
state.statuses.push_back(VariableStatus::BASIC);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (revised_simplex_ == nullptr) {
|
||||
revised_simplex_.reset(new RevisedSimplex());
|
||||
}
|
||||
revised_simplex_->LoadStateForNextSolve(state);
|
||||
}
|
||||
|
||||
namespace {
|
||||
// Computes the "real" problem objective from the one without offset nor
|
||||
// scaling.
|
||||
|
||||
@@ -63,6 +63,23 @@ class LPSolver {
|
||||
// result, assuming that no time limit was specified.
|
||||
void Clear();
|
||||
|
||||
// Advanced usage. This should be called before calling Solve(). It will
|
||||
// configure the solver to try to start from the given point. Note that
|
||||
// calling Clear() will invalidate this information.
|
||||
//
|
||||
// If the set of variables/constraints with a BASIC status does not form a
|
||||
// basis a warning will be logged and the code will ignore it. Otherwise, the
|
||||
// non-basic variables will be initialized to their given status and solving
|
||||
// will start from there (even if the solution is not primal/dual feasible).
|
||||
//
|
||||
// Important: There is no facility to transform this information in sync with
|
||||
// presolve. So you should probably disable presolve when using this since
|
||||
// otherwise there is a good chance that the matrix will change and that the
|
||||
// given basis will make no sense. Even worse if it happens to be factorizable
|
||||
// but doesn't correspond to what was intended.
|
||||
void SetInitialBasis(const VariableStatusRow& variable_statuses,
|
||||
const ConstraintStatusColumn& constraint_statuses);
|
||||
|
||||
// This loads a given solution and computes related quantities so that the
|
||||
// getters below will refer to it.
|
||||
//
|
||||
|
||||
@@ -118,8 +118,6 @@ RevisedSimplex::RevisedSimplex()
|
||||
|
||||
void RevisedSimplex::ClearStateForNextSolve() {
|
||||
SCOPED_TIME_STAT(&function_stats_);
|
||||
solution_state_.num_rows = RowIndex(0);
|
||||
solution_state_.num_cols = ColIndex(0);
|
||||
solution_state_.statuses.clear();
|
||||
}
|
||||
|
||||
@@ -834,10 +832,8 @@ void RevisedSimplex::InitializeVariableStatusesForWarmStart(
|
||||
|
||||
// Start with the given "warm" status from the BasisState if it exists.
|
||||
VariableStatus status = default_status;
|
||||
if (col < num_cols_) {
|
||||
if (col < state.num_cols) {
|
||||
status = state.statuses[col];
|
||||
}
|
||||
if (col < state.statuses.size()) {
|
||||
status = state.statuses[col];
|
||||
}
|
||||
|
||||
// Remove incompatibilities between the warm status and the variable bounds.
|
||||
@@ -1176,8 +1172,6 @@ void RevisedSimplex::DisplayBasicVariableStatistics() {
|
||||
|
||||
void RevisedSimplex::SaveState() {
|
||||
DCHECK_EQ(num_cols_, variables_info_.GetStatusRow().size());
|
||||
solution_state_.num_rows = num_rows_;
|
||||
solution_state_.num_cols = num_cols_;
|
||||
solution_state_.statuses = variables_info_.GetStatusRow();
|
||||
solution_state_has_been_set_externally_ = false;
|
||||
}
|
||||
|
||||
@@ -120,24 +120,19 @@
|
||||
namespace operations_research {
|
||||
namespace glop {
|
||||
|
||||
// This is the minimal amount of information needed to perform a "warm start".
|
||||
// Holds the statuses of the all the variables, including slack variables. There
|
||||
// is no point storing constraint statuses since internally all constraints are
|
||||
// always fixed to zero.
|
||||
//
|
||||
// Holds the statuses of the variables and the slack variables. Using this
|
||||
// information and the original linear program, the basis can be refactorized
|
||||
// and all the needed quantities derived.
|
||||
// Note that this is the minimal amount of information needed to perform a "warm
|
||||
// start". Using this information and the original linear program, the basis can
|
||||
// be refactorized and all the needed quantities derived.
|
||||
//
|
||||
// TODO(user): Introduce another state class to store a complete state of the
|
||||
// solver. Using this state and the original linear program, the solver can be
|
||||
// restarted with as little time overhead as possible. This is especially useful
|
||||
// for strong branching in a MIP context.
|
||||
struct BasisState {
|
||||
// The linear program size for which this state was saved.
|
||||
RowIndex num_rows;
|
||||
ColIndex num_cols;
|
||||
|
||||
// This vector first contains the num_cols normal variable statuses and then
|
||||
// the num_rows slack variable statuses.
|
||||
//
|
||||
// TODO(user): A MIP solver will potentially store a lot of BasicStates so
|
||||
// memory usage is important. It is possible to use only 2 bits for one
|
||||
// VariableStatus enum. To achieve this, the FIXED_VALUE status can be
|
||||
|
||||
Reference in New Issue
Block a user