MPSolver-XPRESS: Remove superfluous calls to XPRSloadlp and XPRScreateprob

This commit is contained in:
Peter Mitri
2025-06-02 13:44:31 +02:00
parent b223ef8134
commit 2b792c01cf
4 changed files with 32 additions and 24 deletions

View File

@@ -21,6 +21,7 @@
#include <memory>
#include <mutex>
#include <string>
#include <numeric>
#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<int> rows(nRows);
std::iota(rows.begin(), rows.end(), 0);
int nCols = getnumcols(mLp);
std::vector<int> 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)) {

View File

@@ -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" +

View File

@@ -65,10 +65,9 @@ std::function<int(XPRSprob prob, int control, XPRSint64* p_value)> XPRSgetintcon
std::function<int(XPRSprob prob, int control, double* p_value)> XPRSgetdblcontrol = nullptr;
std::function<int(XPRSprob prob, int control, char* value, int maxbytes, int* p_nbytes)> XPRSgetstringcontrol = nullptr;
std::function<int(XPRSprob prob, int attrib, int* p_value)> XPRSgetintattrib = nullptr;
std::function<int(XPRSprob prob, int attrib, char* value, int maxbytes, int* p_nbytes)> XPRSgetstringattrib = nullptr;
std::function<int(XPRSprob prob, int attrib, double* p_value)> XPRSgetdblattrib = nullptr;
std::function<int(XPRSprob prob, const char* name, int* p_id, int* p_type)> XPRSgetcontrolinfo = nullptr;
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 = nullptr;
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 XPRSint64 start[], const int collen[], const int rowind[], const double rowcoef[], const double lb[], const double ub[])> XPRSloadlp64 = nullptr;
std::function<int(XPRSprob prob, double objcoef[], int first, int last)> XPRSgetobj = nullptr;
std::function<int(XPRSprob prob, double rhs[], int first, int last)> XPRSgetrhs = nullptr;
std::function<int(XPRSprob prob, double rng[], int first, int last)> XPRSgetrhsrange = nullptr;
@@ -104,6 +103,7 @@ std::function<int(XPRSprob prob, int ncoefs, const int objqcol1[], const int obj
std::function<int(XPRSprob prob, int nrows, const int rowind[], const double rhs[])> XPRSchgrhs = nullptr;
std::function<int(XPRSprob prob, int nrows, const int rowind[], const double rng[])> XPRSchgrhsrange = nullptr;
std::function<int(XPRSprob prob, int nrows, const int rowind[], const char rowtype[])> XPRSchgrowtype = nullptr;
std::function<int(XPRSprob prob, int objidx)> XPRSdelobj = nullptr;
std::function<int(XPRSprob prob, void (XPRS_CC *f_intsol)(XPRSprob cbprob, void* cbdata), void* p, int priority)> XPRSaddcbintsol = nullptr;
std::function<int(XPRSprob prob, void (XPRS_CC *f_intsol)(XPRSprob cbprob, void* cbdata), void* p)> XPRSremovecbintsol = nullptr;
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 = 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");

View File

@@ -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<int(XPRSprob prob, int control, XPRSint64* p_value)>
OR_DLL extern std::function<int(XPRSprob prob, int control, double* p_value)> XPRSgetdblcontrol;
OR_DLL extern std::function<int(XPRSprob prob, int control, char* value, int maxbytes, int* p_nbytes)> XPRSgetstringcontrol;
OR_DLL extern std::function<int(XPRSprob prob, int attrib, int* p_value)> XPRSgetintattrib;
OR_DLL extern std::function<int(XPRSprob prob, int attrib, char* value, int maxbytes, int* p_nbytes)> XPRSgetstringattrib;
OR_DLL extern std::function<int(XPRSprob prob, int attrib, double* p_value)> XPRSgetdblattrib;
extern std::function<int(XPRSprob prob, const char* name, int* p_id, int* p_type)> XPRSgetcontrolinfo;
extern 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;
extern 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 XPRSint64 start[], const int collen[], const int rowind[], const double rowcoef[], const double lb[], const double ub[])> XPRSloadlp64;
OR_DLL extern std::function<int(XPRSprob prob, double objcoef[], int first, int last)> XPRSgetobj;
OR_DLL extern std::function<int(XPRSprob prob, double rhs[], int first, int last)> XPRSgetrhs;
OR_DLL extern std::function<int(XPRSprob prob, double rng[], int first, int last)> XPRSgetrhsrange;
@@ -536,6 +536,7 @@ extern std::function<int(XPRSprob prob, int ncoefs, const int objqcol1[], const
extern std::function<int(XPRSprob prob, int nrows, const int rowind[], const double rhs[])> XPRSchgrhs;
extern std::function<int(XPRSprob prob, int nrows, const int rowind[], const double rng[])> XPRSchgrhsrange;
extern std::function<int(XPRSprob prob, int nrows, const int rowind[], const char rowtype[])> XPRSchgrowtype;
extern std::function<int(XPRSprob prob, int objidx)> XPRSdelobj;
extern std::function<int(XPRSprob prob, void (XPRS_CC *f_intsol)(XPRSprob cbprob, void* cbdata), void* p, int priority)> XPRSaddcbintsol;
extern std::function<int(XPRSprob prob, void (XPRS_CC *f_intsol)(XPRSprob cbprob, void* cbdata), void* p)> XPRSremovecbintsol;
extern 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;