ERGO-Code / HiGHS

Linear optimization software
MIT License
957 stars 177 forks source link

saved MIP solutions pool is empty when solution is found during presolve #1724

Closed lkapelevich closed 5 months ago

lkapelevich commented 6 months ago

I noticed that when an optimal solution is found during presolve, it's not recorded or returned with getSavedMipSolutions().

Any reason not to record it e.g. here?

jajhall commented 6 months ago

Well spotted. No reason not to store it - for completeness

lkapelevich commented 6 months ago

Dropping a test in case it helps save a little bit of time:

TEST_CASE("MIP-get-saved-solutions-presolve", "[highs_test_mip_solver]") {
  const std::string solution_file = "MipImproving.sol";
  Highs highs;
  highs.setOptionValue("output_flag", dev_run);
  highs.setOptionValue("mip_improving_solution_save", true);
  highs.setOptionValue("mip_improving_solution_report_sparse", true);
  highs.setOptionValue("mip_improving_solution_file", solution_file);
  HighsLp lp;
  lp.num_col_ = 2;
  lp.num_row_ = 0;
  lp.col_cost_ = {1, 1};
  lp.col_lower_ = {0, 0};
  lp.col_upper_ = {1, 1};
  lp.integrality_ = {HighsVarType::kInteger, HighsVarType::kInteger};
  lp.row_lower_ = {};
  lp.row_upper_ = {};
  lp.a_matrix_.format_ = MatrixFormat::kColwise;
  lp.a_matrix_.num_col_ = 2;
  lp.a_matrix_.num_row_ = 0;
  lp.a_matrix_.start_ = {0};
  lp.a_matrix_.index_ = {};
  lp.a_matrix_.value_ = {};
  highs.passModel(lp);
  highs.run();
  const std::vector<HighsObjectiveSolution> saved_objective_and_solution =
      highs.getSavedMipSolutions();
  const HighsInt num_saved_solution = saved_objective_and_solution.size();
  REQUIRE(num_saved_solution == 1);
  const HighsInt last_saved_solution = num_saved_solution - 1;
  REQUIRE(saved_objective_and_solution[last_saved_solution].objective ==
          highs.getInfo().objective_function_value);
  for (HighsInt iCol = 0; iCol < highs.getLp().num_col_; iCol++)
    REQUIRE(saved_objective_and_solution[last_saved_solution].col_value[iCol] ==
            highs.getSolution().col_value[iCol]);
  std::remove(solution_file.c_str());
}

I'm not confident I'll get it fully right if I implement a fix. Also I'm not sure what is supposed to happen if we are in a restart and then presolve finds a solution.

jajhall commented 5 months ago

Closed by #1742