21#include "absl/strings/str_format.h"
22#include "absl/strings/str_split.h"
28#include "ilcplex/cplexx.h"
38#define CPX_NAN std::numeric_limits<double>::quiet_NaN()
44#define CHECK_STATUS(s) \
46 int const status_ = s; \
47 CHECK_EQ(0, status_); \
86 double new_value,
double old_value);
102 virtual int64_t
nodes()
const;
115 virtual bool IsLP()
const {
return !mMip; }
116 virtual bool IsMIP()
const {
return mMip; }
130 LOG(DFATAL) <<
"ComputeExactConditionNumber not implemented for"
131 <<
" CPLEX_MIXED_INTEGER_PROGRAMMING";
137 CHECK_STATUS(CPXXgetdblquality(mEnv, mLp, &kappa, CPX_EXACT_KAPPA));
140 LOG(DFATAL) <<
"Cannot get exact condition number without solution";
162 void InvalidateModelSynchronization() {
186 bool const supportIncrementalExtraction;
194 SlowSetCoefficient = 0x0001,
195 SlowClearConstraint = 0x0002,
196 SlowSetObjectiveCoefficient = 0x0004,
197 SlowClearObjective = 0x0008,
198 SlowSetConstraintBounds = 0x0010,
199 SlowSetVariableInteger = 0x0020,
200 SlowSetVariableBounds = 0x0040,
201 SlowUpdatesAll = 0xffff
207 unique_ptr<int[]>
mutable mCstat;
208 unique_ptr<int[]>
mutable mRstat;
211 static void MakeRhs(
double lb,
double ub,
double& rhs,
char& sense,
221 slowUpdates(static_cast<SlowUpdates>(SlowSetObjectiveCoefficient |
222 SlowClearObjective)),
223 supportIncrementalExtraction(false),
228 mEnv = CPXXopenCPLEX(&
status);
230 DCHECK(mEnv !=
nullptr);
235 DCHECK(mLp !=
nullptr);
238 if (mMip)
CHECK_STATUS(CPXXchgprobtype(mEnv, mLp, CPXPROB_MILP));
252 int const major = version / 1000000;
253 version -= major * 1000000;
254 int const release = version / 10000;
255 version -= release * 10000;
256 int const mod = version / 100;
257 version -= mod * 100;
258 int const fix = version;
260 return absl::StrFormat(
"CPLEX library version %d.%02d.%02d.%02d", major,
275 DCHECK(mLp !=
nullptr);
278 if (mMip)
CHECK_STATUS(CPXXchgprobtype(mEnv, mLp, CPXPROB_MILP));
287 CPXXchgobjsen(mEnv, mLp, maximize ? CPX_MAX : CPX_MIN);
299 if (!supportIncrementalExtraction && !(slowUpdates & SlowSetVariableBounds)) {
300 InvalidateModelSynchronization();
306 char const lu[2] = {
'L',
'U'};
307 double const bd[2] = {lb, ub};
313 InvalidateModelSynchronization();
332 if (!supportIncrementalExtraction &&
333 !(slowUpdates && SlowSetVariableInteger)) {
334 InvalidateModelSynchronization();
341 DCHECK_LE(
var_index, CPXXgetnumcols(mEnv, mLp));
342 char const type = integer ? CPX_INTEGER : CPX_CONTINUOUS;
345 InvalidateModelSynchronization();
348 <<
"Attempt to change variable to integer in non-MIP problem!";
354void CplexInterface::MakeRhs(
double lb,
double ub,
double& rhs,
char& sense,
361 }
else if (lb > -CPX_INFBOUND && ub < CPX_INFBOUND) {
381 }
else if (ub < CPX_INFBOUND ||
382 (std::abs(ub) == CPX_INFBOUND && std::abs(lb) > CPX_INFBOUND)) {
387 }
else if (lb > -CPX_INFBOUND ||
388 (std::abs(lb) == CPX_INFBOUND && std::abs(ub) > CPX_INFBOUND)) {
402 DCHECK_GT(std::abs(lb), CPX_INFBOUND);
403 DCHECK_GT(std::abs(ub), CPX_INFBOUND);
404 if (std::abs(lb) > std::abs(ub)) {
405 rhs = (lb < 0) ? -CPX_INFBOUND : CPX_INFBOUND;
408 rhs = (ub < 0) ? -CPX_INFBOUND : CPX_INFBOUND;
424 if (!supportIncrementalExtraction &&
425 !(slowUpdates & SlowSetConstraintBounds)) {
426 InvalidateModelSynchronization();
434 MakeRhs(lb, ub, rhs, sense,
range);
441 InvalidateModelSynchronization();
453 InvalidateModelSynchronization();
463 InvalidateModelSynchronization();
468 double new_value,
double) {
478 if (!supportIncrementalExtraction && !(slowUpdates & SlowSetCoefficient)) {
479 InvalidateModelSynchronization();
481 int const row = constraint->
index();
492 InvalidateModelSynchronization();
498 CPXDIM
const row = constraint->
index();
511 if (!(slowUpdates & SlowClearConstraint)) {
512 InvalidateModelSynchronization();
516 CPXDIM
const len = constraint->coefficients_.size();
517 unique_ptr<CPXDIM[]> rowind(
new CPXDIM[len]);
518 unique_ptr<CPXDIM[]> colind(
new CPXDIM[len]);
519 unique_ptr<double[]> val(
new double[len]);
521 const auto& coeffs = constraint->coefficients_;
522 for (
auto it(coeffs.begin()); it != coeffs.end(); ++it) {
523 CPXDIM
const col = it->first->index();
533 CPXXchgcoeflist(mEnv, mLp, j, rowind.get(), colind.get(), val.get()));
539 CPXDIM
const col = variable->
index();
552 if (supportIncrementalExtraction ||
553 (slowUpdates & SlowSetObjectiveCoefficient)) {
556 InvalidateModelSynchronization();
573 if (supportIncrementalExtraction || (slowUpdates & SlowClearObjective)) {
574 CPXDIM
const cols = CPXXgetnumcols(mEnv, mLp);
575 unique_ptr<CPXDIM[]> ind(
new CPXDIM[cols]);
576 unique_ptr<double[]> zero(
new double[cols]);
578 const auto& coeffs =
solver_->objective_->coefficients_;
579 for (
auto it(coeffs.begin()); it != coeffs.end(); ++it) {
580 CPXDIM
const idx = it->first->index();
583 DCHECK_LT(idx, cols);
589 if (j > 0)
CHECK_STATUS(CPXXchgobj(mEnv, mLp, j, ind.get(), zero.get()));
592 InvalidateModelSynchronization();
601 return static_cast<int64_t
>(CPXXgetmipitcnt(mEnv, mLp));
603 return static_cast<int64_t
>(CPXXgetitcnt(mEnv, mLp));
609 return static_cast<int64_t
>(CPXXgetnodecnt(mEnv, mLp));
611 LOG(DFATAL) <<
"Number of nodes only available for discrete problems";
618 switch (cplex_basis_status) {
628 LOG(DFATAL) <<
"Unknown CPLEX basis status";
636 LOG(FATAL) <<
"Basis status only available for continuous problems";
642 CPXDIM
const rows = CPXXgetnumrows(mEnv, mLp);
643 unique_ptr<int[]> data(
new int[rows]);
653 LOG(FATAL) <<
"Row basis status not available";
661 LOG(FATAL) <<
"Basis status only available for continuous problems";
667 CPXDIM
const cols = CPXXgetnumcols(mEnv, mLp);
668 unique_ptr<int[]> data(
new int[cols]);
676 return xformBasisStatus(mCstat[variable_index]);
678 LOG(FATAL) <<
"Column basis status not available";
690 if (!supportIncrementalExtraction) {
700 int const var_count =
solver_->variables_.size();
701 CPXDIM newcols = var_count - last_extracted;
705 unique_ptr<double[]> obj(
new double[newcols]);
706 unique_ptr<double[]> lb(
new double[newcols]);
707 unique_ptr<double[]> ub(
new double[newcols]);
708 unique_ptr<char[]> ctype(
new char[newcols]);
709 unique_ptr<const char*[]> colname(
new const char*[newcols]);
711 bool have_names =
false;
712 for (
int j = 0, varidx = last_extracted; j < newcols; ++j, ++varidx) {
716 ctype[j] =
var->integer() ? CPX_INTEGER : CPX_CONTINUOUS;
717 colname[j] =
var->name().empty() ? 0 :
var->name().c_str();
718 have_names = have_names ||
var->name().empty();
719 obj[j] =
solver_->objective_->GetCoefficient(
var);
728 for (
int j = last_extracted; j < var_count; ++j) {
734 bool use_newcols =
true;
736 if (supportIncrementalExtraction) {
745 unique_ptr<CPXDIM[]> collen(
new CPXDIM[newcols]);
746 for (CPXDIM j = 0; j < newcols; ++j) collen[j] = 0;
753 const auto& coeffs =
ct->coefficients_;
754 for (
auto it(coeffs.begin()); it != coeffs.end(); ++it) {
755 int const idx = it->first->index();
768 unique_ptr<CPXNNZ[]> begin(
new CPXNNZ[newcols + 2]);
769 unique_ptr<CPXDIM[]> cmatind(
new CPXDIM[nonzeros]);
770 unique_ptr<double[]> cmatval(
new double[nonzeros]);
781 CPXNNZ* cmatbeg = begin.get();
785 for (CPXDIM j = 0; j < newcols; ++j)
786 cmatbeg[j + 1] = cmatbeg[j] + collen[j];
790 CPXDIM
const row =
ct->index();
791 const auto& coeffs =
ct->coefficients_;
792 for (
auto it(coeffs.begin()); it != coeffs.end(); ++it) {
793 int const idx = it->first->index();
795 CPXNNZ
const nz = cmatbeg[idx]++;
797 cmatval[nz] = it->second;
802 CHECK_STATUS(CPXXaddcols(mEnv, mLp, newcols, nonzeros, obj.get(),
803 cmatbeg, cmatind.get(), cmatval.get(),
805 have_names ? colname.get() : 0));
812 CHECK_STATUS(CPXXnewcols(mEnv, mLp, newcols, obj.get(), lb.get(),
813 ub.get(), mMip ? ctype.get() : 0,
814 have_names ? colname.get() : 0));
822 int const cols = CPXXgetnumcols(mEnv, mLp);
823 unique_ptr<CPXDIM[]> ind(
new CPXDIM[newcols]);
824 for (
int j = last_extracted; j < cols; ++j)
825 ind[j - last_extracted] = j;
826 CHECK_STATUS(CPXXchgctype(mEnv, mLp, cols - last_extracted, ind.get(),
832 CPXDIM
const cols = CPXXgetnumcols(mEnv, mLp);
833 if (cols > last_extracted)
834 (void)CPXXdelcols(mEnv, mLp, last_extracted, cols - 1);
836 int const size = variables.size();
837 for (
int j = last_extracted; j <
size; ++j)
849 if (!supportIncrementalExtraction) {
859 CPXDIM
const total =
solver_->constraints_.size();
861 if (total > offset) {
866 CPXDIM newCons = total - offset;
867 CPXDIM
const cols = CPXXgetnumcols(mEnv, mLp);
869 CPXDIM
const chunk = 10;
873 for (CPXDIM c = offset; c < total; ++c)
877 unique_ptr<CPXDIM[]> rmatind(
new CPXDIM[cols]);
878 unique_ptr<double[]> rmatval(
new double[cols]);
879 unique_ptr<CPXNNZ[]> rmatbeg(
new CPXNNZ[chunk]);
880 unique_ptr<char[]> sense(
new char[chunk]);
881 unique_ptr<double[]> rhs(
new double[chunk]);
882 unique_ptr<char const*[]>
name(
new char const*[chunk]);
883 unique_ptr<double[]> rngval(
new double[chunk]);
884 unique_ptr<CPXDIM[]> rngind(
new CPXDIM[chunk]);
885 bool haveRanges =
false;
890 for (CPXDIM c = 0; c < newCons; ) {
894 for (; c < newCons && nextRow < chunk; ++c, ++nextRow) {
899 if (nextNz +
ct->coefficients_.size() > cols) {
900 DCHECK_GT(nextRow, 0);
905 MakeRhs(
ct->lb(),
ct->ub(), rhs[nextRow], sense[nextRow],
907 haveRanges = haveRanges || (rngval[nextRow] != 0.0);
908 rngind[nextRow] = offset + c;
911 rmatbeg[nextRow] = nextNz;
912 const auto& coeffs =
ct->coefficients_;
913 for (
auto it(coeffs.begin()); it != coeffs.end(); ++it) {
914 CPXDIM
const idx = it->first->index();
916 DCHECK_LT(nextNz, cols);
917 DCHECK_LT(idx, cols);
918 rmatind[nextNz] = idx;
919 rmatval[nextNz] = it->second;
925 name[nextRow] =
ct->name().empty() ? 0 :
ct->name().c_str();
928 CHECK_STATUS(CPXXaddrows(mEnv, mLp, 0, nextRow, nextNz, rhs.get(),
929 sense.get(), rmatbeg.get(), rmatind.get(),
930 rmatval.get(), 0,
name.get()));
933 CPXXchgrngval(mEnv, mLp, nextRow, rngind.get(), rngval.get()));
939 CPXDIM
const rows = CPXXgetnumrows(mEnv, mLp);
940 if (rows > offset) (void)CPXXdelrows(mEnv, mLp, offset, rows - 1);
942 int const size = constraints.size();
954 CPXDIM
const cols = CPXXgetnumcols(mEnv, mLp);
957 unique_ptr<CPXDIM[]> ind(
new CPXDIM[cols]);
958 unique_ptr<double[]> val(
new double[cols]);
959 for (CPXDIM j = 0; j < cols; ++j) {
964 const auto& coeffs =
solver_->objective_->coefficients_;
965 for (
auto it = coeffs.begin(); it != coeffs.end(); ++it) {
966 CPXDIM
const idx = it->first->index();
968 DCHECK_LT(idx, cols);
969 val[idx] = it->second;
973 CHECK_STATUS(CPXXchgobj(mEnv, mLp, cols, ind.get(), val.get()));
988 LOG(WARNING) <<
"The relative MIP gap is only available "
989 <<
"for discrete problems.";
1007 CHECK_STATUS(CPXXsetintparam(mEnv, CPX_PARAM_PREIND, CPX_OFF));
1010 CHECK_STATUS(CPXXsetintparam(mEnv, CPX_PARAM_PREIND, CPX_ON));
1023 CHECK_STATUS(CPXXsetintparam(mEnv, CPX_PARAM_SCAIND, -1));
1028 CHECK_STATUS(CPXXsetintparam(mEnv, CPX_PARAM_SCAIND, 0));
1039 int alg = CPX_ALG_NONE;
1041 switch (algorithm) {
1046 alg = CPX_ALG_PRIMAL;
1049 alg = CPX_ALG_BARRIER;
1053 if (alg == CPX_ALG_NONE)
1056 CHECK_STATUS(CPXXsetintparam(mEnv, CPX_PARAM_LPMETHOD, alg));
1060 CHECK_STATUS(CPXXsetintparam(mEnv, CPX_PARAM_STARTALG, alg));
1061 CHECK_STATUS(CPXXsetintparam(mEnv, CPX_PARAM_SUBALG, alg));
1068 return CPXXreadcopyparam(mEnv, filename.c_str()) == 0;
1093 CHECK_STATUS(CPXXsetintparam(mEnv, CPX_PARAM_ADVIND, 0));
1096 CHECK_STATUS(CPXXsetintparam(mEnv, CPX_PARAM_ADVIND, 2));
1107 VLOG(1) << absl::StrFormat(
"Model build in %.3f seconds.", timer.
Get());
1111 CPXXsetintparam(mEnv, CPX_PARAM_SCRIND,
quiet() ? CPX_OFF : CPX_ON));
1113 if (!
solver_->solution_hint_.empty()) {
1114 int const sol_count =
solver_->solution_hint_.size();
1115 long long int beg[1] = {0};
1116 int* varindices =
new int[sol_count];
1117 double* values =
new double[sol_count];
1119 for (
int i = 0; i < sol_count; ++i) {
1120 varindices[i] =
solver_->solution_hint_[i].first->index();
1121 values[i] =
solver_->solution_hint_[i].second;
1123 CPXXaddmipstarts(mEnv, mLp, 1, sol_count, beg, varindices, values, NULL,
1132 solver_->solver_specific_parameter_string_);
1145 status = CPXXmipopt(mEnv, mLp);
1147 status = CPXXlpopt(mEnv, mLp);
1151 (void)CPXXsetintparam(mEnv, CPX_PARAM_SCRIND, CPX_OFF);
1154 VLOG(1) << absl::StrFormat(
"Failed to optimize MIP. Error %d",
status);
1158 VLOG(1) << absl::StrFormat(
"Solved in %.3f seconds.", timer.
Get());
1161 int const cpxstat = CPXXgetstat(mEnv, mLp);
1162 VLOG(1) << absl::StrFormat(
"CPLEX solution status %d.", cpxstat);
1165 int solnmethod, solntype, pfeas, dfeas;
1166 CHECK_STATUS(CPXXsolninfo(mEnv, mLp, &solnmethod, &solntype, &pfeas, &dfeas));
1167 bool const feasible = pfeas != 0;
1170 CPXDIM
const rows = CPXXgetnumrows(mEnv, mLp);
1171 CPXDIM
const cols = CPXXgetnumcols(mEnv, mLp);
1172 DCHECK_EQ(rows,
solver_->constraints_.size());
1173 DCHECK_EQ(cols,
solver_->variables_.size());
1192 unique_ptr<double[]>
x(
new double[cols]);
1194 for (
int i = 0; i <
solver_->variables_.size(); ++i) {
1196 var->set_solution_value(
x[i]);
1197 VLOG(3) <<
var->name() <<
": value =" <<
x[i];
1201 for (
int i = 0; i <
solver_->variables_.size(); ++i)
1206 for (
int i = 0; i <
solver_->variables_.size(); ++i)
1208 for (
int i = 0; i <
solver_->constraints_.size(); ++i)
1213 unique_ptr<double[]>
x(
new double[cols]);
1214 unique_ptr<double[]> dj(
new double[cols]);
1215 if (feasible)
CHECK_STATUS(CPXXgetx(mEnv, mLp,
x.get(), 0, cols - 1));
1216 if (dfeas)
CHECK_STATUS(CPXXgetdj(mEnv, mLp, dj.get(), 0, cols - 1));
1217 for (
int i = 0; i <
solver_->variables_.size(); ++i) {
1219 var->set_solution_value(
x[i]);
1220 bool value =
false, dual =
false;
1223 var->set_solution_value(
x[i]);
1228 var->set_reduced_cost(dj[i]);
1232 VLOG(3) <<
var->name() <<
":"
1233 << (
value ? absl::StrFormat(
" value = %f",
x[i]) :
"")
1234 << (dual ? absl::StrFormat(
" reduced cost = %f", dj[i]) :
"");
1239 unique_ptr<double[]> pi(
new double[rows]);
1240 if (dfeas)
CHECK_STATUS(CPXXgetpi(mEnv, mLp, pi.get(), 0, rows - 1));
1241 for (
int i = 0; i <
solver_->constraints_.size(); ++i) {
1245 ct->set_dual_value(pi[i]);
1249 VLOG(4) <<
"row " <<
ct->index() <<
":"
1250 << (dual ? absl::StrFormat(
" dual = %f", pi[i]) :
"");
1257 case CPX_STAT_OPTIMAL:
1258 case CPXMIP_OPTIMAL:
1261 case CPXMIP_OPTIMAL_TOL:
1265 case CPX_STAT_INFEASIBLE:
1266 case CPXMIP_INFEASIBLE:
1269 case CPX_STAT_UNBOUNDED:
1270 case CPXMIP_UNBOUNDED:
1273 case CPX_STAT_INForUNBD:
1274 case CPXMIP_INForUNBD:
1293 for (
const auto parameter : absl::StrSplit(
parameters, absl::ByAnyChar(
","),
1294 absl::SkipWhitespace())) {
1295 std::vector<std::string> key_value =
1296 absl::StrSplit(parameter, absl::ByAnyChar(
"="), absl::SkipWhitespace());
1297 if (key_value.size() != 2) {
1298 LOG(WARNING) << absl::StrFormat(
1299 "Cannot parse parameter '%s'. Expected format is 'parameter/name = "
1304 std::string identifier = key_value[0];
1305 absl::RemoveExtraAsciiWhitespace(&identifier);
1307 std::string
value = key_value[1];
1308 absl::RemoveExtraAsciiWhitespace(&
value);
1311 if (identifier.find(
"LogFile") != std::string::npos) {
1312 CPXXsetlogfilename(mEnv,
value.c_str(),
"w");
1314 std::string delimiter =
".";
1315 if (
value.find(delimiter) == std::string::npos) {
1316 (void)CPXXsetintparam(mEnv, std::stoi(identifier), std::stoi(
value));
1318 (void)CPXXsetdblparam(mEnv, std::stoi(identifier), std::stod(
value));
1320 VLOG(2) << absl::StrFormat(
"Set parameter %s to %s", identifier,
value);
1323 LOG(WARNING) << absl::StrFormat(
1324 "Cannot parse parameter '%s'. Expected format is 'parameter/name = "
void Start()
When Start() is called multiple times, only the most recent is used.
virtual MPSolver::BasisStatus row_status(int constraint_index) const
Returns the basis status of a row.
virtual void SetOptimizationDirection(bool maximize)
Sets the optimization direction (min/max).
virtual MPSolver::BasisStatus column_status(int variable_index) const
Returns the basis status of a column.
virtual int64_t iterations() const
---— Query statistics on the solution and the solve ---—
bool SetSolverSpecificParametersAsString(const std::string ¶meters) override
virtual double ComputeExactConditionNumber() const
virtual void SetVariableBounds(int var_index, double lb, double ub)
Modifies bounds of an extracted variable.
virtual void * underlying_solver()
Returns the underlying solver.
virtual void ClearObjective()
Clear the objective from all its terms.
virtual void Reset()
---— Model modifications and extraction --—
virtual void AddRowConstraint(MPConstraint *const ct)
Adds a linear constraint.
virtual void ClearConstraint(MPConstraint *const constraint)
Clear a constraint from all its terms.
virtual void ExtractNewVariables()
Extract all variables that have not yet been extracted.
virtual void SetVariableInteger(int var_index, bool integer)
Modifies integrality of an extracted variable.
virtual MPSolver::ResultStatus Solve(MPSolverParameters const ¶m)
virtual void SetCoefficient(MPConstraint *const constraint, MPVariable const *const variable, double new_value, double old_value)
Changes a coefficient in a constraint.
virtual std::string SolverVersion() const
Returns a string describing the underlying solver and its version.
virtual void SetPresolveMode(int value)
virtual int64_t nodes() const
Number of branch-and-bound nodes. Only available for discrete problems.
virtual bool ReadParameterFile(std::string const &filename)
virtual void SetParameters(MPSolverParameters const ¶m)
Set all parameters in the underlying solver.
virtual bool IsContinuous() const
--— Misc --—
virtual void SetObjectiveOffset(double value)
Change the constant term in the linear objective.
virtual void AddVariable(MPVariable *const var)
Add a variable.
virtual void ExtractNewConstraints()
Extract constraints that have not yet been extracted.
virtual bool IsLP() const
Returns true if the problem is continuous and linear.
virtual void SetConstraintBounds(int row_index, double lb, double ub)
Modify bounds of an extracted variable.
virtual void SetLpAlgorithm(int value)
virtual bool IsMIP() const
Returns true if the problem is discrete and linear.
virtual void SetScalingMode(int value)
Sets the scaling mode.
virtual void ExtractObjective()
Extract the objective function.
virtual void SetObjectiveCoefficient(MPVariable const *const variable, double coefficient)
Change a coefficient in the linear objective.
virtual void SetDualTolerance(double value)
CplexInterface(MPSolver *const solver, bool mip)
Creates a LP/MIP instance.
virtual std::string ValidFileExtensionForParameterFile() const
virtual void SetRelativeMipGap(double value)
Set each parameter in the underlying solver.
virtual void SetPrimalTolerance(double value)
int index() const
Returns the index of the constraint in the MPSolver::constraints_.
double offset() const
Gets the constant term in the objective.
void set_variable_as_extracted(int var_index, bool extracted)
bool CheckSolutionIsSynchronized() const
static constexpr int64_t kUnknownNumberOfIterations
void InvalidateSolutionSynchronization()
void set_constraint_as_extracted(int ct_index, bool extracted)
void ResetExtractionInformation()
Resets the extraction information.
int last_variable_index_
Index in MPSolver::constraints_ of last variable extracted.
virtual void SetIntegerParamToUnsupportedValue(MPSolverParameters::IntegerParam param, int value)
Sets a supported integer parameter to an unsupported value.
int last_constraint_index_
Index in MPSolver::variables_ of last constraint extracted.
bool variable_is_extracted(int var_index) const
bool quiet() const
Returns the boolean indicating the verbosity of the solver output.
bool constraint_is_extracted(int ct_index) const
static constexpr int64_t kUnknownNumberOfNodes
void ExtractModel()
Extracts model stored in MPSolver.
double objective_value_
The value of the objective function.
double best_objective_bound_
The value of the best objective bound. Used only for MIP solvers.
bool maximize_
Optimization direction.
void SetMIPParameters(const MPSolverParameters ¶m)
Sets MIP specific parameters in the underlying solver.
void SetCommonParameters(const MPSolverParameters ¶m)
Sets parameters common to LP and MIP in the underlying solver.
MPSolver::ResultStatus result_status_
SynchronizationStatus sync_status_
Indicates whether the model and the solution are synchronized.
PresolveValues
For each categorical parameter, enumeration of possible values.
@ PRESOLVE_OFF
Presolve is off.
@ PRESOLVE_ON
Presolve is on.
LpAlgorithmValues
LP algorithm to use.
@ BARRIER
Barrier algorithm.
@ INCREMENTALITY
Advanced usage: incrementality from one solve to the next.
@ PRESOLVE
Advanced usage: presolve mode.
@ LP_ALGORITHM
Algorithm to solve linear programs.
IncrementalityValues
Advanced usage: Incrementality options.
@ INCREMENTALITY_OFF
Start solve from scratch.
ScalingValues
Advanced usage: Scaling options.
@ SCALING_ON
Scaling is on.
@ SCALING_OFF
Scaling is off.
int GetIntegerParam(MPSolverParameters::IntegerParam param) const
Returns the value of an integer parameter.
int64_t time_limit() const
const std::vector< MPVariable * > & variables() const
@ FEASIBLE
feasible, or stopped by limit.
@ INFEASIBLE
proven infeasible.
@ UNBOUNDED
proven unbounded.
@ ABNORMAL
abnormal, i.e., error of some kind.
const MPObjective & Objective() const
bool SetSolverSpecificParametersAsString(const std::string ¶meters)
const std::vector< MPConstraint * > & constraints() const
The class for variables of a Mathematical Programming (MP) model.
int index() const
Returns the index of the variable in the MPSolver::variables_.
CPXLIBAPI int CPXPUBLIC CPXEsetobjoffset(CPXCENVptr, CPXLPptr, double)
Initial version of this code was written by Daniel Junglas (IBM)
const std::string name
A name for logging purposes.
In SWIG mode, we don't want anything besides these top-level includes.
MPSolverInterface * BuildCplexInterface(bool mip, MPSolver *const solver)
const std::optional< Range > & range