Skip to content

Commit 6570af7

Browse files
committed
Instance 0 no longer logging MIP solver solution report to console, but using Highs::mipRaceResults
1 parent 9b7bc10 commit 6570af7

File tree

9 files changed

+172
-117
lines changed

9 files changed

+172
-117
lines changed

check/TestMipSolver.cpp

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

10391039
TEST_CASE("mip-race", "[highs_test_mip_solver]") {
1040-
const bool ci_test = true; // false;//
1041-
const std::string model = ci_test ? "rgn" : "fiball"; //flugpl
1040+
const bool ci_test = true;
1041+
const std::string model = ci_test ? "flugpl" : "fiball";
10421042
// "neos-3381206-awhea";
10431043
const std::string model_file =
10441044
ci_test ? std::string(HIGHS_DIR) + "/check/instances/" + model + ".mps"
10451045
: "/srv/miplib2017/" + model + ".mps.gz";
10461046
Highs h;
1047-
// if (ci_test) h.setOptionValue("output_flag", dev_run);
1047+
if (ci_test) h.setOptionValue("output_flag", dev_run);
10481048
const HighsInt mip_race_concurrency = ci_test ? 2 : 4;
10491049
h.setOptionValue("mip_race_concurrency", mip_race_concurrency);
10501050
REQUIRE(h.readModel(model_file) == HighsStatus::kOk);
10511051
REQUIRE(h.run() == HighsStatus::kOk);
10521052
REQUIRE(h.getModelStatus() == HighsModelStatus::kOptimal);
10531053

1054-
/*
10551054
if (ci_test) {
10561055
h.clearSolver();
10571056
h.setOptionValue("mip_race_read_solutions", false);
10581057
REQUIRE(h.run() == HighsStatus::kOk);
10591058
REQUIRE(h.getModelStatus() == HighsModelStatus::kOptimal);
10601059
}
1061-
*/
10621060
h.resetGlobalScheduler(true);
10631061
}

highs/Highs.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1715,8 +1715,8 @@ class Highs {
17151715
void saveHighsFiles();
17161716
void getHighsFiles();
17171717
HighsStatus mipRaceResults(HighsMipSolverInfo& mip_solver_info,
1718-
const std::vector<HighsMipSolverInfo>& worker_info,
1719-
const std::vector<double>& mip_time);
1718+
const std::vector<HighsMipSolverInfo>& worker_info,
1719+
const std::vector<double>& mip_time);
17201720
};
17211721

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

