Google OR-Tools: ortools/linear_solver/glop_interface.cc Source File

1

2

3

4

5

6

7

8

9

10

11

12

13

14#include <atomic>

15#include <cstdint>

16#include <memory>

17#include <string>

18#include <utility>

19#include <vector>

20

21#include "absl/base/attributes.h"

22#include "absl/log/check.h"

35

37 public:

40

41

44

45

50 std::atomic<bool>* interrupt) override {

52 }

53

54

55 void Reset() override;

63 double new_value, double old_value) override;

66 double coefficient) override;

69

70

72 int64_t nodes() const override;

75

76

78 bool IsLP() const override;

79 bool IsMIP() const override;

80

83

87

89 const std::vector<MPSolver::BasisStatus>& variable_statuses,

90 const std::vector<MPSolver::BasisStatus>& constraint_statuses) override;

91

100 const std::string& parameters) override;

101

102 private:

103 void NonIncrementalChange();

104

107 std::vector<MPSolver::BasisStatus> column_status_;

108 std::vector<MPSolver::BasisStatus> row_status_;

110 std::atomic<bool> interrupt_solver_;

111};

112

115 linear_program_(),

116 lp_solver_(),

117 column_status_(),

118 row_status_(),

119 parameters_(),

120 interrupt_solver_(false) {}

121

123

125

126

128 linear_program_.Clear();

129 interrupt_solver_ = false;

132

133 linear_program_.SetMaximizationProblem(maximize_);

134 linear_program_.CleanUp();

135

136

137 if (solver_->time_limit()) {

138 VLOG(1) << "Setting time limit = " << solver_->time_limit() << " ms.";

139 parameters_.set_max_time_in_seconds(

140 static_cast<double>(solver_->time_limit()) / 1000.0);

141 }

142

143 solver_->SetSolverSpecificParametersAsString(

144 solver_->solver_specific_parameter_string_);

145 lp_solver_.SetParameters(parameters_);

146 std::unique_ptr<TimeLimit> time_limit =

148 time_limit->RegisterExternalBooleanAsLimit(&interrupt_solver_);

150 lp_solver_.SolveWithTimeLimit(linear_program_, time_limit.get());

151

152

156

157 const int num_vars = solver_->variables_.size();

159 for (int var_id = 0; var_id < num_vars; ++var_id) {

161 const glop::ColIndex lp_solver_var_id(var->index());

162

164 lp_solver_.variable_values()[lp_solver_var_id];

166

168 lp_solver_.reduced_costs()[lp_solver_var_id];

170

172 lp_solver_.variable_statuses()[lp_solver_var_id];

174 }

175

176 const int num_constraints = solver_->constraints_.size();

178 for (int ct_id = 0; ct_id < num_constraints; ++ct_id) {

180 const glop::RowIndex lp_solver_ct_id(ct->index());

181

183 lp_solver_.dual_values()[lp_solver_ct_id];

185

187 lp_solver_.constraint_statuses()[lp_solver_ct_id];

189 }

190

192}

193

195 interrupt_solver_ = true;

196 return true;

197}

198

200

201

202 lp_solver_.Clear();

203}

204

206 NonIncrementalChange();

207}

208

210 NonIncrementalChange();

211}

212

214 LOG(WARNING) << "Glop doesn't deal with integer variables.";

215}

216

218 NonIncrementalChange();

219}

220

222 NonIncrementalChange();

223}

224

226 NonIncrementalChange();

227}

228

231 double new_value, double old_value) {

232 NonIncrementalChange();

233}

234

236 NonIncrementalChange();

237}

238

240 double coefficient) {

241 NonIncrementalChange();

242}

243

245

247

249 return lp_solver_.GetNumberOfSimplexIterations();

250}

251

253 LOG(DFATAL) << "Number of nodes only available for discrete problems";

255}

256

258 return row_status_[constraint_index];

259}

260

262 return column_status_[variable_index];

263}

264

266

268

270

274

276

280

281 const glop::ColIndex num_cols(solver_->variables_.size());

284 const glop::ColIndex new_col = linear_program_.CreateNewVariable();

285 DCHECK_EQ(new_col, col);

287 linear_program_.SetVariableBounds(col, var->lb(), var->ub());

288 }

289}

290

293

294 const glop::RowIndex num_rows(solver_->constraints_.size());

