Skip to content

Commit

Permalink
Now interpreting failure of optimality within checkOptimality
Browse files Browse the repository at this point in the history
  • Loading branch information
jajhall committed Mar 1, 2025
1 parent 45aa121 commit 9d4c84b
Show file tree
Hide file tree
Showing 4 changed files with 15 additions and 30 deletions.
4 changes: 2 additions & 2 deletions check/TestCAPI.c
Original file line number Diff line number Diff line change
Expand Up @@ -1967,7 +1967,7 @@ void test_multiObjective() {
free(col_value);
}

void test_qp_indefinite_failure() {
void testQpIndefiniteFailure() {
void* highs = Highs_create();
HighsInt ret;
const double inf = Highs_getInfinity(highs);
Expand Down Expand Up @@ -2051,7 +2051,7 @@ int main() {
test_feasibilityRelaxation();
test_getModel();
test_multiObjective();
test_qp_indefinite_failure();
test_testQpIndefiniteFailure();
return 0;
}
// test_setSolution();
3 changes: 1 addition & 2 deletions src/Highs.h
Original file line number Diff line number Diff line change
Expand Up @@ -1661,8 +1661,7 @@ class Highs {
bool aFormatOk(const HighsInt num_nz, const HighsInt format);
bool qFormatOk(const HighsInt num_nz, const HighsInt format);
void clearZeroHessian();
HighsStatus checkOptimality(const std::string& solver_type,
HighsStatus return_status);
HighsStatus checkOptimality(const std::string& solver_type);
HighsStatus invertRequirementError(std::string method_name) const;

HighsStatus handleInfCost();
Expand Down
25 changes: 4 additions & 21 deletions src/lp_data/Highs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3746,13 +3746,7 @@ HighsStatus Highs::callSolveLp(HighsLp& lp, const string message) {
return_status = solveLp(solver_object, message);
// Extract the model status
model_status_ = solver_object.model_status_;
if (model_status_ == HighsModelStatus::kOptimal) {
HighsStatus check_status = checkOptimality("LP", return_status);
if (check_status == HighsStatus::kError) {
return_status = check_status;
solver_object.model_status_ = HighsModelStatus::kSolveError;
}
}
if (model_status_ == HighsModelStatus::kOptimal) return checkOptimality("LP");
return return_status;
}

Expand Down Expand Up @@ -3897,13 +3891,7 @@ HighsStatus Highs::callSolveQp() {
info_.simplex_iteration_count += stats.phase1_iterations;
info_.qp_iteration_count += stats.num_iterations;
info_.valid = true;
if (model_status_ == HighsModelStatus::kOptimal) {
HighsStatus check_status = checkOptimality("QP", return_status);
if (check_status == HighsStatus::kError) {
return_status = check_status;
model_status_ = HighsModelStatus::kSolveError;
}
}
if (model_status_ == HighsModelStatus::kOptimal) return checkOptimality("QP");
return return_status;
}

Expand Down Expand Up @@ -3997,13 +3985,8 @@ HighsStatus Highs::callSolveMip() {
? -1
: HighsInt(mip_total_lp_iterations);
info_.valid = true;
if (model_status_ == HighsModelStatus::kOptimal) {
HighsStatus check_status = checkOptimality("MIP", return_status);
if (check_status == HighsStatus::kError) {
return_status = check_status;
model_status_ = HighsModelStatus::kSolveError;
}
}
if (model_status_ == HighsModelStatus::kOptimal)
return_status = checkOptimality("MIP");
if (use_mip_feasibility_tolerance) {
// Overwrite max infeasibility to include integrality if there is a solution
if (solver.solution_objective_ != kHighsInf) {
Expand Down
13 changes: 8 additions & 5 deletions src/lp_data/HighsInterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2442,24 +2442,25 @@ void Highs::clearZeroHessian() {
}
}

HighsStatus Highs::checkOptimality(const std::string& solver_type,
HighsStatus return_status) {
HighsStatus Highs::checkOptimality(const std::string& solver_type) {
// Check for infeasibility measures incompatible with optimality
assert(return_status != HighsStatus::kError);
assert(model_status_ == HighsModelStatus::kOptimal);
// Cannot expect to have no dual_infeasibilities since the QP solver
// (and, of course, the MIP solver) give no dual information
if (info_.num_primal_infeasibilities == 0 &&
info_.num_dual_infeasibilities <= 0)
return HighsStatus::kOk;
HighsLogType log_type = HighsLogType::kWarning;
return_status = HighsStatus::kWarning;
model_status_ = HighsModelStatus::kUnknown;
HighsStatus return_status = HighsStatus::kWarning;
// Check for gross errors
if (info_.max_primal_infeasibility >
sqrt(options_.primal_feasibility_tolerance) ||
(info_.dual_solution_status != kSolutionStatusNone &&
info_.max_dual_infeasibility >
sqrt(options_.dual_feasibility_tolerance))) {
// Check for gross errors
log_type = HighsLogType::kError;
model_status_ = HighsModelStatus::kSolveError;
return_status = HighsStatus::kError;
}
std::stringstream ss;
Expand All @@ -2476,6 +2477,8 @@ HighsStatus Highs::checkOptimality(const std::string& solver_type,
ss << " infeasibilities\n";
const std::string report_string = ss.str();
highsLogUser(options_.log_options, log_type, "%s", report_string.c_str());
highsLogUser(options_.log_options, log_type, "Setting model status to %s\n",
modelStatusToString(model_status_).c_str());
return return_status;
}

Expand Down

0 comments on commit 9d4c84b

Please sign in to comment.