@@ -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