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[]) {
195 LOG(WARNING) <<
"Failed to set solution hint.";
215#if !defined(XPRS_NAN)
216#define XPRS_NAN std::numeric_limits<double>::quiet_NaN()
219using std::unique_ptr;
227 : xprsprob_(xprsprob),
229 num_nodes_(num_nodes),
230 variable_values_(0) {};
237 LOG(WARNING) <<
"AddCut is not implemented yet in XPRESS interface";
241 <<
"AddLazyConstraint is not implemented yet in XPRESS interface";
244 const absl::flat_hash_map<const MPVariable*, double>&
solution)
override;
270 exceptions_mutex_.lock();
271 caught_exceptions_.push_back(std::current_exception());
273 exceptions_mutex_.unlock();
276 exceptions_mutex_.lock();
277 for (
const std::exception_ptr& ex : caught_exceptions_) {
279 std::rethrow_exception(ex);
280 }
catch (std::exception& ex) {
285 LOG(ERROR) <<
"Caught exception during user-defined call-back: "
289 caught_exceptions_.clear();
290 exceptions_mutex_.unlock();
295 std::vector<std::exception_ptr> caught_exceptions_;
296 std::mutex exceptions_mutex_;
320 void Write(
const std::string& filename)
override;
324 void Reset()
override;
333 double new_value,
double old_value)
override;
349 virtual int64_t
nodes()
const;
362 bool IsLP()
const override {
return !mMip; }
363 bool IsMIP()
const override {
return mMip; }
366 const std::vector<MPSolver::BasisStatus>& variable_statuses,
367 const std::vector<MPSolver::BasisStatus>& constraint_statuses)
override;
379 LOG(DFATAL) <<
"ComputeExactConditionNumber not implemented for"
380 <<
" XPRESS_MIXED_INTEGER_PROGRAMMING";
385 LOG(DFATAL) <<
"ComputeExactConditionNumber not implemented for"
386 <<
" XPRESS_LINEAR_PROGRAMMING";
416 void InvalidateModelSynchronization() {
424 void AddSolutionHintToOptimizer();
426 bool readParameters(std::istream& is,
char sep);
442 bool const supportIncrementalExtraction;
450 SlowSetCoefficient = 0x0001,
451 SlowClearConstraint = 0x0002,
452 SlowSetObjectiveCoefficient = 0x0004,
453 SlowClearObjective = 0x0008,
454 SlowSetConstraintBounds = 0x0010,
455 SlowSetVariableInteger = 0x0020,
456 SlowSetVariableBounds = 0x0040,
457 SlowUpdatesAll = 0xffff
465 std::vector<int>
mutable mCstat;
466 std::vector<int>
mutable mRstat;
468 std::vector<int>
mutable initial_variables_basis_status_;
469 std::vector<int>
mutable initial_constraint_basis_status_;
472 static void MakeRhs(
double lb,
double ub,
double& rhs,
char& sense,
475 std::map<std::string, int>& mapStringControls_;
476 std::map<std::string, int>& mapDoubleControls_;
477 std::map<std::string, int>& mapIntegerControls_;
478 std::map<std::string, int>& mapInteger64Controls_;
480 bool SetSolverSpecificParametersAsString(
482 MPCallback* callback_ =
nullptr;
490 int xpress_basis_status);
493 static std::map<std::string, int> mapControls = {
508 static std::map<std::string, int> mapControls = {
593 static std::map<std::string, int> mapControls = {
830 static std::map<std::string, int> mapControls = {
842 supportIncrementalExtraction(false),
843 slowUpdates(SlowClearObjective),
849 CHECK(correctlyLoaded);
852 DCHECK(mLp !=
nullptr);
854 CHECK_STATUS(
XPRSloadlp(mLp,
"newProb", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0));
870 int const major = version / 1000000;
871 version -= major * 1000000;
872 int const release = version / 10000;
873 version -= release * 10000;
874 int const mod = version / 100;
875 version -= mod * 100;
876 int const fix = version;
878 return absl::StrFormat(
"XPRESS library version %d.%02d.%02d.%02d", major,
892 DCHECK(mLp !=
nullptr);
894 CHECK_STATUS(
XPRSloadlp(mLp,
"newProb", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0));
918 if (!supportIncrementalExtraction && !(slowUpdates & SlowSetVariableBounds)) {
919 InvalidateModelSynchronization();
925 char const lu[2] = {
'L',
'U'};
926 double const bd[2] = {lb, ub};
932 InvalidateModelSynchronization();
951 if (!supportIncrementalExtraction &&
952 !(slowUpdates & SlowSetVariableInteger)) {
953 InvalidateModelSynchronization();
964 InvalidateModelSynchronization();
968 <<
"Attempt to change variable to integer in non-MIP problem!";
974void XpressInterface::MakeRhs(
double lb,
double ub,
double& rhs,
char& sense,
989 LOG(DFATAL) <<
"XPRESS does not support contradictory bounds on range "
991 << lb <<
", " << ub <<
"] will be converted to " << ub <<
", "
992 << (ub - std::abs(ub - lb)) <<
"]";
1019 if (std::abs(lb) < std::abs(ub))
1037 if (!supportIncrementalExtraction &&
1038 !(slowUpdates & SlowSetConstraintBounds)) {
1039 InvalidateModelSynchronization();
1044 DCHECK(mLp !=
nullptr);
1047 MakeRhs(lb, ub, rhs, sense,
range);
1062 InvalidateModelSynchronization();
1078 InvalidateModelSynchronization();
1094 InvalidateModelSynchronization();
1099 double new_value,
double) {
1109 if (!supportIncrementalExtraction && !(slowUpdates & SlowSetCoefficient)) {
1110 InvalidateModelSynchronization();
1112 int const row = constraint->
index();
1123 InvalidateModelSynchronization();
1129 int const row = 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();
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);
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());
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 =
ct->coefficients_;
1569 for (
auto coeff : coeffs) {
1570 int const idx = coeff.first->index();
1572 DCHECK_LT(nextNz, cols);
1573 DCHECK_LT(idx, cols);
1574 rmatind[nextNz] = idx;
1575 rmatval[nextNz] = coeff.second;
1582 rngval.get(), rmatbeg.get(), rmatind.get(),
1589 std::vector<int> rows_to_delete;
1590 for (
int i = offset; i < rows; ++i) rows_to_delete.push_back(i);
1592 (void)
XPRSdelrows(mLp, rows_to_delete.size(), rows_to_delete.data());
1594 int const size = constraints.size();
1609 unique_ptr<int[]> ind(
new int[cols]);
1610 unique_ptr<double[]> val(
new double[cols]);
1611 for (
int j = 0; j < cols; ++j) {
1616 const auto& coeffs =
solver_->objective_->coefficients_;
1617 for (
auto coeff : coeffs) {
1618 int const idx = coeff.first->index();
1620 DCHECK_LT(idx, cols);
1621 val[idx] = coeff.second;
1641 LOG(WARNING) <<
"The relative MIP gap is only available "
1642 <<
"for discrete problems.";
1689 auto const algorithm =
1694 switch (algorithm) {
1713 const std::vector<MPSolver::BasisStatus>& statuses) {
1714 std::vector<int> result;
1715 result.resize(statuses.size());
1716 std::transform(statuses.cbegin(), statuses.cend(), result.begin(),
1722 const std::vector<MPSolver::BasisStatus>& variable_statuses,
1723 const std::vector<MPSolver::BasisStatus>& constraint_statuses) {
1725 LOG(DFATAL) << __FUNCTION__ <<
" is only available for LP problems";
1729 initial_constraint_basis_status_ =
1733bool XpressInterface::readParameters(std::istream& is,
char sep) {
1740 bool inValue =
false;
1744 if (is.eof())
break;
1747 LOG(DFATAL) <<
"Failed to parse parameters in " <<
SolverVersion();
1751 }
else if (c == sep) {
1753 if (
name.size() == 0 &&
value.size() == 0) {
1756 }
else if (
name.size() == 0) {
1757 LOG(DFATAL) <<
"Parameter setting without name in " <<
SolverVersion();
1765 }
else if (std::isspace(c)) {
1767 }
else if (inValue) {
1780 std::ifstream s(filename);
1781 if (!s)
return false;
1782 return readParameters(s,
'\n');
1821 VLOG(1) << absl::StrFormat(
"Model build in %.3f seconds.", timer.
Get());
1834 solver_->solver_specific_parameter_string_);
1845 if (!mMip && !initial_variables_basis_status_.empty() &&
1846 !initial_constraint_basis_status_.empty()) {
1848 initial_variables_basis_status_.data()));
1852 this->AddSolutionHintToOptimizer();
1857 if (callback_ !=
nullptr) {
1860 static_cast<void*
>(mp_callback_wrapper), 0));
1868 int xpress_stat = 0;
1877 if (mp_callback_wrapper !=
nullptr) {
1879 delete mp_callback_wrapper;
1891 VLOG(1) << absl::StrFormat(
"Failed to optimize MIP. Error %d",
status);
1895 VLOG(1) << absl::StrFormat(
"Solved in %.3f seconds.", timer.
Get());
1898 VLOG(1) << absl::StrFormat(
"XPRESS solution status %d.", xpress_stat);
1908 DCHECK_EQ(rows,
solver_->constraints_.size());
1909 DCHECK_EQ(cols,
solver_->variables_.size());
1931 unique_ptr<double[]>
x(
new double[cols]);
1933 for (
int i = 0; i <
solver_->variables_.size(); ++i) {
1935 var->set_solution_value(
x[i]);
1936 VLOG(3) <<
var->name() <<
": value =" <<
x[i];
1940 for (
auto& variable :
solver_->variables_)
1945 for (
auto& variable :
solver_->variables_)
1947 for (
auto& constraint :
solver_->constraints_)
1952 unique_ptr<double[]>
x(
new double[cols]);
1953 unique_ptr<double[]> dj(
new double[cols]);
1955 for (
int i = 0; i <
solver_->variables_.size(); ++i) {
1957 var->set_solution_value(
x[i]);
1958 bool value =
false, dual =
false;
1961 var->set_solution_value(
x[i]);
1967 var->set_reduced_cost(dj[i]);
1972 VLOG(3) <<
var->name() <<
":"
1973 << (
value ? absl::StrFormat(
" value = %f",
x[i]) :
"")
1974 << (dual ? absl::StrFormat(
" reduced cost = %f", dj[i]) :
"");
1979 unique_ptr<double[]> pi(
new double[rows]);
1983 for (
int i = 0; i <
solver_->constraints_.size(); ++i) {
1987 ct->set_dual_value(pi[i]);
1992 VLOG(4) <<
"row " <<
ct->index() <<
":"
1993 << (dual ? absl::StrFormat(
" dual = %f", pi[i]) :
"");
2000 switch (xpress_stat) {
2015 switch (xpress_stat) {
2045struct getNameFlag<MPConstraint> {
2052void ExtractNames(
XPRSprob mLp,
const std::vector<T*>& objects) {
2053 const bool have_names =
2054 std::any_of(objects.begin(), objects.end(),
2055 [](
const T*
x) { return !x->name().empty(); });
2062 std::vector<char> all_names;
2063 for (
const auto&
x : objects) {
2064 const std::string& current_name =
x->name();
2065 std::copy(current_name.begin(), current_name.end(),
2066 std::back_inserter(all_names));
2067 all_names.push_back(
'\0');
2072 if (!all_names.empty() && all_names.back() ==
'\0') all_names.pop_back();
2075 objects.size() - 1));
2086 ExtractNames(mLp,
solver_->variables_);
2087 ExtractNames(mLp,
solver_->constraints_);
2089 VLOG(1) <<
"Writing Xpress MPS \"" << filename <<
"\".";
2092 LOG(ERROR) <<
"Xpress: Failed to write MPS!";
2100template <
class Container>
2102 std::stringstream ss(str);
2104 while (std::getline(ss, token, delim)) {
2105 cont.push_back(token);
2115 oldLocale = std::setlocale(LC_NUMERIC,
nullptr);
2116 auto newLocale = std::setlocale(LC_NUMERIC,
"C");
2117 CHECK_EQ(std::string(newLocale),
"C");
2122 const char* oldLocale;
2125#define setParamIfPossible_MACRO(target_map, setter, converter) \
2127 auto matchingParamIter = (target_map).find(paramAndValuePair.first); \
2128 if (matchingParamIter != (target_map).end()) { \
2129 const auto convertedValue = converter(paramAndValuePair.second); \
2130 VLOG(1) << "Setting parameter " << paramAndValuePair.first \
2131 << " to value " << convertedValue << std::endl; \
2132 setter(mLp, matchingParamIter->second, convertedValue); \
2137bool XpressInterface::SetSolverSpecificParametersAsString(
2141 std::vector<std::pair<std::string, std::string> > paramAndValuePairList;
2144 std::string paramName;
2145 while (std::getline(ss, paramName,
' ')) {
2146 std::string paramValue;
2147 if (std::getline(ss, paramValue,
' ')) {
2148 paramAndValuePairList.push_back(std::make_pair(paramName, paramValue));
2150 LOG(ERROR) <<
"No value for parameter " << paramName <<
" : function "
2151 << __FUNCTION__ << std::endl;
2156 ScopedLocale locale;
2157 for (
auto& paramAndValuePair : paramAndValuePairList) {
2164 LOG(ERROR) <<
"Unknown parameter " << paramName <<
" : function "
2165 << __FUNCTION__ << std::endl;
2182 if (!xprs->quiet()) {
2190 printf(
"%*s\n", nLen, sMsg);
2200void XpressInterface::AddSolutionHintToOptimizer() {
2202 const std::size_t len =
solver_->solution_hint_.size();
2207 unique_ptr<int[]> col_ind(
new int[len]);
2208 unique_ptr<double[]> val(
new double[len]);
2210 for (std::size_t i = 0;
i < len; ++
i) {
2211 col_ind[
i] =
solver_->solution_hint_[
i].first->index();
2212 val[
i] =
solver_->solution_hint_[
i].second;
2214 addhint(mLp, len, val.get(), col_ind.get());
2218 if (callback_ !=
nullptr) {
2222 callback_ = mp_callback;
2230 if (callback_with_context ==
nullptr ||
2231 callback_with_context->GetCallback() ==
nullptr) {
2236 std::unique_ptr<XpressMPCallbackContext> cb_context =
2237 std::make_unique<XpressMPCallbackContext>(
2239 callback_with_context->GetCallback()->RunCallback(cb_context.get());
2240 }
catch (std::exception&) {
2241 callback_with_context->CatchException(cbprob);
2250 if (variable_values_.empty()) {
2252 variable_values_.resize(num_vars);
2255 return variable_values_[variable->
index()];
2259 const absl::flat_hash_map<const MPVariable*, double>&
solution) {
2261 const std::size_t len =
solution.size();
2272 <<
"XPRESS does not currently allow suggesting MIP solutions after "
2273 "a kMipSolution event. Try another call-back.";
2276 unique_ptr<int[]> colind(
new int[len]);
2277 unique_ptr<double[]> val(
new double[len]);
2280 colind[i] =
var->index();
2284 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)
int index() const
Returns the index of the constraint in the MPSolver::constraints_.
double offset() const
Gets the constant term in the objective.
void set_variable_as_extracted(int var_index, bool extracted)
bool CheckSolutionIsSynchronized() const
static constexpr int64_t kUnknownNumberOfIterations
void InvalidateSolutionSynchronization()
void set_constraint_as_extracted(int ct_index, bool extracted)
void ResetExtractionInformation()
Resets the extraction information.
int last_variable_index_
Index in MPSolver::constraints_ of last variable extracted.
virtual void SetIntegerParamToUnsupportedValue(MPSolverParameters::IntegerParam param, int value)
Sets a supported integer parameter to an unsupported value.
int last_constraint_index_
Index in MPSolver::variables_ of last constraint extracted.
bool variable_is_extracted(int var_index) const
bool quiet() const
Returns the boolean indicating the verbosity of the solver output.
bool constraint_is_extracted(int ct_index) const
static constexpr int64_t kUnknownNumberOfNodes
void ExtractModel()
Extracts model stored in MPSolver.
double objective_value_
The value of the objective function.
double best_objective_bound_
The value of the best objective bound. Used only for MIP solvers.
bool maximize_
Optimization direction.
void SetMIPParameters(const MPSolverParameters ¶m)
Sets MIP specific parameters in the underlying solver.
void SetCommonParameters(const MPSolverParameters ¶m)
Sets parameters common to LP and MIP in the underlying solver.
MPSolver::ResultStatus result_status_
SynchronizationStatus sync_status_
Indicates whether the model and the solution are synchronized.
PresolveValues
For each categorical parameter, enumeration of possible values.
@ PRESOLVE_OFF
Presolve is off.
@ PRESOLVE_ON
Presolve is on.
LpAlgorithmValues
LP algorithm to use.
@ BARRIER
Barrier algorithm.
@ INCREMENTALITY
Advanced usage: incrementality from one solve to the next.
@ PRESOLVE
Advanced usage: presolve mode.
@ LP_ALGORITHM
Algorithm to solve linear programs.
@ 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.
int64_t time_limit() const
double time_limit_in_secs() const
const std::vector< MPVariable * > & variables() const
@ FEASIBLE
feasible, or stopped by limit.
@ INFEASIBLE
proven infeasible.
@ UNBOUNDED
proven unbounded.
@ ABNORMAL
abnormal, i.e., error of some kind.
const MPObjective & Objective() const
bool SetSolverSpecificParametersAsString(const std::string ¶meters)
const std::vector< MPConstraint * > & constraints() const
The class for variables of a Mathematical Programming (MP) model.
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
double VariableValue(const MPVariable *variable) override
const std::string name
A name for logging purposes.
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[])
static std::map< std::string, int > & getMapIntControls()
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
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, 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 control, int *p_value)> XPRSgetintcontrol
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::function< int(XPRSprob prob, int attrib, double *p_value)> XPRSgetdblattrib
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
std::function< int(XPRSprob prob, int attrib, int *p_value)> XPRSgetintattrib
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.
const std::optional< Range > & range
#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.