Skip to content

Commit 1aaa0c3

Browse files
authored
Merge pull request ERGO-Code#2513 from ERGO-Code/dynamic-redcost-budget
Add a dynamic redcost budget
2 parents aac68db + 80e9b89 commit 1aaa0c3

File tree

1 file changed

+27
-4
lines changed

1 file changed

+27
-4
lines changed

highs/mip/HighsRedcostFixing.cpp

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)