Skip to content

Commit

Permalink
more on HighsRedcostFixing, HighsSeparation, HighsLpRelaxation more …
Browse files Browse the repository at this point in the history
…todos
  • Loading branch information
galabovaa committed Feb 28, 2025
1 parent 90de58f commit b17d159
Show file tree
Hide file tree
Showing 8 changed files with 74 additions and 50 deletions.
1 change: 1 addition & 0 deletions Testing/Temporary/CTestCostData.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
---
4 changes: 2 additions & 2 deletions src/mip/HighsCliqueTable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1900,7 +1900,7 @@ void HighsCliqueTable::cleanupFixed(HighsDomain& globaldom) {
if (nfixings != oldnfixings) propagateAndCleanup(globaldom);
}

HighsInt HighsCliqueTable::getNumImplications(HighsInt col) {
HighsInt HighsCliqueTable::getNumImplications(HighsInt col) const {
// first count all cliques as one implication, so that cliques of size two
// are accounted for already
HighsInt i0 = CliqueVar(col, 0).index();
Expand All @@ -1919,7 +1919,7 @@ HighsInt HighsCliqueTable::getNumImplications(HighsInt col) {
return numimplics;
}

HighsInt HighsCliqueTable::getNumImplications(HighsInt col, bool val) {
HighsInt HighsCliqueTable::getNumImplications(HighsInt col, bool val) const {
HighsInt iVal = CliqueVar(col, val).index();

// each size two clique is one implication
Expand Down
4 changes: 2 additions & 2 deletions src/mip/HighsCliqueTable.h
Original file line number Diff line number Diff line change
Expand Up @@ -286,9 +286,9 @@ class HighsCliqueTable {

void addImplications(HighsDomain& domain, HighsInt col, HighsInt val);

HighsInt getNumImplications(HighsInt col);
HighsInt getNumImplications(HighsInt col) const;

HighsInt getNumImplications(HighsInt col, bool val);
HighsInt getNumImplications(HighsInt col, bool val) const;

void runCliqueMerging(HighsDomain& globaldomain);

Expand Down
9 changes: 6 additions & 3 deletions src/mip/HighsImplications.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,7 @@ bool HighsImplications::runProbing(HighsInt col, HighsInt& numReductions) {
substitutions.push_back(substitution);
colsubstituted[implcol] = true;
++numReductions;
} else {
} else if (mipsolver.mipdata_->workers.size() <= 1) {
double lb = std::min(lbDown, lbUp);
double ub = std::max(ubDown, ubUp);

Expand Down Expand Up @@ -558,7 +558,9 @@ void HighsImplications::separateImpliedBounds(
if (nextCleanupCall < 0) {
// HighsInt oldNumEntries =
// mipsolver.mipdata_->cliquetable.getNumEntries();
mipsolver.mipdata_->cliquetable.runCliqueMerging(globaldomain);
if (mipsolver.mipdata_->workers.size() <= 1)
mipsolver.mipdata_->cliquetable.runCliqueMerging(globaldomain);

// printf("numEntries: %d, beforeMerging: %d\n",
// mipsolver.mipdata_->cliquetable.getNumEntries(), oldNumEntries);
nextCleanupCall =
Expand All @@ -567,7 +569,8 @@ void HighsImplications::separateImpliedBounds(
// printf("nextCleanupCall: %d\n", nextCleanupCall);
}

mipsolver.mipdata_->cliquetable.numNeighbourhoodQueries = oldNumQueries;
if (mipsolver.mipdata_->workers.size() <= 1)
mipsolver.mipdata_->cliquetable.numNeighbourhoodQueries = oldNumQueries;
}

for (std::pair<HighsInt, double> fracint :
Expand Down
1 change: 1 addition & 0 deletions src/mip/HighsMipSolver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,7 @@ void HighsMipSolver::run() {
if (evaluate_node_result == HighsSearch::NodeResult::kSubOptimal) break;

if (search.currentNodePruned()) {
// ig: do we update num_leaves here?
++mipdata_->num_leaves;
search.flushStatistics();
} else {
Expand Down
44 changes: 23 additions & 21 deletions src/mip/HighsRedcostFixing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -150,27 +150,29 @@ void HighsRedcostFixing::propagateRedCost(const HighsMipSolver& mipsolver,
false)) {
bool addedConstraints = false;

HighsInt oldNumConflicts =
mipsolver.mipdata_->conflictPool.getNumConflicts();
for (const HighsDomainChange& domchg : boundChanges) {
if (localdomain.isActive(domchg)) continue;
localdomain.conflictAnalyzeReconvergence(
domchg, inds.data(), vals.data(), inds.size(), rhs,
mipsolver.mipdata_->conflictPool);
}
addedConstraints =
mipsolver.mipdata_->conflictPool.getNumConflicts() != oldNumConflicts;

if (addedConstraints) {
localdomain.propagate();
if (localdomain.infeasible()) return;

boundChanges.erase(
std::remove_if(boundChanges.begin(), boundChanges.end(),
[&](const HighsDomainChange& domchg) {
return localdomain.isActive(domchg);
}),
boundChanges.end());
if (mipsolver.mipdata_->workers.size() <= 1) {
HighsInt oldNumConflicts =
mipsolver.mipdata_->conflictPool.getNumConflicts();
for (const HighsDomainChange& domchg : boundChanges) {
if (localdomain.isActive(domchg)) continue;
localdomain.conflictAnalyzeReconvergence(
domchg, inds.data(), vals.data(), inds.size(), rhs,
mipsolver.mipdata_->conflictPool);
}
addedConstraints =
mipsolver.mipdata_->conflictPool.getNumConflicts() != oldNumConflicts;

if (addedConstraints) {
localdomain.propagate();
if (localdomain.infeasible()) return;

boundChanges.erase(
std::remove_if(boundChanges.begin(), boundChanges.end(),
[&](const HighsDomainChange& domchg) {
return localdomain.isActive(domchg);
}),
boundChanges.end());
}
}

if (!boundChanges.empty()) {
Expand Down
38 changes: 24 additions & 14 deletions src/mip/HighsSeparation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,12 @@ HighsInt HighsSeparation::separationRound(HighsDomain& propdomain,
return numBoundChgs;
};

lp->getMipSolver().timer_.start(implBoundClock);
mipdata.implications.separateImpliedBounds(*lp, lp->getSolution().col_value,
mipdata.cutpool, mipdata.feastol);
lp->getMipSolver().timer_.stop(implBoundClock);
if (&propdomain == &mipdata.domain) {
lp->getMipSolver().timer_.start(implBoundClock);
mipdata.implications.separateImpliedBounds(*lp, lp->getSolution().col_value,
mipdata.cutpool, mipdata.feastol);
lp->getMipSolver().timer_.stop(implBoundClock);
}

HighsInt ncuts = 0;
HighsInt numboundchgs = propagateAndResolve();
Expand All @@ -91,10 +93,12 @@ HighsInt HighsSeparation::separationRound(HighsDomain& propdomain,
else
ncuts += numboundchgs;

lp->getMipSolver().timer_.start(cliqueClock);
mipdata.cliquetable.separateCliques(lp->getMipSolver(), sol.col_value,
mipdata.cutpool, mipdata.feastol);
lp->getMipSolver().timer_.stop(cliqueClock);
if (&propdomain == &mipdata.domain) {
lp->getMipSolver().timer_.start(cliqueClock);
mipdata.cliquetable.separateCliques(lp->getMipSolver(), sol.col_value,
mipdata.cutpool, mipdata.feastol);
lp->getMipSolver().timer_.stop(cliqueClock);
}

numboundchgs = propagateAndResolve();
if (numboundchgs == -1)
Expand All @@ -112,11 +116,13 @@ HighsInt HighsSeparation::separationRound(HighsDomain& propdomain,
}
HighsLpAggregator lpAggregator(*lp);

for (const std::unique_ptr<HighsSeparator>& separator : separators) {
separator->run(*lp, lpAggregator, transLp, mipdata.cutpool);
if (mipdata.domain.infeasible()) {
status = HighsLpRelaxation::Status::kInfeasible;
return 0;
if (&propdomain == &mipdata.domain) {
for (const std::unique_ptr<HighsSeparator>& separator : separators) {
separator->run(*lp, lpAggregator, transLp, mipdata.cutpool);
if (mipdata.domain.infeasible()) {
status = HighsLpRelaxation::Status::kInfeasible;
return 0;
}
}
}

Expand All @@ -126,13 +132,17 @@ HighsInt HighsSeparation::separationRound(HighsDomain& propdomain,
else
ncuts += numboundchgs;

mipdata.cutpool.separate(sol.col_value, propdomain, cutset, mipdata.feastol);
if (&propdomain == &mipdata.domain) {
mipdata.cutpool.separate(sol.col_value, propdomain, cutset, mipdata.feastol);
}

if (cutset.numCuts() > 0) {
ncuts += cutset.numCuts();
lp->addCuts(cutset);
status = lp->resolveLp(&propdomain);
lp->performAging(true);

// only for the master domain.
if (&propdomain == &mipdata.domain && lp->unscaledDualFeasible(status)) {
mipdata.redcostfixing.addRootRedcost(
mipdata.mipsolver, lp->getSolution().col_dual, lp->getObjective());
Expand Down
23 changes: 15 additions & 8 deletions src/mip/HighsTransformedLp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@ HighsTransformedLp::HighsTransformedLp(const HighsLpRelaxation& lprelaxation,
vectorsum.setDimension(numTransformedCol);

for (HighsInt col : mipsolver.mipdata_->continuous_cols) {
mipsolver.mipdata_->implications.cleanupVarbounds(col);
if (mipsolver.mipdata_->workers.size() <= 1)
mipsolver.mipdata_->implications.cleanupVarbounds(col);

if (mipsolver.mipdata_->domain.infeasible()) return;

if (mipsolver.mipdata_->domain.isFixed(col)) continue;
Expand Down Expand Up @@ -63,7 +65,9 @@ HighsTransformedLp::HighsTransformedLp(const HighsLpRelaxation& lprelaxation,
double bestub = mipsolver.mipdata_->domain.col_upper_[col];
double bestlb = mipsolver.mipdata_->domain.col_lower_[col];

mipsolver.mipdata_->implications.cleanupVarbounds(col);
if (mipsolver.mipdata_->workers.size() <= 1)
mipsolver.mipdata_->implications.cleanupVarbounds(col);

if (mipsolver.mipdata_->domain.infeasible()) return;
simpleUbDist[col] = bestub - lpSolution.col_value[col];
if (simpleUbDist[col] <= mipsolver.mipdata_->feastol)
Expand Down Expand Up @@ -185,9 +189,10 @@ bool HighsTransformedLp::transform(std::vector<double>& vals,
bestVub[col].second.maxValue() > ub + mip.mipdata_->feastol) {
bool redundant = false;
bool infeasible = false;
mip.mipdata_->implications.cleanupVub(col, bestVub[col].first,
bestVub[col].second, ub, redundant,
infeasible, false);
if (mip.mipdata_->workers.size() <= 1)
mip.mipdata_->implications.cleanupVub(col, bestVub[col].first,
bestVub[col].second, ub, redundant,
infeasible, false);
}

// the code below uses the difference between the column upper and lower
Expand All @@ -200,9 +205,11 @@ bool HighsTransformedLp::transform(std::vector<double>& vals,
bestVlb[col].second.minValue() < lb - mip.mipdata_->feastol) {
bool redundant = false;
bool infeasible = false;
mip.mipdata_->implications.cleanupVlb(col, bestVlb[col].first,
bestVlb[col].second, lb, redundant,
infeasible, false);

if (mip.mipdata_->workers.size() <= 1)
mip.mipdata_->implications.cleanupVlb(col, bestVlb[col].first,
bestVlb[col].second, lb, redundant,
infeasible, false);
}

// store the old bound type so that we can restore it if the continuous
Expand Down

0 comments on commit b17d159

Please sign in to comment.