@@ -200,6 +200,27 @@ void HighsRedcostFixing::addRootRedcost(const HighsMipSolver& mipsolver,
200200 mipsolver.mipdata_ ->lp .computeBasicDegenerateDuals (
201201 mipsolver.mipdata_ ->feastol );
202202
203+ // Compute maximum number of steps per column with large domain
204+ // max_steps = 2 ** k, k = max(5, min(10 ,round(log(|D| / 10)))),
205+ // D = {col : integral_cols | (ub - lb) >= 512}
206+ // This is to avoid doing 2**10 steps when there's many unbounded columns
207+ HighsInt numRedcostLargeDomainCols = 0 ;
208+ for (HighsInt col : mipsolver.mipdata_ ->integral_cols ) {
209+ if ((mipsolver.mipdata_ ->domain .col_upper_ [col] -
210+ mipsolver.mipdata_ ->domain .col_lower_ [col]) >= 512 &&
211+ std::abs (lpredcost[col]) > mipsolver.mipdata_ ->feastol ) {
212+ numRedcostLargeDomainCols++;
213+ }
214+ }
215+ HighsInt maxNumStepsExp = 10 ;
216+ int expshift = 0 ;
217+ std::frexp (numRedcostLargeDomainCols / 10 , &expshift);
218+ if (expshift > 5 ) {
219+ expshift = std::min (expshift, static_cast <int >(maxNumStepsExp));
220+ maxNumStepsExp = maxNumStepsExp - expshift + 5 ;
221+ }
222+ HighsInt maxNumSteps = static_cast <HighsInt>(1ULL << maxNumStepsExp);
223+
203224 for (HighsInt col : mipsolver.mipdata_ ->integral_cols ) {
204225 if (lpredcost[col] > mipsolver.mipdata_ ->feastol ) {
205226 // col <= (cutoffbound - lpobj)/redcost + lb
@@ -218,13 +239,14 @@ void HighsRedcostFixing::addRootRedcost(const HighsMipSolver& mipsolver,
218239
219240 HighsInt maxub;
220241 if (mipsolver.mipdata_ ->domain .col_upper_ [col] == kHighsInf )
221- maxub = lb + 1024 ;
242+ maxub = lb + maxNumSteps ;
222243 else
223244 maxub = (HighsInt)std::floor (
224245 mipsolver.mipdata_ ->domain .col_upper_ [col] - 0.5 );
225246
226247 HighsInt step = 1 ;
227- if (maxub - lb > 1024 ) step = (maxub - lb + 1023 ) >> 10 ;
248+ if (maxub - lb > maxNumSteps)
249+ step = (maxub - lb + maxNumSteps - 1 ) >> maxNumStepsExp;
228250
229251 for (HighsInt lurkub = lb; lurkub <= maxub; lurkub += step) {
230252 double fracbound = (lurkub - lb + 1 ) - 10 * mipsolver.mipdata_ ->feastol ;
@@ -276,12 +298,13 @@ void HighsRedcostFixing::addRootRedcost(const HighsMipSolver& mipsolver,
276298
277299 HighsInt minlb;
278300 if (mipsolver.mipdata_ ->domain .col_lower_ [col] == -kHighsInf )
279- minlb = ub - 1024 ;
301+ minlb = ub - maxNumSteps ;
280302 else
281303 minlb = (HighsInt)(mipsolver.mipdata_ ->domain .col_lower_ [col] + 1.5 );
282304
283305 HighsInt step = 1 ;
284- if (ub - minlb > 1024 ) step = (ub - minlb + 1023 ) >> 10 ;
306+ if (ub - minlb > maxNumSteps)
307+ step = (ub - minlb + maxNumSteps - 1 ) >> maxNumStepsExp;
285308
286309 for (HighsInt lurklb = minlb; lurklb <= ub; lurklb += step) {
287310 double fracbound = (lurklb - ub - 1 ) + 10 * mipsolver.mipdata_ ->feastol ;
0 commit comments