| 407 | } |
| 408 | |
| 409 | void HighsMipSolverData::startAnalyticCenterComputation( |
| 410 | const highs::parallel::TaskGroup& taskGroup) { |
| 411 | taskGroup.spawn([&]() { |
| 412 | // first check if the analytic centre computation should be cancelled, e.g. |
| 413 | // due to early return in the root node evaluation |
| 414 | // |
| 415 | // Highs instantiation |
| 416 | Highs ipm; |
| 417 | ipm.setProfiling(mipsolver.profiling_); |
| 418 | ipm.setOptionValue("output_flag", false); |
| 419 | const std::vector<double>& sol = ipm.getSolution().col_value; |
| 420 | // Don't use presolve - because this can lead to postsolve putting |
| 421 | // integer variables onto bounds. This is not just a "less good" |
| 422 | // AC. It can have implications leading to erroneous fixing of |
| 423 | // variables and a suboptimal solution declared as optimal. |
| 424 | ipm.setOptionValue("presolve", kHighsOffString); |
| 425 | // Determine the solver |
| 426 | const std::string mip_ipm_solver = mipsolver.options_mip_->mip_ipm_solver; |
| 427 | // Currently use IPX by default and take action on failure here if |
| 428 | // using HiPO. |
| 429 | bool use_hipo = |
| 430 | /* |
| 431 | #ifdef HIPO |
| 432 | // Later use HiPO by default |
| 433 | mip_ipm_solver == kHighsChooseString || |
| 434 | #endif |
| 435 | */ |
| 436 | mip_ipm_solver == kHipoString; |
| 437 | // Later still, pass mip_ipm_solver and take action on failure in |
| 438 | // solveLp |
| 439 | const std::string ipm_solver = use_hipo ? kHipoString : kIpxString; |
| 440 | ipm.setOptionValue("solver", ipm_solver); |
| 441 | ipm.setOptionValue("ipm_iteration_limit", 200); |
| 442 | ipm.setOptionValue("run_crossover", kHighsOffString); |
| 443 | ipm.setOptionValue("run_centring", true); |
| 444 | HighsLp lpmodel(*mipsolver.model_); |
| 445 | lpmodel.col_cost_.assign(lpmodel.num_col_, 0.0); |
| 446 | lpmodel.integrality_.clear(); |
| 447 | ipm.passModel(std::move(lpmodel)); |
| 448 | const bool dump_ipm_lp = false; |
| 449 | if (dump_ipm_lp && !mipsolver.submip) { |
| 450 | const std::string file_name = mipsolver.model_->model_name_ + "_ac.mps"; |
| 451 | printf( |
| 452 | "HighsMipSolverData::startAnalyticCenterComputation: Calling " |
| 453 | "ipm.writeModel(%s)\n", |
| 454 | file_name.c_str()); |
| 455 | ipm.writeModel(file_name); |
| 456 | fflush(stdout); |
| 457 | exit(1); |
| 458 | } |
| 459 | const bool ipm_logging = false; |
| 460 | if (ipm_logging) { |
| 461 | bool output_flag; |
| 462 | ipm.getOptionValue("output_flag", output_flag); |
| 463 | assert(output_flag == false); |
| 464 | (void)output_flag; |
| 465 | ipm.setOptionValue("output_flag", !mipsolver.submip); |
| 466 | } |
nothing calls this directly
no test coverage detected