Skip to content

Commit 6e29317

Browse files
committed
Track reason for precedence constraint
1 parent 7af2517 commit 6e29317

3 files changed

Lines changed: 72 additions & 5 deletions

File tree

highs/mip/HighsImplications.cpp

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -510,6 +510,8 @@ void HighsImplications::rebuild(HighsInt ncols,
510510
substitutions.clear();
511511
precedenceLbs.clear();
512512
precedenceUbs.clear();
513+
precedenceLbSource.clear();
514+
precedenceUbSource.clear();
513515
vubs.clear();
514516
vubs.shrink_to_fit();
515517
vubs.resize(ncols);
@@ -931,14 +933,22 @@ void HighsImplications::applyPrecedenceGraph(
931933
if (boundchg.boundtype == HighsBoundType::kLower) {
932934
const double newLb = domain.col_lower_[boundchg.column] - shift;
933935
if (domain.col_lower_[col] < newLb - domain.feastol()) {
934-
domain.changeBound({newLb, col, HighsBoundType::kLower},
935-
HighsDomain::Reason::unspecified());
936+
const HighsDomain::Reason reason =
937+
precedenceLbSource[i].second ? HighsDomain::Reason::modelRowUpper(
938+
precedenceLbSource[i].first)
939+
: HighsDomain::Reason::modelRowLower(
940+
precedenceLbSource[i].first);
941+
domain.changeBound({newLb, col, HighsBoundType::kLower}, reason);
936942
}
937943
} else if (boundchg.boundtype == HighsBoundType::kUpper) {
938944
const double newUb = domain.col_upper_[boundchg.column] + shift;
939945
if (domain.col_upper_[col] > newUb + domain.feastol()) {
940-
domain.changeBound({newUb, col, HighsBoundType::kUpper},
941-
HighsDomain::Reason::unspecified());
946+
const HighsDomain::Reason reason =
947+
precedenceUbSource[i].second ? HighsDomain::Reason::modelRowUpper(
948+
precedenceUbSource[i].first)
949+
: HighsDomain::Reason::modelRowLower(
950+
precedenceUbSource[i].first);
951+
domain.changeBound({newUb, col, HighsBoundType::kUpper}, reason);
942952
}
943953
}
944954
if (domain.infeasible()) return;

highs/mip/HighsImplications.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ class HighsImplications {
5454
std::vector<HighsHashTree<HighsInt, VarBound>> vlbs;
5555
HighsSparseMatrix precedenceLbs;
5656
HighsSparseMatrix precedenceUbs;
57+
std::vector<std::pair<HighsInt, bool>> precedenceLbSource;
58+
std::vector<std::pair<HighsInt, bool>> precedenceUbSource;
5759

5860
public:
5961
const HighsMipSolver& mipsolver;
@@ -92,6 +94,8 @@ class HighsImplications {
9294
vlbs.resize(numcol);
9395
precedenceLbs.clear();
9496
precedenceUbs.clear();
97+
precedenceLbSource.clear();
98+
precedenceUbSource.clear();
9599
numVarBounds = 0;
96100
maxVarBounds = calcMaxVarBounds(numcol);
97101

@@ -198,7 +202,16 @@ class HighsImplications {
198202
const HighsDomainChange& boundchg) const;
199203

200204
HighsSparseMatrix& getPrecedenceDirectedGraphLb() { return precedenceLbs; }
205+
201206
HighsSparseMatrix& getPrecedenceDirectedGraphUb() { return precedenceUbs; }
207+
208+
std::vector<std::pair<HighsInt, bool>>& getPrecedenceLbSource() {
209+
return precedenceLbSource;
210+
}
211+
212+
std::vector<std::pair<HighsInt, bool>>& getPrecedenceUbSource() {
213+
return precedenceUbSource;
214+
}
202215
};
203216

204217
#endif

highs/presolve/HPresolve.cpp

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1492,6 +1492,8 @@ void HPresolve::createPrecedenceGraph(bool generateUb) const {
14921492
if (precedenceArcs.empty()) {
14931493
precedenceLb.clear();
14941494
implications.getPrecedenceDirectedGraphUb().clear();
1495+
implications.getPrecedenceLbSource().clear();
1496+
implications.getPrecedenceUbSource().clear();
14951497
return;
14961498
}
14971499

@@ -1508,6 +1510,9 @@ void HPresolve::createPrecedenceGraph(bool generateUb) const {
15081510
}
15091511
index.resize(start.back());
15101512
value.resize(start.back());
1513+
std::vector<std::pair<HighsInt, bool>>& precedenceLbReason =
1514+
implications.getPrecedenceLbSource();
1515+
precedenceLbReason.resize(start.back());
15111516
std::vector<HighsInt> pos = start;
15121517
for (const HighsInt row : precedenceArcs) {
15131518
HighsInt x = -1;
@@ -1528,16 +1533,55 @@ void HPresolve::createPrecedenceGraph(bool generateUb) const {
15281533
const HighsInt p = pos[x]++;
15291534
index[p] = y;
15301535
value[p] = model->row_upper_[row] / scale;
1536+
precedenceLbReason[p] = {row, true};
15311537
}
15321538
if (model->row_lower_[row] != -kHighsInf) {
15331539
const HighsInt p = pos[y]++;
15341540
index[p] = x;
15351541
value[p] = -model->row_lower_[row] / scale;
1542+
precedenceLbReason[p] = {row, false};
15361543
}
15371544
}
15381545

15391546
if (generateUb) {
1540-
implications.getPrecedenceDirectedGraphUb().createRowwise(precedenceLb);
1547+
HighsSparseMatrix& precedenceUb =
1548+
implications.getPrecedenceDirectedGraphUb();
1549+
precedenceUb.num_col_ = mipsolver->numCol();
1550+
precedenceUb.num_row_ = mipsolver->numCol();
1551+
precedenceUb.p_end_.clear();
1552+
std::vector<std::pair<HighsInt, bool>>& precedenceUbReason =
1553+
implications.getPrecedenceUbSource();
1554+
precedenceUbReason.resize(start.back());
1555+
1556+
vector<HighsInt>& u_start = precedenceUb.start_;
1557+
vector<HighsInt>& u_index = precedenceUb.index_;
1558+
vector<double>& u_value = precedenceUb.value_;
1559+
1560+
std::vector<HighsInt> u_end;
1561+
u_start.resize(mipsolver->numCol() + 1);
1562+
u_end.assign(mipsolver->numCol(), 0);
1563+
for (HighsInt col = 0; col < mipsolver->numCol(); col++) {
1564+
for (HighsInt i = start[col]; i < start[col + 1]; i++) {
1565+
const HighsInt col2 = index[i];
1566+
u_end[col2]++;
1567+
}
1568+
}
1569+
u_start[0] = 0;
1570+
for (HighsInt col = 0; col < mipsolver->numCol(); col++) {
1571+
u_start[col + 1] = u_start[col] + u_end[col];
1572+
u_end[col] = u_start[col];
1573+
}
1574+
u_index.resize(start.back());
1575+
u_value.resize(start.back());
1576+
for (HighsInt col = 0; col < mipsolver->numCol(); col++) {
1577+
for (HighsInt i = start[col]; i < start[col + 1]; i++) {
1578+
const HighsInt col2 = index[i];
1579+
HighsInt j = u_end[col2]++;
1580+
u_index[j] = col;
1581+
u_value[j] = value[i];
1582+
precedenceUbReason[j] = precedenceLbReason[i];
1583+
}
1584+
}
15411585
}
15421586
}
15431587

0 commit comments

Comments
 (0)