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";
235 LOG(WARNING) <<
"AddLazyConstraint inside Callback is not implemented yet "
236 "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]);
1544 std::vector<int> delayedRows;
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;
1579 delayedRows.push_back(offset + c);
1584 rngval.get(), rmatbeg.get(), rmatind.get(),
1587 if (!delayedRows.empty()) {
1589 mLp,
static_cast<int>(delayedRows.size()), delayedRows.data()));
1595 std::vector<int> rows_to_delete;
1596 for (
int i = offset; i < rows; ++i) rows_to_delete.push_back(i);
1598 (void)
XPRSdelrows(mLp, rows_to_delete.size(), rows_to_delete.data());
1599 std::vector<MPConstraint*>
const& constraints =
solver_->constraints();
1600 int const size = constraints.size();
1615 unique_ptr<int[]> ind(
new int[cols]);
1616 unique_ptr<double[]> val(
new double[cols]);
1617 for (
int j = 0; j < cols; ++j) {
1622 const auto& coeffs =
solver_->objective_->coefficients_;
1623 for (
auto coeff : coeffs) {
1624 int const idx = coeff.first->index();
1626 DCHECK_LT(idx, cols);
1627 val[idx] = coeff.second;
1647 LOG(WARNING) <<
"The relative MIP gap is only available "
1648 <<
"for discrete problems.";
1695 auto const algorithm =
1700 switch (algorithm) {
1719 const std::vector<MPSolver::BasisStatus>& statuses) {
1720 std::vector<int> result;
1721 result.resize(statuses.size());
1722 std::transform(statuses.cbegin(), statuses.cend(), result.begin(),
1728 const std::vector<MPSolver::BasisStatus>& variable_statuses,
1729 const std::vector<MPSolver::BasisStatus>& constraint_statuses) {
1731 LOG(DFATAL) << __FUNCTION__ <<
" is only available for LP problems";
1735 initial_constraint_basis_status_ =
1739bool XpressInterface::readParameters(std::istream& is,
char sep) {
1745 std::string name(
""), value(
"");
1746 bool inValue =
false;
1750 if (is.eof())
break;
1753 LOG(DFATAL) <<
"Failed to parse parameters in " <<
SolverVersion();
1757 }
else if (c == sep) {
1759 if (name.size() == 0 && value.size() == 0) {
1762 }
else if (name.size() == 0) {
1763 LOG(DFATAL) <<
"Parameter setting without name in " <<
SolverVersion();
1771 }
else if (std::isspace(c)) {
1773 }
else if (inValue) {
1786 std::ifstream s(filename);
1787 if (!s)
return false;
1788 return readParameters(s,
'\n');
1827 VLOG(1) << absl::StrFormat(
"Model build in %.3f seconds.", timer.
Get());
1839 solver_->SetSolverSpecificParametersAsString(
1840 solver_->solver_specific_parameter_string_);
1842 VLOG(1) <<
"Setting time limit = " <<
solver_->time_limit() <<
" ms.";
1846 -1 *
solver_->time_limit_in_secs()));
1851 if (!mMip && !initial_variables_basis_status_.empty() &&
1852 !initial_constraint_basis_status_.empty()) {
1854 initial_variables_basis_status_.data()));
1858 this->AddSolutionHintToOptimizer();
1863 if (callback_ !=
nullptr) {
1866 static_cast<void*
>(mp_callback_wrapper), 0));
1874 int xpress_stat = 0;
1883 if (mp_callback_wrapper !=
nullptr) {
1885 delete mp_callback_wrapper;
1897 VLOG(1) << absl::StrFormat(
"Failed to optimize MIP. Error %d", status);
1901 VLOG(1) << absl::StrFormat(
"Solved in %.3f seconds.", timer.
Get());
1904 VLOG(1) << absl::StrFormat(
"XPRESS solution status %d.", xpress_stat);
1914 DCHECK_EQ(rows,
solver_->constraints_.size());
1915 DCHECK_EQ(cols,
solver_->variables_.size());
1937 unique_ptr<double[]> x(
new double[cols]);
1939 for (
int i = 0; i <
solver_->variables_.size(); ++i) {
1942 VLOG(3) << var->
name() <<
": value =" << x[i];
1946 for (
auto& variable :
solver_->variables_)
1951 for (
auto& variable :
solver_->variables_)
1953 for (
auto& constraint :
solver_->constraints_)
1958 unique_ptr<double[]> x(
new double[cols]);
1959 unique_ptr<double[]> dj(
new double[cols]);
1961 for (
int i = 0; i <
solver_->variables_.size(); ++i) {
1964 bool value =
false, dual =
false;
1978 VLOG(3) << var->
name() <<
":"
1979 << (value ? absl::StrFormat(
" value = %f", x[i]) :
"")
1980 << (dual ? absl::StrFormat(
" reduced cost = %f", dj[i]) :
"");
1985 unique_ptr<double[]> pi(
new double[rows]);
1989 for (
int i = 0; i <
solver_->constraints_.size(); ++i) {
1998 VLOG(4) <<
"row " << ct->
index() <<
":"
1999 << (dual ? absl::StrFormat(
" dual = %f", pi[i]) :
"");
2006 switch (xpress_stat) {
2021 switch (xpress_stat) {
2058void ExtractNames(
XPRSprob mLp,
const std::vector<T*>& objects) {
2059 const bool have_names =
2060 std::any_of(objects.begin(), objects.end(),
2061 [](
const T* x) { return !x->name().empty(); });
2068 std::vector<char> all_names;
2069 for (
const auto& x : objects) {
2070 const std::string& current_name =
x->
name();
2071 std::copy(current_name.begin(), current_name.end(),
2072 std::back_inserter(all_names));
2073 all_names.push_back(
'\0');
2078 if (!all_names.empty() && all_names.back() ==
'\0') all_names.pop_back();
2081 objects.size() - 1));
2092 ExtractNames(mLp,
solver_->variables_);
2093 ExtractNames(mLp,
solver_->constraints_);
2095 VLOG(1) <<
"Writing Xpress MPS \"" << filename <<
"\".";
2096 const int status =
XPRSwriteprob(mLp, filename.c_str(),
"");
2098 LOG(ERROR) <<
"Xpress: Failed to write MPS!";
2102template <
class Container>
2104 std::stringstream ss(str);
2106 while (std::getline(ss, token, delim)) {
2107 cont.push_back(token);
2116#define setParamIfPossible_MACRO(target_map, setter, converter, type) \
2118 auto matchingParamIter = (target_map).find(paramAndValuePair.first); \
2119 if (matchingParamIter != (target_map).end()) { \
2120 type convertedValue; \
2121 bool ret = converter(paramAndValuePair.second, &convertedValue); \
2123 VLOG(1) << "Setting parameter " << paramAndValuePair.first \
2124 << " to value " << convertedValue << std::endl; \
2126 setter(mLp, matchingParamIter->second, convertedValue); \
2131bool XpressInterface::SetSolverSpecificParametersAsString(
2132 const std::string& parameters) {
2133 if (parameters.empty())
return true;
2135 std::vector<std::pair<std::string, std::string> > paramAndValuePairList;
2137 std::stringstream ss(parameters);
2138 std::string paramName;
2139 while (std::getline(ss, paramName,
' ')) {
2140 std::string paramValue;
2141 if (std::getline(ss, paramValue,
' ')) {
2142 paramAndValuePairList.push_back(std::make_pair(paramName, paramValue));
2144 LOG(ERROR) <<
"No value for parameter " << paramName <<
" : function "
2145 << __FUNCTION__ << std::endl;
2150 for (
auto& paramAndValuePair : paramAndValuePairList) {
2152 absl::SimpleAtoi<int>,
int);
2154 absl::SimpleAtod,
double);
2158 absl::SimpleAtoi<int64_t>, int64_t);
2159 LOG(ERROR) <<
"Unknown parameter " << paramName <<
" : function "
2160 << __FUNCTION__ << std::endl;
2177 if (!xprs->quiet()) {
2185 printf(
"%*s\n", nLen, sMsg);
2195void XpressInterface::AddSolutionHintToOptimizer() {
2197 const std::size_t len =
solver_->solution_hint_.size();
2202 unique_ptr<int[]> col_ind(
new int[len]);
2203 unique_ptr<double[]> val(
new double[len]);
2205 for (std::size_t i = 0;
i < len; ++
i) {
2206 col_ind[
i] =
solver_->solution_hint_[
i].first->index();
2207 val[
i] =
solver_->solution_hint_[
i].second;
2209 addhint(mLp, len, val.get(), col_ind.get());
2213 if (callback_ !=
nullptr) {
2217 callback_ = mp_callback;
2225 if (callback_with_context ==
nullptr ||
2226 callback_with_context->GetCallback() ==
nullptr) {
2231 std::unique_ptr<XpressMPCallbackContext> cb_context =
2232 std::make_unique<XpressMPCallbackContext>(
2234 callback_with_context->GetCallback()->RunCallback(cb_context.get());
2235 }
catch (std::exception&) {
2236 callback_with_context->CatchException(cbprob);
2245 if (variable_values_.empty()) {
2247 variable_values_.resize(num_vars);
2250 return variable_values_[variable->
index()];
2254 const absl::flat_hash_map<const MPVariable*, double>&
solution) {
2256 const std::size_t len =
solution.size();
2267 <<
"XPRESS does not currently allow suggesting MIP solutions after "
2268 "a kMipSolution event. Try another call-back.";
2271 unique_ptr<int[]> colind(
new int[len]);
2272 unique_ptr<double[]> val(
new double[len]);
2274 for (
const auto& [var, value] :
solution) {
2275 colind[i] = var->
index();
2279 addhint(*xprsprob_, len, val.get(), colind.get());
2289const void*
const kRegisterXpress ABSL_ATTRIBUTE_UNUSED = [] {
2298const void*
const kRegisterXpressMip ABSL_ATTRIBUTE_UNUSED = [] {
MPCallback * GetCallback() const
MPCallbackWrapper(MPCallback *callback)
void CatchException(XPRSprob cbprob)
void LogCaughtExceptions()
bool is_lazy() const
Advanced usage: returns true if the constraint is "lazy" (see below).
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)
bool CheckSolutionIsSynchronized() const
static constexpr int64_t kUnknownNumberOfIterations
friend class MPConstraint
void InvalidateSolutionSynchronization()
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
bool constraint_is_extracted(int ct_index) const
static constexpr int64_t kUnknownNumberOfNodes
double best_objective_bound_
void SetMIPParameters(const MPSolverParameters ¶m)
MPSolverInterface(MPSolver *solver)
void SetCommonParameters(const MPSolverParameters ¶m)
MPSolver::ResultStatus result_status_
SynchronizationStatus sync_status_
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.
@ XPRESS_MIXED_INTEGER_PROGRAMMING
@ XPRESS_LINEAR_PROGRAMMING
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
virtual int64_t nodes() const
MPSolver::BasisStatus column_status(int variable_index) const override
void ClearObjective() override
void SetOptimizationDirection(bool maximize) override
void AddRowConstraint(MPConstraint *ct) override
void SetObjectiveOffset(double value) override
double ComputeExactConditionNumber() const override
bool IsLP() const override
virtual bool ReadParameterFile(std::string const &filename)
void SetCoefficient(MPConstraint *constraint, MPVariable const *variable, double new_value, double old_value) override
void SetVariableBounds(int var_index, double lb, double ub) override
XpressInterface(MPSolver *solver, bool mip)
void Write(const std::string &filename) override
void * underlying_solver() override
MPSolver::ResultStatus Solve(MPSolverParameters const ¶m) override
void ExtractObjective() override
void ClearConstraint(MPConstraint *constraint) override
void SetConstraintBounds(int row_index, double lb, double ub) override
void SetRelativeMipGap(double value) override
void SetDualTolerance(double value) override
void ExtractNewVariables() override
bool InterruptSolve() override
void SetScalingMode(int value) override
void AddVariable(MPVariable *var) override
void SetObjectiveCoefficient(MPVariable const *variable, double coefficient) override
void SetStartingLpBasis(const std::vector< MPSolver::BasisStatus > &variable_statuses, const std::vector< MPSolver::BasisStatus > &constraint_statuses) override
void SetLpAlgorithm(int value) override
void SetCallback(MPCallback *mp_callback) override
virtual int64_t iterations() const
void ExtractNewConstraints() override
virtual std::string ValidFileExtensionForParameterFile() const
void SetPrimalTolerance(double value) override
void SetParameters(MPSolverParameters const ¶m) override
bool SupportsCallbacks() const override
void SetVariableInteger(int var_index, bool integer) override
~XpressInterface() override
void SetPresolveMode(int value) override
bool IsMIP() const override
bool IsContinuous() const override
std::string SolverVersion() const override
void AddCut(const LinearRange &cutting_plane) override
bool UpdateFromXpressState(XPRSprob cbprob)
MPCallbackEvent Event() override
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
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 nrows, const int rowind[])> XPRSloaddelayedrows
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)
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
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)
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)
bool XpressIsCorrectlyInstalled()
std::vector< int > XpressBasisStatusesFrom(const std::vector< MPSolver::BasisStatus > &statuses)
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)
#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
#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_OBJ_MINIMIZE
#define XPRS_NETSTALLLIMIT
#define XPRS_PREBNDREDQUAD
#define XPRS_BARPRIMALSTOP
#define setParamIfPossible_MACRO(target_map, setter, converter, type)