@@ -1526,7 +1526,55 @@ HPresolve::Result HPresolve::runProbing(HighsPostsolveStack& postsolve_stack) {
15261526
15271527 // store binary variables in vector with their number of implications on
15281528 // other binaries
1529- std::vector<std::tuple<int64_t , HighsInt, HighsInt, HighsInt>> binaries;
1529+ std::vector<std::pair<double , double >> simscore (model->num_col_ );
1530+ for (HighsInt i = 0 ; i != model->num_row_ ; ++i) {
1531+ HighsInt start = mipsolver->mipdata_ ->ARstart_ [i];
1532+ HighsInt end = mipsolver->mipdata_ ->ARstart_ [i + 1 ];
1533+ HighsInt kminusone = end - start - 1 ;
1534+ if (kminusone == 0 ) continue ;
1535+ const double rhs = mipsolver->rowUpper (i);
1536+ const double lhs = mipsolver->rowLower (i);
1537+ const double minactivity = domain.getMinActivity (i);
1538+ const double maxactivity = domain.getMaxActivity (i);
1539+ if (!((minactivity != -kHighsInf && rhs != kHighsInf ) ||
1540+ (maxactivity != kHighsInf && lhs != -kHighsInf )))
1541+ continue ;
1542+ for (HighsInt j = start; j != end; ++j) {
1543+ const HighsInt col = mipsolver->mipdata_ ->ARindex_ [j];
1544+ if (domain.isBinary (col)) {
1545+ double val = mipsolver->mipdata_ ->ARvalue_ [j];
1546+ if (val == 0 ) continue ;
1547+ if (minactivity != -kHighsInf && rhs != kHighsInf ) {
1548+ double row_range = rhs - minactivity;
1549+ if (row_range <= primal_feastol) continue ;
1550+ double rel_range_closed = std::abs (val) / row_range;
1551+ assert (rel_range_closed >= 0 &&
1552+ rel_range_closed <= 1 + primal_feastol);
1553+ if (val > 0 )
1554+ simscore[col].second +=
1555+ std::sqrt (kminusone) * rel_range_closed * rel_range_closed;
1556+ else
1557+ simscore[col].first +=
1558+ std::sqrt (kminusone) * rel_range_closed * rel_range_closed;
1559+ }
1560+ if (maxactivity != kHighsInf && lhs != -kHighsInf ) {
1561+ double row_range = maxactivity - lhs;
1562+ if (row_range <= primal_feastol) continue ;
1563+ double rel_range_closed = std::abs (val) / row_range;
1564+ assert (rel_range_closed >= 0 &&
1565+ rel_range_closed <= 1 + primal_feastol);
1566+ if (val > 0 )
1567+ simscore[col].first +=
1568+ std::sqrt (kminusone) * rel_range_closed * rel_range_closed;
1569+ else
1570+ simscore[col].second +=
1571+ std::sqrt (kminusone) * rel_range_closed * rel_range_closed;
1572+ }
1573+ }
1574+ }
1575+ }
1576+ std::vector<std::tuple<int64_t , HighsInt, double , HighsInt, HighsInt>>
1577+ binaries;
15301578
15311579 if (!mipsolver->mipdata_ ->cliquetable .isFull ()) {
15321580 binaries.reserve (model->num_col_ );
@@ -1538,8 +1586,10 @@ HPresolve::Result HPresolve::runProbing(HighsPostsolveStack& postsolve_stack) {
15381586 binaries.emplace_back (
15391587 -std::min (int64_t {5000 }, int64_t (implicsUp) * implicsDown) /
15401588 (int64_t {1 } + static_cast <int64_t >(numProbes[i])),
1541- -std::min (HighsInt{100 }, implicsUp + implicsDown), random.integer (),
1542- i);
1589+ -std::min (HighsInt{100 }, implicsUp + implicsDown),
1590+ -simscore[i].first * simscore[i].second -
1591+ std::max (simscore[i].first , simscore[i].second ),
1592+ random.integer (), i);
15431593 }
15441594 }
15451595 }
@@ -1606,7 +1656,7 @@ HPresolve::Result HPresolve::runProbing(HighsPostsolveStack& postsolve_stack) {
16061656 }
16071657
16081658 for (const auto & binvar : binaries) {
1609- HighsInt i = std::get<3 >(binvar);
1659+ HighsInt i = std::get<4 >(binvar);
16101660
16111661 if (cliquetable.getSubstitution (i) != nullptr || !domain.isBinary (i))
16121662 continue ;
0 commit comments