Skip to content

Commit a5dc18a

Browse files
committed
Fix error with complementation
1 parent e64f692 commit a5dc18a

2 files changed

Lines changed: 64 additions & 71 deletions

File tree

highs/mip/HighsCutGeneration.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -682,7 +682,7 @@ bool HighsCutGeneration::separateLiftedFlowCover() {
682682
vals[rowlen] = -liftedbincoef;
683683
inds[rowlen] = snfr.origBinCols[i];
684684
if (snfr.complementation[i]) {
685-
tmpRhs -= -liftedbincoef;
685+
tmpRhs -= vals[rowlen];
686686
vals[rowlen] = -vals[rowlen];
687687
}
688688
rowlen++;

highs/mip/HighsTransformedLp.cpp

Lines changed: 63 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -665,62 +665,57 @@ bool HighsTransformedLp::transformSNFRelaxation(
665665
return false;
666666
}
667667
}
668+
668669
const double sign = coef >= 0 ? 1 : -1;
669-
if (complement) origbincoef = -origbincoef;
670+
double complorigbincoef = complement ? -origbincoef : origbincoef;
671+
double vbconstant = complement ? vb.constant + vb.coef : vb.constant;
672+
double vbcoef = complement ? -vb.coef : vb.coef;
673+
double val;
674+
670675
if (isVub) {
671-
double val = complement ? sign * (coef * -vb.coef + origbincoef)
672-
: sign * (coef * vb.coef + origbincoef);
676+
val = sign * (coef * vbcoef + (sign >= 0 ? std::min(0.0, complorigbincoef) : std::max(0.0, complorigbincoef)));
673677
if (val > kHighsInf) return false;
674678
if (val < 0) {
675-
val = complement ? sign * (coef * -vb.coef) : sign * (coef * vb.coef);
679+
val = sign * (coef * vbcoef);
676680
if (val < 0) return false;
677681
inclbincoef = false;
678682
}
679683
if (inclbincoef) {
680-
val = complement
681-
? sign * (coef * (lb - (vb.constant + vb.coef)) + origbincoef)
682-
: sign * (coef * (lb - vb.constant) + origbincoef);
684+
val = sign * (coef * (lb - vbconstant) + (sign >= 0 ? std::min(0.0, origbincoef) : std::max(0.0, origbincoef)));
683685
if (val < 0) {
684-
val = complement ? sign * (coef * (lb - (vb.constant + vb.coef)))
685-
: sign * (coef * (lb - vb.constant));
686+
val = sign * (coef * (lb - vbconstant));
686687
if (val < 0) return false;
687688
inclbincoef = false;
688-
val = complement ? sign * (coef * -vb.coef) : sign * (coef * vb.coef);
689+
val = sign * (coef * vbcoef);
689690
if (val < 0) return false;
690691
}
691692
} else {
692-
val = complement ? sign * (coef * (lb - (vb.constant + vb.coef)))
693-
: sign * (coef * (lb - vb.constant));
693+
val = sign * (coef * (lb - vbconstant));
694694
if (val < 0) return false;
695695
}
696696
} else {
697-
double val = complement ? sign * ((coef * -vb.coef) + origbincoef)
698-
: sign * ((coef * vb.coef) + origbincoef);
697+
val = sign * (coef * vbcoef + (sign >= 0 ? std::max(0.0, complorigbincoef) : std::min(0.0, complorigbincoef)));
699698
if (-val > kHighsInf) return false;
700699
if (val > 0) {
701-
val = complement ? sign * (coef * -vb.coef) : sign * (coef * vb.coef);
700+
val = sign * (coef * vbcoef);
702701
if (val > 0) return false;
703702
inclbincoef = false;
704703
}
705704
if (inclbincoef) {
706-
val =
707-
complement
708-
? sign * ((coef * (ub - (vb.constant + vb.coef))) + origbincoef)
709-
: sign * ((coef * (ub - vb.constant)) + origbincoef);
705+
val = sign * (coef * (ub - vbconstant) + (sign >= 0 ? std::max(0.0, origbincoef) : std::min(0.0, origbincoef)));
710706
if (val > 0) {
711-
val = complement ? sign * (coef * (ub - (vb.constant + vb.coef)))
712-
: sign * (coef * (ub - vb.constant));
707+
val = sign * (coef * (ub - vbconstant));
713708
if (val > 0) return false;
714709
inclbincoef = false;
715-
val = complement ? sign * (coef * -vb.coef) : sign * (coef * vb.coef);
710+
val = sign * (coef * vbcoef);
716711
if (val > 0) return false;
717712
}
718713
} else {
719-
val = complement ? sign * (coef * (ub - (vb.constant + vb.coef)))
720-
: sign * (coef * (ub - vb.constant));
714+
val = sign * (coef * (ub - vbconstant));
721715
if (val > 0) return false;
722716
}
723717
}
718+
724719
return true;
725720
};
726721

