Skip to content

Commit

Permalink
Squashed 'scipy/optimize/_highs/' changes from fbdda9438..075b95922
Browse files Browse the repository at this point in the history
075b95922 Merge pull request #21 from ERGO-Code/presolveCleanBounds
862131490 Added cleanBounds to resolve minor inconsistencies in bounds after presolve and return error if large

git-subtree-dir: scipy/optimize/_highs
git-subtree-split: 075b959220fa00469455f4b19dc0a677ddf9737c
  • Loading branch information
mckib2 committed Apr 12, 2020
1 parent dc7fece commit a15ff5a
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 0 deletions.
4 changes: 4 additions & 0 deletions src/lp_data/Highs.cpp
Expand Up @@ -387,6 +387,10 @@ basis_.valid_, hmos_[0].basis_.valid_);
HighsLp& reduced_lp = presolve_info.getReducedProblem();
// Validate the reduced LP
assert(assessLp(reduced_lp, options_) == HighsStatus::OK);
call_status = cleanBounds(options_, reduced_lp);
return_status =
interpretCallStatus(call_status, return_status, "cleanBounds");
if (return_status == HighsStatus::Error) return return_status;
// Add reduced lp object to vector of HighsModelObject,
// so the last one in lp_ is the presolved one.

Expand Down
45 changes: 45 additions & 0 deletions src/lp_data/HighsLpUtils.cpp
Expand Up @@ -615,6 +615,51 @@ HighsStatus assessMatrix(const HighsOptions& options, const int vec_dim,
return return_status;
}

HighsStatus cleanBounds(const HighsOptions& options, HighsLp& lp) {
double max_residual = 0;
int num_change = 0;
for (int iCol = 0; iCol < lp.numCol_; iCol++) {
double residual = lp.colLower_[iCol] - lp.colUpper_[iCol];
if (residual > options.primal_feasibility_tolerance) {
HighsLogMessage(options.logfile, HighsMessageType::ERROR,
"Column %d has inconsistent bounds [%g, %g] (residual = "
"%g) after presolve ",
iCol, lp.colLower_[iCol], lp.colUpper_[iCol], residual);
return HighsStatus::Error;
} else if (residual > 0) {
num_change++;
max_residual = std::max(residual, max_residual);
double mid = 0.5 * (lp.colLower_[iCol] + lp.colUpper_[iCol]);
lp.colLower_[iCol] = mid;
lp.colUpper_[iCol] = mid;
}
}
for (int iRow = 0; iRow < lp.numRow_; iRow++) {
double residual = lp.rowLower_[iRow] - lp.rowUpper_[iRow];
if (residual > options.primal_feasibility_tolerance) {
HighsLogMessage(options.logfile, HighsMessageType::ERROR,
"Row %d has inconsistent bounds [%g, %g] (residual = %g) "
"after presolve ",
iRow, lp.rowLower_[iRow], lp.rowUpper_[iRow], residual);
return HighsStatus::Error;
} else if (residual > 0) {
num_change++;
max_residual = std::max(residual, max_residual);
double mid = 0.5 * (lp.rowLower_[iRow] + lp.rowUpper_[iRow]);
lp.rowLower_[iRow] = mid;
lp.rowUpper_[iRow] = mid;
}
}
if (num_change) {
HighsLogMessage(options.logfile, HighsMessageType::WARNING,
"Resolved %d inconsistent bounds (maximum residual = "
"%9.4g) after presolve ",
num_change, max_residual);
return HighsStatus::Warning;
}
return HighsStatus::OK;
}

HighsStatus scaleLpColCosts(const HighsOptions& options, HighsLp& lp,
vector<double>& colScale, const bool interval,
const int from_col, const int to_col,
Expand Down
2 changes: 2 additions & 0 deletions src/lp_data/HighsLpUtils.h
Expand Up @@ -55,6 +55,8 @@ HighsStatus assessMatrix(const HighsOptions& options, const int vec_dim,
const double small_matrix_value,
const double large_matrix_value, bool normalise);

HighsStatus cleanBounds(const HighsOptions& options, HighsLp& lp);

HighsStatus scaleLpColCosts(const HighsOptions& options, HighsLp& lp,
vector<double>& colScale, const bool interval,
const int from_col, const int to_col,
Expand Down

0 comments on commit a15ff5a

Please sign in to comment.