@@ -4665,6 +4665,13 @@ HPresolve::Result HPresolve::dualFixing(HighsPostsolveStack& postsolve_stack,
46654665 // return if variable is already fixed
46664666 if (model->col_lower_ [col] == model->col_upper_ [col]) return Result::kOk ;
46674667
4668+ // struct for single equation handling
4669+ struct equationNonZero {
4670+ HighsInt col;
4671+ double val;
4672+ HighsInt mark;
4673+ };
4674+
46684675 // lambda for variable substitution
46694676 auto substituteCol = [&](HighsInt col, HighsInt row, HighsInt direction,
46704677 double colBound, double otherColBound) {
@@ -4760,41 +4767,45 @@ HPresolve::Result HPresolve::dualFixing(HighsPostsolveStack& postsolve_stack,
47604767 };
47614768
47624769 // lambda for fixing variables
4763- auto fixCols = [&](const std::vector<std::pair<HighsInt, double >>& vars ,
4770+ auto fixCols = [&](const std::vector<equationNonZero>& equationRowVector ,
47644771 HighsInt direction) {
4765- for (const auto & elm : vars) {
4766- if (direction * elm.second > 0 )
4767- HPRESOLVE_CHECKED_CALL (fixColToUpper (postsolve_stack, elm.first ));
4772+ for (const auto & rowNz : equationRowVector) {
4773+ if (direction * rowNz.mark >= 0 ) continue ;
4774+ if (direction * rowNz.val > 0 )
4775+ HPRESOLVE_CHECKED_CALL (fixColToUpper (postsolve_stack, rowNz.col ));
47684776 else
4769- HPRESOLVE_CHECKED_CALL (fixColToLower (postsolve_stack, elm. first ));
4777+ HPRESOLVE_CHECKED_CALL (fixColToLower (postsolve_stack, rowNz. col ));
47704778 }
47714779 return Result::kOk ;
47724780 };
47734781
47744782 // lambda for handling single equations
47754783 auto handleSingleEquation = [&](HighsInt row) {
47764784 assert (isEquation (row));
4777- std::vector<std::pair<HighsInt, double >> sPlus ;
4778- std::vector<std::pair<HighsInt, double >> sMinus ;
4779- sPlus .reserve (rowsize[row]);
4780- sMinus .reserve (rowsize[row]);
4781- std::vector<HighsInt> sMark (model->num_col_ , 0 );
4785+ std::vector<equationNonZero> equationRowVector;
4786+ equationRowVector.reserve (rowsize[row]);
4787+ HighsInt numSPlus = 0 ;
4788+ HighsInt numSMinus = 0 ;
47824789 for (const auto & rowNz : getRowVector (row)) {
47834790 // flip column direction if coefficient is negative
47844791 // (equivalent to negating the column's coefficients)
47854792 HighsInt colDirection = std::copysign (HighsInt{1 }, rowNz.value ());
4793+ HighsInt mark = 0 ;
47864794 if (checkColumn (rowNz.index (), colDirection, row)) {
47874795 // store in S_+
4788- sPlus . push_back ( std::make_pair (rowNz. index (), rowNz. value ())) ;
4789- sMark [rowNz. index ()] = 1 ;
4796+ numSPlus++ ;
4797+ mark = 1 ;
47904798 } else if (checkColumn (rowNz.index (), -colDirection, row)) {
47914799 // store in S_-
4792- sMinus . push_back ( std::make_pair (rowNz. index (), rowNz. value ())) ;
4793- sMark [rowNz. index ()] = -1 ;
4800+ numSMinus++ ;
4801+ mark = -1 ;
47944802 }
4803+ // store non-zero
4804+ equationRowVector.emplace_back (
4805+ equationNonZero{rowNz.index (), rowNz.value (), mark});
47954806 }
47964807 // return if both sets are empty
4797- if (sPlus . empty () && sMinus . empty () ) return Result::kOk ;
4808+ if (numSPlus == 0 && numSMinus == 0 ) return Result::kOk ;
47984809 // compute activities
47994810 HighsCDouble activityTPlus = 0.0 ;
48004811 HighsCDouble activityTMinus = 0.0 ;
@@ -4804,41 +4815,41 @@ HPresolve::Result HPresolve::dualFixing(HighsPostsolveStack& postsolve_stack,
48044815 bool activityTMinusFinite = true ;
48054816 bool activitySCPlusFinite = true ;
48064817 bool activitySCMinusFinite = true ;
4807- for (const auto & rowNz : getRowVector (row) ) {
4808- if (sMark [ rowNz.index ()] <= 0 ||
4809- model->integrality_ [rowNz.index () ] != HighsVarType::kContinuous )
4818+ for (const auto & rowNz : equationRowVector ) {
4819+ if (rowNz.mark <= 0 ||
4820+ model->integrality_ [rowNz.col ] != HighsVarType::kContinuous )
48104821 // T_+
4811- computeActivity (rowNz.index () , rowNz.value () , activityTPlus,
4822+ computeActivity (rowNz.col , rowNz.val , activityTPlus,
48124823 activityTPlusFinite, HighsInt{1 });
48134824 else
48144825 // S^C_+
4815- computeActivity (rowNz.index () , rowNz.value () , activitySCPlus,
4826+ computeActivity (rowNz.col , rowNz.val , activitySCPlus,
48164827 activitySCPlusFinite, HighsInt{-1 });
4817- if (sMark [ rowNz.index ()] >= 0 ||
4818- model->integrality_ [rowNz.index () ] != HighsVarType::kContinuous )
4828+ if (rowNz.mark >= 0 ||
4829+ model->integrality_ [rowNz.col ] != HighsVarType::kContinuous )
48194830 // T_-
4820- computeActivity (rowNz.index () , rowNz.value () , activityTMinus,
4831+ computeActivity (rowNz.col , rowNz.val , activityTMinus,
48214832 activityTMinusFinite, HighsInt{-1 });
48224833 else
48234834 // S^C_-
4824- computeActivity (rowNz.index () , rowNz.value () , activitySCMinus,
4835+ computeActivity (rowNz.col , rowNz.val , activitySCMinus,
48254836 activitySCMinusFinite, HighsInt{1 });
48264837 // break if activities are not finite
4827- if ((sMinus . empty () || !activityTPlusFinite || !activitySCPlusFinite) &&
4828- (sPlus . empty () || !activityTMinusFinite || !activitySCMinusFinite))
4838+ if ((numSMinus == 0 || !activityTPlusFinite || !activitySCPlusFinite) &&
4839+ (numSPlus == 0 || !activityTMinusFinite || !activitySCMinusFinite))
48294840 break ;
48304841 }
48314842 // fix variables
4832- if (! sMinus . empty () && activityTPlusFinite && activitySCPlusFinite &&
4843+ if (numSMinus > 0 && activityTPlusFinite && activitySCPlusFinite &&
48334844 activityTPlus + activitySCPlus <=
48344845 model->row_lower_ [row] + primal_feastol)
48354846 // fix all variables in S_-
4836- HPRESOLVE_CHECKED_CALL (fixCols (sMinus , HighsInt{1 }));
4837- else if (! sPlus . empty () && activityTMinusFinite && activitySCMinusFinite &&
4847+ HPRESOLVE_CHECKED_CALL (fixCols (equationRowVector , HighsInt{1 }));
4848+ else if (numSPlus > 0 && activityTMinusFinite && activitySCMinusFinite &&
48384849 activityTMinus + activitySCMinus >=
48394850 model->row_lower_ [row] - primal_feastol)
48404851 // fix all variables in S_+
4841- HPRESOLVE_CHECKED_CALL (fixCols (sPlus , HighsInt{-1 }));
4852+ HPRESOLVE_CHECKED_CALL (fixCols (equationRowVector , HighsInt{-1 }));
48424853 return Result::kOk ;
48434854 };
48444855
0 commit comments