 |
OR-Tools
8.0
|
Go to the documentation of this file.
22 #include "absl/status/status.h"
23 #include "absl/strings/str_format.h"
35 #include "CbcConfig.h"
36 #include "CbcMessage.hpp"
37 #include "CbcModel.hpp"
38 #include "CoinModel.hpp"
39 #include "OsiClpSolverInterface.hpp"
52 void Reset()
override;
60 CHECK_GE(num_threads, 1);
61 num_threads_ = num_threads;
62 return absl::OkStatus();
74 bool IsLP()
const override {
return false; }
75 bool IsMIP()
const override {
return true; }
88 const MPVariable*
const variable,
double new_value,
89 double old_value)
override {
116 LOG(FATAL) <<
"Basis status only available for continuous problems";
121 LOG(FATAL) <<
"Basis status only available for continuous problems";
139 void ResetBestObjectiveBound();
144 void SetRelativeMipGap(
double value)
override;
145 void SetPrimalTolerance(
double value)
override;
146 void SetDualTolerance(
double value)
override;
147 void SetPresolveMode(
int value)
override;
148 void SetScalingMode(
int value)
override;
149 void SetLpAlgorithm(
int value)
override;
151 OsiClpSolverInterface osi_;
155 double best_objective_bound_;
157 double relative_mip_gap_;
158 int num_threads_ = 1;
168 best_objective_bound_(-std::numeric_limits<double>::infinity()),
170 osi_.setStrParam(OsiProbName,
solver_->name_);
180 osi_.setStrParam(OsiProbName,
solver_->name_);
184 void CBCInterface::ResetBestObjectiveBound() {
186 best_objective_bound_ = std::numeric_limits<double>::infinity();
188 best_objective_bound_ = -std::numeric_limits<double>::infinity();
195 osi_.setObjSense(maximize ? -1 : 1);
203 int MPSolverVarIndexToCbcVarIndex(
int var_index) {
return var_index + 1; }
209 osi_.setColBounds(MPSolverVarIndexToCbcVarIndex(var_index), lb, ub);
220 osi_.setInteger(MPSolverVarIndexToCbcVarIndex(var_index));
222 osi_.setContinuous(MPSolverVarIndexToCbcVarIndex(var_index));
232 osi_.setRowBounds(
index, lb, ub);
252 if (!
solver_->variables_.empty()) {
255 if (!
solver_->constraints_.empty()) {
270 if (
solver_->variables_.empty() &&
solver_->constraints_.empty()) {
285 build.addColumn(0,
nullptr,
nullptr, 1.0, 1.0,
287 const int nb_vars =
solver_->variables_.size();
288 for (
int i = 0; i < nb_vars; ++i) {
292 if (
var->name().empty()) {
293 build.addColumn(0,
nullptr,
nullptr,
var->lb(),
var->ub(), obj_coeff,
294 nullptr,
var->integer());
296 build.addColumn(0,
nullptr,
nullptr,
var->lb(),
var->ub(), obj_coeff,
297 var->name().c_str(),
var->integer());
302 int max_row_length = 0;
303 for (
int i = 0; i <
solver_->constraints_.size(); ++i) {
306 if (
ct->coefficients_.size() > max_row_length) {
307 max_row_length =
ct->coefficients_.size();
310 std::unique_ptr<int[]> indices(
new int[max_row_length]);
311 std::unique_ptr<double[]> coefs(
new double[max_row_length]);
313 for (
int i = 0; i <
solver_->constraints_.size(); ++i) {
315 const int size =
ct->coefficients_.size();
317 for (
const auto& entry :
ct->coefficients_) {
318 const int index = MPSolverVarIndexToCbcVarIndex(entry.first->index());
320 coefs[j] = entry.second;
323 if (
ct->name().empty()) {
324 build.addRow(size, indices.get(), coefs.get(),
ct->lb(),
ct->ub());
326 build.addRow(size, indices.get(), coefs.get(),
ct->lb(),
ct->ub(),
330 osi_.loadFromCoinModel(build);
346 VLOG(1) << absl::StrFormat(
"Model built in %.3f seconds.", timer.
Get());
348 ResetBestObjectiveBound();
351 CbcModel
model(osi_);
354 CoinMessageHandler message_handler;
355 model.passInMessageHandler(&message_handler);
357 message_handler.setLogLevel(0, 0);
358 message_handler.setLogLevel(1, 0);
359 message_handler.setLogLevel(2, 0);
360 message_handler.setLogLevel(3, 0);
362 message_handler.setLogLevel(0, 1);
363 message_handler.setLogLevel(1, 1);
364 message_handler.setLogLevel(2, 1);
365 message_handler.setLogLevel(3, 1);
380 SetParameters(param);
383 model.setTypePresolve(0);
386 model.setAllowableFractionGap(relative_mip_gap_);
390 ? callCbc(
"-solve ",
model)
391 : callCbc(absl::StrCat(
"-threads ", num_threads_,
" -solve "),
model);
392 const int kBadReturnStatus = 777;
393 CHECK_NE(kBadReturnStatus, return_status);
396 VLOG(1) << absl::StrFormat(
"Solved in %.3f seconds.", timer.
Get());
399 int tmp_status =
model.status();
401 VLOG(1) <<
"cbc result status: " << tmp_status;
414 switch (tmp_status) {
418 if (
model.isProvenOptimal()) {
420 }
else if (
model.isContinuousUnbounded()) {
422 }
else if (
model.isProvenInfeasible()) {
424 }
else if (
model.isAbandoned()) {
431 if (
model.bestSolution() !=
nullptr) {
447 const double*
const values =
model.bestSolution();
448 if (values !=
nullptr) {
450 for (
int i = 0; i <
solver_->variables_.size(); ++i) {
452 const int var_index = MPSolverVarIndexToCbcVarIndex(
var->index());
453 const double val = values[var_index];
454 var->set_solution_value(val);
455 VLOG(3) <<
var->name() <<
"=" << val;
458 VLOG(1) <<
"No feasible solution found.";
462 iterations_ =
model.getIterationCount();
463 nodes_ =
model.getNodeCount();
464 best_objective_bound_ =
model.getBestPossibleObjValue();
465 VLOG(1) <<
"best objective bound=" << best_objective_bound_;
488 return best_objective_bound_;
504 void CBCInterface::SetRelativeMipGap(
double value) {
505 relative_mip_gap_ =
value;
508 void CBCInterface::SetPrimalTolerance(
double value) {
516 void CBCInterface::SetDualTolerance(
double value) {
524 void CBCInterface::SetPresolveMode(
int value) {
536 void CBCInterface::SetScalingMode(
int value) {
540 void CBCInterface::SetLpAlgorithm(
int value) {
549 #endif // #if defined(USE_CBC)
void * underlying_solver() override
void ClearObjective() override
@ DUAL_TOLERANCE
Advanced usage: tolerance for dual feasibility of basic solutions.
virtual void ExtractModel()
double trivial_worst_objective_bound() const
@ LP_ALGORITHM
Algorithm to solve linear programs.
const MPObjective & Objective() const
Returns the objective object.
@ UNBOUNDED
proven unbounded.
double GetCoefficient(const MPVariable *const var) const
Gets the coefficient of a given variable in the objective.
This mathematical programming (MP) solver class is the main class though which users build and solve ...
double best_objective_bound() const override
void SetVariableBounds(int var_index, double lb, double ub) override
virtual bool CheckBestObjectiveBoundExists() const
MPVariable * LookupVariableOrNull(const std::string &var_name) const
Looks up a variable by name, and returns nullptr if it does not exist.
The vehicle routing library lets one model and solve generic vehicle routing problems ranging from th...
double offset() const
Gets the constant term in the objective.
void InvalidateSolutionSynchronization()
MPSolver::BasisStatus column_status(int variable_index) const override
@ ABNORMAL
abnormal, i.e., error of some kind.
This class stores parameter settings for LP and MIP solvers.
The class for constraints of a Mathematical Programming (MP) model.
void AddVariable(MPVariable *const var) override
@ PRESOLVE_ON
Presolve is on.
MPSolverInterface * BuildCBCInterface(MPSolver *const solver)
int GetIntegerParam(MPSolverParameters::IntegerParam param) const
Returns the value of an integer parameter.
void ResetExtractionInformation()
CBCInterface(MPSolver *const solver)
void ClearConstraint(MPConstraint *const constraint) override
static constexpr int64 kUnknownNumberOfIterations
bool IsMIP() const override
void SetUnsupportedDoubleParam(MPSolverParameters::DoubleParam param)
@ NOT_SOLVED
not been solved yet.
void ExtractNewVariables() override
static constexpr int64 kUnknownNumberOfNodes
@ PRESOLVE
Advanced usage: presolve mode.
void SetObjectiveCoefficient(const MPVariable *const variable, double coefficient) override
void AddRowConstraint(MPConstraint *const ct) override
BasisStatus
Advanced usage: possible basis status values for a variable and the slack variable of a linear constr...
MPConstraint * LookupConstraintOrNull(const std::string &constraint_name) const
Looks up a constraint by name, and returns nullptr if it does not exist.
static const double kDefaultPrimalTolerance
int64 iterations() const override
absl::Status SetNumThreads(int num_threads) override
virtual void SetUnsupportedIntegerParam(MPSolverParameters::IntegerParam param)
@ INCREMENTALITY_OFF
Start solve from scratch.
SynchronizationStatus sync_status_
std::string SolverVersion() const override
double time_limit_in_secs() const
@ PRIMAL_TOLERANCE
Advanced usage: tolerance for primal feasibility of basic solutions.
void SetConstraintBounds(int row_index, double lb, double ub) override
void ExtractObjective() override
ResultStatus
The status of solving the problem.
void SetObjectiveOffset(double value) override
void SetMIPParameters(const MPSolverParameters ¶m)
bool IsLP() const override
static const double kDefaultDualTolerance
bool IsContinuous() const override
void SetCoefficient(MPConstraint *const constraint, const MPVariable *const variable, double new_value, double old_value) override
void set_variable_as_extracted(int var_index, bool extracted)
@ SCALING
Advanced usage: enable or disable matrix scaling.
void SetVariableInteger(int var_index, bool integer) override
@ INCREMENTALITY
Advanced usage: incrementality from one solve to the next.
The class for variables of a Mathematical Programming (MP) model.
A C++ wrapper that provides a simple and unified interface to several linear programming and mixed in...
void SetCommonParameters(const MPSolverParameters ¶m)
int64 nodes() const override
@ INFEASIBLE
proven infeasible.
void SetOptimizationDirection(bool maximize) override
bool CheckSolutionIsSynchronized() const
MPSolver::BasisStatus row_status(int constraint_index) const override
MPSolver::ResultStatus result_status_
void set_constraint_as_extracted(int ct_index, bool extracted)
void ExtractNewConstraints() override
MPSolver::ResultStatus Solve(const MPSolverParameters ¶m) override
@ FEASIBLE
feasible, or stopped by limit.