295 for (glop::RowIndex row(0); row < num_rows; ++row) {

298

299 const double lb = ct->lb();

300 const double ub = ct->ub();

301 const glop::RowIndex new_row = linear_program_.CreateNewConstraint();

302 DCHECK_EQ(new_row, row);

303 linear_program_.SetConstraintBounds(row, lb, ub);

304

305 for (const auto& entry : ct->coefficients_) {

306 const int var_index = entry.first->index();

308 const glop::ColIndex col(var_index);

309 const double coeff = entry.second;

310 linear_program_.SetCoefficient(row, col, coeff);

311 }

312 }

313}

314

316 linear_program_.SetObjectiveOffset(solver_->Objective().offset());

317 for (const auto& entry : solver_->objective_->coefficients_) {

318 const int var_index = entry.first->index();

319 const glop::ColIndex col(var_index);

320 const double coeff = entry.second;

321 linear_program_.SetObjectiveCoefficient(col, coeff);

322 }

323}

324

326 const std::vector<MPSolver::BasisStatus>& variable_statuses,

327 const std::vector<MPSolver::BasisStatus>& constraint_statuses) {

332 }

335 }

336 lp_solver_.SetInitialBasis(glop_variable_statuses, glop_constraint_statuses);

337}

338

340 parameters_.Clear();

341 parameters_.set_log_search_progress(!quiet_);

344}

345

352

354

355

356

359 value);

360 }

361}

362

371

373 switch (value) {

375 parameters_.set_use_preprocessing(false);

376 break;

378 parameters_.set_use_preprocessing(true);

379 break;

380 default:

383 }

384 }

385}

386

388 switch (value) {

390 parameters_.set_use_scaling(false);

391 break;

393 parameters_.set_use_scaling(true);

394 break;

395 default:

398 }

399 }

400}

401

403 switch (value) {

405 parameters_.set_use_dual_simplex(true);

406 break;

408 parameters_.set_use_dual_simplex(false);

409 break;

410 default:

413 value);

414 }

415 }

416}

417

419 const std::string& parameters) {

420

421

422

423

425 lp_solver_.SetParameters(parameters_);

426 return true;

427 }

428 return false;

429}

430

431void GLOPInterface::NonIncrementalChange() {

432

434}

435

436namespace {

437

438

439const void* const kRegisterGlop ABSL_ATTRIBUTE_UNUSED = [] {

441 [](MPSolver* const solver) { return new GLOPInterface(solver); },

443 return nullptr;

444}();

445

446}

447

448}

int64_t nodes() const override

Definition glop_interface.cc:252

void SetParameters(const MPSolverParameters &param) override

Definition glop_interface.cc:339

void SetRelativeMipGap(double value) override

Definition glop_interface.cc:346

void ExtractNewConstraints() override

Definition glop_interface.cc:291

void SetCoefficient(MPConstraint *constraint, const MPVariable *variable, double new_value, double old_value) override

Definition glop_interface.cc:229

bool IsMIP() const override

Definition glop_interface.cc:269

void ExtractNewVariables() override

Definition glop_interface.cc:277

bool InterruptSolve() override

Definition glop_interface.cc:194

bool IsContinuous() const override

Definition glop_interface.cc:265

void SetVariableInteger(int index, bool integer) override

Definition glop_interface.cc:213

GLOPInterface(MPSolver *solver)

Definition glop_interface.cc:113

bool SetSolverSpecificParametersAsString(const std::string &parameters) override

Definition glop_interface.cc:418

MPSolutionResponse DirectlySolveProto(LazyMutableCopy< MPModelRequest > request, std::atomic< bool > *interrupt) override

Definition glop_interface.cc:49

void SetObjectiveOffset(double value) override

Definition glop_interface.cc:244

void Reset() override

Definition glop_interface.cc:199

void ClearConstraint(MPConstraint *constraint) override

Definition glop_interface.cc:235

void SetPrimalTolerance(double value) override

Definition glop_interface.cc:353

void * underlying_solver() override

Definition glop_interface.cc:275

void AddRowConstraint(MPConstraint *ct) override

Definition glop_interface.cc:221

void ExtractObjective() override

Definition glop_interface.cc:315

void SetObjectiveCoefficient(const MPVariable *variable, double coefficient) override

Definition glop_interface.cc:239

MPSolver::ResultStatus Solve(const MPSolverParameters &param) override

Definition glop_interface.cc:124

void ClearObjective() override

Definition glop_interface.cc:246

~GLOPInterface() override

Definition glop_interface.cc:122

MPSolver::BasisStatus row_status(int constraint_index) const override

Definition glop_interface.cc:257

int64_t iterations() const override

Definition glop_interface.cc:248

MPSolver::BasisStatus column_status(int variable_index) const override

