Skip to content

Commit cfa1614

Browse files
authored
Merge pull request ERGO-Code#2335 from ERGO-Code/fix-2334
Fix 2334
2 parents 55dd0bf + cc1bdfa commit cfa1614

File tree

1 file changed

+29
-10
lines changed

1 file changed

+29
-10
lines changed

highs/mip/HighsCutGeneration.cpp

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -589,14 +589,15 @@ bool HighsCutGeneration::cmirCutGenerationHeuristic(double minEfficacy,
589589
double oneoveroneminusf0 = 1.0 / (1.0 - f0);
590590
if (oneoveroneminusf0 > maxCMirScale) continue;
591591

592-
double sqrnorm = scale * scale * continuoussqrnorm;
593-
double viol = scale * continuouscontribution * oneoveroneminusf0 - downrhs;
592+
double contscale = scale * oneoveroneminusf0;
593+
double sqrnorm = contscale * contscale * continuoussqrnorm;
594+
double viol = contscale * continuouscontribution - downrhs;
594595

595596
for (HighsInt j : integerinds) {
596597
double scalaj = vals[j] * scale;
597598
double downaj = fast_floor(scalaj + kHighsTiny);
598599
double fj = scalaj - downaj;
599-
double aj = downaj + std::max(0.0, fj - f0);
600+
double aj = downaj + std::max(0.0, (fj - f0) * oneoveroneminusf0);
600601
updateViolationAndNorm(j, aj, viol, sqrnorm);
601602
}
602603

@@ -621,14 +622,15 @@ bool HighsCutGeneration::cmirCutGenerationHeuristic(double minEfficacy,
621622
double oneoveroneminusf0 = 1.0 / (1.0 - f0);
622623
if (oneoveroneminusf0 > maxCMirScale) continue;
623624

624-
double sqrnorm = scale * scale * continuoussqrnorm;
625-
double viol = scale * continuouscontribution * oneoveroneminusf0 - downrhs;
625+
double contscale = scale * oneoveroneminusf0;
626+
double sqrnorm = contscale * contscale * continuoussqrnorm;
627+
double viol = contscale * continuouscontribution - downrhs;
626628

627629
for (HighsInt j : integerinds) {
628630
double scalaj = vals[j] * scale;
629631
double downaj = fast_floor(scalaj + kHighsTiny);
630632
double fj = scalaj - downaj;
631-
double aj = downaj + std::max(0.0, fj - f0);
633+
double aj = downaj + std::max(0.0, (fj - f0) * oneoveroneminusf0);
632634
updateViolationAndNorm(j, aj, viol, sqrnorm);
633635
}
634636

@@ -665,14 +667,15 @@ bool HighsCutGeneration::cmirCutGenerationHeuristic(double minEfficacy,
665667
continue;
666668
}
667669

668-
double sqrnorm = scale * scale * continuoussqrnorm;
669-
double viol = scale * continuouscontribution * oneoveroneminusf0 - downrhs;
670+
double contscale = scale * oneoveroneminusf0;
671+
double sqrnorm = contscale * contscale * continuoussqrnorm;
672+
double viol = contscale * continuouscontribution - downrhs;
670673

671674
for (HighsInt j : integerinds) {
672675
double scalaj = vals[j] * scale;
673676
double downaj = fast_floor(scalaj + kHighsTiny);
674677
double fj = scalaj - downaj;
675-
double aj = downaj + std::max(0.0, fj - f0);
678+
double aj = downaj + std::max(0.0, (fj - f0) * oneoveroneminusf0);
676679
updateViolationAndNorm(j, aj, viol, sqrnorm);
677680
}
678681

@@ -708,12 +711,28 @@ bool HighsCutGeneration::cmirCutGenerationHeuristic(double minEfficacy,
708711
double downaj = floor(double(scalaj + kHighsTiny));
709712
HighsCDouble fj = scalaj - downaj;
710713
HighsCDouble aj = downaj;
711-
if (fj > f0) aj += fj - f0;
714+
if (fj > f0) aj += (fj - f0) * oneoveroneminusf0;
712715

713716
vals[j] = double(aj * bestdelta);
714717
}
715718
}
716719

720+
#ifndef NDEBUG
721+
// Check if the computed cut has the correct efficacy
722+
{
723+
double checkviol = -downrhs * bestdelta;
724+
double checknorm = 0.0;
725+
for (HighsInt j = 0; j != rowlen; ++j) {
726+
if (vals[j] == 0.0) continue;
727+
updateViolationAndNorm(j, vals[j], checkviol, checknorm);
728+
}
729+
double checkefficacy = checkviol / sqrt(checknorm);
730+
// the efficacy can become infinite if the cut 0 <= -1 is derived
731+
assert(fabs(checkefficacy - bestefficacy) < 0.001 ||
732+
fabs(checkefficacy) >= 1e30);
733+
}
734+
#endif
735+
717736
return true;
718737
}
719738

0 commit comments

Comments
 (0)