Skip to content

Commit 786c616

Browse files
authored
Merge pull request ERGO-Code#2321 from fwesselm/coeffStren
Fix 1517
2 parents c7e48d5 + 3c7917b commit 786c616

File tree

3 files changed

+224
-327
lines changed

3 files changed

+224
-327
lines changed

highs/presolve/HPresolve.cpp

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3774,28 +3774,41 @@ HPresolve::Result HPresolve::rowPresolve(HighsPostsolveStack& postsolve_stack,
37743774
}
37753775

37763776
auto strengthenCoefs = [&](HighsCDouble& rhs, HighsInt direction,
3777-
double maxCoefValue) {
3777+
HighsCDouble maxAbsCoefValue) {
37783778
// iterate over non-zero positions instead of iterating over the
37793779
// HighsMatrixSlice (provided by HPresolve::getStoredRow) because the
37803780
// latter contains pointers to Acol and Avalue that may be invalidated
37813781
// if these vectors are reallocated (see std::vector::push_back
37823782
// performed in HPresolve::addToMatrix).
37833783
for (HighsInt rowiter : rowpositions) {
3784+
// max. absolute coefficient should not be negative
3785+
assert(maxAbsCoefValue >= 0);
3786+
37843787
// get column index and coefficient
37853788
HighsInt col = Acol[rowiter];
3786-
double val = Avalue[rowiter];
3789+
double val = direction * Avalue[rowiter];
3790+
3791+
// get lower and upper bounds
3792+
double col_lower = impliedRowBounds.getImplVarLower(row, col);
3793+
double col_upper = impliedRowBounds.getImplVarUpper(row, col);
37873794

37883795
// skip continuous variables
37893796
if (model->integrality_[col] == HighsVarType::kContinuous) continue;
37903797

3791-
if (direction * val > maxCoefValue + primal_feastol) {
3792-
double delta = direction * maxCoefValue - val;
3793-
addToMatrix(row, col, delta);
3794-
rhs += delta * model->col_upper_[col];
3795-
} else if (direction * val < -maxCoefValue - primal_feastol) {
3796-
double delta = -direction * maxCoefValue - val;
3797-
addToMatrix(row, col, delta);
3798-
rhs += delta * model->col_lower_[col];
3798+
if (val > maxAbsCoefValue + primal_feastol) {
3799+
assert(col_upper != kHighsInf);
3800+
// new matrix coefficient is direction * maxAbsCoefValue; subtract
3801+
// existing matrix coefficient to get delta
3802+
HighsCDouble delta = direction * (maxAbsCoefValue - val);
3803+
addToMatrix(row, col, static_cast<double>(delta));
3804+
rhs += delta * col_upper;
3805+
} else if (val < -maxAbsCoefValue - primal_feastol) {
3806+
assert(col_lower != -kHighsInf);
3807+
// new matrix coefficient is (-direction) * maxAbsCoefValue;
3808+
// subtract existing matrix coefficient to get delta
3809+
HighsCDouble delta = -direction * (maxAbsCoefValue + val);
3810+
addToMatrix(row, col, static_cast<double>(delta));
3811+
rhs += delta * col_lower;
37993812
}
38003813
}
38013814
};
@@ -3805,7 +3818,8 @@ HPresolve::Result HPresolve::rowPresolve(HighsPostsolveStack& postsolve_stack,
38053818
// <= constraint: try to strengthen coefficients
38063819
HighsCDouble rhs = model->row_upper_[row];
38073820
strengthenCoefs(rhs, HighsInt{1},
3808-
impliedRowUpper - model->row_upper_[row]);
3821+
static_cast<HighsCDouble>(impliedRowUpper) -
3822+
model->row_upper_[row]);
38093823
model->row_upper_[row] = static_cast<double>(rhs);
38103824
}
38113825

@@ -3814,7 +3828,8 @@ HPresolve::Result HPresolve::rowPresolve(HighsPostsolveStack& postsolve_stack,
38143828
// >= constraint: try to strengthen coefficients
38153829
HighsCDouble rhs = model->row_lower_[row];
38163830
strengthenCoefs(rhs, HighsInt{-1},
3817-
model->row_lower_[row] - impliedRowLower);
3831+
model->row_lower_[row] -
3832+
static_cast<HighsCDouble>(impliedRowLower));
38183833
model->row_lower_[row] = static_cast<double>(rhs);
38193834
}
38203835
}

0 commit comments

Comments
 (0)