@@ -186,6 +186,7 @@ void HighsTableauSeparator::separateLpSolution(HighsLpRelaxation& lpRelaxation,
186186 pdqsort_branchless (fractionalBasisvars.begin (), fractionalBasisvars.end ());
187187 double bestScore = -1.0 ;
188188
189+ HighsLpAggregator lpMultiAggregator = lpAggregator;
189190 HighsInt numCuts = cutpool.getNumCuts ();
190191 const double bestScoreFac[] = {0.0025 , 0.01 };
191192
@@ -197,45 +198,59 @@ void HighsTableauSeparator::separateLpSolution(HighsLpRelaxation& lpRelaxation,
197198 break ;
198199
199200 assert (lpAggregator.isEmpty ());
200- for (std::pair<HighsInt, double > rowWeight : fracvar.row_ep )
201+ for (std::pair<HighsInt, double > rowWeight : fracvar.row_ep ) {
201202 lpAggregator.addRow (rowWeight.first , rowWeight.second );
202-
203- lpAggregator.getCurrentAggregation (baseRowInds, baseRowVals, false );
204-
205- if (10 * (baseRowInds.size () - fracvar.row_ep .size ()) >
206- 10000 + static_cast <size_t >(mip.numCol ())) {
207- lpAggregator.clear ();
208- continue ;
203+ lpMultiAggregator.addRow (rowWeight.first , rowWeight.second );
209204 }
210205
211- HighsInt len = baseRowInds.size ();
212- if (len > (HighsInt)fracvar.row_ep .size ()) {
213- double maxAbsVal = 0.0 ;
214- double minAbsVal = kHighsInf ;
215- for (HighsInt i = 0 ; i < len; ++i) {
216- if (baseRowInds[i] < mip.numCol ()) {
217- maxAbsVal = std::max (std::abs (baseRowVals[i]), maxAbsVal);
218- minAbsVal = std::min (std::abs (baseRowVals[i]), minAbsVal);
206+ auto generateTableauCut = [&](HighsLpAggregator& aggregator) {
207+ aggregator.getCurrentAggregation (baseRowInds, baseRowVals, false );
208+
209+ if (10 * (baseRowInds.size () - fracvar.row_ep .size ()) >
210+ 10000 + static_cast <size_t >(mip.numCol ())) {
211+ aggregator.clear ();
212+ return false ;
213+ }
214+
215+ HighsInt len = baseRowInds.size ();
216+ if (len > (HighsInt)fracvar.row_ep .size ()) {
217+ double maxAbsVal = 0.0 ;
218+ double minAbsVal = kHighsInf ;
219+ for (HighsInt i = 0 ; i < len; ++i) {
220+ if (baseRowInds[i] < mip.numCol ()) {
221+ maxAbsVal = std::max (std::abs (baseRowVals[i]), maxAbsVal);
222+ minAbsVal = std::min (std::abs (baseRowVals[i]), minAbsVal);
223+ }
224+ }
225+ if (maxAbsVal / minAbsVal > 1e6 ) {
226+ aggregator.clear ();
227+ return false ;
219228 }
220229 }
221- if (maxAbsVal / minAbsVal > 1e6 ) {
222- lpAggregator.clear ();
223- continue ;
224- }
225- }
226230
227- mip.mipdata_ ->debugSolution .checkRowAggregation (
228- lpSolver.getLp (), baseRowInds.data (), baseRowVals.data (),
229- baseRowInds.size ());
231+ mip.mipdata_ ->debugSolution .checkRowAggregation (
232+ lpSolver.getLp (), baseRowInds.data (), baseRowVals.data (),
233+ baseRowInds.size ());
234+
235+ double rhs = 0 ;
236+ cutGen.generateCut (transLp, baseRowInds, baseRowVals, rhs);
237+ if (mip.mipdata_ ->domain .infeasible ()) return true ;
230238
231- double rhs = 0 ;
232- cutGen.generateCut (transLp, baseRowInds, baseRowVals, rhs);
233- if (mip.mipdata_ ->domain .infeasible ()) break ;
239+ aggregator.getCurrentAggregation (baseRowInds, baseRowVals, true );
240+ rhs = 0 ;
241+ cutGen.generateCut (transLp, baseRowInds, baseRowVals, rhs);
242+ if (mip.mipdata_ ->domain .infeasible ()) return true ;
243+ return false ;
244+ };
234245
235- lpAggregator.getCurrentAggregation (baseRowInds, baseRowVals, true );
236- rhs = 0 ;
237- cutGen.generateCut (transLp, baseRowInds, baseRowVals, rhs);
238- if (mip.mipdata_ ->domain .infeasible ()) break ;
246+ bool infeasible = generateTableauCut (lpAggregator);
247+ if (infeasible) break ;
248+
249+ if (bestScore != -1.0 || cutpool.getNumCuts () != numCuts) {
250+ infeasible = generateTableauCut (lpMultiAggregator);
251+ if (infeasible) break ;
252+ lpAggregator.swap (lpMultiAggregator);
253+ }
239254
240255 lpAggregator.clear ();
241256 if (bestScore == -1.0 && cutpool.getNumCuts () != numCuts)
0 commit comments