Cplex/Xpress blind fix #2296

This commit is contained in:
Mizux Seiha
2020-12-22 11:20:36 +01:00
parent 7cd948e9ea
commit c5d6f7f603
2 changed files with 16 additions and 52 deletions

View File

@@ -100,8 +100,6 @@ class CplexInterface : public MPSolverInterface {
virtual int64 iterations() const;
// Number of branch-and-bound nodes. Only available for discrete problems.
virtual int64 nodes() const;
// Best objective bound. Only available for discrete problems.
virtual double best_objective_bound() const;
// Returns the basis status of a row.
virtual MPSolver::BasisStatus row_status(int constraint_index) const;
@@ -613,27 +611,6 @@ int64 CplexInterface::nodes() const {
}
}
// Returns the best objective bound. Only available for discrete problems.
double CplexInterface::best_objective_bound() const {
if (mMip) {
if (!CheckSolutionIsSynchronized() || !CheckBestObjectiveBoundExists())
// trivial_worst_objective_bound() returns sense*infinity,
// that is meaningful even for infeasible problems
return trivial_worst_objective_bound();
if (solver_->variables_.size() == 0 && solver_->constraints_.size() == 0) {
// For an empty model the best objective bound is just the offset.
return solver_->Objective().offset();
} else {
double value = CPX_NAN;
CHECK_STATUS(CPXXgetbestobjval(mEnv, mLp, &value));
return value;
}
} else {
LOG(DFATAL) << "Best objective bound only available for discrete problems";
return trivial_worst_objective_bound();
}
}
// Transform a CPLEX basis status to an MPSolver basis status.
MPSolver::BasisStatus CplexInterface::xformBasisStatus(int cplex_basis_status) {
switch (cplex_basis_status) {
@@ -1182,13 +1159,20 @@ MPSolver::ResultStatus CplexInterface::Solve(MPSolverParameters const& param) {
// Capture objective function value.
objective_value_ = CPX_NAN;
if (pfeas) CHECK_STATUS(CPXXgetobjval(mEnv, mLp, &objective_value_));
VLOG(1) << "objective = " << objective_value_;
best_objective_bound_ = CPX_NAN;
if (feasible) {
CHECK_STATUS(CPXXgetobjval(mEnv, mLp, &objective_value_));
if (mMip) {
CHECK_STATUS(CPXXgetbestobjval(mEnv, mLp, &best_objective_bound_));
}
}
VLOG(1) << "objective=" << objective_value_
<< ", bound=" << best_objective_bound_;
// Capture primal and dual solutions
if (mMip) {
// If there is a primal feasible solution then capture it.
if (pfeas) {
if (feasible) {
if (cols > 0) {
unique_ptr<double[]> x(new double[cols]);
CHECK_STATUS(CPXXgetx(mEnv, mLp, x.get(), 0, cols - 1));
@@ -1213,14 +1197,14 @@ MPSolver::ResultStatus CplexInterface::Solve(MPSolverParameters const& param) {
if (cols > 0) {
unique_ptr<double[]> x(new double[cols]);
unique_ptr<double[]> dj(new double[cols]);
if (pfeas) CHECK_STATUS(CPXXgetx(mEnv, mLp, x.get(), 0, cols - 1));
if (feasible) CHECK_STATUS(CPXXgetx(mEnv, mLp, x.get(), 0, cols - 1));
if (dfeas) CHECK_STATUS(CPXXgetdj(mEnv, mLp, dj.get(), 0, cols - 1));
for (int i = 0; i < solver_->variables_.size(); ++i) {
MPVariable* const var = solver_->variables_[i];
var->set_solution_value(x[i]);
bool value = false, dual = false;
if (pfeas) {
if (feasible) {
var->set_solution_value(x[i]);
value = true;
} else

View File

@@ -147,8 +147,6 @@ class XpressInterface : public MPSolverInterface {
virtual int64 iterations() const;
// Number of branch-and-bound nodes. Only available for discrete problems.
virtual int64 nodes() const;
// Best objective bound. Only available for discrete problems.
virtual double best_objective_bound() const;
// Returns the basis status of a row.
virtual MPSolver::BasisStatus row_status(int constraint_index) const;
@@ -746,27 +744,6 @@ int64 XpressInterface::nodes() const {
}
}
// Returns the best objective bound. Only available for discrete problems.
double XpressInterface::best_objective_bound() const {
if (mMip) {
if (!CheckSolutionIsSynchronized() || !CheckBestObjectiveBoundExists())
// trivial_worst_objective_bound() returns sense*infinity,
// that is meaningful even for infeasible problems
return trivial_worst_objective_bound();
if (solver_->variables_.size() == 0 && solver_->constraints_.size() == 0) {
// For an empty model the best objective bound is just the offset.
return solver_->Objective().offset();
} else {
double value = XPRS_NAN;
CHECK_STATUS(XPRSgetdblattrib(mLp, XPRS_BESTBOUND, &value));
return value;
}
} else {
LOG(DFATAL) << "Best objective bound only available for discrete problems";
return trivial_worst_objective_bound();
}
}
// Transform a XPRESS basis status to an MPSolver basis status.
MPSolver::BasisStatus XpressInterface::xformBasisStatus(
int xpress_basis_status) {
@@ -1341,14 +1318,17 @@ MPSolver::ResultStatus XpressInterface::Solve(MPSolverParameters const& param) {
// Capture objective function value.
objective_value_ = XPRS_NAN;
best_objective_bound_ = XPRS_NAN;
if (feasible) {
if (mMip) {
CHECK_STATUS(XPRSgetdblattrib(mLp, XPRS_MIPOBJVAL, &objective_value_));
CHECK_STATUS(XPRSgetdblattrib(mLp, XPRS_BESTBOUND, &best_objective_bound_));
} else {
CHECK_STATUS(XPRSgetdblattrib(mLp, XPRS_LPOBJVAL, &objective_value_));
}
}
VLOG(1) << "objective = " << objective_value_;
VLOG(1) << "objective=" << objective_value_
<< ", bound=" << best_objective_bound_;
// Capture primal and dual solutions
if (mMip) {