@@ -4030,127 +4030,11 @@ HighsStatus Highs::callSolveMip() {
40304030 use_lp = withoutSemiVariables (model_.lp_ , solution_,
40314031 options_.primal_feasibility_tolerance );
40324032 }
4033- // Start timing any MIP race before its presolve and parallel MIP
4034- // solver calls. This timer is stopped in Highs::mipRaceResults
4035- // after any postsolve is performed
4036- double mip_race_time = -this ->timer_ .read ();
4037- HighsLp presolved_lp;
4038- const HighsInt mip_race_concurrency = this ->options_ .mip_race_concurrency ;
4039- const bool run_mip_race = mip_race_concurrency > 1 ;
4040- // Determine whether to do a single presolve before any MIP race
4041- //
4042- // Doesn't work when there are semi-variables since they have to be
4043- // converted into the use_lp instance, and this->presolve(); works
4044- // on the incumbent model
4045- const bool use_mip_race_single_presolve =
4046- run_mip_race && options_.mip_race_single_presolve &&
4047- options_.presolve != kHighsOffString && !has_semi_variables;
4048- // Take a copy of the presolve option in case it's switched off for
4049- // a single presolve MIP race
4050- const std::string presolve = this ->options_ .presolve ;
4051- if (use_mip_race_single_presolve) {
4052- // Perform presolve before the MIP race
4053- //
4054- // NB Highs::presolve() is normally called externally, so calls
4055- // returnFromHighs(). This will stop the run clock, and check that
4056- // called_return_from_optimize_model is true - when it isn't. So,
4057- // add a hack to set called_return_from_optimize_model true before
4058- // the call to presolve...
4059- assert (!this ->called_return_from_optimize_model );
4060- this ->called_return_from_optimize_model = true ;
4061- HighsStatus call_status = this ->presolve ();
4062- // ... then set it back to false and restart the run clock
4063- this ->called_return_from_optimize_model = false ;
4064- this ->timer_ .start ();
4065- if (call_status != HighsStatus::kOk ) return call_status;
4066- presolved_lp = this ->getPresolvedLp ();
4067- this ->options_ .presolve = kHighsOffString ;
4068- }
4069- // Create the master MIP solver instance that will exist beyond any
4070- // MIP race
4071- HighsLp& lp =
4072- has_semi_variables
4073- ? use_lp
4074- : (use_mip_race_single_presolve ? presolved_lp : model_.lp_ );
4033+ HighsLp& lp = has_semi_variables ? use_lp : model_.lp_ ;
40754034 HighsMipSolver solver (callback_, options_, lp, solution_);
40764035 HighsMipSolverInfo mip_solver_info;
4077- if (run_mip_race) {
4078- // Set up the shared memory for the MIP solver race
4079- MipRaceRecord mip_race_record;
4080- mip_race_record.initialise (mip_race_concurrency, lp.num_col_ );
4081- // Set up the shared memory for the concurrent MIP terminator
4082- auto terminator_record =
4083- solver.initialiseTerminatorRecord (mip_race_concurrency);
4084- // Don't allow callbacks for workers
4085- HighsCallback worker_callback = callback_;
4086- worker_callback.clear ();
4087- // Race the MIP solver!
4088- highsLogUser (options_.log_options , HighsLogType::kInfo ,
4089- " \n Starting MIP race with %d instances: behaviour is "
4090- " non-deterministic!\n\n " ,
4091- int (mip_race_concurrency));
4092- // Define the HighsMipSolverInfo record for each worker
4093- std::vector<HighsMipSolverInfo> worker_info (mip_race_concurrency);
4094- // Set up the vector of options settings for workers
4095- std::vector<HighsOptions> worker_options;
4096- // std::vector<HighsMipSolver*> worker;
4097- std::vector<double > mip_time (mip_race_concurrency);
4098- for (HighsInt instance = 0 ; instance < mip_race_concurrency; instance++) {
4099- HighsOptions instance_options = options_;
4100- // No workers log to console
4101- instance_options.log_to_console = false ;
4102- instance_options.setLogOptions ();
4103- // Use the instance ID as an offset to the random seed
4104- instance_options.random_seed = options_.random_seed + instance;
4105- std::string worker_log_file =
4106- " mip_worker" + std::to_string (instance) + " .log" ;
4107- if (options_.output_flag )
4108- highsOpenLogFile (instance_options, worker_log_file);
4109- worker_options.push_back (instance_options);
4110- }
4111- highs::parallel::for_each (
4112- 0 , mip_race_concurrency, [&](HighsInt start, HighsInt end) {
4113- for (HighsInt instance = start; instance < end; instance++) {
4114- if (instance == 0 ) {
4115- solver.initialiseTerminator (mip_race_concurrency, instance,
4116- terminator_record.data ());
4117- solver.initialiseMipRace (mip_race_concurrency, instance,
4118- &mip_race_record);
4119- mip_time[instance] = -timer_.read ();
4120- solver.run ();
4121- mip_time[instance] += timer_.read ();
4122- mip_solver_info = getMipSolverInfo (solver);
4123- } else {
4124- HighsMipSolver worker (worker_callback, worker_options[instance],
4125- lp, solution_);
4126- worker.initialiseTerminator (mip_race_concurrency, instance,
4127- terminator_record.data ());
4128- worker.initialiseMipRace (mip_race_concurrency, instance,
4129- &mip_race_record);
4130- mip_time[instance] = -timer_.read ();
4131- worker.run ();
4132- mip_time[instance] += timer_.read ();
4133- worker_info[instance] = getMipSolverInfo (worker);
4134- }
4135- }
4136- });
4137- // Determine the winner and report on the solution
4138- HighsStatus call_status =
4139- this ->mipRaceResults (use_mip_race_single_presolve, mip_solver_info,
4140- worker_info, mip_time, mip_race_time);
4141- // Restore the presolve option - that will have been set to
4142- // kHighsOffString for a single presolve MIP race
4143- this ->options_ .presolve = presolve;
4144-
4145- if (call_status == HighsStatus::kError ) {
4146- const bool undo_mods = true ;
4147- return returnFromOptimizeModel (HighsStatus::kError , undo_mods);
4148- }
4149- } else {
4150- // Run a single MIP solver
4151- solver.run ();
4152- mip_solver_info = getMipSolverInfo (solver);
4153- }
4036+ solver.run ();
4037+ mip_solver_info = getMipSolverInfo (solver);
41544038 options_.log_dev_level = log_dev_level;
41554039 // Set the return_status, model status and, for completeness, scaled
41564040 // model status
@@ -4160,14 +4044,7 @@ HighsStatus Highs::callSolveMip() {
41604044 // Extract the solution
41614045 if (mip_solver_info.solution_objective != kHighsInf ) {
41624046 // There is a primal solution
4163- HighsInt solver_solution_size = mip_solver_info.solution .size ();
4164- const bool solver_solution_size_ok = solver_solution_size >= lp.num_col_ ;
4165- if (!solver_solution_size)
4166- highsLogUser (
4167- options_.log_options , HighsLogType::kError ,
4168- " After MIP race, size of solution is %d < %d = lp.num_col_\n " ,
4169- int (solver_solution_size), int (lp.num_col_ ));
4170- assert (solver_solution_size >= lp.num_col_ );
4047+ //
41714048 // If the original model has semi-variables, its solution is
41724049 // (still) given by the first model_.lp_.num_col_ entries of the
41734050 // solution from the MIP solver
@@ -4240,10 +4117,9 @@ HighsStatus Highs::callSolveMip() {
42404117 return return_status;
42414118}
42424119
4243- // Only called from Highs::postsolve and Highs::mipRaceResults
4244- HighsStatus Highs::callRunPostsolve (
4245- const HighsSolution& solution, const HighsBasis& basis,
4246- const bool suppress_mip_model_status_warning) {
4120+ // Only called from Highs::postsolve
4121+ HighsStatus Highs::callRunPostsolve (const HighsSolution& solution,
4122+ const HighsBasis& basis) {
42474123 HighsStatus return_status = HighsStatus::kOk ;
42484124 HighsStatus call_status;
42494125 const HighsLp& presolved_lp = presolve_.getReducedProblem ();
@@ -4308,12 +4184,9 @@ HighsStatus Highs::callRunPostsolve(
43084184 max_integrality_violation);
43094185 }
43104186 }
4311- // When calling postsolve after MIP race on presolved model,
4312- // model status can be trusted so suppress the warning message
4313- if (!suppress_mip_model_status_warning)
4314- highsLogUser (
4315- options_.log_options , HighsLogType::kWarning ,
4316- " Postsolve performed for MIP, but model status cannot be known\n " );
4187+ highsLogUser (
4188+ options_.log_options , HighsLogType::kWarning ,
4189+ " Postsolve performed for MIP, but model status cannot be known\n " );
43174190 } else {
43184191 highsLogUser (options_.log_options , HighsLogType::kError ,
43194192 " Postsolve return status is %d\n " , (int )postsolve_status);
0 commit comments