Skip to content

Commit ffdb2a4

Browse files
committed
Generate flow cover cut only if cmir was successful
1 parent 5e2251c commit ffdb2a4

File tree

1 file changed

+59
-44
lines changed

1 file changed

+59
-44
lines changed

highs/mip/HighsCutGeneration.cpp

Lines changed: 59 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1343,8 +1343,7 @@ bool HighsCutGeneration::generateCut(HighsTransformedLp& transLp,
13431343
}
13441344
#endif
13451345

1346-
// Try to generate a lifted simple generalized flow cover cut
1347-
bool flowCoverSuccess = false;
1346+
// Copy data to later generate lifted simple generalized flow cover cut
13481347
std::vector<double> flowCoverVals;
13491348
std::vector<HighsInt> flowCoverInds;
13501349
double flowCoverRhs = rhs_;
@@ -1354,30 +1353,26 @@ bool HighsCutGeneration::generateCut(HighsTransformedLp& transLp,
13541353
lpRelaxation.getMipSolver().options_mip_->mip_cut_flow_cover) {
13551354
flowCoverVals = vals_;
13561355
flowCoverInds = inds_;
1357-
flowCoverSuccess = tryGenerateFlowCoverCut(
1358-
transLp, flowCoverInds, flowCoverVals, flowCoverRhs, flowCoverEfficacy);
1356+
genFlowCover = true;
1357+
} else {
1358+
genFlowCover = false;
13591359
}
13601360

1361-
bool cmirSuccess = false;
13621361
bool intsPositive = true;
1363-
bool hasUnboundedInts = false;
1364-
bool hasGeneralInts = false;
1365-
bool hasContinuous = false;
1366-
if (!transLp.transform(vals_, upper, solval, inds_, rhs_, intsPositive)) {
1367-
cmirSuccess = false;
1368-
goto postprocess;
1369-
}
1362+
if (!transLp.transform(vals_, upper, solval, inds_, rhs_, intsPositive))
1363+
return false;
13701364

13711365
rowlen = inds_.size();
13721366
this->inds = inds_.data();
13731367
this->vals = vals_.data();
13741368
this->rhs = rhs_;
13751369
complementation.clear();
1370+
bool hasUnboundedInts = false;
1371+
bool hasGeneralInts = false;
1372+
bool hasContinuous = false;
13761373
if (!preprocessBaseInequality(hasUnboundedInts, hasGeneralInts,
1377-
hasContinuous)) {
1378-
cmirSuccess = false;
1379-
goto postprocess;
1380-
}
1374+
hasContinuous))
1375+
return false;
13811376

13821377
// it can happen that there is an unbounded integer variable during the
13831378
// transform call so that the integers are not transformed to positive values.
@@ -1397,13 +1392,9 @@ bool HighsCutGeneration::generateCut(HighsTransformedLp& transLp,
13971392
}
13981393

13991394
// try to generate a cut
1400-
if (!tryGenerateCut(
1401-
inds_, vals_, hasUnboundedInts, hasGeneralInts, hasContinuous,
1402-
std::max(0.9 * flowCoverEfficacy, 10 * feastol),
1403-
onlyInitialCMIRScale)) {
1404-
cmirSuccess = false;
1405-
goto postprocess;
1406-
}
1395+
if (!tryGenerateCut(inds_, vals_, hasUnboundedInts, hasGeneralInts,
1396+
hasContinuous, 10 * feastol, onlyInitialCMIRScale))
1397+
return false;
14071398

14081399
// remove the complementation if exists
14091400
removeComplementation();
@@ -1416,24 +1407,53 @@ bool HighsCutGeneration::generateCut(HighsTransformedLp& transLp,
14161407
vals[i] = vals[rowlen];
14171408
}
14181409
}
1419-
cmirSuccess = true;
1420-
1421-
postprocess:
1422-
if (!cmirSuccess && !flowCoverSuccess) return false;
14231410

