26#include "absl/strings/numbers.h"
27#include "absl/strings/str_format.h"
33#define XPRS_INTEGER 'I'
34#define XPRS_CONTINUOUS 'C'
39#define CHECK_STATUS(s) \
41 int const status_ = s; \
42 CHECK_EQ(0, status_); \
51 return "XPRESS library version unknown";
53 int const major = version / 100;
54 version -= major * 100;
55 int const release = version;
57 return absl::StrFormat(
"XPRESS library version %d.%02d", major, release);
62 std::string
const& value) {
65 LOG(DFATAL) <<
"Empty value for parameter '" << name <<
"' in "
74 LOG(DFATAL) <<
"Unknown parameter '" << name <<
"' in "
80 std::stringstream v(value);
81 v.imbue(std::locale(
"C"));
87 LOG(DFATAL) <<
"Failed to parse value '" << value
88 <<
"' for int parameter '" << name <<
"' in "
93 LOG(DFATAL) <<
"Failed to set int parameter '" << name <<
"' to "
102 LOG(DFATAL) <<
"Failed to parse value '" << value
103 <<
"' for int64_t parameter '" << name <<
"' in "
108 LOG(DFATAL) <<
"Failed to set int64_t parameter '" << name <<
"' to "
117 LOG(DFATAL) <<
"Failed to parse value '" << value
118 <<
"' for dbl parameter '" << name <<
"' in "
123 LOG(DFATAL) <<
"Failed to set double parameter '" << name <<
"' to "
131 LOG(DFATAL) <<
"Unsupported parameter type " << type <<
" for parameter '"
142 VLOG(0) << absl::StrFormat(
"Function line %d did not execute correctly: %s\n",
186 static int indexes[1] = {-1};
187 double values[1] = {-value};
193 const int colind[]) {
196 if (
int status =
XPRSaddmipsol(mLp, length, solval, colind, NULL)) {
197 LOG(WARNING) <<
"Failed to set solution hint.";
210#if !defined(XPRS_NAN)
211#define XPRS_NAN std::numeric_limits<double>::quiet_NaN()
214using std::unique_ptr;
222 : xprsprob_(xprsprob),
224 num_nodes_(num_nodes),
225 variable_values_(0) {};
232 LOG(WARNING) <<
"AddCut is not implemented yet in XPRESS interface";
236 <<
"AddLazyConstraint is not implemented yet in XPRESS interface";
239 const absl::flat_hash_map<const MPVariable*, double>&
solution)
override;
265 exceptions_mutex_.lock();
266 caught_exceptions_.push_back(std::current_exception());
268 exceptions_mutex_.unlock();
271 exceptions_mutex_.lock();
272 for (
const std::exception_ptr& ex : caught_exceptions_) {
274 std::rethrow_exception(ex);
275 }
catch (std::exception& ex) {
280 LOG(ERROR) <<
"Caught exception during user-defined call-back: "
284 caught_exceptions_.clear();
285 exceptions_mutex_.unlock();
290 std::vector<std::exception_ptr> caught_exceptions_;
291 std::mutex exceptions_mutex_;
315 void Write(
const std::string& filename)
override;
319 void Reset()
override;
328 double new_value,
double old_value)
override;
334 double coefficient)
override;
344 virtual int64_t
nodes()
const;
357 bool IsLP()
const override {
return !mMip; }
358 bool IsMIP()
const override {
return mMip; }
361 const std::vector<MPSolver::BasisStatus>& variable_statuses,
362 const std::vector<MPSolver::BasisStatus>& constraint_statuses)
override;
374 LOG(DFATAL) <<
"ComputeExactConditionNumber not implemented for"
375 <<
" XPRESS_MIXED_INTEGER_PROGRAMMING";
380 LOG(DFATAL) <<
"ComputeExactConditionNumber not implemented for"
381 <<
" XPRESS_LINEAR_PROGRAMMING";
411 void InvalidateModelSynchronization() {
419 void AddSolutionHintToOptimizer();
421 bool readParameters(std::istream& is,
char sep);
430 absl::btree_map<int, std::map<int, double> >
431 fixedOrderCoefficientsPerConstraint;
444 bool const supportIncrementalExtraction;
452 SlowSetCoefficient = 0x0001,
453 SlowClearConstraint = 0x0002,
454 SlowSetObjectiveCoefficient = 0x0004,
455 SlowClearObjective = 0x0008,
456 SlowSetConstraintBounds = 0x0010,
457 SlowSetVariableInteger = 0x0020,
458 SlowSetVariableBounds = 0x0040,
459 SlowUpdatesAll = 0xffff
467 std::vector<int>
mutable mCstat;
468 std::vector<int>
mutable mRstat;
470 std::vector<int>
mutable initial_variables_basis_status_;
471 std::vector<int>
mutable initial_constraint_basis_status_;
474 static void MakeRhs(
double lb,
double ub,
double& rhs,
char& sense,
477 std::map<std::string, int>& mapStringControls_;
478 std::map<std::string, int>& mapDoubleControls_;
479 std::map<std::string, int>& mapIntegerControls_;
480 std::map<std::string, int>& mapInteger64Controls_;
482 bool SetSolverSpecificParametersAsString(
483 const std::string& parameters)
override;
484 MPCallback* callback_ =
nullptr;
492 int xpress_basis_status);
495 static std::map<std::string, int> mapControls = {
510 static std::map<std::string, int> mapControls = {
595 static std::map<std::string, int> mapControls = {
832 static std::map<std::string, int> mapControls = {
844 supportIncrementalExtraction(false),
845 slowUpdates(SlowClearObjective),
851 CHECK(correctlyLoaded);
854 DCHECK(mLp !=
nullptr);
871 int const major = version / 1000000;
872 version -= major * 1000000;
873 int const release = version / 10000;
874 version -= release * 10000;
875 int const mod = version / 100;
876 version -= mod * 100;
877 int const fix = version;
879 return absl::StrFormat(
"XPRESS library version %d.%02d.%02d.%02d", major,
887 std::vector<int> rows(nRows);
888 std::iota(rows.begin(), rows.end(), 0);
890 std::vector<int> cols(nCols);
891 std::iota(cols.begin(), cols.end(), 0);
914 if (!supportIncrementalExtraction && !(slowUpdates & SlowSetVariableBounds)) {
915 InvalidateModelSynchronization();
921 char const lu[2] = {
'L',
'U'};
922 double const bd[2] = {lb, ub};
923 int const idx[2] = {var_index, var_index};
928 InvalidateModelSynchronization();
947 if (!supportIncrementalExtraction &&
948 !(slowUpdates & SlowSetVariableInteger)) {
949 InvalidateModelSynchronization();
960 InvalidateModelSynchronization();
964 <<
"Attempt to change variable to integer in non-MIP problem!";
970void XpressInterface::MakeRhs(
double lb,
double ub,
double& rhs,
char& sense,
985 LOG(DFATAL) <<
"XPRESS does not support contradictory bounds on range "
987 << lb <<
", " << ub <<
"] will be converted to " << ub <<
", "
988 << (ub - std::abs(ub - lb)) <<
"]";
991 range = std::abs(ub - lb);
1014 if (std::abs(lb) < std::abs(ub))
1032 if (!supportIncrementalExtraction &&
1033 !(slowUpdates & SlowSetConstraintBounds)) {
1034 InvalidateModelSynchronization();
1039 DCHECK(mLp !=
nullptr);
1042 MakeRhs(lb, ub, rhs, sense, range);
1057 InvalidateModelSynchronization();
1073 InvalidateModelSynchronization();
1089 InvalidateModelSynchronization();
1094 double new_value,
double) {
1097 fixedOrderCoefficientsPerConstraint[constraint->
index()][variable->
index()] =
1107 if (!supportIncrementalExtraction && !(slowUpdates & SlowSetCoefficient)) {
1108 InvalidateModelSynchronization();
1110 int const row = constraint->
index();
1111 int const col = variable->
index();
1121 InvalidateModelSynchronization();
1127 int const row = constraint->
index();
1132 fixedOrderCoefficientsPerConstraint.erase(constraint->
index());
1142 if (!(slowUpdates & SlowClearConstraint)) {
1143 InvalidateModelSynchronization();
1147 int const len = constraint->coefficients_.size();
1148 unique_ptr<int[]> rowind(
new int[len]);
1149 unique_ptr<int[]> colind(
new int[len]);
1150 unique_ptr<double[]> val(
new double[len]);
1152 const auto& coeffs = constraint->coefficients_;
1153 for (
auto coeff : coeffs) {
1154 int const col = coeff.first->index();
1168 double coefficient) {
1169 int const col = variable->
index();
1182 if (supportIncrementalExtraction ||
1183 (slowUpdates & SlowSetObjectiveCoefficient)) {
1186 InvalidateModelSynchronization();
1204 if (supportIncrementalExtraction || (slowUpdates & SlowClearObjective)) {
1206 unique_ptr<int[]> ind(
new int[cols]);
1207 unique_ptr<double[]> zero(
new double[cols]);
1209 const auto& coeffs =
solver_->objective_->coefficients_;
1210 for (
auto coeff : coeffs) {
1211 int const idx = coeff.first->index();
1214 DCHECK_LT(idx, cols);
1225 InvalidateModelSynchronization();
1233 return static_cast<int64_t
>(
getitcnt(mLp));
1239 return static_cast<int64_t
>(
getnodecnt(mLp));
1241 LOG(DFATAL) <<
"Number of nodes only available for discrete problems";
1248 int xpress_basis_status) {
1249 switch (xpress_basis_status) {
1259 LOG(DFATAL) <<
"Unknown XPRESS basis status";
1266 switch (mpsolver_basis_status) {
1278 LOG(DFATAL) <<
"Unknown MPSolver basis status";
1286 LOG(FATAL) <<
"Basis status only available for continuous problems";
1291 if (mRstat.empty()) {
1293 mRstat.resize(rows);
1300 if (!mRstat.empty()) {
1303 LOG(FATAL) <<
"Row basis status not available";
1311 LOG(FATAL) <<
"Basis status only available for continuous problems";
1316 if (mCstat.empty()) {
1318 mCstat.resize(cols);
1325 if (!mCstat.empty()) {
1328 LOG(FATAL) <<
"Column basis status not available";
1340 if (!supportIncrementalExtraction) {
1350 int const var_count =
solver_->variables_.size();
1351 int new_col_count = var_count - last_extracted;
1352 if (new_col_count > 0) {
1355 unique_ptr<double[]> obj(
new double[new_col_count]);
1356 unique_ptr<double[]> lb(
new double[new_col_count]);
1357 unique_ptr<double[]> ub(
new double[new_col_count]);
1358 unique_ptr<char[]> ctype(
new char[new_col_count]);
1360 for (
int j = 0, var_idx = last_extracted; j < new_col_count;
1366 obj[j] =
solver_->objective_->GetCoefficient(var);
1374 std::vector<MPVariable*>
const& variables =
solver_->variables();
1375 for (
int j = last_extracted; j < var_count; ++j) {
1381 bool use_new_cols =
true;
1383 if (supportIncrementalExtraction) {
1392 unique_ptr<int[]> collen(
new int[new_col_count]);
1393 for (
int j = 0; j < new_col_count; ++j) collen[j] = 0;
1400 const auto& coeffs = ct->coefficients_;
1401 for (
auto coeff : coeffs) {
1402 int const idx = coeff.first->index();
1414 use_new_cols =
false;
1415 unique_ptr<int[]>
begin(
new int[new_col_count + 2]);
1416 unique_ptr<int[]> cmatind(
new int[nonzeros]);
1417 unique_ptr<double[]> cmatval(
new double[nonzeros]);
1428 int* cmatbeg =
begin.get();
1432 for (
int j = 0; j < new_col_count; ++j)
1433 cmatbeg[j + 1] = cmatbeg[j] + collen[j];
1437 int const row = ct->
index();
1438 const auto& coeffs = ct->coefficients_;
1439 for (
auto coeff : coeffs) {
1440 int const idx = coeff.first->index();
1442 int const nz = cmatbeg[idx]++;
1444 cmatval[nz] = coeff.second;
1450 cmatbeg, cmatind.get(), cmatval.get(),
1451 lb.get(), ub.get()));
1459 std::vector<int> collen(new_col_count, 0);
1460 std::vector<int> cmatbeg(new_col_count, 0);
1461 unique_ptr<int[]> cmatind(
new int[1]);
1462 unique_ptr<double[]> cmatval(
new double[1]);
1467 cmatbeg.data(), cmatind.get(), cmatval.get(),
1468 lb.get(), ub.get()));
1471 unique_ptr<int[]> ind(
new int[new_col_count]);
1472 for (
int j = 0; j < cols; ++j) ind[j] = j;
1474 XPRSchgcoltype(mLp, cols - last_extracted, ind.get(), ctype.get()));
1484 unique_ptr<int[]> ind(
new int[new_col_count]);
1485 for (
int j = last_extracted; j < cols; ++j)
1486 ind[j - last_extracted] = j;
1494 if (cols > last_extracted) {
1495 std::vector<int> cols_to_delete;
1496 for (
int i = last_extracted; i < cols; ++i) cols_to_delete.push_back(i);
1497 (void)
XPRSdelcols(mLp, cols_to_delete.size(), cols_to_delete.data());
1499 std::vector<MPVariable*>
const& variables =
solver_->variables();
1500 int const size = variables.size();
1501 for (
int j = last_extracted; j < size; ++j)
1512 if (!supportIncrementalExtraction) {
1522 int const total =
solver_->constraints_.size();
1524 if (total > offset) {
1529 int newCons = total - offset;
1531 int const chunk = newCons;
1538 unique_ptr<int[]> rmatind(
new int[cols]);
1539 unique_ptr<double[]> rmatval(
new double[cols]);
1540 unique_ptr<int[]> rmatbeg(
new int[chunk]);
1541 unique_ptr<char[]> sense(
new char[chunk]);
1542 unique_ptr<double[]> rhs(
new double[chunk]);
1543 unique_ptr<double[]> rngval(
new double[chunk]);
1548 for (
int c = 0; c < newCons; ) {
1552 for (; c < newCons && nextRow < chunk; ++c, ++nextRow) {
1557 if (nextNz + ct->coefficients_.size() > cols) {
1558 DCHECK_GT(nextRow, 0);
1563 MakeRhs(ct->
lb(), ct->
ub(), rhs[nextRow], sense[nextRow],
1567 rmatbeg[nextRow] = nextNz;
1568 const auto& coeffs = fixedOrderCoefficientsPerConstraint[ct->
index()];
1569 for (
auto [idx, coeff] : coeffs) {
1571 DCHECK_LT(nextNz, cols);
1572 DCHECK_LT(idx, cols);
1573 rmatind[nextNz] = idx;
1574 rmatval[nextNz] = coeff;
1581 rngval.get(), rmatbeg.get(), rmatind.get(),
1588 std::vector<int> rows_to_delete;
1589 for (
int i = offset; i < rows; ++i) rows_to_delete.push_back(i);
1591 (void)
XPRSdelrows(mLp, rows_to_delete.size(), rows_to_delete.data());
1592 std::vector<MPConstraint*>
const& constraints =
solver_->constraints();
1593 int const size = constraints.size();
1608 unique_ptr<int[]> ind(
new int[cols]);
1609 unique_ptr<double[]> val(
new double[cols]);
1610 for (
int j = 0; j < cols; ++j) {
1615 const auto& coeffs =
solver_->objective_->coefficients_;
1616 for (
auto coeff : coeffs) {
1617 int const idx = coeff.first->index();
1619 DCHECK_LT(idx, cols);
1620 val[idx] = coeff.second;
1640 LOG(WARNING) <<
"The relative MIP gap is only available "
1641 <<
"for discrete problems.";
1688 auto const algorithm =
1693 switch (algorithm) {
1712 const std::vector<MPSolver::BasisStatus>& statuses) {
1713 std::vector<int> result;
1714 result.resize(statuses.size());
1715 std::transform(statuses.cbegin(), statuses.cend(), result.begin(),
1721 const std::vector<MPSolver::BasisStatus>& variable_statuses,
1722 const std::vector<MPSolver::BasisStatus>& constraint_statuses) {
1724 LOG(DFATAL) << __FUNCTION__ <<
" is only available for LP problems";
1728 initial_constraint_basis_status_ =
1732bool XpressInterface::readParameters(std::istream& is,
char sep) {
1738 std::string name(
""), value(
"");
1739 bool inValue =
false;
1743 if (is.eof())
break;
1746 LOG(DFATAL) <<
"Failed to parse parameters in " <<
SolverVersion();
1750 }
else if (c == sep) {
1752 if (name.size() == 0 && value.size() == 0) {
1755 }
else if (name.size() == 0) {
1756 LOG(DFATAL) <<
"Parameter setting without name in " <<
SolverVersion();
1764 }
else if (std::isspace(c)) {
1766 }
else if (inValue) {
1779 std::ifstream s(filename);
1780 if (!s)
return false;
1781 return readParameters(s,
'\n');
1820 VLOG(1) << absl::StrFormat(
"Model build in %.3f seconds.", timer.
Get());
1832 solver_->SetSolverSpecificParametersAsString(
1833 solver_->solver_specific_parameter_string_);
1835 VLOG(1) <<
"Setting time limit = " <<
solver_->time_limit() <<
" ms.";
1839 -1 *
solver_->time_limit_in_secs()));
1844 if (!mMip && !initial_variables_basis_status_.empty() &&
1845 !initial_constraint_basis_status_.empty()) {
1847 initial_variables_basis_status_.data()));
1851 this->AddSolutionHintToOptimizer();
1856 if (callback_ !=
nullptr) {
1859 static_cast<void*
>(mp_callback_wrapper), 0));
1867 int xpress_stat = 0;
1876 if (mp_callback_wrapper !=
nullptr) {
1878 delete mp_callback_wrapper;
1890 VLOG(1) << absl::StrFormat(
"Failed to optimize MIP. Error %d", status);
1894 VLOG(1) << absl::StrFormat(
"Solved in %.3f seconds.", timer.
Get());
1897 VLOG(1) << absl::StrFormat(
"XPRESS solution status %d.", xpress_stat);
1907 DCHECK_EQ(rows,
solver_->constraints_.size());
1908 DCHECK_EQ(cols,
solver_->variables_.size());
1930 unique_ptr<double[]> x(
new double[cols]);
1932 for (
int i = 0; i <
solver_->variables_.size(); ++i) {
1935 VLOG(3) << var->
name() <<
": value =" << x[i];
1939 for (
auto& variable :
solver_->variables_)
1944 for (
auto& variable :
solver_->variables_)
1946 for (
auto& constraint :
solver_->constraints_)
1951 unique_ptr<double[]> x(
new double[cols]);
1952 unique_ptr<double[]> dj(
new double[cols]);
1954 for (
int i = 0; i <
solver_->variables_.size(); ++i) {
1957 bool value =
false, dual =
false;
1971 VLOG(3) << var->
name() <<
":"
1972 << (value ? absl::StrFormat(
" value = %f", x[i]) :
"")
1973 << (dual ? absl::StrFormat(
" reduced cost = %f", dj[i]) :
"");
1978 unique_ptr<double[]> pi(
new double[rows]);
1982 for (
int i = 0; i <
solver_->constraints_.size(); ++i) {
1991 VLOG(4) <<
"row " << ct->
index() <<
":"
1992 << (dual ? absl::StrFormat(
" dual = %f", pi[i]) :
"");
1999 switch (xpress_stat) {
2014 switch (xpress_stat) {
2051void ExtractNames(
XPRSprob mLp,
const std::vector<T*>& objects) {
2052 const bool have_names =
2053 std::any_of(objects.begin(), objects.end(),
2054 [](
const T* x) { return !x->name().empty(); });
2061 std::vector<char> all_names;
2062 for (
const auto& x : objects) {
2063 const std::string& current_name =
x->
name();
2064 std::copy(current_name.begin(), current_name.end(),
2065 std::back_inserter(all_names));
2066 all_names.push_back(
'\0');
2071 if (!all_names.empty() && all_names.back() ==
'\0') all_names.pop_back();
2074 objects.size() - 1));
2085 ExtractNames(mLp,
solver_->variables_);
2086 ExtractNames(mLp,
solver_->constraints_);
2088 VLOG(1) <<
"Writing Xpress MPS \"" << filename <<
"\".";
2089 const int status =
XPRSwriteprob(mLp, filename.c_str(),
"");
2091 LOG(ERROR) <<
"Xpress: Failed to write MPS!";
2099template <
class Container>
2101 std::stringstream ss(str);
2103 while (std::getline(ss, token, delim)) {
2104 cont.push_back(token);
2113#define setParamIfPossible_MACRO(target_map, setter, converter, type) \
2115 auto matchingParamIter = (target_map).find(paramAndValuePair.first); \
2116 if (matchingParamIter != (target_map).end()) { \
2117 type convertedValue; \
2118 bool ret = converter(paramAndValuePair.second, &convertedValue); \
2120 VLOG(1) << "Setting parameter " << paramAndValuePair.first \
2121 << " to value " << convertedValue << std::endl; \
2123 setter(mLp, matchingParamIter->second, convertedValue); \
2128bool XpressInterface::SetSolverSpecificParametersAsString(
2129 const std::string& parameters) {
2130 if (parameters.empty())
return true;
2132 std::vector<std::pair<std::string, std::string> > paramAndValuePairList;
2134 std::stringstream ss(parameters);
2135 std::string paramName;
2136 while (std::getline(ss, paramName,
' ')) {
2137 std::string paramValue;
2138 if (std::getline(ss, paramValue,
' ')) {
2139 paramAndValuePairList.push_back(std::make_pair(paramName, paramValue));
2141 LOG(ERROR) <<
"No value for parameter " << paramName <<
" : function "
2142 << __FUNCTION__ << std::endl;
2147 for (
auto& paramAndValuePair : paramAndValuePairList) {
2149 absl::SimpleAtoi<int>,
int);
2151 absl::SimpleAtod,
double);
2155 absl::SimpleAtoi<int64_t>, int64_t);
2156 LOG(ERROR) <<
"Unknown parameter " << paramName <<
" : function "
2157 << __FUNCTION__ << std::endl;
2174 if (!xprs->quiet()) {
2182 printf(
"%*s\n", nLen, sMsg);
2192void XpressInterface::AddSolutionHintToOptimizer() {
2194 const std::size_t len =
solver_->solution_hint_.size();
2199 unique_ptr<int[]> col_ind(
new int[len]);
2200 unique_ptr<double[]> val(
new double[len]);
2202 for (std::size_t i = 0;
i < len; ++
i) {
2203 col_ind[
i] =
solver_->solution_hint_[
i].first->index();
2204 val[
i] =
solver_->solution_hint_[
i].second;
2206 addhint(mLp, len, val.get(), col_ind.get());
2210 if (callback_ !=
nullptr) {
2214 callback_ = mp_callback;
2222 if (callback_with_context ==
nullptr ||
2223 callback_with_context->GetCallback() ==
nullptr) {
2228 std::unique_ptr<XpressMPCallbackContext> cb_context =
2229 std::make_unique<XpressMPCallbackContext>(
2231 callback_with_context->GetCallback()->RunCallback(cb_context.get());
2232 }
catch (std::exception&) {
2233 callback_with_context->CatchException(cbprob);
2242 if (variable_values_.empty()) {
2244 variable_values_.resize(num_vars);
2247 return variable_values_[variable->
index()];
2251 const absl::flat_hash_map<const MPVariable*, double>&
solution) {
2253 const std::size_t len =
solution.size();
2264 <<
"XPRESS does not currently allow suggesting MIP solutions after "
2265 "a kMipSolution event. Try another call-back.";
2268 unique_ptr<int[]> colind(
new int[len]);
2269 unique_ptr<double[]> val(
new double[len]);
2271 for (
const auto& [var, value] :
solution) {
2272 colind[i] = var->
index();
2276 addhint(*xprsprob_, len, val.get(), colind.get());
void Start()
When Start() is called multiple times, only the most recent is used.
Wraps the MPCallback in order to catch and store exceptions.
MPCallback * GetCallback() const
MPCallbackWrapper(MPCallback *callback)
void CatchException(XPRSprob cbprob)
void LogCaughtExceptions()
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_.
void set_variable_as_extracted(int var_index, bool extracted)
bool CheckSolutionIsSynchronized() const
static constexpr int64_t kUnknownNumberOfIterations
friend class MPConstraint
To access the maximize_ bool and the MPSolver.
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.
MPSolverInterface(MPSolver *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.
@ SCALING
Advanced usage: enable or disable matrix scaling.
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.
@ FEASIBLE
feasible, or stopped by limit.
@ INFEASIBLE
proven infeasible.
@ UNBOUNDED
proven unbounded.
@ ABNORMAL
abnormal, i.e., error of some kind.
The class for variables of a Mathematical Programming (MP) model.
bool integer() const
Returns the integrality requirement of the variable.
double lb() const
Returns the lower bound.
double ub() const
Returns the upper bound.
const std::string & name() const
Returns the name of the variable.
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_.
MPSolver::BasisStatus row_status(int constraint_index) const override
Returns the basis status of a row.
virtual int64_t nodes() const
Number of branch-and-bound nodes. Only available for discrete problems.
MPSolver::BasisStatus column_status(int variable_index) const override
Returns the basis status of a column.
void ClearObjective() override
Clear the objective from all its terms.
void SetOptimizationDirection(bool maximize) override
Sets the optimization direction (min/max).
void AddRowConstraint(MPConstraint *ct) override
Adds a linear constraint.
void SetObjectiveOffset(double value) override
Change the constant term in the linear objective.
double ComputeExactConditionNumber() const override
bool IsLP() const override
Returns true if the problem is continuous and linear.
virtual bool ReadParameterFile(std::string const &filename)
void Reset() override
---— Model modifications and extraction --—
void SetCoefficient(MPConstraint *constraint, MPVariable const *variable, double new_value, double old_value) override
Changes a coefficient in a constraint.
void SetVariableBounds(int var_index, double lb, double ub) override
Modifies bounds of an extracted variable.
XpressInterface(MPSolver *solver, bool mip)
Creates an LP/MIP instance.
void Write(const std::string &filename) override
Writes the model.
void * underlying_solver() override
Returns the underlying solver.
MPSolver::ResultStatus Solve(MPSolverParameters const ¶m) override
void ExtractObjective() override
Extract the objective function.
void ClearConstraint(MPConstraint *constraint) override
Clear a constraint from all its terms.
void SetConstraintBounds(int row_index, double lb, double ub) override
Modify bounds of an extracted variable.
void SetRelativeMipGap(double value) override
Set each parameter in the underlying solver.
void SetDualTolerance(double value) override
void ExtractNewVariables() override
Extract all variables that have not yet been extracted.
bool InterruptSolve() override
void SetScalingMode(int value) override
Sets the scaling mode.
void AddVariable(MPVariable *var) override
Add a variable.
void SetObjectiveCoefficient(MPVariable const *variable, double coefficient) override
Change a coefficient in the linear objective.
void SetStartingLpBasis(const std::vector< MPSolver::BasisStatus > &variable_statuses, const std::vector< MPSolver::BasisStatus > &constraint_statuses) override
See MPSolver::SetStartingLpBasis().
void SetLpAlgorithm(int value) override
void SetCallback(MPCallback *mp_callback) override
See MPSolver::SetCallback() for details.
virtual int64_t iterations() const
---— Query statistics on the solution and the solve ---—
void ExtractNewConstraints() override
Extract constraints that have not yet been extracted.
virtual std::string ValidFileExtensionForParameterFile() const
void SetPrimalTolerance(double value) override
void SetParameters(MPSolverParameters const ¶m) override
Set all parameters in the underlying solver.
bool SupportsCallbacks() const override
void SetVariableInteger(int var_index, bool integer) override
Modifies integrality of an extracted variable.
~XpressInterface() override
void SetPresolveMode(int value) override
bool IsMIP() const override
Returns true if the problem is discrete and linear.
bool IsContinuous() const override
--— Misc --—
std::string SolverVersion() const override
Returns a string describing the underlying solver and its version.
void AddCut(const LinearRange &cutting_plane) override
bool UpdateFromXpressState(XPRSprob cbprob)
MPCallbackEvent Event() override
Implementation of the interface.
int64_t NumExploredNodes() override
bool CanQueryVariableValues() override
XpressMPCallbackContext(XPRSprob *xprsprob, MPCallbackEvent event, int num_nodes)
double SuggestSolution(const absl::flat_hash_map< const MPVariable *, double > &solution) override
void AddLazyConstraint(const LinearRange &lazy_constraint) override
friend class XpressInterface
double VariableValue(const MPVariable *variable) override
absl::string_view name() const
In SWIG mode, we don't want anything besides these top-level includes.
std::function< int(XPRSprob prob, int objidx)> XPRSdelobj
std::function< int(XPRSprob prob, void(XPRS_CC *f_intsol)(XPRSprob cbprob, void *cbdata), void *p, int priority)> XPRSaddcbintsol
std::function< int(XPRSprob prob, int control)> XPRSsetdefaultcontrol
std::function< int(XPRSprob prob, int nrows, const int rowind[], const char rowtype[])> XPRSchgrowtype
void addhint(const XPRSprob &mLp, int length, const double solval[], const int colind[])
std::function< int(XPRSprob prob, int attrib, int *p_value)> XPRSgetintattrib
static std::map< std::string, int > & getMapIntControls()
std::function< int(XPRSprob prob, int attrib, double *p_value)> XPRSgetdblattrib
std::function< int(XPRSprob prob, const char *filename, const char *flags)> XPRSwriteprob
std::function< int(XPRSprob prob, void(XPRS_CC *f_message)(XPRSprob cbprob, void *cbdata, const char *msg, int msglen, int msgtype), void *p, int priority)> XPRSaddcbmessage
Select next search node to expand Select next item_i to add this new search node to the search Generate a new search node where item_i is not in the knapsack Check validity of this new partial solution(using propagators) - If valid
static MPSolver::BasisStatus XpressToMPSolverBasisStatus(int xpress_basis_status)
Transform XPRESS basis status to MPSolver basis status.
bool initXpressEnv(bool verbose, int xpress_oem_license_key)
! init XPRESS environment.
std::function< int(XPRSprob prob, int length, const double solval[], const int colind[], const char *name)> XPRSaddmipsol
int getnumcols(const XPRSprob &mLp)
std::function< int(XPRSprob prob, double x[], double slack[])> XPRSgetmipsol
std::function< int(XPRSprob prob, int nbounds, const int colind[], const char bndtype[], const double bndval[])> XPRSchgbounds
int getnodecnt(const XPRSprob &mLp)
bool stringToCharPtr(const std::string &var, const char **out)
std::function< int(XPRSprob prob, const int rowstat[], const int colstat[])> XPRSloadbasis
std::function< int(XPRSprob prob, int row, int col, double coef)> XPRSchgcoef
std::function< int(XPRSprob prob, int nrows, const int rowind[])> XPRSdelrows
std::function< int(XPRSprob prob, int ncols, const int colind[])> XPRSdelcols
std::string getSolverVersion(XPRSprob const &prob)
void interruptXPRESS(XPRSprob &xprsProb, CUSTOM_INTERRUPT_REASON reason)
std::function< int(XPRSprob prob, int control, int *p_value)> XPRSgetintcontrol
std::function< int(XPRSprob prob, void(XPRS_CC *f_intsol)(XPRSprob cbprob, void *cbdata), void *p)> XPRSremovecbintsol
@ kMipSolution
Called every time a new MIP incumbent is found.
std::function< int(XPRSprob prob, int ncols, const int colind[], const char coltype[])> XPRSchgcoltype
std::function< int(XPRSprob prob, const char *name, int *p_id, int *p_type)> XPRSgetcontrolinfo
std::function< int(XPRSprob prob, double x[], double slack[], double duals[], double djs[])> XPRSgetlpsol
std::function< int(XPRSprob prob)> XPRSpostsolve
std::function< int(XPRSprob prob, int nrows, const int rowind[], const double rng[])> XPRSchgrhsrange
int setobjoffset(const XPRSprob &mLp, double value)
std::function< int(XPRSprob prob, int type, const char names[], int first, int last)> XPRSaddnames
static int MPSolverToXpressBasisStatus(MPSolver::BasisStatus mpsolver_basis_status)
Transform MPSolver basis status to XPRESS status.
std::function< int(XPRSprob prob, int ncoefs, const int rowind[], const int colind[], const double rowcoef[])> XPRSchgmcoef
std::function< int(void)> XPRSfree
std::function< int(XPRSprob prob, int reason)> XPRSinterrupt
int getitcnt(const XPRSprob &mLp)
std::vector< int > XpressBasisStatusesFrom(const std::vector< MPSolver::BasisStatus > &statuses)
MPSolverInterface * BuildXpressInterface(bool mip, MPSolver *const solver)
void splitMyString(const std::string &str, Container &cont, char delim=' ')
std::function< int(XPRSprob prob, int control, int value)> XPRSsetintcontrol
std::function< int(XPRSprob prob, int nrows, int ncoefs, const char rowtype[], const double rhs[], const double rng[], const int start[], const int colind[], const double rowcoef[])> XPRSaddrows
static std::map< std::string, int > & getMapStringControls()
std::function< int(XPRSprob prob, char *errmsg)> XPRSgetlasterror
void XPRS_CC XpressIntSolCallbackImpl(XPRSprob cbprob, void *cbdata)
std::function< int(XPRSprob prob)> XPRSdestroyprob
int getnumrows(const XPRSprob &mLp)
void printError(const XPRSprob &mLp, int line)
void XPRS_CC optimizermsg(XPRSprob prob, void *data, const char *sMsg, int nLen, int nMsgLvl)
std::function< int(XPRSprob prob, int control, double value)> XPRSsetdblcontrol
std::function< int(XPRSprob prob, int control, const char *value)> XPRSsetstrcontrol
std::function< int(XPRSprob prob, int ncols, int ncoefs, const double objcoef[], const int start[], const int rowind[], const double rowcoef[], const double lb[], const double ub[])> XPRSaddcols
static std::map< std::string, int > & getMapDoubleControls()
ClosedInterval::Iterator begin(ClosedInterval interval)
std::function< int(XPRSprob prob, const char *flags)> XPRSmipoptimize
std::function< int(XPRSprob prob, int nrows, const int rowind[], const double rhs[])> XPRSchgrhs
std::function< int(XPRSprob prob, int ncols, const int colind[], const double objcoef[])> XPRSchgobj
std::function< int(XPRSprob *p_prob)> XPRScreateprob
std::function< int(XPRSprob prob, const char *flags)> XPRSlpoptimize
static std::map< std::string, int > & getMapInt64Controls()
std::function< int(XPRSprob prob, int control, XPRSint64 value)> XPRSsetintcontrol64
std::function< int(XPRSprob prob, int objsense)> XPRSchgobjsense
std::function< int(XPRSprob prob, int rowstat[], int colstat[])> XPRSgetbasis
bool readParameter(XPRSprob const &prob, std::string const &name, std::string const &value)
Apply the specified name=value setting to prob.
#define XPRS_COMPUTEEXECSERVICE
#define XPRS_BARORDERTHREADS
#define XPRS_EXTRAMIPENTS
#define XPRS_MAXMEMORYHARD
#define XPRS_HEURSEARCHTARGETSIZE
#define XPRS_RELAXTREEMEMORYLIMIT
#define XPRS_CROSSOVERRELPIVOTTOL
#define XPRS_BARGAPTARGET
#define XPRS_TREECUTSELECT
#define XPRS_TUNERTHREADS
#define XPRS_MAXPAGELINES
#define XPRS_MAXCHECKSONMAXTIME
#define XPRS_HEURDIVEITERLIMIT
#define XPRS_GLOBALBOUNDINGBOX
#define XPRS_FEASTOLPERTURB
#define XPRS_TREEFILELOGINTERVAL
#define XPRS_HEURSEARCHTREESELECT
#define XPRS_RESOURCESTRATEGY
#define XPRS_TREEMEMORYSAVINGTARGET
#define XPRS_QUADRATICUNSHIFT
#define XPRS_MIPABSGAPNOTIFYOBJ
#define XPRS_CROSSOVERITERLIMIT
#define XPRS_TYPE_NOTDEFINED
#define XPRS_MIPKAPPAFREQ
#define XPRS_CROSSOVERFEASWEIGHT
#define XPRS_BRANCHCHOICE
#define XPRS_OBJ_MAXIMIZE
#define XPRS_FEASIBILITYJUMP
#define XPRS_OUTPUTCONTROLS
#define XPRS_MIP_SOLUTION
#define XPRS_BARPRESOLVEOPS
#define XPRS_MIPABSGAPNOTIFY
#define XPRS_HEURSEARCHFREQ
#define XPRS_BARINDEFLIMIT
#define XPRS_SIFTPRESOLVEOPS
#define XPRS_VARSELECTION
#define XPRS_CHECKINPUTDATA
#define XPRS_PLUSINFINITY
#define XPRS_EIGENVALUETOL
#define XPRS_DUMMYCONTROL
#define XPRS_COMPUTEJOBPRIORITY
#define XPRS_NUMERICALEMPHASIS
#define XPRS_MAXLOCALBACKTRACK
#define XPRS_CROSSOVERRELPIVOTTOLSAFE
#define XPRS_IFCHECKCONVEXITY
#define XPRS_MIPRESTARTFACTOR
#define XPRS_MIPADDCUTOFF
#define XPRS_SERIALIZEPREINTSOL
#define XPRS_HEURFORCESPECIALOBJ
#define XPRS_ALGAFTERCROSSOVER
#define XPRS_HEURDIVESPEEDUP
#define XPRS_BACKTRACKTIE
#define XPRS_MIP_UNBOUNDED
#define XPRS_PRECONVERTSEPARABLE
#define XPRS_PRECOMPONENTSEFFORT
#define XPRS_COMPUTEMATX_IISMAXTIME
#define XPRS_MPSBOUNDNAME
#define XPRS_DUALSTRATEGY
#define XPRS_BAROBJPERTURB
#define XPRS_MIPFRACREDUCE
#define XPRS_OBJSCALEFACTOR
#define XPRS_SOLTIMELIMIT
#define XPRS_USERSOLHEURISTIC
#define XPRS_BARFAILITERLIMIT
#define XPRS_PRECLIQUESTRATEGY
#define XPRS_FEASTOLTARGET
#define XPRS_MIPRELGAPNOTIFY
#define XPRS_HISTORYCOSTS
#define XPRS_HEURSEARCHROOTCUTFREQ
#define XPRS_MIPTERMINATIONMETHOD
#define XPRS_MAXSTALLTIME
#define XPRS_BRANCHSTRUCTURAL
struct xo_prob_struct * XPRSprob
Copyright 2019-2023 RTE.
#define XPRS_HEURSEARCHROOTSELECT
#define XPRS_MIPDUALREDUCTIONS
#define XPRS_BARNUMSTABILITY
#define XPRS_PRESOLVEPASSES
#define XPRS_IGNORECONTAINERMEMORYLIMIT
#define XPRS_PRIMALUNSHIFT
#define XPRS_CONCURRENTTHREADS
#define XPRS_HEURSEARCHEFFORT
#define XPRS_MAXIMPLIEDBOUND
#define XPRS_ROOTPRESOLVE
#define XPRS_CROSSOVERTHREADS
#define XPRS_PREBNDREDCONE
#define XPRS_MAXCHECKSONMAXCUTTIME
#define XPRS_MUTEXCALLBACKS
#define XPRS_MIPRELCUTOFF
#define XPRS_MPS18COMPATIBLE
#define XPRS_BARSTARTWEIGHT
#define XPRS_OPTIMALITYTOLTARGET
#define XPRS_PREANALYTICCENTER
#define XPRS_HEURDIVESTRATEGY
#define XPRS_BREADTHFIRST
#define XPRS_LOCALBACKTRACK
#define XPRS_TUNERMAXTIME
#define XPRS_FEASIBILITYPUMP
#define XPRS_REPAIRINDEFINITEQMAX
#define XPRS_TUNERHISTORY
#define XPRS_REPAIRINDEFINITEQ
#define XPRS_TREEDIAGNOSTICS
#define XPRS_PRECONFIGURATION
#define XPRS_CROSSOVEROPS
#define XPRS_MIPABSGAPNOTIFYBOUND
#define XPRS_COMPUTEMATX_IIS
#define XPRS_CONFLICTCUTS
#define XPRS_INDPRELINBIGM
#define XPRS_PRIMALPERTURB
#define XPRS_ALGAFTERNETWORK
#define XPRS_DUALGRADIENT
#define XPRS_PRECOMPONENTS
#define XPRS_NODEPROBINGEFFORT
#define XPRS_PWLNONCONVEXTRANSFORMATION
#define XPRS_TREECOMPRESSION
#define XPRS_PRESOLVEMAXGROW
#define XPRS_TREEMEMORYLIMIT
#define XPRS_MIPCOMPONENTS
#define XPRS_TUNERSESSIONNAME
#define XPRS_BARFREESCALE
#define XPRS_TUNEROUTPUTPATH
#define XPRS_MARKOWITZTOL
#define XPRS_HEURDIVERANDOMIZE
#define XPRS_PWLDUALREDUCTIONS
#define XPRS_BARLARGEBOUND
#define XPRS_OPTIMALITYTOL
#define XPRS_MAXSCALEFACTOR
#define XPRS_CROSSOVERACCURACYTOL
#define XPRS_PRECONEDECOMP
#define XPRS_HEUREMPHASIS
#define XPRS_BARITERLIMIT
#define XPRS_TUNERVERBOSE
#define XPRS_TUNERPERMUTE
#define XPRS_PREOBJCUTDETECT
#define XPRS_PREPROTECTDUAL
#define XPRS_REPAIRINFEASTIMELIMIT
#define XPRS_MPSNAMELENGTH
#define XPRS_GENCONSDUALREDUCTIONS
#define XPRS_LP_UNBOUNDED
#define XPRS_GENCONSABSTRANSFORMATION
#define XPRS_LPREFINEITERLIMIT
#define XPRS_HEURDIVESOFTROUNDING
#define XPRS_MIPREFINEITERLIMIT
#define XPRS_REPAIRINFEASMAXTIME
#define XPRS_MAXTREEFILESIZE
#define XPRS_HEURBEFORELP
#define XPRS_CALLBACKCHECKTIMEDELAY
#define XPRS_LNPITERLIMIT
#define XPRS_BARREGULARIZE
#define XPRS_NODESELECTION
#define XPRS_IGNORECONTAINERCPULIMIT
#define XPRS_CALLBACKFROMMASTERTHREAD
#define XPRS_MIPCONCURRENTNODES
#define XPRS_EXTRASETELEMS
#define XPRS_MIPABSCUTOFF
#define XPRS_TREECOVERCUTS
#define XPRS_DENSECOLLIMIT
#define XPRS_SLEEPONTHREADWAIT
#define XPRS_GLOBALSPATIALBRANCHIFPREFERORIG
#define XPRS_NAMES_COLUMN
#define XPRS_FORCEPARALLELDUAL
#define XPRS_MIPCONCURRENTSOLVES
#define XPRS_CROSSOVERDRP
#define XPRS_MIPRESTARTGAPTHRESHOLD
#define XPRS_MINUSINFINITY
#define XPRS_PREIMPLICATIONS
#define XPRS_MPSRANGENAME
#define XPRS_MAXMCOEFFBUFFERELEMS
#define XPRS_DETERMINISTIC
#define XPRS_MIPTOLTARGET
#define XPRS_MAXMEMORYSOFT
#define XPRS_TUNERMETHODFILE
#define XPRS_PREPERMUTESEED
#define XPRS_CC
NOLINTEND(runtime/int)
#define XPRS_OBJ_MINIMIZE
#define XPRS_NETSTALLLIMIT
#define XPRS_PREBNDREDQUAD
#define XPRS_BARPRIMALSTOP
#define setParamIfPossible_MACRO(target_map, setter, converter, type)
#define XPRS_INTEGER
Initial version of this code was provided by RTE.