@@ -4258,3 +4258,75 @@ void HighsMipSolverInfo::clear() {
42584258 this ->total_lp_iterations = -kHighsSize_tInf ;
42594259 this ->primal_dual_integral = -kHighsInf ;
42604260}
4261+
4262+ HighsStatus Highs::mipRaceResults (HighsMipSolverInfo& mip_solver_info,
4263+ const std::vector<HighsMipSolverInfo>& worker_info,
4264+ const std::vector<double >& mip_time) {
4265+
4266+ const HighsInt mip_race_concurrency = this ->options_ .mip_race_concurrency ;
4267+ HighsInt winning_instance = -1 ;
4268+ HighsModelStatus winning_model_status = HighsModelStatus::kNotset ;
4269+ for (HighsInt instance = 0 ; instance < mip_race_concurrency; instance++) {
4270+ const HighsMipSolverInfo& solver_info =
4271+ instance == 0 ? mip_solver_info : worker_info[instance];
4272+ HighsModelStatus instance_model_status = solver_info.modelstatus ;
4273+ highsLogUser (options_.log_options , HighsLogType::kInfo ,
4274+ " Solver %d has best objective %15.8g, gap %6.2f\% (time "
4275+ " = %6.2f), and status %s\n " ,
4276+ int (instance), solver_info.solution_objective ,
4277+ 1e2 * solver_info.gap , mip_time[instance],
4278+ modelStatusToString (instance_model_status).c_str ());
4279+ if (instance_model_status != HighsModelStatus::kHighsInterrupt ) {
4280+ // Definitive status for this instance, so check compatibility
4281+ // with any current winning model status
4282+ if (winning_model_status != HighsModelStatus::kNotset ) {
4283+ if (winning_model_status != instance_model_status) {
4284+ highsLogUser (options_.log_options , HighsLogType::kError ,
4285+ " MIP race: conflict between status \" %s\" for "
4286+ " instance %d and status \" %s\" for instance %d\n " ,
4287+ modelStatusToString (winning_model_status).c_str (),
4288+ int (winning_instance),
4289+ modelStatusToString (instance_model_status).c_str (),
4290+ int (instance));
4291+ return HighsStatus::kError ;
4292+ }
4293+ } else {
4294+ winning_model_status = instance_model_status;
4295+ winning_instance = instance;
4296+ }
4297+ }
4298+ }
4299+ if (winning_instance > 0 ) mip_solver_info = worker_info[winning_instance];
4300+ highsLogUser (options_.log_options , HighsLogType::kInfo , " Solving report\n " );
4301+ highsLogUser (options_.log_options , HighsLogType::kInfo , " Model %s\n " ,
4302+ this ->model_ .lp_ .model_name_ .c_str ());
4303+ highsLogUser (options_.log_options , HighsLogType::kInfo , " Status %s\n " ,
4304+ modelStatusToString (mip_solver_info.modelstatus ).c_str ());
4305+ highsLogUser (options_.log_options , HighsLogType::kInfo , " Primal bound %.12g\n " ,
4306+ mip_solver_info.primal_bound );
4307+ highsLogUser (options_.log_options , HighsLogType::kInfo , " Dual bound %.12g\n " ,
4308+ mip_solver_info.dual_bound );
4309+ highsLogUser (options_.log_options , HighsLogType::kInfo , " Gap %g%% (tolerance: %g%%)\n " ,
4310+ 1e2 *mip_solver_info.gap , 1e2 *options_.mip_rel_gap );
4311+ highsLogUser (options_.log_options , HighsLogType::kInfo , " P-D integral %.12g\n " ,
4312+ mip_solver_info.primal_dual_integral );
4313+ highsLogUser (options_.log_options , HighsLogType::kInfo , " Solution status %.12g\n " ,
4314+ mip_solver_info.solution_objective );
4315+ highsLogUser (options_.log_options , HighsLogType::kInfo , " %.12g (bound viol.)\n " ,
4316+ mip_solver_info.bound_violation );
4317+ highsLogUser (options_.log_options , HighsLogType::kInfo , " %.12g (int. viol.)\n " ,
4318+ mip_solver_info.integrality_violation );
4319+ highsLogUser (options_.log_options , HighsLogType::kInfo , " %.12g (row viol.)\n " ,
4320+ mip_solver_info.row_violation );
4321+ highsLogUser (options_.log_options , HighsLogType::kInfo , " Timing %.2f\n " ,
4322+ mip_time[winning_instance]);
4323+ highsLogUser (options_.log_options , HighsLogType::kInfo , " Nodes %llu\n " ,
4324+ mip_solver_info.node_count );
4325+ highsLogUser (options_.log_options , HighsLogType::kInfo , " LP iterations %llu\n " ,
4326+ mip_solver_info.total_lp_iterations );
4327+ /*
4328+ Solution status feasible
4329+ Max sub-MIP depth 1
4330+ */
4331+ return HighsStatus::kOk ;
4332+ }
0 commit comments