Definition glop_interface.cc:261

void SetConstraintBounds(int index, double lb, double ub) override

Definition glop_interface.cc:217

bool IsLP() const override

Definition glop_interface.cc:267

void SetOptimizationDirection(bool maximize) override

Definition glop_interface.cc:205

void SetDualTolerance(double value) override

Definition glop_interface.cc:363

void SetStartingLpBasis(const std::vector< MPSolver::BasisStatus > &variable_statuses, const std::vector< MPSolver::BasisStatus > &constraint_statuses) override

Definition glop_interface.cc:325

void SetVariableBounds(int index, double lb, double ub) override

Definition glop_interface.cc:209

std::string SolverVersion() const override

Definition glop_interface.cc:271

void SetPresolveMode(int value) override

Definition glop_interface.cc:372

void AddVariable(MPVariable *var) override

Definition glop_interface.cc:225

void SetScalingMode(int value) override

Definition glop_interface.cc:387

void SetLpAlgorithm(int value) override

Definition glop_interface.cc:402

bool SupportsDirectlySolveProto(std::atomic< bool > *interrupt) const override

Definition glop_interface.cc:46

void set_dual_value(double dual_value)

double lb() const

Returns the lower bound.

double ub() const

Returns the upper bound.

int index() const

Returns the index of the constraint in the MPSolver::constraints_.

static MPSolverInterfaceFactoryRepository * GetInstance()

void Register(MPSolverInterfaceFactory factory, MPSolver::OptimizationProblemType problem_type, std::function< bool()> is_runtime_ready={})

void set_variable_as_extracted(int var_index, bool extracted)

friend class MPConstraint

void set_constraint_as_extracted(int ct_index, bool extracted)

void ResetExtractionInformation()

virtual void SetIntegerParamToUnsupportedValue(MPSolverParameters::IntegerParam param, int value)

int last_constraint_index_

bool variable_is_extracted(int var_index) const

static constexpr int64_t kUnknownNumberOfNodes

void SetDoubleParamToUnsupportedValue(MPSolverParameters::DoubleParam param, double value)

MPSolverInterface(MPSolver *solver)

void SetCommonParameters(const MPSolverParameters &param)

MPSolver::ResultStatus result_status_

SynchronizationStatus sync_status_

@ DUAL_TOLERANCE

Advanced usage: tolerance for dual feasibility of basic solutions.

@ RELATIVE_MIP_GAP

Limit for relative MIP gap.

@ PRESOLVE_OFF

Presolve is off.

@ PRESOLVE_ON

Presolve is on.

static const int kDefaultIntegerParamValue

@ PRESOLVE

Advanced usage: presolve mode.

@ LP_ALGORITHM

Algorithm to solve linear programs.

@ SCALING

Advanced usage: enable or disable matrix scaling.

@ SCALING_ON

Scaling is on.

@ SCALING_OFF

Scaling is off.

int GetIntegerParam(MPSolverParameters::IntegerParam param) const

Returns the value of an integer parameter.

static const double kDefaultDoubleParamValue

@ GLOP_LINEAR_PROGRAMMING

The class for variables of a Mathematical Programming (MP) model.

double lb() const

Returns the lower bound.

double ub() const

Returns the upper bound.

void set_reduced_cost(double reduced_cost)

void set_solution_value(double value)

int index() const

Returns the index of the variable in the MPSolver::variables_.

static std::unique_ptr< TimeLimit > FromParameters(const Parameters &parameters)

static std::string GlopVersion()

void push_back(const value_type &val)

StrictITIVector< RowIndex, ConstraintStatus > ConstraintStatusColumn

StrictITIVector< ColIndex, VariableStatus > VariableStatusRow

MPSolver::ResultStatus GlopToMPSolverResultStatus(glop::ProblemStatus s)

glop::VariableStatus MPSolverToGlopVariableStatus(MPSolver::BasisStatus s)

glop::ConstraintStatus MPSolverToGlopConstraintStatus(MPSolver::BasisStatus s)

MPSolutionResponse GlopSolveProto(LazyMutableCopy< MPModelRequest > request, std::atomic< bool > *interrupt_solve, std::function< void(const std::string &)> logging_callback)

bool ProtobufTextFormatMergeFromString(absl::string_view proto_text_string, ProtoType *proto)

MPSolver::BasisStatus GlopToMPSolverConstraintStatus(glop::ConstraintStatus s)

MPSolver::BasisStatus GlopToMPSolverVariableStatus(glop::VariableStatus s)