Skip to content

Commit 3559715

Browse files
committed
Use storeRow and getStoredRow
1 parent 6944afe commit 3559715

File tree

1 file changed

+36
-25
lines changed

1 file changed

+36
-25
lines changed

highs/presolve/HPresolve.cpp

Lines changed: 36 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -4605,10 +4605,23 @@ HPresolve::Result HPresolve::dualFixing(HighsPostsolveStack& postsolve_stack,
46054605
}
46064606
};
46074607

4608+
// lambda for checking whether a row provides an implied bound
4609+
auto hasImpliedBound = [&](HighsInt row, double val) {
4610+
return ((val < 0 && model->row_upper_[row] != kHighsInf) ||
4611+
(val > 0 && model->row_lower_[row] != -kHighsInf));
4612+
};
4613+
46084614
// lambda for variable substitution
46094615
auto substituteCol = [&](HighsInt col, HighsInt row, HighsInt direction,
46104616
double colBound, double otherColBound) {
4611-
for (const auto& rowNz : getRowVector(row)) {
4617+
// some bookkeeping
4618+
HighsInt colNonZerosChecked = 0;
4619+
HighsInt binVarsTried = 0;
4620+
// use storeRow and getStoredRow since getRowVector's rowroot[row] would be
4621+
// overwritten by subsequent findNonZero calls, which would produce
4622+
// undefined behavior
4623+
storeRow(row);
4624+
for (const auto& rowNz : getStoredRow()) {
46124625
// skip column index that was passed to this lambda
46134626
if (rowNz.index() == col) continue;
46144627

@@ -4618,25 +4631,27 @@ HPresolve::Result HPresolve::dualFixing(HighsPostsolveStack& postsolve_stack,
46184631
model->col_upper_[rowNz.index()] != 1.0)
46194632
continue;
46204633

4621-
// check if setting the binary variable to its lower bound bound makes the
4622-
// row redundant
4623-
double rhs = 0.0;
4624-
double residual = 0.0;
4625-
if (model->row_upper_[row] != kHighsInf) {
4626-
rhs = model->row_upper_[row];
4627-
residual = impliedRowBounds.getResidualSumUpperOrig(row, rowNz.index(),
4628-
rowNz.value());
4629-
} else {
4630-
rhs = -model->row_lower_[row];
4631-
residual = -impliedRowBounds.getResidualSumLowerOrig(row, rowNz.index(),
4632-
rowNz.value());
4633-
}
4634-
// skip binary variable if the row has not become redundant
4635-
if (residual > rhs + primal_feastol) continue;
4634+
// skip binary variable if setting it to its lower bound bound does not
4635+
// make the row redundant
4636+
if (model->row_upper_[row] != kHighsInf &&
4637+
impliedRowBounds.getResidualSumUpperOrig(row, rowNz.index(),
4638+
rowNz.value()) >
4639+
model->row_upper_[row] + primal_feastol)
4640+
continue;
4641+
if (model->row_lower_[row] != -kHighsInf &&
4642+
impliedRowBounds.getResidualSumLowerOrig(row, rowNz.index(),
4643+
rowNz.value()) <
4644+
model->row_lower_[row] - primal_feastol)
4645+
continue;
46364646

46374647
// store triplets (row, nonzero, nonzero) in a vector to speed up search
4648+
binVarsTried++;
4649+
nzs.clear();
46384650
if (colsize[col] < colsize[rowNz.index()]) {
46394651
for (const auto& colNz : getColumnVector(col)) {
4652+
// skip non-zeros that do not yield an implied bound
4653+
if (!hasImpliedBound(colNz.index(), direction * colNz.value()))
4654+
continue;
46404655
HighsInt nzPos = findNonzero(colNz.index(), rowNz.index());
46414656
if (nzPos == -1) continue;
46424657
nzs.push_back({colNz.index(), colNz.value(), Avalue[nzPos]});
@@ -4645,22 +4660,19 @@ HPresolve::Result HPresolve::dualFixing(HighsPostsolveStack& postsolve_stack,
46454660
for (const auto& colNz : getColumnVector(rowNz.index())) {
46464661
HighsInt nzPos = findNonzero(colNz.index(), col);
46474662
if (nzPos == -1) continue;
4663+
// skip non-zeros that do not yield an implied bound
4664+
if (!hasImpliedBound(colNz.index(), direction * Avalue[nzPos]))
4665+
continue;
46484666
nzs.push_back({colNz.index(), Avalue[nzPos], colNz.value()});
46494667
}
46504668
}
46514669

4652-
// identify best implied bound
4670+
// store best bound
46534671
double bestBound = -kHighsInf;
46544672
for (const auto& triplet : nzs) {
4655-
// skip rows directly that do not yield an implied bound
4656-
if ((direction * triplet.jval > 0 ||
4657-
model->row_upper_[triplet.row] == kHighsInf) &&
4658-
(direction * triplet.jval < 0 ||
4659-
model->row_lower_[triplet.row] == -kHighsInf))
4660-
continue;
4661-
46624673
// compute implied bound from row given that the binary variable is at
46634674
// its upper bound
4675+
colNonZerosChecked++;
46644676
double rhs = 0.0;
46654677
double residual = 0.0;
46664678
if (direction * triplet.jval < 0) {
@@ -4692,7 +4704,6 @@ HPresolve::Result HPresolve::dualFixing(HighsPostsolveStack& postsolve_stack,
46924704
HPRESOLVE_CHECKED_CALL(checkLimits(postsolve_stack));
46934705
break;
46944706
}
4695-
nzs.clear();
46964707
}
46974708
return Result::kOk;
46984709
};

0 commit comments

Comments
 (0)