Skip to content

Commit 9b7bc10

Browse files
committed
Create gap string method
1 parent 884f745 commit 9b7bc10

File tree

4 files changed

+83
-35
lines changed

4 files changed

+83
-35
lines changed

check/TestMipSolver.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1037,7 +1037,7 @@ TEST_CASE("issue-2432", "[highs_test_mip_solver]") {
10371037
}
10381038

10391039
TEST_CASE("mip-race", "[highs_test_mip_solver]") {
1040-
const bool ci_test = false;//true; //
1040+
const bool ci_test = true; // false;//
10411041
const std::string model = ci_test ? "rgn" : "fiball"; //flugpl
10421042
// "neos-3381206-awhea";
10431043
const std::string model_file =
@@ -1051,11 +1051,13 @@ TEST_CASE("mip-race", "[highs_test_mip_solver]") {
10511051
REQUIRE(h.run() == HighsStatus::kOk);
10521052
REQUIRE(h.getModelStatus() == HighsModelStatus::kOptimal);
10531053

1054+
/*
10541055
if (ci_test) {
10551056
h.clearSolver();
10561057
h.setOptionValue("mip_race_read_solutions", false);
10571058
REQUIRE(h.run() == HighsStatus::kOk);
10581059
REQUIRE(h.getModelStatus() == HighsModelStatus::kOptimal);
10591060
}
1061+
*/
10601062
h.resetGlobalScheduler(true);
10611063
}

highs/Highs.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1714,6 +1714,9 @@ class Highs {
17141714
bool optionsHasHighsFiles() const;
17151715
void saveHighsFiles();
17161716
void getHighsFiles();
1717+
HighsStatus mipRaceResults(HighsMipSolverInfo& mip_solver_info,
1718+
const std::vector<HighsMipSolverInfo>& worker_info,
1719+
const std::vector<double>& mip_time);
17171720
};
17181721

17191722
// Start of deprecated methods not in the Highs class

highs/lp_data/Highs.cpp

Lines changed: 5 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -4108,41 +4108,12 @@ HighsStatus Highs::callSolveMip() {
41084108
}
41094109
}
41104110
});
4111-
// Report on the solver and workers, and identify which has won!
4112-
HighsInt winning_instance = -1;
4113-
HighsModelStatus winning_model_status = HighsModelStatus::kNotset;
4114-
highsLogUser(options_.log_options, HighsLogType::kInfo,
4115-
"MIP race results:\n");
4116-
for (HighsInt instance = 0; instance < mip_race_concurrency; instance++) {
4117-
const HighsMipSolverInfo& solver_info =
4118-
instance == 0 ? mip_solver_info : worker_info[instance];
4119-
HighsModelStatus instance_model_status = solver_info.modelstatus;
4120-
highsLogUser(options_.log_options, HighsLogType::kInfo,
4121-
" Solver %d has best objective %15.8g, gap %6.2f\% (time "
4122-
"= %6.2f), and status %s\n",
4123-
int(instance), solver_info.solution_objective,
4124-
1e2 * solver_info.gap, mip_time[instance],
4125-
modelStatusToString(instance_model_status).c_str());
4126-
if (instance_model_status != HighsModelStatus::kHighsInterrupt) {
4127-
// Definitive status for this instance, so check compatibility
4128-
// with any current winning model status
4129-
if (winning_model_status != HighsModelStatus::kNotset) {
4130-
if (winning_model_status != instance_model_status) {
4131-
highsLogUser(options_.log_options, HighsLogType::kError,
4132-
"MIP race: conflict between status \"%s\" for "
4133-
"instance %d and status \"%s\" for instance %d\n",
4134-
modelStatusToString(winning_model_status).c_str(),
4135-
int(winning_instance),
4136-
modelStatusToString(instance_model_status).c_str(),
4137-
int(instance));
4138-
}
4139-
} else {
4140-
winning_model_status = instance_model_status;
4141-
winning_instance = instance;
4142-
}
4143-
}
4111+
// Determine the winner and report on the solution
4112+
HighsStatus call_status = this->mipRaceResults(mip_solver_info, worker_info, mip_time);
4113+
if (call_status == HighsStatus::kError) {
4114+
const bool undo_mods = true;
4115+
return returnFromOptimizeModel(HighsStatus::kError, undo_mods);
41444116
}
4145-
if (winning_instance > 0) mip_solver_info = worker_info[winning_instance];
41464117
} else {
41474118
// Run a single MIP solver
41484119
solver.run();

highs/lp_data/HighsInterface.cpp

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)