Skip to content

Commit 45df9ca

Browse files
committed
Allow vbcol to be used mult. times
1 parent f8e1982 commit 45df9ca

File tree

3 files changed

+30
-56
lines changed

3 files changed

+30
-56
lines changed

highs/mip/HighsCutGeneration.cpp

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -725,13 +725,6 @@ bool HighsCutGeneration::separateLiftedFlowCover() {
725725
}
726726
}
727727

728-
#ifndef NDEBUG
729-
// TODO: Remove this if algorithm changes to allow multiple bin col usages
730-
for (HighsInt i = 0; i < rowlen; i++) {
731-
for (HighsInt j = i + 1; j < rowlen; j++) assert(inds[i] != inds[j]);
732-
}
733-
#endif
734-
735728
rhs = static_cast<double>(tmpRhs);
736729
return true;
737730
}
@@ -1568,17 +1561,6 @@ bool HighsCutGeneration::generateConflict(HighsDomain& localdomain,
15681561
}
15691562

15701563
void HighsCutGeneration::initSNFRelaxation() {
1571-
HighsInt numTransformedCol = lpRelaxation.numCols() + lpRelaxation.numRows();
1572-
if (static_cast<HighsInt>(snfr.binColUsed.size()) < numTransformedCol) {
1573-
snfr.binColUsed.resize(numTransformedCol);
1574-
snfr.origBinColCoef.resize(numTransformedCol);
1575-
}
1576-
for (HighsInt i = 0; i != static_cast<HighsInt>(snfr.binColUsed.size());
1577-
++i) {
1578-
snfr.binColUsed[i] = false;
1579-
snfr.origBinColCoef[i] = 0;
1580-
}
1581-
15821564
if (static_cast<HighsInt>(snfr.coef.size()) < rowlen) {
15831565
snfr.origBinCols.resize(rowlen);
15841566
snfr.origContCols.resize(rowlen);

highs/mip/HighsCutGeneration.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -119,9 +119,6 @@ class HighsCutGeneration {
119119

120120
/// Single Node Flow Relaxation for flow cover cuts
121121
struct SNFRelaxation {
122-
std::vector<bool> binColUsed; // has col been used in a vub
123-
std::vector<double> origBinColCoef; // original bin col coef
124-
125122
HighsInt numNnzs; // number of nonzeros
126123
std::vector<HighsInt> coef; // coefficients of cols in SNFR
127124
std::vector<double> vubCoef; // coefficients in vub of cols in SNFR

highs/mip/HighsTransformedLp.cpp

Lines changed: 30 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -627,7 +627,6 @@ bool HighsTransformedLp::transformSNFRelaxation(
627627
double coef, double origbincoef, double lb,
628628
double ub, bool isVub) {
629629
if (bincol == -1) return false;
630-
if (snfr.binColUsed[bincol]) return false;
631630
if (abs(vb.coef) >= 1e+6) return false;
632631
if (isVub && lb < vb.constant) return false;
633632
if (!isVub && ub > vb.constant) return false;
@@ -653,10 +652,6 @@ bool HighsTransformedLp::transformSNFRelaxation(
653652
assert(binsolval >= -lprelaxation.getMipSolver().mipdata_->feastol &&
654653
binsolval <= 1 + lprelaxation.getMipSolver().mipdata_->feastol);
655654
assert(vubcoef >= -1e-10);
656-
for (HighsInt j = 0; j < snfr.numNnzs; j++) {
657-
assert(snfr.origBinCols[j] == -1 || snfr.origBinCols[j] != origbincol);
658-
assert(snfr.origContCols[j] == -1 || snfr.origContCols[j] != origcontcol);
659-
}
660655
snfr.origBinCols[snfr.numNnzs] = origbincol;
661656
snfr.origContCols[snfr.numNnzs] = origcontcol;
662657
snfr.binSolval[snfr.numNnzs] = binsolval;
@@ -677,7 +672,7 @@ bool HighsTransformedLp::transformSNFRelaxation(
677672
double ub = getUb(col);
678673
if (colIsBinary(col, lb, ub)) {
679674
numBinCols++;
680-
snfr.origBinColCoef[col] = vals[i];
675+
vectorsum.add(col, vals[i]);
681676
std::swap(inds[i], inds[numNz - numBinCols]);
682677
std::swap(vals[i], vals[numNz - numBinCols]);
683678
continue;
@@ -695,14 +690,18 @@ bool HighsTransformedLp::transformSNFRelaxation(
695690
if (ub - lb < mip.options_mip_->small_matrix_value) {
696691
rhs -= std::min(lb, ub) * vals[i];
697692
tmpSnfrRhs -= std::min(lb, ub) * vals[i];
698-
if (colIsBinary(col, lb, ub)) {
699-
snfr.origBinColCoef[col] = 0;
700-
}
701693
remove(i);
702694
continue;
703695
}
704696

697+
// We are using vectorsum to keep track of the binary coefficients
698+
if (colIsBinary(col, lb, ub) && vectorsum.getValue(col) == 0) {
699+
++i;
700+
continue;
701+
}
702+
705703
if (lb == -kHighsInf || ub == kHighsInf) {
704+
vectorsum.clear();
706705
return false;
707706
}
708707

@@ -738,53 +737,46 @@ bool HighsTransformedLp::transformSNFRelaxation(
738737

739738
// Transform entry into the SNFR
740739
if (colIsBinary(col, lb, ub)) {
741-
if (snfr.binColUsed[col] == false) {
742-
if (vals[i] >= 0) {
743-
addSNFRentry(col, -1, getLpSolution(col),
744-
getLpSolution(col) * vals[i], 1, vals[i], 0, vals[i], 0);
745-
} else {
746-
addSNFRentry(col, -1, getLpSolution(col),
747-
-getLpSolution(col) * vals[i], -1, -vals[i], 0, -vals[i],
748-
0);
749-
}
750-
snfr.binColUsed[col] = true;
740+
if (vals[i] >= 0) {
741+
addSNFRentry(col, -1, getLpSolution(col),
742+
getLpSolution(col) * vals[i], 1, vals[i], 0, vals[i], 0);
743+
} else {
744+
addSNFRentry(col, -1, getLpSolution(col),
745+
-getLpSolution(col) * vals[i], -1, -vals[i], 0, -vals[i],
746+
0);
751747
}
752748
} else {
753749
if (lbDist[col] < ubDist[col] - mip.mipdata_->feastol) {
754750
if (!checkValidityVB(bestVlb[col].first, bestVlb[col].second, vals[i],
755-
snfr.origBinColCoef[bestVlb[col].first], lb, ub,
751+
vectorsum.getValue(bestVlb[col].first), lb, ub,
756752
false)) {
757753
boundTypes[col] = BoundType::kSimpleLb;
758754
} else if (simpleLbDist[col] > lbDist[col] + mip.mipdata_->feastol) {
759755
boundTypes[col] = BoundType::kVariableLb;
760-
snfr.binColUsed[bestVlb[col].first] = true;
761756
} else
762757
boundTypes[col] = BoundType::kSimpleLb;
763758
} else if (ubDist[col] < lbDist[col] - mip.mipdata_->feastol) {
764759
if (!checkValidityVB(bestVub[col].first, bestVub[col].second, vals[i],
765-
snfr.origBinColCoef[bestVub[col].first], lb, ub,
760+
vectorsum.getValue(bestVub[col].first), lb, ub,
766761
true)) {
767762
boundTypes[col] = BoundType::kSimpleUb;
768763
} else if (simpleUbDist[col] > ubDist[col] + mip.mipdata_->feastol) {
769764
boundTypes[col] = BoundType::kVariableUb;
770-
snfr.binColUsed[bestVub[col].first] = true;
771765
} else {
772766
boundTypes[col] = BoundType::kSimpleUb;
773767
}
774768
} else if (vals[i] > 0) {
775769
if (checkValidityVB(bestVlb[col].first, bestVlb[col].second, vals[i],
776-
snfr.origBinColCoef[bestVlb[col].first], lb, ub,
770+
vectorsum.getValue(bestVlb[col].first), lb, ub,
777771
false)) {
778-
snfr.binColUsed[bestVlb[col].first] = true;
779772
boundTypes[col] = BoundType::kVariableLb;
780773
} else {
781774
boundTypes[col] = BoundType::kSimpleLb;
782775
}
783776
} else {
784777
if (checkValidityVB(bestVub[col].first, bestVub[col].second, vals[i],
785-
snfr.origBinColCoef[bestVub[col].first], lb, ub,
778+
vectorsum.getValue(bestVub[col].first), lb, ub,
786779
true)) {
787-
snfr.binColUsed[bestVub[col].first] = true;
788780
boundTypes[col] = BoundType::kVariableUb;
789781
} else {
790782
boundTypes[col] = BoundType::kSimpleUb;
@@ -830,21 +822,22 @@ bool HighsTransformedLp::transformSNFRelaxation(
830822
vals[i] * (HighsCDouble(getLpSolution(col)) -
831823
bestVlb[col].second.constant) +
832824
(HighsCDouble(lpSolution.col_value[vbcol]) *
833-
snfr.origBinColCoef[vbcol]));
825+
vectorsum.getValue(vbcol)));
834826
vbcoef = static_cast<double>(HighsCDouble(vals[i]) *
835827
bestVlb[col].second.coef +
836-
snfr.origBinColCoef[vbcol]);
828+
vectorsum.getValue(vbcol));
837829
aggrconstant = static_cast<double>(HighsCDouble(vals[i]) *
838830
bestVlb[col].second.constant);
839831
if (vals[i] >= 0) {
840832
addSNFRentry(vbcol, col, lpSolution.col_value[vbcol], -substsolval,
841-
-1, -vbcoef, aggrconstant, -snfr.origBinColCoef[vbcol],
833+
-1, -vbcoef, aggrconstant, -vectorsum.getValue(vbcol),
842834
-vals[i]);
843835
} else {
844836
addSNFRentry(vbcol, col, lpSolution.col_value[vbcol], substsolval,
845-
1, vbcoef, -aggrconstant, snfr.origBinColCoef[vbcol],
837+
1, vbcoef, -aggrconstant, vectorsum.getValue(vbcol),
846838
vals[i]);
847839
}
840+
vectorsum.values[vbcol] = 0;
848841
tmpSnfrRhs -= aggrconstant;
849842
break;
850843
case BoundType::kVariableUb:
@@ -853,21 +846,22 @@ bool HighsTransformedLp::transformSNFRelaxation(
853846
vals[i] * (HighsCDouble(getLpSolution(col)) -
854847
bestVub[col].second.constant) +
855848
(HighsCDouble(lpSolution.col_value[vbcol]) *
856-
snfr.origBinColCoef[vbcol]));
849+
vectorsum.getValue(vbcol)));
857850
vbcoef = static_cast<double>(HighsCDouble(vals[i]) *
858851
bestVub[col].second.coef +
859-
snfr.origBinColCoef[vbcol]);
852+
vectorsum.getValue(vbcol));
860853
aggrconstant = static_cast<double>(HighsCDouble(vals[i]) *
861854
bestVub[col].second.constant);
862855
if (vals[i] >= 0) {
863856
addSNFRentry(vbcol, col, lpSolution.col_value[vbcol], substsolval,
864-
1, vbcoef, -aggrconstant, snfr.origBinColCoef[vbcol],
857+
1, vbcoef, -aggrconstant, vectorsum.getValue(vbcol),
865858
vals[i]);
866859
} else {
867860
addSNFRentry(vbcol, col, lpSolution.col_value[vbcol], -substsolval,
868-
-1, -vbcoef, aggrconstant, -snfr.origBinColCoef[vbcol],
861+
-1, -vbcoef, aggrconstant, -vectorsum.getValue(vbcol),
869862
-vals[i]);
870863
}
864+
vectorsum.values[vbcol] = 0;
871865
tmpSnfrRhs -= aggrconstant;
872866
break;
873867
}
@@ -876,6 +870,7 @@ bool HighsTransformedLp::transformSNFRelaxation(
876870
i++;
877871
}
878872

873+
vectorsum.clear();
879874
snfr.rhs = static_cast<double>(tmpSnfrRhs);
880875
if (numNz == 0 && rhs >= -mip.mipdata_->feastol) return false;
881876
return true;

0 commit comments

Comments
 (0)