25#include "absl/strings/str_format.h"
31#define XPRS_INTEGER 'I'
32#define XPRS_CONTINUOUS 'C'
37#define CHECK_STATUS(s) \
39 int const status_ = s; \
40 CHECK_EQ(0, status_); \
49 return "XPRESS library version unknown";
51 int const major = version / 100;
52 version -= major * 100;
53 int const release = version;
55 return absl::StrFormat(
"XPRESS library version %d.%02d", major, release);
60 std::string
const& value) {
63 LOG(DFATAL) <<
"Empty value for parameter '" << name <<
"' in "
72 LOG(DFATAL) <<
"Unknown parameter '" << name <<
"' in "
78 std::stringstream v(value);
79 v.imbue(std::locale(
"C"));
85 LOG(DFATAL) <<
"Failed to parse value '" << value
86 <<
"' for int parameter '" << name <<
"' in "
91 LOG(DFATAL) <<
"Failed to set int parameter '" << name <<
"' to "
100 LOG(DFATAL) <<
"Failed to parse value '" << value
101 <<
"' for int64_t parameter '" << name <<
"' in "
106 LOG(DFATAL) <<
"Failed to set int64_t parameter '" << name <<
"' to "
115 LOG(DFATAL) <<
"Failed to parse value '" << value
116 <<
"' for dbl parameter '" << name <<
"' in "
121 LOG(DFATAL) <<
"Failed to set double parameter '" << name <<
"' to "
129 LOG(DFATAL) <<
"Unsupported parameter type " << type <<
" for parameter '"
140 VLOG(0) << absl::StrFormat(
"Function line %d did not execute correctly: %s\n",
184 static int indexes[1] = {-1};
185 double values[1] = {-value};
191 const int colind[]) {
194 if (
int status =
XPRSaddmipsol(mLp, length, solval, colind, NULL)) {
195 LOG(WARNING) <<
"Failed to set solution hint.";
208#if !defined(XPRS_NAN)
209#define XPRS_NAN std::numeric_limits<double>::quiet_NaN()
212using std::unique_ptr;
220 : xprsprob_(xprsprob),
222 num_nodes_(num_nodes),
223 variable_values_(0) {};
230 LOG(WARNING) <<
"AddCut is not implemented yet in XPRESS interface";
234 <<
"AddLazyConstraint is not implemented yet in XPRESS interface";
237 const absl::flat_hash_map<const MPVariable*, double>&
solution)
override;
263 exceptions_mutex_.lock();
264 caught_exceptions_.push_back(std::current_exception());
266 exceptions_mutex_.unlock();
269 exceptions_mutex_.lock();
270 for (
const std::exception_ptr& ex : caught_exceptions_) {
272 std::rethrow_exception(ex);
273 }
catch (std::exception& ex) {
278 LOG(ERROR) <<
"Caught exception during user-defined call-back: "
282 caught_exceptions_.clear();
283 exceptions_mutex_.unlock();
288 std::vector<std::exception_ptr> caught_exceptions_;
289 std::mutex exceptions_mutex_;
313 void Write(
const std::string& filename)
override;
317 void Reset()
override;
326 double new_value,
double old_value)
override;
332 double coefficient)
override;
342 virtual int64_t
nodes()
const;
355 bool IsLP()
const override {
return !mMip; }
356 bool IsMIP()
const override {
return mMip; }
359 const std::vector<MPSolver::BasisStatus>& variable_statuses,
360 const std::vector<MPSolver::BasisStatus>& constraint_statuses)
override;
372 LOG(DFATAL) <<
"ComputeExactConditionNumber not implemented for"
373 <<
" XPRESS_MIXED_INTEGER_PROGRAMMING";
378 LOG(DFATAL) <<
"ComputeExactConditionNumber not implemented for"
379 <<
" XPRESS_LINEAR_PROGRAMMING";
409 void InvalidateModelSynchronization() {
417 void AddSolutionHintToOptimizer();
419 bool readParameters(std::istream& is,
char sep);
435 bool const supportIncrementalExtraction;
443 SlowSetCoefficient = 0x0001,
444 SlowClearConstraint = 0x0002,
445 SlowSetObjectiveCoefficient = 0x0004,
446 SlowClearObjective = 0x0008,
447 SlowSetConstraintBounds = 0x0010,
448 SlowSetVariableInteger = 0x0020,
449 SlowSetVariableBounds = 0x0040,
450 SlowUpdatesAll = 0xffff
458 std::vector<int>
mutable mCstat;
459 std::vector<int>
mutable mRstat;
461 std::vector<int>
mutable initial_variables_basis_status_;
462 std::vector<int>
mutable initial_constraint_basis_status_;
465 static void MakeRhs(
double lb,
double ub,
double& rhs,
char& sense,
468 std::map<std::string, int>& mapStringControls_;
469 std::map<std::string, int>& mapDoubleControls_;
470 std::map<std::string, int>& mapIntegerControls_;
471 std::map<std::string, int>& mapInteger64Controls_;
473 bool SetSolverSpecificParametersAsString(
474 const std::string& parameters)
override;
475 MPCallback* callback_ =
nullptr;
483 int xpress_basis_status);
486 static std::map<std::string, int> mapControls = {
501 static std::map<std::string, int> mapControls = {
586 static std::map<std::string, int> mapControls = {
823 static std::map<std::string, int> mapControls = {
835 supportIncrementalExtraction(false),
836 slowUpdates(SlowClearObjective),
842 CHECK(correctlyLoaded);
845 DCHECK(mLp !=
nullptr);
847 CHECK_STATUS(
XPRSloadlp(mLp,
"newProb", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0));
863 int const major = version / 1000000;
864 version -= major * 1000000;
865 int const release = version / 10000;
866 version -= release * 10000;
867 int const mod = version / 100;
868 version -= mod * 100;
869 int const fix = version;
871 return absl::StrFormat(
"XPRESS library version %d.%02d.%02d.%02d", major,
885 DCHECK(mLp !=
nullptr);
887 CHECK_STATUS(
XPRSloadlp(mLp,
"newProb", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0));
911 if (!supportIncrementalExtraction && !(slowUpdates & SlowSetVariableBounds)) {
912 InvalidateModelSynchronization();
918 char const lu[2] = {
'L',
'U'};
919 double const bd[2] = {lb, ub};
920 int const idx[2] = {var_index, var_index};
925 InvalidateModelSynchronization();
944 if (!supportIncrementalExtraction &&
945 !(slowUpdates & SlowSetVariableInteger)) {
946 InvalidateModelSynchronization();
957 InvalidateModelSynchronization();
961 <<
"Attempt to change variable to integer in non-MIP problem!";
967void XpressInterface::MakeRhs(
double lb,
double ub,
double& rhs,
char& sense,
982 LOG(DFATAL) <<
"XPRESS does not support contradictory bounds on range "
984 << lb <<
", " << ub <<
"] will be converted to " << ub <<
", "
985 << (ub - std::abs(ub - lb)) <<
"]";
1012 if (std::abs(lb) < std::abs(ub))
1030 if (!supportIncrementalExtraction &&
1031 !(slowUpdates & SlowSetConstraintBounds)) {
1032 InvalidateModelSynchronization();
1037 DCHECK(mLp !=
nullptr);
1040 MakeRhs(lb, ub, rhs, sense, range);
1055 InvalidateModelSynchronization();
1071 InvalidateModelSynchronization();
1087 InvalidateModelSynchronization();
1092 double new_value,
double) {
1102 if (!supportIncrementalExtraction && !(slowUpdates & SlowSetCoefficient)) {
1103 InvalidateModelSynchronization();
1105 int const row = constraint->
index();
1106 int const col = variable->
index();
1116 InvalidateModelSynchronization();
1122 int const row = constraint->
index();
1135 if (!(slowUpdates & SlowClearConstraint)) {
1136 InvalidateModelSynchronization();
1140 int const len = constraint->coefficients_.size();
1141 unique_ptr<int[]> rowind(
new int[len]);
1142 unique_ptr<int[]> colind(
new int[len]);
1143 unique_ptr<double[]> val(
new double[len]);
1145 const auto& coeffs = constraint->coefficients_;
1146 for (
auto coeff : coeffs) {
1147 int const col = coeff.first->index();
1161 double coefficient) {
1162 int const col = variable->
index();
1175 if (supportIncrementalExtraction ||
1176 (slowUpdates & SlowSetObjectiveCoefficient)) {
1179 InvalidateModelSynchronization();
1197 if (supportIncrementalExtraction || (slowUpdates & SlowClearObjective)) {
1199 unique_ptr<int[]> ind(
new int[cols]);
1200 unique_ptr<double[]> zero(
new double[cols]);
1202 const auto& coeffs =
solver_->objective_->coefficients_;
1203 for (
auto coeff : coeffs) {
1204 int const idx = coeff.first->index();
1207 DCHECK_LT(idx, cols);
1218 InvalidateModelSynchronization();
1226 return static_cast<int64_t
>(
getitcnt(mLp));
1232 return static_cast<int64_t
>(
getnodecnt(mLp));
1234 LOG(DFATAL) <<
"Number of nodes only available for discrete problems";
1241 int xpress_basis_status) {
1242 switch (xpress_basis_status) {
1252 LOG(DFATAL) <<
"Unknown XPRESS basis status";
1259 switch (mpsolver_basis_status) {
1271 LOG(DFATAL) <<
"Unknown MPSolver basis status";
1279 LOG(FATAL) <<
"Basis status only available for continuous problems";
1284 if (mRstat.empty()) {
1286 mRstat.resize(rows);
1293 if (!mRstat.empty()) {
1296 LOG(FATAL) <<
"Row basis status not available";
1304 LOG(FATAL) <<
"Basis status only available for continuous problems";
1309 if (mCstat.empty()) {
1311 mCstat.resize(cols);
1318 if (!mCstat.empty()) {
1321 LOG(FATAL) <<
"Column basis status not available";
1333 if (!supportIncrementalExtraction) {
1343 int const var_count =
solver_->variables_.size();
1344 int new_col_count = var_count - last_extracted;
1345 if (new_col_count > 0) {
1348 unique_ptr<double[]> obj(
new double[new_col_count]);
1349 unique_ptr<double[]> lb(
new double[new_col_count]);
1350 unique_ptr<double[]> ub(
new double[new_col_count]);
1351 unique_ptr<char[]> ctype(
new char[new_col_count]);
1353 for (
int j = 0, var_idx = last_extracted; j < new_col_count;
1359 obj[j] =
solver_->objective_->GetCoefficient(var);
1367 std::vector<MPVariable*>
const& variables =
solver_->variables();
1368 for (
int j = last_extracted; j < var_count; ++j) {
1374 bool use_new_cols =
true;
1376 if (supportIncrementalExtraction) {
1385 unique_ptr<int[]> collen(
new int[new_col_count]);
1386 for (
int j = 0; j < new_col_count; ++j) collen[j] = 0;
1393 const auto& coeffs = ct->coefficients_;
1394 for (
auto coeff : coeffs) {
1395 int const idx = coeff.first->index();
1407 use_new_cols =
false;
1408 unique_ptr<int[]> begin(
new int[new_col_count + 2]);
1409 unique_ptr<int[]> cmatind(
new int[nonzeros]);
1410 unique_ptr<double[]> cmatval(
new double[nonzeros]);
1421 int* cmatbeg = begin.get();
1425 for (
int j = 0; j < new_col_count; ++j)
1426 cmatbeg[j + 1] = cmatbeg[j] + collen[j];
1430 int const row = ct->
index();
1431 const auto& coeffs = ct->coefficients_;
1432 for (
auto coeff : coeffs) {
1433 int const idx = coeff.first->index();
1435 int const nz = cmatbeg[idx]++;
1437 cmatval[nz] = coeff.second;
1443 cmatbeg, cmatind.get(), cmatval.get(),
1444 lb.get(), ub.get()));
1452 std::vector<int> collen(new_col_count, 0);
1453 std::vector<int> cmatbeg(new_col_count, 0);
1454 unique_ptr<int[]> cmatind(
new int[1]);
1455 unique_ptr<double[]> cmatval(
new double[1]);
1460 cmatbeg.data(), cmatind.get(), cmatval.get(),
1461 lb.get(), ub.get()));
1464 unique_ptr<int[]> ind(
new int[new_col_count]);
1465 for (
int j = 0; j < cols; ++j) ind[j] = j;
1467 XPRSchgcoltype(mLp, cols - last_extracted, ind.get(), ctype.get()));
1477 unique_ptr<int[]> ind(
new int[new_col_count]);
1478 for (
int j = last_extracted; j < cols; ++j)
1479 ind[j - last_extracted] = j;
1487 if (cols > last_extracted) {
1488 std::vector<int> cols_to_delete;
1489 for (
int i = last_extracted; i < cols; ++i) cols_to_delete.push_back(i);
1490 (void)
XPRSdelcols(mLp, cols_to_delete.size(), cols_to_delete.data());
1492 std::vector<MPVariable*>
const& variables =
solver_->variables();
1493 int const size = variables.size();
1494 for (
int j = last_extracted; j < size; ++j)
1505 if (!supportIncrementalExtraction) {
1515 int const total =
solver_->constraints_.size();
1517 if (total > offset) {
1522 int newCons = total - offset;
1524 int const chunk = newCons;
1531 unique_ptr<int[]> rmatind(
new int[cols]);
1532 unique_ptr<double[]> rmatval(
new double[cols]);
1533 unique_ptr<int[]> rmatbeg(
new int[chunk]);
1534 unique_ptr<char[]> sense(
new char[chunk]);
1535 unique_ptr<double[]> rhs(
new double[chunk]);
1536 unique_ptr<double[]> rngval(
new double[chunk]);
1541 for (
int c = 0; c < newCons; ) {
1545 for (; c < newCons && nextRow < chunk; ++c, ++nextRow) {
1550 if (nextNz + ct->coefficients_.size() > cols) {
1551 DCHECK_GT(nextRow, 0);
1556 MakeRhs(ct->
lb(), ct->
ub(), rhs[nextRow], sense[nextRow],
1560 rmatbeg[nextRow] = nextNz;
1561 const auto& coeffs = ct->coefficients_;
1562 for (
auto coeff : coeffs) {
1563 int const idx = coeff.first->index();
1565 DCHECK_LT(nextNz, cols);
1566 DCHECK_LT(idx, cols);
1567 rmatind[nextNz] = idx;
1568 rmatval[nextNz] = coeff.second;
1575 rngval.get(), rmatbeg.get(), rmatind.get(),
1582 std::vector<int> rows_to_delete;
1583 for (
int i = offset; i < rows; ++i) rows_to_delete.push_back(i);
1585 (void)
XPRSdelrows(mLp, rows_to_delete.size(), rows_to_delete.data());
1586 std::vector<MPConstraint*>
const& constraints =
solver_->constraints();
1587 int const size = constraints.size();
1602 unique_ptr<int[]> ind(
new int[cols]);
1603 unique_ptr<double[]> val(
new double[cols]);
1604 for (
int j = 0; j < cols; ++j) {
1609 const auto& coeffs =
solver_->objective_->coefficients_;
1610 for (
auto coeff : coeffs) {
1611 int const idx = coeff.first->index();
1613 DCHECK_LT(idx, cols);
1614 val[idx] = coeff.second;
1634 LOG(WARNING) <<
"The relative MIP gap is only available "
1635 <<
"for discrete problems.";
1682 auto const algorithm =
1687 switch (algorithm) {
1706 const std::vector<MPSolver::BasisStatus>& statuses) {
1707 std::vector<int> result;
1708 result.resize(statuses.size());
1709 std::transform(statuses.cbegin(), statuses.cend(), result.begin(),
1715 const std::vector<MPSolver::BasisStatus>& variable_statuses,
1716 const std::vector<MPSolver::BasisStatus>& constraint_statuses) {
1718 LOG(DFATAL) << __FUNCTION__ <<
" is only available for LP problems";
1722 initial_constraint_basis_status_ =
1726bool XpressInterface::readParameters(std::istream& is,
char sep) {
1732 std::string name(
""), value(
"");
1733 bool inValue =
false;
1737 if (is.eof())
break;
1740 LOG(DFATAL) <<
"Failed to parse parameters in " <<
SolverVersion();
1744 }
else if (c == sep) {
1746 if (name.size() == 0 && value.size() == 0) {
1749 }
else if (name.size() == 0) {
1750 LOG(DFATAL) <<
"Parameter setting without name in " <<
SolverVersion();
1758 }
else if (std::isspace(c)) {
1760 }
else if (inValue) {
1773 std::ifstream s(filename);
1774 if (!s)
return false;
1775 return readParameters(s,
'\n');
1814 VLOG(1) << absl::StrFormat(
"Model build in %.3f seconds.", timer.
Get());
1826 solver_->SetSolverSpecificParametersAsString(
1827 solver_->solver_specific_parameter_string_);
1829 VLOG(1) <<
"Setting time limit = " <<
solver_->time_limit() <<
" ms.";
1833 -1 *
solver_->time_limit_in_secs()));
1838 if (!mMip && !initial_variables_basis_status_.empty() &&
1839 !initial_constraint_basis_status_.empty()) {
1841 initial_variables_basis_status_.data()));
1845 this->AddSolutionHintToOptimizer();
1850 if (callback_ !=
nullptr) {
1853 static_cast<void*
>(mp_callback_wrapper), 0));
1861 int xpress_stat = 0;
1870 if (mp_callback_wrapper !=
nullptr) {
1872 delete mp_callback_wrapper;
1884 VLOG(1) << absl::StrFormat(
"Failed to optimize MIP. Error %d", status);
1888 VLOG(1) << absl::StrFormat(
"Solved in %.3f seconds.", timer.
Get());
1891 VLOG(1) << absl::StrFormat(
"XPRESS solution status %d.", xpress_stat);
1901 DCHECK_EQ(rows,
solver_->constraints_.size());
1902 DCHECK_EQ(cols,
solver_->variables_.size());
1924 unique_ptr<double[]> x(
new double[cols]);
1926 for (
int i = 0; i <
solver_->variables_.size(); ++i) {
1929 VLOG(3) << var->
name() <<
": value =" << x[i];
1933 for (
auto& variable :
solver_->variables_)
1938 for (
auto& variable :
solver_->variables_)
1940 for (
auto& constraint :
solver_->constraints_)
1945 unique_ptr<double[]> x(
new double[cols]);
1946 unique_ptr<double[]> dj(
new double[cols]);
1948 for (
int i = 0; i <
solver_->variables_.size(); ++i) {
1951 bool value =
false, dual =
false;
1965 VLOG(3) << var->
name() <<
":"
1966 << (value ? absl::StrFormat(
" value = %f", x[i]) :
"")
1967 << (dual ? absl::StrFormat(
" reduced cost = %f", dj[i]) :
"");
1972 unique_ptr<double[]> pi(
new double[rows]);
1976 for (
int i = 0; i <
solver_->constraints_.size(); ++i) {
1985 VLOG(4) <<
"row " << ct->
index() <<
":"
1986 << (dual ? absl::StrFormat(
" dual = %f", pi[i]) :
"");
1993 switch (xpress_stat) {
2008 switch (xpress_stat) {
2045void ExtractNames(
XPRSprob mLp,
const std::vector<T*>& objects) {
2046 const bool have_names =
2047 std::any_of(objects.begin(), objects.end(),
2048 [](
const T* x) { return !x->name().empty(); });
2055 std::vector<char> all_names;
2056 for (
const auto& x : objects) {
2057 const std::string& current_name =
x->
name();
2058 std::copy(current_name.begin(), current_name.end(),
2059 std::back_inserter(all_names));
2060 all_names.push_back(
'\0');
2065 if (!all_names.empty() && all_names.back() ==
'\0') all_names.pop_back();
2068 objects.size() - 1));
2079 ExtractNames(mLp,
solver_->variables_);
2080 ExtractNames(mLp,
solver_->constraints_);
2082 VLOG(1) <<
"Writing Xpress MPS \"" << filename <<
"\".";
2083 const int status =
XPRSwriteprob(mLp, filename.c_str(),
"");
2085 LOG(ERROR) <<
"Xpress: Failed to write MPS!";
2093template <
class Container>
2095 std::stringstream ss(str);
2097 while (std::getline(ss, token, delim)) {
2098 cont.push_back(token);
2108 oldLocale = std::setlocale(LC_NUMERIC,
nullptr);
2109 auto newLocale = std::setlocale(LC_NUMERIC,
"C");
2110 CHECK_EQ(std::string(newLocale),
"C");
2115 const char* oldLocale;
2118#define setParamIfPossible_MACRO(target_map, setter, converter) \
2120 auto matchingParamIter = (target_map).find(paramAndValuePair.first); \
2121 if (matchingParamIter != (target_map).end()) { \
2122 const auto convertedValue = converter(paramAndValuePair.second); \
2123 VLOG(1) << "Setting parameter " << paramAndValuePair.first \
2124 << " to value " << convertedValue << std::endl; \
2125 setter(mLp, matchingParamIter->second, convertedValue); \
2130bool XpressInterface::SetSolverSpecificParametersAsString(
2131 const std::string& parameters) {
2132 if (parameters.empty())
return true;
2134 std::vector<std::pair<std::string, std::string> > paramAndValuePairList;
2136 std::stringstream ss(parameters);
2137 std::string paramName;
2138 while (std::getline(ss, paramName,
' ')) {
2139 std::string paramValue;
2140 if (std::getline(ss, paramValue,
' ')) {
2141 paramAndValuePairList.push_back(std::make_pair(paramName, paramValue));
2143 LOG(ERROR) <<
"No value for parameter " << paramName <<
" : function "
2144 << __FUNCTION__ << std::endl;
2149 ScopedLocale locale;
2150 for (
auto& paramAndValuePair : paramAndValuePairList) {
2157 LOG(ERROR) <<
"Unknown parameter " << paramName <<
" : function "
2158 << __FUNCTION__ << std::endl;
2175 if (!xprs->quiet()) {
2183 printf(
"%*s\n", nLen, sMsg);
2193void XpressInterface::AddSolutionHintToOptimizer() {
2195 const std::size_t len =
solver_->solution_hint_.size();
2200 unique_ptr<int[]> col_ind(
new int[len]);
2201 unique_ptr<double[]> val(
new double[len]);
2203 for (std::size_t i = 0;
i < len; ++
i) {
2204 col_ind[
i] =
solver_->solution_hint_[
i].first->index();
2205 val[
i] =
solver_->solution_hint_[
i].second;
2207 addhint(mLp, len, val.get(), col_ind.get());
2211 if (callback_ !=
nullptr) {
2215 callback_ = mp_callback;
2223 if (callback_with_context ==
nullptr ||
2224 callback_with_context->GetCallback() ==
nullptr) {
2229 std::unique_ptr<XpressMPCallbackContext> cb_context =
2230 std::make_unique<XpressMPCallbackContext>(
2232 callback_with_context->GetCallback()->RunCallback(cb_context.get());
2233 }
catch (std::exception&) {
2234 callback_with_context->CatchException(cbprob);
2243 if (variable_values_.empty()) {
2245 variable_values_.resize(num_vars);
2248 return variable_values_[variable->
index()];
2252 const absl::flat_hash_map<const MPVariable*, double>&
solution) {
2254 const std::size_t len =
solution.size();
2265 <<
"XPRESS does not currently allow suggesting MIP solutions after "
2266 "a kMipSolution event. Try another call-back.";
2269 unique_ptr<int[]> colind(
new int[len]);
2270 unique_ptr<double[]> val(
new double[len]);
2272 for (
const auto& [var, value] :
solution) {
2273 colind[i] = var->
index();
2277 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, 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)
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(XPRSprob prob, const char *probname, int ncols, int nrows, const char rowtype[], const double rhs[], const double rng[], const double objcoef[], const int start[], const int collen[], const int rowind[], const double rowcoef[], const double lb[], const double ub[])> XPRSloadlp
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
const char * stringToCharPtr(std::string &var)
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()
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
This is the 'define' section.
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
Initial version of this code was provided by 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_OBJ_MINIMIZE
#define XPRS_NETSTALLLIMIT
#define XPRS_PREBNDREDQUAD
#define XPRS_BARPRIMALSTOP
#define setParamIfPossible_MACRO(target_map, setter, converter)
#define XPRS_INTEGER
Initial version of this code was provided by RTE.