Skip to content

Commit a66b641

Browse files
committed
Writing incumbent solutions to shared memory
1 parent e38d32c commit a66b641

File tree

5 files changed

+58
-1
lines changed

5 files changed

+58
-1
lines changed

highs/lp_data/HStruct.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,11 @@ struct MipRaceIncumbent {
7373
};
7474

7575
struct MipRaceRecord {
76+
std::vector<bool> terminate;
7677
std::vector<MipRaceIncumbent> record;
7778
void clear();
7879
void initialise(const HighsInt num_race_instance, const HighsInt num_col);
80+
void report() const;
7981
};
8082

8183
struct HighsBasis {

highs/lp_data/Highs.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4027,7 +4027,17 @@ HighsStatus Highs::callSolveMip() {
40274027
options_.primal_feasibility_tolerance);
40284028
}
40294029
HighsLp& lp = has_semi_variables ? use_lp : model_.lp_;
4030+
//
4031+
// Set up the shared memory for the MIP solver race
4032+
const HighsInt num_num_race_instance = 2;
4033+
MipRaceRecord mip_race_record;
4034+
mip_race_record.initialise(num_num_race_instance, lp.num_col_);
4035+
mip_race_record.report();
40304036
HighsMipSolver solver(callback_, options_, lp, solution_);
4037+
// Initialise the pointer to the shared memory space
4038+
solver.mip_race_record_ = &mip_race_record;
4039+
solver.my_mip_race_instance_ = 0;
4040+
// Run the MIP solver!
40314041
solver.run();
40324042
options_.log_dev_level = log_dev_level;
40334043
// Set the return_status, model status and, for completeness, scaled

highs/mip/HighsMipSolver.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -972,3 +972,9 @@ bool HighsMipSolver::solutionFeasible(const HighsLp* lp,
972972
row_violation <= mip_feasibility_tolerance;
973973
return feasible;
974974
}
975+
976+
void HighsMipSolver::makeMipRaceRecord(const double objective,
977+
const std::vector<double>& solution) {
978+
this->mip_race_record_->record[this->my_mip_race_instance_].write(objective, solution);
979+
this->mip_race_record_->report();
980+
}

highs/mip/HighsMipSolver.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@ class HighsMipSolver {
5555

5656
HighsMipAnalysis analysis_;
5757

58+
HighsInt my_mip_race_instance_;
59+
MipRaceRecord* mip_race_record_;
60+
5861
void run();
5962

6063
HighsInt numCol() const { return model_->num_col_; }
@@ -107,6 +110,7 @@ class HighsMipSolver {
107110
const std::vector<double>* pass_row_value,
108111
double& bound_violation, double& row_violation,
109112
double& integrality_violation, HighsCDouble& obj) const;
113+
void makeMipRaceRecord(const double objective, const std::vector<double>& solution);
110114
};
111115

112116
#endif

highs/mip/HighsMipSolverData.cpp

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -736,6 +736,7 @@ void HighsMipSolverData::runSetup() {
736736
upper_bound -= mipsolver.model_->offset_;
737737

738738
if (mipsolver.solution_objective_ != kHighsInf) {
739+
// Assigning new incumbent
739740
incumbent = postSolveStack.getReducedPrimalSolution(mipsolver.solution_);
740741
// return the objective value in the transformed space
741742
double solobj =
@@ -764,6 +765,10 @@ void HighsMipSolverData::runSetup() {
764765
upper_bound);
765766

766767
double new_upper_limit = computeNewUpperLimit(solobj, 0.0, 0.0);
768+
// Possibly write the improving solution to the shared memory space
769+
if (!mipsolver.submip && mipsolver.mip_race_record_)
770+
mipsolver.makeMipRaceRecord(solobj, incumbent);
771+
767772
saveReportMipSolution(new_upper_limit);
768773
if (new_upper_limit < upper_limit) {
769774
upper_limit = new_upper_limit;
@@ -1399,13 +1404,17 @@ bool HighsMipSolverData::addIncumbent(const std::vector<double>& sol,
13991404
updatePrimalDualIntegral(lower_bound, lower_bound, prev_upper_bound,
14001405
upper_bound);
14011406

1407+
// Assigning new incumbent
14021408
incumbent = sol;
14031409
double new_upper_limit = computeNewUpperLimit(solobj, 0.0, 0.0);
14041410

14051411
if (!is_user_solution && !mipsolver.submip)
14061412
saveReportMipSolution(new_upper_limit);
14071413
if (new_upper_limit < upper_limit) {
14081414
++numImprovingSols;
1415+
// Possibly write the improving solution to the shared memory space
1416+
if (!mipsolver.submip && mipsolver.mip_race_record_)
1417+
mipsolver.makeMipRaceRecord(solobj, incumbent);
14091418
upper_limit = new_upper_limit;
14101419
optimality_limit =
14111420
computeNewUpperLimit(solobj, mipsolver.options_mip_->mip_abs_gap,
@@ -1438,6 +1447,7 @@ bool HighsMipSolverData::addIncumbent(const std::vector<double>& sol,
14381447
printDisplayLine(solution_source);
14391448
}
14401449
} else if (incumbent.empty())
1450+
// Assigning new incumbent
14411451
incumbent = sol;
14421452

14431453
return true;
@@ -2821,13 +2831,38 @@ bool MipRaceIncumbent::readOk(double& objective,
28212831
return this->start_write_incumbent == start_write_incumbent;
28222832
}
28232833

2824-
void MipRaceRecord::clear() { this->record.clear(); }
2834+
void MipRaceRecord::clear() {
2835+
this->terminate.clear();
2836+
this->record.clear();
2837+
}
28252838

28262839
void MipRaceRecord::initialise(const HighsInt num_race_instance,
28272840
const HighsInt num_col) {
28282841
this->clear();
2842+
this->terminate.assign(num_race_instance, false);
28292843
MipRaceIncumbent mip_race_incumbent;
28302844
mip_race_incumbent.initialise(num_col);
28312845
for (HighsInt instance = 0; instance < num_race_instance; instance++)
28322846
this->record.push_back(mip_race_incumbent);
28332847
}
2848+
2849+
void MipRaceRecord::report() const {
2850+
HighsInt num_race_instance = this->terminate.size();
2851+
printf("\nMipRaceRecord:");
2852+
for (HighsInt instance = 0; instance < num_race_instance; instance++)
2853+
printf(" %11d", int(instance));
2854+
printf("\nTerminate: ");
2855+
for (HighsInt instance = 0; instance < num_race_instance; instance++)
2856+
printf(" %11s", this->terminate[instance] ? "T" : "F");
2857+
printf("\nStartWrite: ");
2858+
for (HighsInt instance = 0; instance < num_race_instance; instance++)
2859+
printf(" %11d", this->record[instance].start_write_incumbent);
2860+
printf("\nObjective: ");
2861+
for (HighsInt instance = 0; instance < num_race_instance; instance++)
2862+
printf(" %11.4g", this->record[instance].best_incumbent_objective);
2863+
printf("\nFinishWrite: ");
2864+
for (HighsInt instance = 0; instance < num_race_instance; instance++)
2865+
printf(" %11d", this->record[instance].finish_write_incumbent);
2866+
printf("\n\n");
2867+
}
2868+

0 commit comments

Comments
 (0)