 |
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)
int64 nodes() const override
int GetIntegerParam(MPSolverParameters::IntegerParam param) const
Returns the value of an integer parameter.
std::string SolverVersion() const override
@ LP_ALGORITHM
Algorithm to solve linear programs.
The class for variables of a Mathematical Programming (MP) model.
This mathematical programming (MP) solver class is the main class though which users build and solve ...
void SetOptimizationDirection(bool maximize) override
MPSolver::ResultStatus result_status_
@ DUAL_TOLERANCE
Advanced usage: tolerance for dual feasibility of basic solutions.
bool IsLP() const override
The class for constraints of a Mathematical Programming (MP) model.
@ FEASIBLE
feasible, or stopped by limit.
void ClearConstraint(MPConstraint *const constraint) override
void ExtractNewConstraints() override
void AddVariable(MPVariable *const var) override
MPConstraint * LookupConstraintOrNull(const std::string &constraint_name) const
Looks up a constraint by name, and returns nullptr if it does not exist.
double GetCoefficient(const MPVariable *const var) const
Gets the coefficient of a given variable in the objective.
double offset() const
Gets the constant term in the objective.
bool IsMIP() const override
void set_variable_as_extracted(int var_index, bool extracted)
void ClearObjective() override
static const double kDefaultDualTolerance
The vehicle routing library lets one model and solve generic vehicle routing problems ranging from th...
@ SCALING
Advanced usage: enable or disable matrix scaling.
bool IsContinuous() const override
void * underlying_solver() override
absl::Status SetNumThreads(int num_threads) override
This class stores parameter settings for LP and MIP solvers.
virtual void ExtractModel()
void SetUnsupportedDoubleParam(MPSolverParameters::DoubleParam param)
bool CheckSolutionIsSynchronized() const
void SetCoefficient(MPConstraint *const constraint, const MPVariable *const variable, double new_value, double old_value) override
int64 iterations() const override
static const double kDefaultPrimalTolerance
MPSolver::BasisStatus column_status(int variable_index) const override
@ INCREMENTALITY
Advanced usage: incrementality from one solve to the next.
void ExtractNewVariables() override
void SetCommonParameters(const MPSolverParameters ¶m)
MPSolverInterface * BuildCBCInterface(MPSolver *const solver)
void ExtractObjective() override
void SetObjectiveCoefficient(const MPVariable *const variable, double coefficient) override
MPSolver::ResultStatus Solve(const MPSolverParameters ¶m) override
void set_constraint_as_extracted(int ct_index, bool extracted)
@ ABNORMAL
abnormal, i.e., error of some kind.
CBCInterface(MPSolver *const solver)
void AddRowConstraint(MPConstraint *const ct) override
void ResetExtractionInformation()
static constexpr int64 kUnknownNumberOfNodes
@ INCREMENTALITY_OFF
Start solve from scratch.
MPVariable * LookupVariableOrNull(const std::string &var_name) const
Looks up a variable by name, and returns nullptr if it does not exist.
void SetVariableBounds(int var_index, double lb, double ub) override
void SetObjectiveOffset(double value) override
void SetConstraintBounds(int row_index, double lb, double ub) override
virtual bool CheckBestObjectiveBoundExists() const
void SetMIPParameters(const MPSolverParameters ¶m)
@ PRESOLVE
Advanced usage: presolve mode.
const MPObjective & Objective() const
Returns the objective object.
ResultStatus
The status of solving the problem.
double best_objective_bound() const override
virtual void SetUnsupportedIntegerParam(MPSolverParameters::IntegerParam param)
@ PRIMAL_TOLERANCE
Advanced usage: tolerance for primal feasibility of basic solutions.
double time_limit_in_secs() const
BasisStatus
Advanced usage: possible basis status values for a variable and the slack variable of a linear constr...
void SetVariableInteger(int var_index, bool integer) override
static constexpr int64 kUnknownNumberOfIterations
MPSolver::BasisStatus row_status(int constraint_index) const override
@ PRESOLVE_ON
Presolve is on.
double trivial_worst_objective_bound() const
@ INFEASIBLE
proven infeasible.
SynchronizationStatus sync_status_
void InvalidateSolutionSynchronization()
@ UNBOUNDED
proven unbounded.
@ NOT_SOLVED
not been solved yet.