diff --git a/ortools/linear_solver/xpress_interface.cc b/ortools/linear_solver/xpress_interface.cc index 590ab4eaad..0fa2b23465 100644 --- a/ortools/linear_solver/xpress_interface.cc +++ b/ortools/linear_solver/xpress_interface.cc @@ -21,6 +21,7 @@ #include #include #include +#include #include "absl/strings/str_format.h" #include "ortools/base/logging.h" @@ -844,7 +845,6 @@ XpressInterface::XpressInterface(MPSolver* const solver, bool mip) CHECK_STATUS(status); DCHECK(mLp != nullptr); // should not be NULL if status=0 int nReturn = XPRSaddcbmessage(mLp, optimizermsg, (void*)this, 0); - CHECK_STATUS(XPRSloadlp(mLp, "newProb", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); CHECK_STATUS( XPRSchgobjsense(mLp, maximize_ ? XPRS_OBJ_MAXIMIZE : XPRS_OBJ_MINIMIZE)); } @@ -875,20 +875,15 @@ std::string XpressInterface::SolverVersion() const { // ------ Model modifications and extraction ----- void XpressInterface::Reset() { - // Instead of explicitly clearing all modeling objects we - // just delete the problem object and allocate a new one. - CHECK_STATUS(XPRSdestroyprob(mLp)); - - int status; - status = XPRScreateprob(&mLp); - CHECK_STATUS(status); - DCHECK(mLp != nullptr); // should not be NULL if status=0 - int nReturn = XPRSaddcbmessage(mLp, optimizermsg, (void*)this, 0); - CHECK_STATUS(XPRSloadlp(mLp, "newProb", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); - - CHECK_STATUS( - XPRSchgobjsense(mLp, maximize_ ? XPRS_OBJ_MAXIMIZE : XPRS_OBJ_MINIMIZE)); - + int nRows = getnumrows(mLp); + std::vector rows(nRows); + std::iota(rows.begin(), rows.end(), 0); + int nCols = getnumcols(mLp); + std::vector cols(nCols); + std::iota(cols.begin(), cols.end(), 0); + XPRSdelrows(mLp, nRows, rows.data()); + XPRSdelcols(mLp, nCols, cols.data()); + XPRSdelobj(mLp, 0); ResetExtractionInformation(); mCstat.clear(); mRstat.clear(); @@ -985,8 +980,7 @@ void XpressInterface::MakeRhs(double lb, double ub, double& rhs, char& sense, << (ub - std::abs(ub - lb)) << "]"; } rhs = ub; - range = std::abs( - ub - lb); // This happens implicitly by XPRSaddrows() and XPRSloadlp() + range = std::abs(ub - lb); // This happens implicitly by XPRSaddrows() sense = 'R'; } else if (ub < XPRS_PLUSINFINITY || (std::abs(ub) == XPRS_PLUSINFINITY && std::abs(lb) > XPRS_PLUSINFINITY)) { diff --git a/ortools/linear_solver/xpress_interface_test.cc b/ortools/linear_solver/xpress_interface_test.cc index 36e020cb07..16925a1e36 100644 --- a/ortools/linear_solver/xpress_interface_test.cc +++ b/ortools/linear_solver/xpress_interface_test.cc @@ -155,6 +155,15 @@ class XPRSGetter { return value; } + std::string getStringAttribute(int attrib) { + std::string value(280, '\0'); + int valueSize; + EXPECT_STATUS(XPRSgetstringattrib(prob(), attrib, &value[0], value.size(), + &valueSize)); + value.resize(valueSize - 1); + return value; + } + private: MPSolver* solver_; @@ -400,12 +409,16 @@ TEST_F(XpressFixtureMIP, Reset) { solver.MakeBoolVar("x1"); solver.MakeBoolVar("x2"); solver.MakeRowConstraint(12., 100.0); + solver.MutableObjective()->SetMaximization(); solver.Solve(); EXPECT_EQ(getter.getNumConstraints(), 1); EXPECT_EQ(getter.getNumVariables(), 2); + auto oldProbUuid = getter.getStringAttribute(XPRS_UUID); solver.Reset(); + EXPECT_EQ(getter.getStringAttribute(XPRS_UUID), oldProbUuid); EXPECT_EQ(getter.getNumConstraints(), 0); EXPECT_EQ(getter.getNumVariables(), 0); + EXPECT_EQ(getter.getObjectiveSense(), XPRS_OBJ_MAXIMIZE); } TEST_F(XpressFixtureMIP, MakeIntVar) { @@ -737,7 +750,7 @@ TEST_F(XpressFixtureMIP, Write) { // disable formatting to keep the expected MPS readable // clang-format off std::string expectedMps = std::string("") + - "NAME newProb" + "\n" + + "NAME " + "\n" + "OBJSENSE MAXIMIZE" + "\n" + "ROWS" + "\n" + " N __OBJ___ " + "\n" + diff --git a/ortools/xpress/environment.cc b/ortools/xpress/environment.cc index 51f1025a76..5e628099e2 100644 --- a/ortools/xpress/environment.cc +++ b/ortools/xpress/environment.cc @@ -65,10 +65,9 @@ std::function XPRSgetintcon std::function XPRSgetdblcontrol = nullptr; std::function XPRSgetstringcontrol = nullptr; std::function XPRSgetintattrib = nullptr; +std::function XPRSgetstringattrib = nullptr; std::function XPRSgetdblattrib = nullptr; std::function XPRSgetcontrolinfo = nullptr; -std::function XPRSloadlp = nullptr; -std::function XPRSloadlp64 = nullptr; std::function XPRSgetobj = nullptr; std::function XPRSgetrhs = nullptr; std::function XPRSgetrhsrange = nullptr; @@ -104,6 +103,7 @@ std::function XPRSchgrhs = nullptr; std::function XPRSchgrhsrange = nullptr; std::function XPRSchgrowtype = nullptr; +std::function XPRSdelobj = nullptr; std::function XPRSaddcbintsol = nullptr; std::function XPRSremovecbintsol = nullptr; std::function XPRSaddcbmessage = nullptr; @@ -141,9 +141,8 @@ void LoadXpressFunctions(DynamicLibrary* xpress_dynamic_library) { xpress_dynamic_library->GetFunction(&XPRSgetdblcontrol, "XPRSgetdblcontrol"); xpress_dynamic_library->GetFunction(&XPRSgetstringcontrol, "XPRSgetstringcontrol"); xpress_dynamic_library->GetFunction(&XPRSgetintattrib, "XPRSgetintattrib"); + xpress_dynamic_library->GetFunction(&XPRSgetstringattrib, "XPRSgetstringattrib"); xpress_dynamic_library->GetFunction(&XPRSgetdblattrib, "XPRSgetdblattrib"); - xpress_dynamic_library->GetFunction(&XPRSloadlp, "XPRSloadlp"); - xpress_dynamic_library->GetFunction(&XPRSloadlp64, "XPRSloadlp64"); xpress_dynamic_library->GetFunction(&XPRSgetobj, "XPRSgetobj"); xpress_dynamic_library->GetFunction(&XPRSgetrhs, "XPRSgetrhs"); xpress_dynamic_library->GetFunction(&XPRSgetrhsrange, "XPRSgetrhsrange"); @@ -179,6 +178,7 @@ void LoadXpressFunctions(DynamicLibrary* xpress_dynamic_library) { xpress_dynamic_library->GetFunction(&XPRSchgrhs, "XPRSchgrhs"); xpress_dynamic_library->GetFunction(&XPRSchgrhsrange, "XPRSchgrhsrange"); xpress_dynamic_library->GetFunction(&XPRSchgrowtype, "XPRSchgrowtype"); + xpress_dynamic_library->GetFunction(&XPRSdelobj, "XPRSdelobj"); xpress_dynamic_library->GetFunction(&XPRSaddcbintsol, "XPRSaddcbintsol"); xpress_dynamic_library->GetFunction(&XPRSremovecbintsol, "XPRSremovecbintsol"); xpress_dynamic_library->GetFunction(&XPRSaddcbmessage, "XPRSaddcbmessage"); diff --git a/ortools/xpress/environment.h b/ortools/xpress/environment.h index 1db953f629..9a1fe558be 100644 --- a/ortools/xpress/environment.h +++ b/ortools/xpress/environment.h @@ -453,6 +453,7 @@ absl::Status LoadXpressDynamicLibrary(std::string& xpresspath); #define XPRS_ALG_BARRIER 4 #define XPRS_OBJ_MINIMIZE 1 #define XPRS_OBJ_MAXIMIZE -1 +#define XPRS_UUID 3011 // *************************************************************************** // * variable types * // *************************************************************************** @@ -497,10 +498,9 @@ OR_DLL extern std::function OR_DLL extern std::function XPRSgetdblcontrol; OR_DLL extern std::function XPRSgetstringcontrol; OR_DLL extern std::function XPRSgetintattrib; +OR_DLL extern std::function XPRSgetstringattrib; OR_DLL extern std::function XPRSgetdblattrib; extern std::function XPRSgetcontrolinfo; -extern std::function XPRSloadlp; -extern std::function XPRSloadlp64; OR_DLL extern std::function XPRSgetobj; OR_DLL extern std::function XPRSgetrhs; OR_DLL extern std::function XPRSgetrhsrange; @@ -536,6 +536,7 @@ extern std::function XPRSchgrhs; extern std::function XPRSchgrhsrange; extern std::function XPRSchgrowtype; +extern std::function XPRSdelobj; extern std::function XPRSaddcbintsol; extern std::function XPRSremovecbintsol; extern std::function XPRSaddcbmessage;