@@ -864,9 +859,13 @@ bool HighsTransformedLp::transformSNFRelaxation(
864859
boundType = BoundType::kSimpleUb;
865860
}
866861

862+
double vbconstant;
867863
double vbcoef;
868864
double substsolval;
865+
double aggrvbcoef;
869866
double aggrconstant;
867+
double binsolval;
868+
double bincoef;
870869
HighsInt vbcol;
871870
switch (boundType) {
872871
case BoundType::kSimpleLb:
@@ -876,13 +875,13 @@ bool HighsTransformedLp::transformSNFRelaxation(
876875
// rhs -= a_j * u_j
877876
substsolval = static_cast<double>(
878877
vals[i] * (HighsCDouble(getLpSolution(col)) - ub));
879-
vbcoef = static_cast<double>(vals[i] * (HighsCDouble(ub) - lb));
878+
aggrvbcoef = static_cast<double>(vals[i] * (HighsCDouble(ub) - lb));
880879
aggrconstant = static_cast<double>(HighsCDouble(vals[i]) * ub);
881880
if (vals[i] >= 0) {
882-
addSNFRentry(-1, col, 1.0, -substsolval, -1, vbcoef, aggrconstant,
881+
addSNFRentry(-1, col, 1.0, -substsolval, -1, aggrvbcoef, aggrconstant,
883882
0, -vals[i], false);
884883
} else {
885-
addSNFRentry(-1, col, 1, substsolval, 1, -vbcoef, -aggrconstant, 0,
884+
addSNFRentry(-1, col, 1, substsolval, 1, -aggrvbcoef, -aggrconstant, 0,
886885
vals[i], false);
887886
}
888887
tmpSnfrRhs -= aggrconstant;
@@ -895,13 +894,13 @@ bool HighsTransformedLp::transformSNFRelaxation(
895894
// rhs -= a_j * l_j
896895
substsolval = static_cast<double>(
897896
vals[i] * (HighsCDouble(getLpSolution(col)) - lb));
898-
vbcoef = static_cast<double>(vals[i] * (HighsCDouble(ub) - lb));
897+
aggrvbcoef = static_cast<double>(vals[i] * (HighsCDouble(ub) - lb));
899898
aggrconstant = static_cast<double>(HighsCDouble(vals[i]) * lb);
900899
if (vals[i] >= 0) {
901-
addSNFRentry(-1, col, 1, substsolval, 1, vbcoef, -aggrconstant, 0,
900+
addSNFRentry(-1, col, 1, substsolval, 1, aggrvbcoef, -aggrconstant, 0,
902901
vals[i], false);
903902
} else {
904-
addSNFRentry(-1, col, 1, -substsolval, -1, -vbcoef, aggrconstant, 0,
903+
addSNFRentry(-1, col, 1, -substsolval, -1, -aggrvbcoef, aggrconstant, 0,
905904
-vals[i], false);
906905
}
907906
tmpSnfrRhs -= aggrconstant;
@@ -915,34 +914,31 @@ bool HighsTransformedLp::transformSNFRelaxation(
915914
// 0 <= y'_j <= (a_j l'_j + c_j)x_j
916915
// rhs -= a_j * d_j
917916
vbcol = bestVlb[col].first;
917+
vbconstant = bestVlb[col].second.constant + (complementvlb ? bestVlb[col].second.coef : 0);
918+
vbcoef = complementvlb ? -bestVlb[col].second.coef : bestVlb[col].second.coef;
919+
bincoef = inclbincolvlb ? complementvlb ? -vectorsum.getValue(vbcol) : vectorsum.getValue(vbcol) : 0;
920+
binsolval = lpSolution.col_value[vbcol];
921+
if (complementvlb) binsolval = 1 - binsolval;
918922
substsolval =
919923
static_cast<double>(vals[i] * (HighsCDouble(getLpSolution(col)) -
920-
bestVlb[col].second.constant) +
921-
(HighsCDouble(lpSolution.col_value[vbcol]) *
922-
vectorsum.getValue(vbcol)));
923-
vbcoef = static_cast<double>(
924-
HighsCDouble(vals[i]) * (complementvlb
925-
? -bestVlb[col].second.coef
926-
: bestVlb[col].second.coef) +
927-
(inclbincolvlb ? (complementvlb ? -vectorsum.getValue(vbcol) : vectorsum.getValue(vbcol)) : 0));
924+
vbconstant) +
925+
(HighsCDouble(binsolval) *
926+
bincoef));
927+
aggrvbcoef = static_cast<double>(
928+
HighsCDouble(vals[i]) * vbcoef + bincoef);
928929
aggrconstant = static_cast<double>(
929-
HighsCDouble(vals[i]) *
930-
(complementvlb
931-
? bestVlb[col].second.constant + bestVlb[col].second.coef
932-
: bestVlb[col].second.constant)) + (complementvlb && inclbincolvlb ? vectorsum.getValue(vbcol) : 0);
930+
HighsCDouble(vals[i]) * vbconstant + (complementvlb && inclbincolvlb ? vectorsum.getValue(vbcol) : 0));
933931
if (vals[i] >= 0) {
934932
addSNFRentry(vbcol, col,
935-
complementvlb ? 1 - lpSolution.col_value[vbcol]
936-
: lpSolution.col_value[vbcol],
937-
-substsolval, -1, -vbcoef, aggrconstant,
938-
inclbincolvlb ? (complementvlb ? vectorsum.getValue(vbcol) : -vectorsum.getValue(vbcol)) : 0,
933+
binsolval,
934+
-substsolval, -1, -aggrvbcoef, aggrconstant,
935+
-bincoef,
939936
-vals[i], complementvlb);
940937
} else {
941938
addSNFRentry(vbcol, col,
942-
complementvlb ? 1 - lpSolution.col_value[vbcol]
943-
: lpSolution.col_value[vbcol],
944-
substsolval, 1, vbcoef, -aggrconstant,
945-
inclbincolvlb ? (complementvlb ? -vectorsum.getValue(vbcol) : vectorsum.getValue(vbcol)) : 0, vals[i],
939+
binsolval,
940+
substsolval, 1, aggrvbcoef, -aggrconstant,
941+
bincoef, vals[i],
946942
complementvlb);
947943
}
948944
if (inclbincolvlb) vectorsum.values[vbcol] = 0;
@@ -957,34 +953,31 @@ bool HighsTransformedLp::transformSNFRelaxation(
957953
// 0 <= y'_j <= -(a_j u'_j + c_j)x_j
958954
// rhs -= a_j * d_j
959955
vbcol = bestVub[col].first;
956+
vbconstant = bestVub[col].second.constant + (complementvub ? bestVub[col].second.coef : 0);
957+
vbcoef = complementvub ? -bestVub[col].second.coef : bestVub[col].second.coef;
958+
bincoef = inclbincolvub ? complementvub ? -vectorsum.getValue(vbcol) : vectorsum.getValue(vbcol) : 0;
959+
binsolval = lpSolution.col_value[vbcol];
960+
if (complementvub) binsolval = 1 - binsolval;
960961
substsolval =
961962
static_cast<double>(vals[i] * (HighsCDouble(getLpSolution(col)) -
962-
bestVub[col].second.constant) +
963-
(HighsCDouble(lpSolution.col_value[vbcol]) *
964-
vectorsum.getValue(vbcol)));
965-
vbcoef = static_cast<double>(
966-
HighsCDouble(vals[i]) * (complementvub
967-
? -bestVub[col].second.coef
968-
: bestVub[col].second.coef) +
969-
(inclbincolvub ? (complementvub ? -vectorsum.getValue(vbcol) : vectorsum.getValue(vbcol)) : 0));
963+
vbconstant) +
964+
(HighsCDouble(binsolval) *
965+
bincoef));
966+
aggrvbcoef = static_cast<double>(
967+
HighsCDouble(vals[i]) * vbcoef + bincoef);
970968
aggrconstant = static_cast<double>(
971-
HighsCDouble(vals[i]) *
972-
(complementvub
973-
? bestVub[col].second.constant + bestVub[col].second.coef
974-
: bestVub[col].second.constant)) + (complementvub && inclbincolvub ? vectorsum.getValue(vbcol) : 0);
969+
HighsCDouble(vals[i]) * vbconstant + (complementvub && inclbincolvub ? vectorsum.getValue(vbcol) : 0));
975970
if (vals[i] >= 0) {
976971
addSNFRentry(vbcol, col,
977-
complementvub ? 1 - lpSolution.col_value[vbcol]
978-
: lpSolution.col_value[vbcol],
979-
substsolval, 1, vbcoef, -aggrconstant,
980-
inclbincolvub ? (complementvub ? -vectorsum.getValue(vbcol) : vectorsum.getValue(vbcol)) : 0, vals[i],
972+
binsolval,
973+
substsolval, 1, aggrvbcoef, -aggrconstant,
974+
bincoef, vals[i],
981975
complementvub);
982976
} else {
983977
addSNFRentry(vbcol, col,
984-
complementvub ? 1 - lpSolution.col_value[vbcol]
985-
: lpSolution.col_value[vbcol],
986-
-substsolval, -1, -vbcoef, aggrconstant,
987-
inclbincolvub ? (complementvub ? vectorsum.getValue(vbcol) : -vectorsum.getValue(vbcol)) : 0,
978+
binsolval,
979+
-substsolval, -1, -aggrvbcoef, aggrconstant,
980+
-bincoef,
988981
-vals[i], complementvub);
989982
}
990983
if (inclbincolvub) vectorsum.values[vbcol] = 0;

0 commit comments

Comments
 (0)