Skip to content

Commit eadde68

Browse files
committed
Add utility for computing locks
1 parent 4c789fd commit eadde68

File tree

2 files changed

+48
-39
lines changed

2 files changed

+48
-39
lines changed

highs/presolve/HPresolve.cpp

Lines changed: 45 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -4468,6 +4468,35 @@ HPresolve::Result HPresolve::detectDominatedCol(
44684468
return Result::kOk;
44694469
}
44704470

4471+
void HPresolve::computeLocks(
4472+
HighsInt col, bool considerObjective,
4473+
std::function<bool(HighsInt, bool)> lockCallback) const {
4474+
// if the callback returns true, we stop examining the locks
4475+
if (considerObjective) {
4476+
// consider objective function
4477+
if (model->col_cost_[col] < 0) {
4478+
// downlock
4479+
if (lockCallback(-1, false)) return;
4480+
} else if (model->col_cost_[col] > 0) {
4481+
// uplock
4482+
if (lockCallback(-1, true)) return;
4483+
}
4484+
}
4485+
4486+
// check coefficients
4487+
for (const auto& nz : getColumnVector(col)) {
4488+
// implied lower bound -> downlock
4489+
if (yieldsImpliedLowerBound(nz.index(), nz.value()) &&
4490+
lockCallback(nz.index(), false))
4491+
break;
4492+
4493+
// implied upper bound -> uplock
4494+
if (yieldsImpliedUpperBound(nz.index(), nz.value()) &&
4495+
lockCallback(nz.index(), true))
4496+
break;
4497+
}
4498+
}
4499+
44714500
HPresolve::Result HPresolve::dualFixing(HighsPostsolveStack& postsolve_stack,
44724501
HighsInt col) {
44734502
// fix variables or tighten bounds using dual arguments
@@ -4479,43 +4508,6 @@ HPresolve::Result HPresolve::dualFixing(HighsPostsolveStack& postsolve_stack,
44794508
// return if variable is already fixed
44804509
if (model->col_lower_[col] == model->col_upper_[col]) return Result::kOk;
44814510

4482-
// lambda for computing locks
4483-
auto computeLocks = [&](HighsInt col, HighsInt& numDownLocks,
4484-
HighsInt& numUpLocks, HighsInt& downLockRow,
4485-
HighsInt& upLockRow) {
4486-
// initialise
4487-
numDownLocks = 0;
4488-
numUpLocks = 0;
4489-
downLockRow = -1;
4490-
upLockRow = -1;
4491-
4492-
// consider objective function
4493-
if (model->col_cost_[col] > 0)
4494-
numUpLocks++;
4495-
else if (model->col_cost_[col] < 0)
4496-
numDownLocks++;
4497-
4498-
// check coefficients
4499-
for (const auto& nz : getColumnVector(col)) {
4500-
// update number of locks
4501-
if (yieldsImpliedLowerBound(nz.index(), nz.value())) {
4502-
// implied lower bound -> downlock
4503-
numDownLocks++;
4504-
downLockRow = nz.index();
4505-
}
4506-
4507-
if (yieldsImpliedUpperBound(nz.index(), nz.value())) {
4508-
// implied upper bound -> uplock
4509-
numUpLocks++;
4510-
upLockRow = nz.index();
4511-
}
4512-
4513-
// stop early if there are locks in both directions, since the variable
4514-
// cannot be fixed in this case.
4515-
if (numDownLocks > 1 && numUpLocks > 1) break;
4516-
}
4517-
};
4518-
45194511
// lambda for variable substitution
45204512
auto substituteCol = [&](HighsInt col, HighsInt row, HighsInt direction,
45214513
double colBound, double otherColBound) {
@@ -4604,12 +4596,26 @@ HPresolve::Result HPresolve::dualFixing(HighsPostsolveStack& postsolve_stack,
46044596
return true;
46054597
};
46064598

4607-
// compute locks
4599+
// lambda callback for lock computation
46084600
HighsInt numDownLocks = 0;
46094601
HighsInt numUpLocks = 0;
46104602
HighsInt downLockRow = -1;
46114603
HighsInt upLockRow = -1;
4612-
computeLocks(col, numDownLocks, numUpLocks, downLockRow, upLockRow);
4604+
auto lockCallback = [&](HighsInt row, bool isUpLock) {
4605+
// count locks and remember row index
4606+
if (isUpLock) {
4607+
numUpLocks++;
4608+
upLockRow = row;
4609+
} else {
4610+
numDownLocks++;
4611+
downLockRow = row;
4612+
}
4613+
// stop early if there are locks in both directions, since the variable
4614+
// cannot be fixed in this case.
4615+
return numDownLocks > 1 && numUpLocks > 1;
4616+
};
4617+
// compute locks
4618+
computeLocks(col, true, lockCallback);
46134619

46144620
// check if variable can be fixed
46154621
if (numDownLocks == 0 || numUpLocks == 0) {

highs/presolve/HPresolve.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,9 @@ class HPresolve {
389389
Result detectDominatedCol(HighsPostsolveStack& postsolve_stack, HighsInt col,
390390
bool handleSingletonRows = true);
391391

392+
void computeLocks(HighsInt col, bool considerObjective,
393+
std::function<bool(HighsInt, bool)> lockCallback) const;
394+
392395
Result dualFixing(HighsPostsolveStack& postsolve_stack, HighsInt col);
393396

394397
Result singletonColStuffing(HighsPostsolveStack& postsolve_stack,

0 commit comments

Comments
 (0)