Skip to content

Commit 13a5edf

Browse files
committed
Add an additional complementation attempt for strongcg
1 parent bdfe69d commit 13a5edf

File tree

1 file changed

+64
-10
lines changed

1 file changed

+64
-10
lines changed

highs/mip/HighsCutGeneration.cpp

Lines changed: 64 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -549,6 +549,7 @@ bool HighsCutGeneration::cmirCutGenerationHeuristic(double minEfficacy,
549549
// Positive coefficient values later set to 0 so have no contribution
550550
updateViolationAndNorm(i, vals[i], continuouscontribution,
551551
continuoussqrnorm);
552+
// StrongCG cannot be computed when negative coefficients for cont exist
552553
strongcg = false;
553554
}
554555
}
@@ -704,11 +705,10 @@ bool HighsCutGeneration::cmirCutGenerationHeuristic(double minEfficacy,
704705
double f0 = scalrhs - downrhs;
705706
double oneoveroneminusf0 = 1.0 / (1.0 - f0);
706707
// Skip numerically troublesome cuts
707-
double oneoverf0 = 1 / f0;
708-
double k = fast_ceil(oneoverf0) - 1;
709-
if (oneoverf0 - k < 1e-3 || oneoverf0 - k > 1 - 1e-3) {
708+
if (fractionality(1 / f0) < 1e-3) {
710709
strongcg = false;
711710
} else {
711+
double k = fast_ceil(1 / f0) - 1;
712712
// All coefficients of continuous variables are 0 in strong CG cut
713713
double sqrnorm = 0;
714714
double viol = -downrhs;
@@ -717,20 +717,18 @@ bool HighsCutGeneration::cmirCutGenerationHeuristic(double minEfficacy,
717717
double scalaj = vals[j] * scale;
718718
double downaj = fast_floor(scalaj + kHighsTiny);
719719
double fj = scalaj - downaj;
720-
if (fj <= f0 + feastol) {
721-
double aj = downaj;
722-
updateViolationAndNorm(j, aj, viol, sqrnorm);
723-
} else {
720+
double aj = downaj;
721+
if (fj >= f0 + 10 * feastol) {
724722
double pj = fast_ceil(k * (fj - f0) * oneoveroneminusf0 - 1e-4);
725-
double aj = downaj + (pj / (k + 1));
726-
updateViolationAndNorm(j, aj, viol, sqrnorm);
723+
aj += pj / (k + 1);
727724
}
725+
updateViolationAndNorm(j, aj, viol, sqrnorm);
728726
}
729727
if (sqrnorm <= kHighsTiny) {
730728
strongcg = false;
731729
} else {
732730
double efficacy = viol / sqrt(sqrnorm);
733-
// Use the strong CG cut instead of the CMIR if efficacy is larger
731+
// Use the strongCG cut instead of the CMIR if efficacy is larger
734732
if (efficacy < bestefficacy + epsilon) {
735733
strongcg = false;
736734
} else {
@@ -740,6 +738,62 @@ bool HighsCutGeneration::cmirCutGenerationHeuristic(double minEfficacy,
740738
}
741739
}
742740

741+
if (strongcg) {
742+
// try to flip complementation of integers to increase efficacy
743+
double delta = bestdelta;
744+
double scale = 1.0 / delta;
745+
for (HighsInt i : integerinds) {
746+
if (upper[i] == kHighsInf) continue;
747+
if (solval[i] <= feastol) continue;
748+
749+
flipComplementation(i);
750+
751+
double scalrhs = double(rhs) * scale;
752+
double downrhs = fast_floor(scalrhs);
753+
754+
double f0 = scalrhs - downrhs;
755+
if (f0 < f0min || f0 > f0max) {
756+
flipComplementation(i);
757+
continue;
758+
}
759+
760+
double oneoveroneminusf0 = 1.0 / (1.0 - f0);
761+
if (oneoveroneminusf0 > maxCMirScale) {
762+
flipComplementation(i);
763+
continue;
764+
}
765+
766+
if (fractionality(1 / f0) < 1e-3) {
767+
flipComplementation(i);
768+
continue;
769+
}
770+
771+
double k = fast_ceil(1 / f0) - 1;
772+
773+
double sqrnorm = 0;
774+
double viol = -downrhs;
775+
776+
for (HighsInt j : integerinds) {
777+
double scalaj = vals[j] * scale;
778+
double downaj = fast_floor(scalaj + kHighsTiny);
779+
double fj = scalaj - downaj;
780+
double aj = downaj;
781+
if (fj - f0 >= 10 * feastol) {
782+
double pj = fast_ceil(k * (fj - f0) * oneoveroneminusf0 - 1e-4);
783+
aj += (pj / (k + 1));
784+
}
785+
updateViolationAndNorm(j, aj, viol, sqrnorm);
786+
}
787+
788+
double efficacy = viol / sqrt(sqrnorm);
789+
if (efficacy > bestefficacy) {
790+
bestefficacy = efficacy;
791+
} else {
792+
flipComplementation(i);
793+
}
794+
}
795+
}
796+
743797
HighsCDouble scale = 1.0 / HighsCDouble(bestdelta);
744798
HighsCDouble scalrhs = rhs * scale;
745799
double downrhs = floor(double(scalrhs));

0 commit comments

Comments
 (0)