Skip to content

Commit 2ef25d0

Browse files
committed
Do not record redundant rows when lifting is inactivated
1 parent 5a20ac8 commit 2ef25d0

File tree

3 files changed

+40
-22
lines changed

3 files changed

+40
-22
lines changed

src/mip/HighsDomain.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1545,7 +1545,8 @@ void HighsDomain::updateActivityLbChange(HighsInt col, double oldbound,
15451545
}
15461546
#endif
15471547

1548-
if (mip->row_lower_[mip->a_matrix_.index_[i]] != -kHighsInf &&
1548+
if (recordRedundantRows_ &&
1549+
mip->row_lower_[mip->a_matrix_.index_[i]] != -kHighsInf &&
15491550
mip->row_upper_[mip->a_matrix_.index_[i]] == kHighsInf)
15501551
updateRedundantRows(mip->a_matrix_.index_[i], HighsInt{1},
15511552
activitymininf_[mip->a_matrix_.index_[i]],
@@ -1596,7 +1597,8 @@ void HighsDomain::updateActivityLbChange(HighsInt col, double oldbound,
15961597
}
15971598
#endif
15981599

1599-
if (mip->row_lower_[mip->a_matrix_.index_[i]] == -kHighsInf &&
1600+
if (recordRedundantRows_ &&
1601+
mip->row_lower_[mip->a_matrix_.index_[i]] == -kHighsInf &&
16001602
mip->row_upper_[mip->a_matrix_.index_[i]] != kHighsInf)
16011603
updateRedundantRows(mip->a_matrix_.index_[i], HighsInt{-1},
16021604
activitymaxinf_[mip->a_matrix_.index_[i]],
@@ -1698,7 +1700,8 @@ void HighsDomain::updateActivityUbChange(HighsInt col, double oldbound,
16981700
}
16991701
#endif
17001702

1701-
if (mip->row_lower_[mip->a_matrix_.index_[i]] == -kHighsInf &&
1703+
if (recordRedundantRows_ &&
1704+
mip->row_lower_[mip->a_matrix_.index_[i]] == -kHighsInf &&
17021705
mip->row_upper_[mip->a_matrix_.index_[i]] != kHighsInf)
17031706
updateRedundantRows(mip->a_matrix_.index_[i], HighsInt{-1},
17041707
activitymaxinf_[mip->a_matrix_.index_[i]],
@@ -1752,7 +1755,8 @@ void HighsDomain::updateActivityUbChange(HighsInt col, double oldbound,
17521755
}
17531756
#endif
17541757

1755-
if (mip->row_lower_[mip->a_matrix_.index_[i]] != -kHighsInf &&
1758+
if (recordRedundantRows_ &&
1759+
mip->row_lower_[mip->a_matrix_.index_[i]] != -kHighsInf &&
17561760
mip->row_upper_[mip->a_matrix_.index_[i]] == kHighsInf)
17571761
updateRedundantRows(mip->a_matrix_.index_[i], HighsInt{1},
17581762
activitymininf_[mip->a_matrix_.index_[i]],

src/mip/HighsDomain.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,7 @@ class HighsDomain {
308308
std::deque<CutpoolPropagation> cutpoolpropagation;
309309
std::deque<ConflictPoolPropagation> conflictPoolPropagation;
310310

311-
bool infeasible_ = 0;
311+
bool infeasible_ = false;
312312
Reason infeasible_reason;
313313
HighsInt infeasible_pos;
314314

@@ -333,6 +333,7 @@ class HighsDomain {
333333
std::vector<HighsInt> colUpperPos_;
334334
std::vector<HighsInt> branchPos_;
335335
HighsHashTable<HighsInt> redundant_rows_;
336+
bool recordRedundantRows_ = false;
336337

337338
public:
338339
std::vector<double> col_lower_;
@@ -364,7 +365,8 @@ class HighsDomain {
364365
colUpperPos_(other.colUpperPos_),
365366
branchPos_(other.branchPos_),
366367
col_lower_(other.col_lower_),
367-
col_upper_(other.col_upper_) {
368+
col_upper_(other.col_upper_),
369+
recordRedundantRows_(other.recordRedundantRows_) {
368370
for (CutpoolPropagation& cutpoolprop : cutpoolpropagation)
369371
cutpoolprop.domain = this;
370372
for (ConflictPoolPropagation& conflictprop : conflictPoolPropagation)
@@ -396,6 +398,7 @@ class HighsDomain {
396398
branchPos_ = other.branchPos_;
397399
col_lower_ = other.col_lower_;
398400
col_upper_ = other.col_upper_;
401+
recordRedundantRows_ = other.recordRedundantRows_;
399402
for (CutpoolPropagation& cutpoolprop : cutpoolpropagation)
400403
cutpoolprop.domain = this;
401404
for (ConflictPoolPropagation& conflictprop : conflictPoolPropagation)
@@ -643,6 +646,8 @@ class HighsDomain {
643646
const HighsHashTable<HighsInt>& getRedundantRows();
644647

645648
double getRedundantRowValue(HighsInt row) const;
649+
650+
void setRecordRedundantRows(bool val) { recordRedundantRows_ = val; };
646651
};
647652

648653
#endif

src/mip/HighsImplications.cpp

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,13 @@
1515
bool HighsImplications::computeImplications(HighsInt col, bool val) {
1616
HighsDomain& globaldomain = mipsolver.mipdata_->domain;
1717
HighsCliqueTable& cliquetable = mipsolver.mipdata_->cliquetable;
18-
globaldomain.clearRedundantRows();
1918
globaldomain.propagate();
20-
if (globaldomain.infeasible() || globaldomain.isFixed(col)) {
21-
globaldomain.clearRedundantRows();
22-
return true;
23-
}
19+
if (globaldomain.infeasible() || globaldomain.isFixed(col)) return true;
20+
21+
// record redundant rows for lifting
22+
assert(globaldomain.getRedundantRows().size() == 0);
23+
if (storeLiftingOpportunity != nullptr)
24+
globaldomain.setRecordRedundantRows(true);
2425

2526
const auto& domchgstack = globaldomain.getDomainChangeStack();
2627
const auto& domchgreason = globaldomain.getDomainChangeReason();
@@ -33,28 +34,36 @@ bool HighsImplications::computeImplications(HighsInt col, bool val) {
3334
else
3435
globaldomain.changeBound(HighsBoundType::kUpper, col, 0);
3536

36-
auto isInfeasible = [&]() {
37+
auto storeLiftingOpportunities = [&](HighsInt col, double val) {
38+
// use callback to store new lifting opportunities; negate column index if
39+
// variable is set to its lower bound
40+
if (storeLiftingOpportunity != nullptr) {
41+
for (const auto& elm : globaldomain.getRedundantRows())
42+
storeLiftingOpportunity(
43+
elm.key(), (val ? 1 : -1) * col,
44+
(val ? -1 : 1) * globaldomain.getRedundantRowValue(elm.key()));
45+
globaldomain.clearRedundantRows();
46+
globaldomain.setRecordRedundantRows(false);
47+
}
48+
};
49+
50+
auto isInfeasible = [&](HighsInt col, double val) {
3751
if (!globaldomain.infeasible()) return false;
3852
globaldomain.backtrack();
3953
globaldomain.clearChangedCols(changedend);
4054
cliquetable.vertexInfeasible(globaldomain, col, val);
41-
globaldomain.clearRedundantRows();
55+
storeLiftingOpportunities(col, val);
4256
return true;
4357
};
4458

45-
if (isInfeasible()) return true;
59+
if (isInfeasible(col, val)) return true;
4660

4761
globaldomain.propagate();
4862

49-
if (isInfeasible()) return true;
63+
if (isInfeasible(col, val)) return true;
5064

51-
// use callback to store new lifting opportunities; negate column index if
52-
// variable is set to its lower bound
53-
if (storeLiftingOpportunity != nullptr)
54-
for (const auto& elm : globaldomain.getRedundantRows())
55-
storeLiftingOpportunity(
56-
elm.key(), (val ? 1 : -1) * col,
57-
(val ? -1 : 1) * globaldomain.getRedundantRowValue(elm.key()));
65+
// inform caller about lifting opportunities
66+
storeLiftingOpportunities(col, val);
5867

5968
HighsInt stackimplicend = domchgstack.size();
6069
numImplications += stackimplicend;

0 commit comments

Comments
 (0)