14241411
// transform the cut back into the original space, i.e. remove the bound
14251412
// substitution and replace implicit slack variables
1426-
if (cmirSuccess) {
1427-
rhs_ = (double)rhs;
1428-
vals_.resize(rowlen);
1429-
inds_.resize(rowlen);
1430-
if (!transLp.untransform(vals_, inds_, rhs_)) return false;
1431-
} else {
1432-
rhs_ = flowCoverRhs;
1433-
std::swap(vals_, flowCoverVals);
1434-
std::swap(inds_, flowCoverInds);
1435-
integralSupport = false;
1436-
integralCoefficients = false;
1413+
rhs_ = (double)rhs;
1414+
vals_.resize(rowlen);
1415+
inds_.resize(rowlen);
1416+
if (!transLp.untransform(vals_, inds_, rhs_)) return false;
1417+
1418+
const auto& sol = lpRelaxation.getSolution().col_value;
1419+
1420+
// Try to generate a lifted simple generalized flow cover cut
1421+
if (genFlowCover) {
1422+
bool flowCoverSuccess = tryGenerateFlowCoverCut(
1423+
transLp, flowCoverInds, flowCoverVals, flowCoverRhs, flowCoverEfficacy);
1424+
if (flowCoverSuccess) {
1425+
HighsInt rowlen_ = inds_.size();
1426+
double viol = -rhs_;
1427+
double sqrnorm = 0;
1428+
double efficacy = 0;
1429+
for (HighsInt i = 0; i != rowlen_; ++i) {
1430+
HighsInt col = inds_[i];
1431+
viol += vals_[i] * sol[col];
1432+
if (vals_[i] >= 0 &&
1433+
sol[col] <=
1434+
lpRelaxation.getMipSolver().mipdata_->domain.col_lower_[col] +
1435+
lpRelaxation.getMipSolver().mipdata_->feastol)
1436+
continue;
1437+
if (vals_[i] < 0 &&
1438+
sol[col] >=
1439+
lpRelaxation.getMipSolver().mipdata_->domain.col_upper_[col] -
1440+
lpRelaxation.getMipSolver().mipdata_->feastol)
1441+
continue;
1442+
sqrnorm += vals_[i] * vals_[i];
1443+
}
1444+
if (sqrnorm == 0) {
1445+
efficacy = 0;
1446+
} else {
1447+
efficacy = viol / sqrt(sqrnorm);
1448+
}
1449+
if (flowCoverSuccess && flowCoverEfficacy > 1.2 * efficacy) {
1450+
rhs_ = flowCoverRhs;
1451+
std::swap(vals_, flowCoverVals);
1452+
std::swap(inds_, flowCoverInds);
1453+
integralSupport = false;
1454+
integralCoefficients = false;
1455+
}
1456+
}
14371457
}
14381458

14391459
rowlen = inds_.size();
@@ -1455,7 +1475,6 @@ bool HighsCutGeneration::generateCut(HighsTransformedLp& transLp,
14551475

14561476
// finally determine the violation of the cut in the original space
14571477
HighsCDouble violation = -rhs_;
1458-
const auto& sol = lpRelaxation.getSolution().col_value;
14591478
for (HighsInt i = 0; i != rowlen; ++i) violation += sol[inds[i]] * vals_[i];
14601479

14611480
if (violation <= 10 * feastol) return false;
@@ -1973,11 +1992,7 @@ bool HighsCutGeneration::tryGenerateCut(std::vector<HighsInt>& inds_,
19731992
rhs = tmpRhs;
19741993
} else {
19751994
// accept cut and increase minimum efficiency requirement for cmir cut
1976-
if (minEfficacy > 10 * feastol) {
1977-
minMirEfficacy = std::max(minEfficacy, efficacy + 10 * feastol);
1978-
} else {
1979-
minMirEfficacy += efficacy;
1980-
}
1995+
minMirEfficacy += efficacy;
19811996
std::swap(tmpRhs, rhs);
19821997
}
19831998
}

0 commit comments

Comments
 (0)