highs/lp_data/HStruct.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,7 @@ struct HighsMipSolverInfo {
194194
double dual_bound;
195195
double primal_bound;
196196
double gap;
197+
HighsInt max_submip_level;
197198
int64_t node_count;
198199
int64_t total_lp_iterations;
199200
double primal_dual_integral;

highs/lp_data/Highs.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4109,9 +4109,10 @@ HighsStatus Highs::callSolveMip() {
41094109
}
41104110
});
41114111
// Determine the winner and report on the solution
4112-
HighsStatus call_status = this->mipRaceResults(mip_solver_info, worker_info, mip_time);
4112+
HighsStatus call_status =
4113+
this->mipRaceResults(mip_solver_info, worker_info, mip_time);
41134114
if (call_status == HighsStatus::kError) {
4114-
const bool undo_mods = true;
4115+
const bool undo_mods = true;
41154116
return returnFromOptimizeModel(HighsStatus::kError, undo_mods);
41164117
}
41174118
} else {
@@ -4897,6 +4898,7 @@ HighsMipSolverInfo getMipSolverInfo(const HighsMipSolver& mip_solver) {
48974898
mip_solver_info.dual_bound = mip_solver.dual_bound_;
48984899
mip_solver_info.primal_bound = mip_solver.primal_bound_;
48994900
mip_solver_info.gap = mip_solver.gap_;
4901+
mip_solver_info.max_submip_level = mip_solver.max_submip_level;
49004902
mip_solver_info.node_count = mip_solver.node_count_;
49014903
mip_solver_info.total_lp_iterations = mip_solver.total_lp_iterations_;
49024904
mip_solver_info.primal_dual_integral = mip_solver.primal_dual_integral_;

highs/lp_data/HighsInterface.cpp

Lines changed: 84 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "Highs.h"
1414
#include "lp_data/HighsLpUtils.h"
1515
#include "lp_data/HighsModelUtils.h"
16+
#include "mip/HighsMipSolver.h" // For getGapString
1617
#include "model/HighsHessianUtils.h"
1718
#include "simplex/HSimplex.h"
1819
#include "util/HighsMatrixUtils.h"
@@ -4254,79 +4255,109 @@ void HighsMipSolverInfo::clear() {
42544255
this->dual_bound = -kHighsInf;
42554256
this->primal_bound = -kHighsInf;
42564257
this->gap = -kHighsInf;
4258+
this->max_submip_level = -1;
42574259
this->node_count = -kHighsSize_tInf;
42584260
this->total_lp_iterations = -kHighsSize_tInf;
42594261
this->primal_dual_integral = -kHighsInf;
42604262
}
42614263

4262-
HighsStatus Highs::mipRaceResults(HighsMipSolverInfo& mip_solver_info,
4263-
const std::vector<HighsMipSolverInfo>& worker_info,
4264-
const std::vector<double>& mip_time) {
4265-
4264+
HighsStatus Highs::mipRaceResults(
4265+
HighsMipSolverInfo& mip_solver_info,
4266+
const std::vector<HighsMipSolverInfo>& worker_info,
4267+
const std::vector<double>& mip_time) {
42664268
const HighsInt mip_race_concurrency = this->options_.mip_race_concurrency;
42674269
HighsInt winning_instance = -1;
42684270
HighsModelStatus winning_model_status = HighsModelStatus::kNotset;
4271+
highsLogUser(options_.log_options, HighsLogType::kInfo,
4272+
"/nMIP race results\n");
42694273
for (HighsInt instance = 0; instance < mip_race_concurrency; instance++) {
42704274
const HighsMipSolverInfo& solver_info =
4271-
instance == 0 ? mip_solver_info : worker_info[instance];
4275+
instance == 0 ? mip_solver_info : worker_info[instance];
42724276
HighsModelStatus instance_model_status = solver_info.modelstatus;
42734277
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());
4278+
" Solver %d has best objective %15.8g, gap %6.2f\% (time "
4279+
"= %6.2f), and status %s\n",
4280+
int(instance), solver_info.solution_objective,
4281+
1e2 * solver_info.gap, mip_time[instance],
4282+
modelStatusToString(instance_model_status).c_str());
42794283
if (instance_model_status != HighsModelStatus::kHighsInterrupt) {
42804284
// Definitive status for this instance, so check compatibility
42814285
// with any current winning model status
42824286
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-
}
4287+
if (winning_model_status != instance_model_status) {
4288+
highsLogUser(options_.log_options, HighsLogType::kError,
4289+
"MIP race: conflict between status \"%s\" for "
4290+
"instance %d and status \"%s\" for instance %d\n",
4291+
modelStatusToString(winning_model_status).c_str(),
4292+
int(winning_instance),
4293+
modelStatusToString(instance_model_status).c_str(),
4294+
int(instance));
4295+
return HighsStatus::kError;
4296+
}
42934297
} else {
4294-
winning_model_status = instance_model_status;
4295-
winning_instance = instance;
4298+
winning_model_status = instance_model_status;
4299+
winning_instance = instance;
42964300
}
42974301
}
42984302
}
42994303
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-
*/
4304+
std::array<char, 128> gapString = getGapString(
4305+
mip_solver_info.gap, mip_solver_info.primal_bound, &options_);
4306+
4307+
bool havesolution = mip_solver_info.solution_objective != kHighsInf;
4308+
bool feasible;
4309+
std::string solutionstatus = "-";
4310+
if (havesolution) {
4311+
feasible =
4312+
mip_solver_info.bound_violation <= options_.mip_feasibility_tolerance &&
4313+
mip_solver_info.integrality_violation <=
4314+
options_.mip_feasibility_tolerance &&
4315+
mip_solver_info.row_violation <= options_.mip_feasibility_tolerance;
4316+
} else {
4317+
feasible = false;
4318+
}
4319+
solutionstatus = feasible ? "feasible" : "infeasible";
4320+
4321+
highsLogUser(options_.log_options, HighsLogType::kInfo, "Solving report\n");
4322+
highsLogUser(options_.log_options, HighsLogType::kInfo,
4323+
" Model %s\n",
4324+
this->model_.lp_.model_name_.c_str());
4325+
highsLogUser(options_.log_options, HighsLogType::kInfo,
4326+
" Status %s\n",
4327+
modelStatusToString(mip_solver_info.modelstatus).c_str());
4328+
highsLogUser(options_.log_options, HighsLogType::kInfo,
4329+
" Primal bound %.12g\n", mip_solver_info.primal_bound);
4330+
highsLogUser(options_.log_options, HighsLogType::kInfo,
4331+
" Dual bound %.12g\n", mip_solver_info.dual_bound);
4332+
highsLogUser(options_.log_options, HighsLogType::kInfo,
4333+
" Gap %s\n", gapString.data());
4334+
highsLogUser(options_.log_options, HighsLogType::kInfo,
4335+
" P-D integral %.12g\n",
4336+
mip_solver_info.primal_dual_integral);
4337+
highsLogUser(options_.log_options, HighsLogType::kInfo,
4338+
" Solution status %s\n", solutionstatus.c_str());
4339+
highsLogUser(options_.log_options, HighsLogType::kInfo,
4340+
" %.12g\n",
4341+
mip_solver_info.solution_objective);
4342+
highsLogUser(options_.log_options, HighsLogType::kInfo,
4343+
" %.12g (bound viol.)\n",
4344+
mip_solver_info.bound_violation);
4345+
highsLogUser(options_.log_options, HighsLogType::kInfo,
4346+
" %.12g (int. viol.)\n",
4347+
mip_solver_info.integrality_violation);
4348+
highsLogUser(options_.log_options, HighsLogType::kInfo,
4349+
" %.12g (row viol.)\n",
4350+
mip_solver_info.row_violation);
4351+
highsLogUser(options_.log_options, HighsLogType::kInfo,
4352+
" Timing %.2f\n", mip_time[winning_instance]);
4353+
highsLogUser(options_.log_options, HighsLogType::kInfo,
4354+
" Max sub-MIP depth %d\n",
4355+
int(mip_solver_info.max_submip_level));
4356+
highsLogUser(options_.log_options, HighsLogType::kInfo,
4357+
" Nodes %llu\n",
4358+
(long long unsigned)(mip_solver_info.node_count));
4359+
highsLogUser(options_.log_options, HighsLogType::kInfo,
4360+
" LP iterations %llu\n",
4361+
(long long unsigned)(mip_solver_info.total_lp_iterations));
43314362
return HighsStatus::kOk;
43324363
}

0 commit comments

Comments
 (0)