From a9a4f32646bf73660ff0eafab71689494ee05b7d Mon Sep 17 00:00:00 2001 From: Andrea Sgattoni Date: Tue, 14 Nov 2023 13:38:53 +0100 Subject: [PATCH 01/10] first step --- ortools/linear_solver/xpress_interface.cc | 46 +++++++++++++++++------ 1 file changed, 34 insertions(+), 12 deletions(-) diff --git a/ortools/linear_solver/xpress_interface.cc b/ortools/linear_solver/xpress_interface.cc index c28cab27fdf..5513738f3ab 100644 --- a/ortools/linear_solver/xpress_interface.cc +++ b/ortools/linear_solver/xpress_interface.cc @@ -357,6 +357,9 @@ class XpressInterface : public MPSolverInterface { bool IsLP() const override { return !mMip; } bool IsMIP() const override { return mMip; } + void SetStartingLpBasis( + const std::vector& /*variable_statuses*/, + const std::vector& /*constraint_statuses*/) override; void SetStartingLpBasisInt( const std::vector& variable_statuses, const std::vector& constraint_statuses) override; @@ -422,7 +425,7 @@ class XpressInterface : public MPSolverInterface { void AddSolutionHintToOptimizer(); // Transform XPRESS basis status to MPSolver basis status. - static MPSolver::BasisStatus xformBasisStatus(int xpress_basis_status); + static MPSolver::BasisStatus XpressToMPSolverBasisStatus(int xpress_basis_status); bool readParameters(std::istream& is, char sep); @@ -464,8 +467,8 @@ class XpressInterface : public MPSolverInterface { std::vector mutable mCstat; std::vector mutable mRstat; - std::vector mutable initCstat; - std::vector mutable initRstat; + std::vector mutable initCstat_; + std::vector mutable initRstat_; // Set up the right-hand side of a constraint from its lower and upper bound. static void MakeRhs(double lb, double ub, double& rhs, char& sense, @@ -484,7 +487,7 @@ class XpressInterface : public MPSolverInterface { // Transform XPRESS basis status to MPSolver basis status. static MPSolver::BasisStatus xformBasisStatus(int xpress_basis_status); // Transform MPSolver basis status to XPRESS status -static int convertToXpressBasisStatus( +static int MPSolverToXpressBasisStatus( MPSolver::BasisStatus mpsolver_basis_status); static std::map& getMapStringControls() { @@ -1243,7 +1246,7 @@ int64_t XpressInterface::nodes() const { } // Transform a XPRESS basis status to an MPSolver basis status. -MPSolver::BasisStatus XpressInterface::xformBasisStatus( +MPSolver::BasisStatus XpressInterface::XpressToMPSolverBasisStatus( int xpress_basis_status) { switch (xpress_basis_status) { case XPRS_AT_LOWER: @@ -1260,7 +1263,7 @@ MPSolver::BasisStatus XpressInterface::xformBasisStatus( } } -int convertToXpressBasisStatus(MPSolver::BasisStatus mpsolver_basis_status) { +int MPSolverToXpressBasisStatus(MPSolver::BasisStatus mpsolver_basis_status) { switch (mpsolver_basis_status) { case MPSolver::AT_LOWER_BOUND: return XPRS_AT_LOWER; @@ -1294,7 +1297,7 @@ MPSolver::BasisStatus XpressInterface::row_status(int constraint_index) const { } if (!mRstat.empty()) { - return xformBasisStatus(mRstat[constraint_index]); + return XpressToMPSolverBasisStatus(mRstat[constraint_index]); } else { LOG(FATAL) << "Row basis status not available"; return MPSolver::FREE; @@ -1319,7 +1322,7 @@ MPSolver::BasisStatus XpressInterface::column_status(int variable_index) const { } if (!mCstat.empty()) { - return xformBasisStatus(mCstat[variable_index]); + return XpressToMPSolverBasisStatus(mCstat[variable_index]); } else { LOG(FATAL) << "Column basis status not available"; return MPSolver::FREE; @@ -1745,6 +1748,25 @@ void XpressInterface::SetLpAlgorithm(int value) { CHECK_STATUS(XPRSsetintcontrol(mLp, XPRS_DEFAULTALG, alg)); } } +void XpressInterface::SetStartingLpBasis( + const std::vector& variable_statuses, + const std::vector& constraint_statuses){ + if (mMip) { + LOG(DFATAL) << __FUNCTION__ << " is only available for LP problems"; + return; + } + std::vector initCstat; + std::vector initRstat; + for (const MPSolver::BasisStatus& status : variable_statuses) { + initCstat.push_back(MPSolverToXpressBasisStatus(status)); + } + for (const MPSolver::BasisStatus& status : constraint_statuses) { + initRstat.push_back(MPSolverToXpressBasisStatus(status)); + } + initCstat_ = initCstat; + initRstat_ = initRstat; + // shouldn't we call XPRSloadbasis(mLp, initRstat_.data(), initCstat_.data()) ? +} // Convert statuses for later use (Solve) void XpressInterface::SetStartingLpBasisInt( @@ -1755,9 +1777,9 @@ void XpressInterface::SetStartingLpBasisInt( return; } // Column = variable - initCstat = variable_statuses; + initCstat_ = variable_statuses; // Row = constraint - initRstat = constraint_statuses; + initRstat_ = constraint_statuses; } void XpressInterface::GetFinalLpBasisInt( @@ -1889,8 +1911,8 @@ MPSolver::ResultStatus XpressInterface::Solve(MPSolverParameters const& param) { // Load basis if present // TODO : check number of variables / constraints - if (!mMip && !initCstat.empty() && !initRstat.empty()) { - CHECK_STATUS(XPRSloadbasis(mLp, initRstat.data(), initCstat.data())); + if (!mMip && !initCstat_.empty() && !initRstat_.empty()) { + CHECK_STATUS(XPRSloadbasis(mLp, initRstat_.data(), initCstat_.data())); } // Set the hint (if any) From fd1de9366e62c82a65808cfaf921311cf428776a Mon Sep 17 00:00:00 2001 From: Andrea Sgattoni Date: Tue, 14 Nov 2023 13:44:41 +0100 Subject: [PATCH 02/10] first step SetStartingLpBasisInt and GetFinalLpBasisInt --- ortools/linear_solver/linear_solver.h | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/ortools/linear_solver/linear_solver.h b/ortools/linear_solver/linear_solver.h index edcc49ee61e..a0300ff5c44 100644 --- a/ortools/linear_solver/linear_solver.h +++ b/ortools/linear_solver/linear_solver.h @@ -727,12 +727,6 @@ class MPSolver { const std::vector& variable_statuses, const std::vector& constraint_statuses); - void SetStartingLpBasisInt(const std::vector& variable_statuses, - const std::vector& constraint_statuses); - - void GetFinalLpBasisInt(std::vector& variable_statuses, - std::vector& constraint_statuses); - /** * Infinity. * @@ -1801,24 +1795,6 @@ class MPSolverInterface { LOG(FATAL) << "Not supported by this solver."; } - // See MPSolver::SetStartingLpBasis(). - // Do not convert to MPSolver::BasisStatus, use integers - // Sometimes, converting to MPSolver::BasisStatus leads to a loss of information - // For that reason, we give the possibiity to recover the "raw" basis - virtual void SetStartingLpBasisInt( - const std::vector& /* variable_statuses */, - const std::vector& /* constraint_statuses */) { - LOG(FATAL) << "Not supported by this solver."; - } - - // See MPSolver::SetStartingLpBasis(). - // Do not convert to MPSolver::BasisStatus, use integers - virtual void GetFinalLpBasisInt( - std::vector& /* variable_statuses */, - std::vector& /* constraint_statuses */) { - LOG(FATAL) << "Not supported by this solver."; - } - virtual double infinity() { return std::numeric_limits::infinity(); } virtual bool InterruptSolve() { return false; } From b7e2ad21560a89b1470f832cc746f1a432110399 Mon Sep 17 00:00:00 2001 From: Andrea Sgattoni Date: Tue, 14 Nov 2023 13:46:05 +0100 Subject: [PATCH 03/10] fix wrong push --- ortools/linear_solver/xpress_interface.cc | 39 ----------------------- 1 file changed, 39 deletions(-) diff --git a/ortools/linear_solver/xpress_interface.cc b/ortools/linear_solver/xpress_interface.cc index 5513738f3ab..08f87a5f43d 100644 --- a/ortools/linear_solver/xpress_interface.cc +++ b/ortools/linear_solver/xpress_interface.cc @@ -360,12 +360,6 @@ class XpressInterface : public MPSolverInterface { void SetStartingLpBasis( const std::vector& /*variable_statuses*/, const std::vector& /*constraint_statuses*/) override; - void SetStartingLpBasisInt( - const std::vector& variable_statuses, - const std::vector& constraint_statuses) override; - - void GetFinalLpBasisInt(std::vector& variable_statuses, - std::vector& constraint_statuses) override; void ExtractNewVariables() override; void ExtractNewConstraints() override; @@ -1768,39 +1762,6 @@ void XpressInterface::SetStartingLpBasis( // shouldn't we call XPRSloadbasis(mLp, initRstat_.data(), initCstat_.data()) ? } -// Convert statuses for later use (Solve) -void XpressInterface::SetStartingLpBasisInt( - const std::vector& variable_statuses, - const std::vector& constraint_statuses) { - if (mMip) { - LOG(DFATAL) << __FUNCTION__ << " is only available for LP problems"; - return; - } - // Column = variable - initCstat_ = variable_statuses; - // Row = constraint - initRstat_ = constraint_statuses; -} - -void XpressInterface::GetFinalLpBasisInt( - std::vector& variable_statuses, - std::vector& constraint_statuses) { - if (mMip) { - LOG(DFATAL) << __FUNCTION__ << " is only available for LP problems"; - return; - } - - const int rows = getnumrows(mLp); - const int cols = getnumcols(mLp); - // 1. Resize vectors if needed - variable_statuses.resize(cols); - constraint_statuses.resize(rows); - - // 2. Extract basis - CHECK_STATUS( - XPRSgetbasis(mLp, constraint_statuses.data(), variable_statuses.data())); -} - bool XpressInterface::readParameters(std::istream& is, char sep) { // - parameters must be specified as NAME=VALUE // - settings must be separated by sep From 5b53bbfc4e5e2b9dbe5706a7e3c35327b34391b7 Mon Sep 17 00:00:00 2001 From: Andrea Sgattoni Date: Tue, 14 Nov 2023 17:55:48 +0100 Subject: [PATCH 04/10] improve code --- ortools/linear_solver/xpress_interface.cc | 26 ++++++++++++----------- 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/ortools/linear_solver/xpress_interface.cc b/ortools/linear_solver/xpress_interface.cc index 08f87a5f43d..81dadf43bcc 100644 --- a/ortools/linear_solver/xpress_interface.cc +++ b/ortools/linear_solver/xpress_interface.cc @@ -458,11 +458,13 @@ class XpressInterface : public MPSolverInterface { // Hence, we query the status only once and cache the array. This is // much faster in case the basis status of more than one row/column // is required. + + // TODO std::vector mutable mCstat; std::vector mutable mRstat; - std::vector mutable initCstat_; - std::vector mutable initRstat_; + std::vector mutable initial_variables_basis_status_; + std::vector mutable initial_constraint_basis_status_; // Set up the right-hand side of a constraint from its lower and upper bound. static void MakeRhs(double lb, double ub, double& rhs, char& sense, @@ -1749,17 +1751,16 @@ void XpressInterface::SetStartingLpBasis( LOG(DFATAL) << __FUNCTION__ << " is only available for LP problems"; return; } - std::vector initCstat; - std::vector initRstat; + initial_variables_basis_status_.clear(); + initial_variables_basis_status_.reserve(variable_statuses.size()); for (const MPSolver::BasisStatus& status : variable_statuses) { - initCstat.push_back(MPSolverToXpressBasisStatus(status)); + initial_variables_basis_status_.push_back(MPSolverToXpressBasisStatus(status)); } + initial_constraint_basis_status_.reserve(constraint_statuses.size()); + initial_constraint_basis_status_.clear(); for (const MPSolver::BasisStatus& status : constraint_statuses) { - initRstat.push_back(MPSolverToXpressBasisStatus(status)); + initial_constraint_basis_status_.push_back(MPSolverToXpressBasisStatus(status)); } - initCstat_ = initCstat; - initRstat_ = initRstat; - // shouldn't we call XPRSloadbasis(mLp, initRstat_.data(), initCstat_.data()) ? } bool XpressInterface::readParameters(std::istream& is, char sep) { @@ -1872,8 +1873,9 @@ MPSolver::ResultStatus XpressInterface::Solve(MPSolverParameters const& param) { // Load basis if present // TODO : check number of variables / constraints - if (!mMip && !initCstat_.empty() && !initRstat_.empty()) { - CHECK_STATUS(XPRSloadbasis(mLp, initRstat_.data(), initCstat_.data())); + if (!mMip && !initial_variables_basis_status_.empty() && !initial_constraint_basis_status_.empty()) { + CHECK_STATUS(XPRSloadbasis(mLp, initial_constraint_basis_status_.data(), + initial_variables_basis_status_.data())); } // Set the hint (if any) @@ -2074,7 +2076,7 @@ void XpressInterface::Write(const std::string& filename) { VLOG(1) << "Writing Xpress MPS \"" << filename << "\"."; const int status = XPRSwriteprob(mLp, filename.c_str(), ""); if (status) { - LOG(ERROR) << "Xpress: Failed to write MPS! "; + LOG(ERROR) << "Xpress: Failed to write MPS! ExtractModel"; } } From 474ece4b0cec6bd253ba7c073de12ac0d2aa35b3 Mon Sep 17 00:00:00 2001 From: Andrea Sgattoni Date: Wed, 15 Nov 2023 12:15:55 +0100 Subject: [PATCH 05/10] fix error --- ortools/linear_solver/xpress_interface.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ortools/linear_solver/xpress_interface.cc b/ortools/linear_solver/xpress_interface.cc index 81dadf43bcc..e34a0f8ce05 100644 --- a/ortools/linear_solver/xpress_interface.cc +++ b/ortools/linear_solver/xpress_interface.cc @@ -1756,8 +1756,8 @@ void XpressInterface::SetStartingLpBasis( for (const MPSolver::BasisStatus& status : variable_statuses) { initial_variables_basis_status_.push_back(MPSolverToXpressBasisStatus(status)); } - initial_constraint_basis_status_.reserve(constraint_statuses.size()); initial_constraint_basis_status_.clear(); + initial_constraint_basis_status_.reserve(constraint_statuses.size()); for (const MPSolver::BasisStatus& status : constraint_statuses) { initial_constraint_basis_status_.push_back(MPSolverToXpressBasisStatus(status)); } From 8475339eb2d2fcfbac278a81a311c643382010ec Mon Sep 17 00:00:00 2001 From: Andrea Sgattoni Date: Thu, 16 Nov 2023 14:17:11 +0100 Subject: [PATCH 06/10] accept suggestions from flomnes --- ortools/linear_solver/xpress_interface.cc | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/ortools/linear_solver/xpress_interface.cc b/ortools/linear_solver/xpress_interface.cc index e34a0f8ce05..c83fcfdc26c 100644 --- a/ortools/linear_solver/xpress_interface.cc +++ b/ortools/linear_solver/xpress_interface.cc @@ -418,9 +418,6 @@ class XpressInterface : public MPSolverInterface { // SetHint() void AddSolutionHintToOptimizer(); - // Transform XPRESS basis status to MPSolver basis status. - static MPSolver::BasisStatus XpressToMPSolverBasisStatus(int xpress_basis_status); - bool readParameters(std::istream& is, char sep); private: @@ -480,11 +477,12 @@ class XpressInterface : public MPSolverInterface { MPCallback* callback_ = nullptr; }; -// Transform XPRESS basis status to MPSolver basis status. -static MPSolver::BasisStatus xformBasisStatus(int xpress_basis_status); // Transform MPSolver basis status to XPRESS status static int MPSolverToXpressBasisStatus( MPSolver::BasisStatus mpsolver_basis_status); +// Transform XPRESS basis status to MPSolver basis status. +static MPSolver::BasisStatus XpressToMPSolverBasisStatus( + int xpress_basis_status); static std::map& getMapStringControls() { static std::map mapControls = { @@ -1242,7 +1240,7 @@ int64_t XpressInterface::nodes() const { } // Transform a XPRESS basis status to an MPSolver basis status. -MPSolver::BasisStatus XpressInterface::XpressToMPSolverBasisStatus( +static MPSolver::BasisStatus XpressToMPSolverBasisStatus( int xpress_basis_status) { switch (xpress_basis_status) { case XPRS_AT_LOWER: @@ -1259,7 +1257,7 @@ MPSolver::BasisStatus XpressInterface::XpressToMPSolverBasisStatus( } } -int MPSolverToXpressBasisStatus(MPSolver::BasisStatus mpsolver_basis_status) { +static int MPSolverToXpressBasisStatus(MPSolver::BasisStatus mpsolver_basis_status) { switch (mpsolver_basis_status) { case MPSolver::AT_LOWER_BOUND: return XPRS_AT_LOWER; @@ -2076,7 +2074,7 @@ void XpressInterface::Write(const std::string& filename) { VLOG(1) << "Writing Xpress MPS \"" << filename << "\"."; const int status = XPRSwriteprob(mLp, filename.c_str(), ""); if (status) { - LOG(ERROR) << "Xpress: Failed to write MPS! ExtractModel"; + LOG(ERROR) << "Xpress: Failed to write MPS!"; } } From 38ad092277ebfc21465f1a0ffacda43c542c0fe2 Mon Sep 17 00:00:00 2001 From: Florian OMNES <26088210+flomnes@users.noreply.github.com> Date: Fri, 17 Nov 2023 12:52:20 +0100 Subject: [PATCH 07/10] Add test on number iterations with LP basis --- .../linear_solver/xpress_interface_test.cc | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/ortools/linear_solver/xpress_interface_test.cc b/ortools/linear_solver/xpress_interface_test.cc index 4df44841be8..503f18cabcf 100644 --- a/ortools/linear_solver/xpress_interface_test.cc +++ b/ortools/linear_solver/xpress_interface_test.cc @@ -226,6 +226,25 @@ void buildLargeMip(MPSolver& solver, int numVars, int maxTime) { solver.EnableOutput(); } +void buildLargeLp(MPSolver& solver, int numVars) { + MPObjective* obj = solver.MutableObjective(); + obj->SetMaximization(); + for (int i = 0; i < numVars; ++i) { + MPVariable* x = solver.MakeNumVar(-(i * i) % 21, + (i * i) % 55, + "x_" + std::to_string(i)); + obj->SetCoefficient(x, (i * i) % 23); + int min = -50; + int max = (i * i) % 664 + 55; + MPConstraint* c = solver.MakeRowConstraint(min, max); + c->SetCoefficient(x, i % 331); + for (int j = 0; j < i; ++j) { + c->SetCoefficient(solver.variable(j), i + j); + } + } + solver.EnableOutput(); +} + class MyMPCallback : public MPCallback { private: MPSolver* mpSolver_; @@ -282,6 +301,35 @@ TEST(XpressInterface, isLP) { EXPECT_EQ(solver.IsMIP(), false); } +TEST(XpressInterface, LpStartingBasis) { + UNITTEST_INIT_LP(); + buildLargeLp(solver, 1000); + // First, we record the number of iterations without an initial basis + solver.Solve(); + const auto iterInit = solver.iterations(); + EXPECT_GE(iterInit, 1000); + + // Here, we retrieve the final basis + std::vector varStatus, constrStatus; + for (auto* var : solver.variables()) { + varStatus.push_back(var->basis_status()); + } + for (auto* constr : solver.constraints()) { + constrStatus.push_back(constr->basis_status()); + } + + // Then we slightly modify the problem... + MPObjective* obj = solver.MutableObjective(); + obj->SetCoefficient(solver.variables().at(1), + 100); + // Here, we provide the final basis of the previous (similar) problem + solver.SetStartingLpBasis(varStatus, constrStatus); + solver.Solve(); + const auto iterWithBasis = solver.iterations(); + // ...and check that few iterations have been performed + EXPECT_LT(iterWithBasis, 10); +} + TEST(XpressInterface, NumVariables) { UNITTEST_INIT_MIP(); MPVariable* x1 = solver.MakeNumVar(-1., 5.1, "x1"); From 63c51817034f0e08366a2772a85f55dffdf49adf Mon Sep 17 00:00:00 2001 From: Andrea Sgattoni Date: Fri, 17 Nov 2023 15:34:26 +0100 Subject: [PATCH 08/10] fix gtests flags --- ortools/linear_solver/xpress_interface_test.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/ortools/linear_solver/xpress_interface_test.cc b/ortools/linear_solver/xpress_interface_test.cc index 503f18cabcf..cbd1351c6ca 100644 --- a/ortools/linear_solver/xpress_interface_test.cc +++ b/ortools/linear_solver/xpress_interface_test.cc @@ -1355,7 +1355,6 @@ TEST(XpressInterface, CallbackThrowsException) { } // namespace operations_research int main(int argc, char** argv) { - InitGoogle(argv[0], &argc, &argv, true); absl::SetFlag(&FLAGS_logtostderr, 1); testing::InitGoogleTest(&argc, argv); auto solver = operations_research::MPSolver::CreateSolver("XPRESS_LP"); From e732569b5810baa966510a720b398381ea6dbe6a Mon Sep 17 00:00:00 2001 From: Andrea Sgattoni Date: Fri, 17 Nov 2023 15:34:41 +0100 Subject: [PATCH 09/10] refactor --- ortools/linear_solver/xpress_interface.cc | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/ortools/linear_solver/xpress_interface.cc b/ortools/linear_solver/xpress_interface.cc index ba640c0f35c..453f1ab72ba 100644 --- a/ortools/linear_solver/xpress_interface.cc +++ b/ortools/linear_solver/xpress_interface.cc @@ -1742,6 +1742,15 @@ void XpressInterface::SetLpAlgorithm(int value) { CHECK_STATUS(XPRSsetintcontrol(mLp, XPRS_DEFAULTALG, alg)); } } +std::vector XpressBasisStatusesFrom( + const std::vector& statuses) { + std::vector result; + result.reserve(statuses.size()); + std::transform(statuses.cbegin(), statuses.cend(), result.begin(), + MPSolverToXpressBasisStatus); + return result; +} + void XpressInterface::SetStartingLpBasis( const std::vector& variable_statuses, const std::vector& constraint_statuses){ @@ -1749,16 +1758,8 @@ void XpressInterface::SetStartingLpBasis( LOG(DFATAL) << __FUNCTION__ << " is only available for LP problems"; return; } - initial_variables_basis_status_.clear(); - initial_variables_basis_status_.reserve(variable_statuses.size()); - for (const MPSolver::BasisStatus& status : variable_statuses) { - initial_variables_basis_status_.push_back(MPSolverToXpressBasisStatus(status)); - } - initial_constraint_basis_status_.clear(); - initial_constraint_basis_status_.reserve(constraint_statuses.size()); - for (const MPSolver::BasisStatus& status : constraint_statuses) { - initial_constraint_basis_status_.push_back(MPSolverToXpressBasisStatus(status)); - } + initial_variables_basis_status_=XpressBasisStatusesFrom(variable_statuses); + initial_constraint_basis_status_=XpressBasisStatusesFrom(constraint_statuses); } bool XpressInterface::readParameters(std::istream& is, char sep) { From 254fd489a81f1c9a487cde75dff670cc87dd53aa Mon Sep 17 00:00:00 2001 From: Andrea Sgattoni Date: Fri, 17 Nov 2023 16:03:36 +0100 Subject: [PATCH 10/10] suggestions by @flomnes --- ortools/linear_solver/xpress_interface.cc | 8 ++++---- ortools/linear_solver/xpress_interface_test.cc | 3 +-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/ortools/linear_solver/xpress_interface.cc b/ortools/linear_solver/xpress_interface.cc index 453f1ab72ba..b707c15a7e8 100644 --- a/ortools/linear_solver/xpress_interface.cc +++ b/ortools/linear_solver/xpress_interface.cc @@ -358,8 +358,8 @@ class XpressInterface : public MPSolverInterface { bool IsMIP() const override { return mMip; } void SetStartingLpBasis( - const std::vector& /*variable_statuses*/, - const std::vector& /*constraint_statuses*/) override; + const std::vector& variable_statuses, + const std::vector& constraint_statuses) override; void ExtractNewVariables() override; void ExtractNewConstraints() override; @@ -1758,8 +1758,8 @@ void XpressInterface::SetStartingLpBasis( LOG(DFATAL) << __FUNCTION__ << " is only available for LP problems"; return; } - initial_variables_basis_status_=XpressBasisStatusesFrom(variable_statuses); - initial_constraint_basis_status_=XpressBasisStatusesFrom(constraint_statuses); + initial_variables_basis_status_ = XpressBasisStatusesFrom(variable_statuses); + initial_constraint_basis_status_ = XpressBasisStatusesFrom(constraint_statuses); } bool XpressInterface::readParameters(std::istream& is, char sep) { diff --git a/ortools/linear_solver/xpress_interface_test.cc b/ortools/linear_solver/xpress_interface_test.cc index cbd1351c6ca..184fe4e3596 100644 --- a/ortools/linear_solver/xpress_interface_test.cc +++ b/ortools/linear_solver/xpress_interface_test.cc @@ -320,8 +320,7 @@ TEST(XpressInterface, LpStartingBasis) { // Then we slightly modify the problem... MPObjective* obj = solver.MutableObjective(); - obj->SetCoefficient(solver.variables().at(1), - 100); + obj->SetCoefficient(solver.variable(1), 100); // Here, we provide the final basis of the previous (similar) problem solver.SetStartingLpBasis(varStatus, constrStatus); solver.Solve();