Skip to content

Commit 9d0eee8

Browse files
committed
Correctly add incumbent to worker or global
1 parent a53e0da commit 9d0eee8

File tree

2 files changed

+72
-34
lines changed

2 files changed

+72
-34
lines changed

highs/mip/HighsMipSolver.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -355,8 +355,9 @@ void HighsMipSolver::run() {
355355
// TODO: Should we be propagating this first?
356356
if (num_workers > 1) resetGlobalDomain(true);
357357
destroyOldWorkers();
358-
constructAdditionalWorkerData(master_worker);
358+
if (num_workers > 1) constructAdditionalWorkerData(master_worker);
359359
master_worker.upper_bound = mipdata_->upper_bound;
360+
assert(master_worker.solutions_.empty());
360361
master_worker.solutions_.clear();
361362
for (HighsInt i = 1; i != num_workers; ++i) {
362363
createNewWorker(i);

highs/mip/HighsPrimalHeuristics.cpp

Lines changed: 70 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -252,8 +252,8 @@ class HeuristicNeighbourhood {
252252

253253
void HighsPrimalHeuristics::rootReducedCost(HighsMipWorker& worker) {
254254
std::vector<std::pair<double, HighsDomainChange>> lurkingBounds =
255-
mipsolver.mipdata_->redcostfixing.getLurkingBounds(mipsolver,
256-
worker.getGlobalDomain());
255+
mipsolver.mipdata_->redcostfixing.getLurkingBounds(
256+
mipsolver, worker.getGlobalDomain());
257257
if (10 * lurkingBounds.size() < mipsolver.mipdata_->integral_cols.size())
258258
return;
259259
pdqsort(lurkingBounds.begin(), lurkingBounds.end(),
@@ -282,7 +282,8 @@ void HighsPrimalHeuristics::rootReducedCost(HighsMipWorker& worker) {
282282
while (true) {
283283
localdom.propagate();
284284
if (localdom.infeasible()) {
285-
localdom.conflictAnalysis(*worker.conflictpool_, worker.getGlobalDomain());
285+
localdom.conflictAnalysis(*worker.conflictpool_,
286+
worker.getGlobalDomain());
286287

287288
double prev_lower_bound = mipsolver.mipdata_->lower_bound;
288289

@@ -335,10 +336,11 @@ void HighsPrimalHeuristics::RENS(HighsMipWorker& worker,
335336
HighsDomain& localdom = heur.getLocalDomain();
336337
heur.setHeuristic(true);
337338

338-
intcols.erase(
339-
std::remove_if(intcols.begin(), intcols.end(),
340-
[&](HighsInt i) { return worker.getGlobalDomain().isFixed(i); }),
341-
intcols.end());
339+
intcols.erase(std::remove_if(intcols.begin(), intcols.end(),
340+
[&](HighsInt i) {
341+
return worker.getGlobalDomain().isFixed(i);
342+
}),
343+
intcols.end());
342344

343345
HighsLpRelaxation heurlp(*worker.lprelaxation_);
344346
// only use the global upper limit as LP limit so that dual proofs are valid
@@ -418,7 +420,8 @@ void HighsPrimalHeuristics::RENS(HighsMipWorker& worker,
418420
heur.branchUpwards(i, downval, downval - 0.5);
419421
localdom.propagate();
420422
if (localdom.infeasible()) {
421-
localdom.conflictAnalysis(*worker.conflictpool_, worker.getGlobalDomain());
423+
localdom.conflictAnalysis(*worker.conflictpool_,
424+
worker.getGlobalDomain());
422425
break;
423426
}
424427
}
@@ -427,7 +430,8 @@ void HighsPrimalHeuristics::RENS(HighsMipWorker& worker,
427430
heur.branchDownwards(i, upval, upval + 0.5);
428431
localdom.propagate();
429432
if (localdom.infeasible()) {
430-
localdom.conflictAnalysis(*worker.conflictpool_, worker.getGlobalDomain());
433+
localdom.conflictAnalysis(*worker.conflictpool_,
434+
worker.getGlobalDomain());
431435
break;
432436
}
433437
}
@@ -488,7 +492,8 @@ void HighsPrimalHeuristics::RENS(HighsMipWorker& worker,
488492
heur.branchUpwards(fracint.first, fixval, fracint.second);
489493
localdom.propagate();
490494
if (localdom.infeasible()) {
491-
localdom.conflictAnalysis(*worker.conflictpool_, worker.getGlobalDomain());
495+
localdom.conflictAnalysis(*worker.conflictpool_,
496+
worker.getGlobalDomain());
492497
break;
493498
}
494499

@@ -500,7 +505,8 @@ void HighsPrimalHeuristics::RENS(HighsMipWorker& worker,
500505
heur.branchDownwards(fracint.first, fixval, fracint.second);
501506
localdom.propagate();
502507
if (localdom.infeasible()) {
503-
localdom.conflictAnalysis(*worker.conflictpool_, worker.getGlobalDomain());
508+
localdom.conflictAnalysis(*worker.conflictpool_,
509+
worker.getGlobalDomain());
504510
break;
505511
}
506512

@@ -582,10 +588,11 @@ void HighsPrimalHeuristics::RINS(HighsMipWorker& worker,
582588

583589
if (relaxationsol.size() != static_cast<size_t>(mipsolver.numCol())) return;
584590

585-
intcols.erase(
586-
std::remove_if(intcols.begin(), intcols.end(),
587-
[&](HighsInt i) { return worker.getGlobalDomain().isFixed(i); }),
588-
intcols.end());
591+
intcols.erase(std::remove_if(intcols.begin(), intcols.end(),
592+
[&](HighsInt i) {
593+
return worker.getGlobalDomain().isFixed(i);
594+
}),
595+
intcols.end());
589596

590597
HighsPseudocost pscost(mipsolver.mipdata_->pseudocost);
591598

@@ -787,7 +794,8 @@ void HighsPrimalHeuristics::RINS(HighsMipWorker& worker,
787794
++numBranched;
788795
heur.branchUpwards(fracint->first, fixval, fracint->second);
789796
if (localdom.infeasible()) {
790-
localdom.conflictAnalysis(*worker.conflictpool_, worker.getGlobalDomain());
797+
localdom.conflictAnalysis(*worker.conflictpool_,
798+
worker.getGlobalDomain());
791799
break;
792800
}
793801

@@ -798,7 +806,8 @@ void HighsPrimalHeuristics::RINS(HighsMipWorker& worker,
798806
++numBranched;
799807
heur.branchDownwards(fracint->first, fixval, fracint->second);
800808
if (localdom.infeasible()) {
801-
localdom.conflictAnalysis(*worker.conflictpool_, worker.getGlobalDomain());
809+
localdom.conflictAnalysis(*worker.conflictpool_,
810+
worker.getGlobalDomain());
802811
break;
803812
}
804813

@@ -898,12 +907,14 @@ bool HighsPrimalHeuristics::tryRoundedPoint(HighsMipWorker& worker,
898907

899908
localdom.fixCol(col, intval, HighsDomain::Reason::branching());
900909
if (localdom.infeasible()) {
901-
localdom.conflictAnalysis(*worker.conflictpool_, worker.getGlobalDomain());
910+
localdom.conflictAnalysis(*worker.conflictpool_,
911+
worker.getGlobalDomain());
902912
return false;
903913
}
904914
localdom.propagate();
905915
if (localdom.infeasible()) {
906-
localdom.conflictAnalysis(*worker.conflictpool_, worker.getGlobalDomain());
916+
localdom.conflictAnalysis(*worker.conflictpool_,
917+
worker.getGlobalDomain());
907918
return false;
908919
}
909920
}
@@ -933,9 +944,11 @@ bool HighsPrimalHeuristics::tryRoundedPoint(HighsMipWorker& worker,
933944
std::vector<HighsInt> inds;
934945
std::vector<double> vals;
935946
double rhs;
936-
if (lprelax.computeDualInfProof(worker.getGlobalDomain(), inds, vals, rhs)) {
947+
if (lprelax.computeDualInfProof(worker.getGlobalDomain(), inds, vals,
948+
rhs)) {
937949
HighsCutGeneration cutGen(lprelax, *worker.cutpool_);
938-
cutGen.generateConflict(localdom, worker.getGlobalDomain(), inds, vals, rhs);
950+
cutGen.generateConflict(localdom, worker.getGlobalDomain(), inds, vals,
951+
rhs);
939952
}
940953
return false;
941954
} else if (lprelax.unscaledPrimalFeasible(st)) {
@@ -946,7 +959,12 @@ bool HighsPrimalHeuristics::tryRoundedPoint(HighsMipWorker& worker,
946959
return worker.trySolution(lpsol, solution_source);
947960
} else {
948961
// all integer variables are fixed -> add incumbent
949-
worker.addIncumbent(lpsol, lprelax.getObjective(), solution_source);
962+
if (mipsolver.mipdata_->parallelLockActive()) {
963+
worker.addIncumbent(lpsol, lprelax.getObjective(), solution_source);
964+
} else {
965+
mipsolver.mipdata_->addIncumbent(lpsol, lprelax.getObjective(),
966+
solution_source);
967+
}
950968
return true;
951969
}
952970
}
@@ -1031,12 +1049,14 @@ void HighsPrimalHeuristics::randomizedRounding(
10311049

10321050
localdom.fixCol(i, intval, HighsDomain::Reason::branching());
10331051
if (localdom.infeasible()) {
1034-
localdom.conflictAnalysis(*worker.conflictpool_, worker.getGlobalDomain());
1052+
localdom.conflictAnalysis(*worker.conflictpool_,
1053+
worker.getGlobalDomain());
10351054
return;
10361055
}
10371056
localdom.propagate();
10381057
if (localdom.infeasible()) {
1039-
localdom.conflictAnalysis(*worker.conflictpool_, worker.getGlobalDomain());
1058+
localdom.conflictAnalysis(*worker.conflictpool_,
1059+
worker.getGlobalDomain());
10401060
return;
10411061
}
10421062
}
@@ -1068,15 +1088,23 @@ void HighsPrimalHeuristics::randomizedRounding(
10681088
std::vector<HighsInt> inds;
10691089
std::vector<double> vals;
10701090
double rhs;
1071-
if (lprelax.computeDualInfProof(worker.getGlobalDomain(), inds, vals, rhs)) {
1091+
if (lprelax.computeDualInfProof(worker.getGlobalDomain(), inds, vals,
1092+
rhs)) {
10721093
HighsCutGeneration cutGen(lprelax, *worker.cutpool_);
1073-
cutGen.generateConflict(localdom, worker.getGlobalDomain(), inds, vals, rhs);
1094+
cutGen.generateConflict(localdom, worker.getGlobalDomain(), inds, vals,
1095+
rhs);
10741096
}
10751097

10761098
} else if (lprelax.unscaledPrimalFeasible(st))
1077-
worker.addIncumbent(lprelax.getLpSolver().getSolution().col_value,
1078-
lprelax.getObjective(),
1079-
kSolutionSourceRandomizedRounding);
1099+
if (mipsolver.mipdata_->parallelLockActive()) {
1100+
worker.addIncumbent(lprelax.getLpSolver().getSolution().col_value,
1101+
lprelax.getObjective(),
1102+
kSolutionSourceRandomizedRounding);
1103+
} else {
1104+
mipsolver.mipdata_->addIncumbent(
1105+
lprelax.getLpSolver().getSolution().col_value,
1106+
lprelax.getObjective(), kSolutionSourceRandomizedRounding);
1107+
}
10801108
} else {
10811109
worker.trySolution(localdom.col_lower_, kSolutionSourceRandomizedRounding);
10821110
}
@@ -1488,12 +1516,14 @@ void HighsPrimalHeuristics::feasibilityPump(HighsMipWorker& worker) {
14881516
if (!localdom.infeasible()) {
14891517
localdom.fixCol(i, intval, HighsDomain::Reason::branching());
14901518
if (localdom.infeasible()) {
1491-
localdom.conflictAnalysis(*worker.conflictpool_, worker.getGlobalDomain());
1519+
localdom.conflictAnalysis(*worker.conflictpool_,
1520+
worker.getGlobalDomain());
14921521
continue;
14931522
}
14941523
localdom.propagate();
14951524
if (localdom.infeasible()) {
1496-
localdom.conflictAnalysis(*worker.conflictpool_, worker.getGlobalDomain());
1525+
localdom.conflictAnalysis(*worker.conflictpool_,
1526+
worker.getGlobalDomain());
14971527
continue;
14981528
}
14991529
}
@@ -1551,8 +1581,15 @@ void HighsPrimalHeuristics::feasibilityPump(HighsMipWorker& worker) {
15511581

15521582
if (lprelax.getFractionalIntegers().empty() &&
15531583
lprelax.unscaledPrimalFeasible(status))
1554-
worker.addIncumbent(lprelax.getLpSolver().getSolution().col_value,
1555-
lprelax.getObjective(), kSolutionSourceFeasibilityPump);
1584+
if (mipsolver.mipdata_->parallelLockActive()) {
1585+
worker.addIncumbent(lprelax.getLpSolver().getSolution().col_value,
1586+
lprelax.getObjective(),
1587+
kSolutionSourceFeasibilityPump);
1588+
} else {
1589+
mipsolver.mipdata_->addIncumbent(
1590+
lprelax.getLpSolver().getSolution().col_value, lprelax.getObjective(),
1591+
kSolutionSourceFeasibilityPump);
1592+
}
15561593
}
15571594

15581595
void HighsPrimalHeuristics::centralRounding(HighsMipWorker& worker) {

0 commit comments

Comments
 (0)