Cplex/Xpress blind fix #2296
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user