Only called from Highs::postsolve
| 4449 | |
| 4450 | // Only called from Highs::postsolve |
| 4451 | HighsStatus Highs::callRunPostsolve(const HighsSolution& solution, |
| 4452 | const HighsBasis& basis) { |
| 4453 | HighsStatus return_status = HighsStatus::kOk; |
| 4454 | HighsStatus call_status; |
| 4455 | const HighsLp& presolved_lp = presolve_.getReducedProblem(); |
| 4456 | |
| 4457 | // Must at least have a primal column solution of the right size |
| 4458 | if (HighsInt(solution.col_value.size()) != presolved_lp.num_col_) { |
| 4459 | highsLogUser( |
| 4460 | options_.log_options, HighsLogType::kError, |
| 4461 | "Primal solution provided to postsolve is of size %d rather than %d\n", |
| 4462 | int(solution.col_value.size()), int(presolved_lp.num_col_)); |
| 4463 | return HighsStatus::kError; |
| 4464 | } |
| 4465 | // Check any basis that is supplied |
| 4466 | const bool basis_supplied = |
| 4467 | basis.col_status.size() > 0 || basis.row_status.size() > 0 || basis.valid; |
| 4468 | if (basis_supplied) { |
| 4469 | if (!isBasisConsistent(presolved_lp, basis)) { |
| 4470 | highsLogUser( |
| 4471 | options_.log_options, HighsLogType::kError, |
| 4472 | "Basis provided to postsolve is incorrect size or inconsistent\n"); |
| 4473 | return HighsStatus::kError; |
| 4474 | } |
| 4475 | } |
| 4476 | // Copy in the solution provided |
| 4477 | presolve_.data_.recovered_solution_ = solution; |
| 4478 | // Ignore any row values |
| 4479 | presolve_.data_.recovered_solution_.row_value.assign(presolved_lp.num_row_, |
| 4480 | 0); |
| 4481 | presolve_.data_.recovered_solution_.value_valid = true; |
| 4482 | |
| 4483 | if (this->model_.isMip() && !basis.valid) { |
| 4484 | // Postsolving a MIP without a valid basis - which, if valid, |
| 4485 | // would imply that the relaxation had been solved, a case handled |
| 4486 | // below |
| 4487 | // |
| 4488 | // Ignore any dual values |
| 4489 | presolve_.data_.recovered_solution_.dual_valid = false; |
| 4490 | presolve_.data_.recovered_solution_.col_dual.clear(); |
| 4491 | presolve_.data_.recovered_solution_.row_dual.clear(); |
| 4492 | // Ignore any basis |
| 4493 | presolve_.data_.recovered_basis_.valid = false; |
| 4494 | |
| 4495 | HighsPostsolveStatus postsolve_status = runPostsolve(); |
| 4496 | |
| 4497 | if (postsolve_status == HighsPostsolveStatus::kSolutionRecovered) { |
| 4498 | this->solution_ = presolve_.data_.recovered_solution_; |
| 4499 | this->model_status_ = HighsModelStatus::kUnknown; |
| 4500 | invalidateInfo(); |
| 4501 | HighsLp& lp = this->model_.lp_; |
| 4502 | this->info_.objective_function_value = |
| 4503 | computeObjectiveValue(lp, this->solution_); |
| 4504 | const bool is_qp = this->model_.isQp(); |
| 4505 | assert(!is_qp); |
| 4506 | const bool get_residuals = true; |
| 4507 | getKktFailures(this->options_, is_qp, this->model_.lp_, |
| 4508 | this->model_.lp_.col_cost_, this->solution_, this->info_, |
nothing calls this directly
no test coverage detected