Skip to content

Commit

Permalink
Merge branch 'deterministic-heuristic-scheduler' into 'master'
Browse files Browse the repository at this point in the history
Removed option to set timelimit for subscips in heur_scheduler.

See merge request integer/scip!3626
  • Loading branch information
svigerske committed Jan 11, 2025
2 parents 6ad221a + c1d3ac2 commit 5372f6f
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 25 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ Interface changes

### Changed parameters

- heuristics/scheduler/heurtimelimit removed to avoid indeterministic behavior of scheduler heuristic, uses main time limit instead

### New parameters

- branching/pscost/discountfactor, branching/relpscost/discountfactor as the discount factor for ancestral pseudo costs in pscost and relpscost branching rules
Expand Down
41 changes: 16 additions & 25 deletions src/scip/heur_scheduler.c
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,6 @@
#define LPLIMFAC 4.0
#define DEFAULT_INITDURINGROOT FALSE
#define DEFAULT_MAXCALLSSAMESOL -1 /**< number of allowed executions of the heuristic on the same incumbent solution */
#define DEFAULT_HEURTIMELIMIT 60.0 /**< time limit for a single heuristic run */

/*
* bandit algorithm parameters
Expand Down Expand Up @@ -467,7 +466,6 @@ struct SCIP_HeurData
SCIP_Bool initduringroot; /**< should the heuristic be executed multiple times during the root node? */
int maxnconflicts; /**< maximum number of conflicts detected by diving heur so far */
SCIP_Bool defaultroot; /**< should the default priorities be used at the root node */
SCIP_Real heurtimelimit; /**< time limit for a single heuristic run */
/* bandit algorithm parameters */
SCIP_Real exp3_gamma; /**< weight between uniform (gamma ~ 1) and weight driven (gamma ~ 0) probability distribution for exp3 */
SCIP_Real exp3_beta; /**< reward offset between 0 and 1 at every observation for exp3 */
Expand Down Expand Up @@ -635,15 +633,14 @@ void updateFixingRate(
case SCIP_STATUS_STALLNODELIMIT:
case SCIP_STATUS_USERINTERRUPT:
case SCIP_STATUS_TERMINATE:
case SCIP_STATUS_TIMELIMIT:
case SCIP_STATUS_NODELIMIT:
/* increase the fixing rate (make the subproblem easier) only if no solution was found */
if( runstats->nbestsolsfound <= 0 )
increaseFixingRate(fx);
break;
/* fall through cases to please lint */
case SCIP_STATUS_UNKNOWN:
case SCIP_STATUS_TOTALNODELIMIT:
case SCIP_STATUS_TIMELIMIT:
case SCIP_STATUS_MEMLIMIT:
case SCIP_STATUS_GAPLIMIT:
case SCIP_STATUS_PRIMALLIMIT:
Expand Down Expand Up @@ -1193,17 +1190,18 @@ void updateHeurStatsDiving(
static
void updateHeurStatsLNS(
HEUR_STATS* runstats, /**< run statistics */
NH* neighborhood, /**< the selected neighborhood or NULL if diving was used */
SCIP_STATUS* subscipstatus /**< status of the sub-SCIP solve or NULL if diving was used */
NH* neighborhood, /**< the selected neighborhood */
SCIP_STATUS* subscipstatus /**< status of the sub-SCIP solve */
)
{ /*lint --e{715}*/
{
HEUR_STATS* stats;

assert( subscipstatus != NULL );

stats = &neighborhood->stats;
assert(runstats != NULL);
assert(neighborhood != NULL);
assert(subscipstatus != NULL);

/* update LNS specific statistics */
stats = &neighborhood->stats;
stats->usednodes += runstats->usednodes;
++stats->statushist[getHistIndex(*subscipstatus)]; /* update the counter for the subscip status */

Expand Down Expand Up @@ -2002,10 +2000,12 @@ SCIP_RETCODE determineLimits(

heurdata = SCIPheurGetData(heur);

/* set time and memory */
/* check whether there is enough time and memory left */
SCIP_CALL( SCIPgetRealParam(scip, "limits/time", &solvelimits->timelimit) );
if( ! SCIPisInfinity(scip, solvelimits->timelimit) )
solvelimits->timelimit -= SCIPgetSolvingTime(scip);
SCIP_CALL( SCIPgetRealParam(scip, "limits/memory", &solvelimits->memorylimit) );
SCIP_CALL( SCIPgetBoolParam(scip, "misc/avoidmemout", &avoidmemout) );
solvelimits->timelimit = heurdata->heurtimelimit;

/* substract the memory already used by the main SCIP and the estimated memory usage of external software */
if( ! SCIPisInfinity(scip, solvelimits->memorylimit) )
Expand All @@ -2016,13 +2016,14 @@ SCIP_RETCODE determineLimits(

/* abort if no time is left or not enough memory (we don't abort in this case if misc_avoidmemout == FALSE)
* to create a copy of SCIP, including external memory usage */
if( avoidmemout && solvelimits->memorylimit <= 2.0*SCIPgetMemExternEstim(scip)/1048576.0 )
if( solvelimits->timelimit <= 0.0 || (avoidmemout && solvelimits->memorylimit <= 2.0*SCIPgetMemExternEstim(scip)/1048576.0) )
{
SCIPdebugMsg(scip, "Aborting LNS heuristic call: Not enough memory or time left.\n");
*runagain = FALSE;
return SCIP_OKAY;
}

/* TODO: set stalling limit */
solvelimits->stallnodes = -1;
solvelimits->nodelimit = (SCIP_Longint) heurdata->neighborhoods[selection]->nodelimit;

Expand All @@ -2035,8 +2036,7 @@ SCIP_Real getReward(
SCIP* scip, /**< SCIP data structure */
SCIP_HEURDATA* heurdata, /**< heuristic data of the scheduler neighborhood */
int selection, /**< index of selected heuristic */
HEUR_STATS* runstats, /**< run statistics */
SCIP_STATUS subscipstatus /**< status of the sub-SCIP if LNS was used */
HEUR_STATS* runstats /**< run statistics */
)
{
SCIP_Real totalreward;
Expand All @@ -2051,11 +2051,6 @@ SCIP_Real getReward(
else
effortsaved = MIN(1.0, (SCIP_Real) runstats->usednodes / (SCIP_Real)heurdata->maxlnsnodelimit);
effortsaved = (1.0 - effortsaved);

/* if LNS heuristic terminated because of the time limit, punish it */
if( selection > heurdata->ndiving && subscipstatus == SCIP_STATUS_TIMELIMIT )
effortsaved = 0.0;

assert(effortsaved >= 0.0 && effortsaved <= 1.0);
assert(heurdata->maxlnsnodelimit > 0);
assert(heurdata->maxdivingnodelimit > 0);
Expand Down Expand Up @@ -2944,7 +2939,7 @@ SCIP_DECL_HEUREXEC(heurExecScheduler)
updateHeurStatsLNS(stats, heurdata->neighborhoods[selection - heurdata->ndiving], &subscipstatus);

/* observe reward */
reward = getReward(scip, heurdata, selection, stats, subscipstatus);
reward = getReward(scip, heurdata, selection, stats);

/* call was successfull if solution was found */
if( stats->nbestsolsfound > 0 )
Expand Down Expand Up @@ -4467,10 +4462,6 @@ SCIP_RETCODE SCIPincludeHeurScheduler(
"tolerance by which the fixing rate may be exceeded without generic unfixing",
&heurdata->unfixtol, TRUE, DEFAULT_UNFIXTOL, 0.0, 1.0, NULL, NULL) );

SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/heurtimelimit",
"time limit for a single heuristic run",
&heurdata->heurtimelimit, TRUE, DEFAULT_HEURTIMELIMIT, 0.0, SCIP_REAL_MAX, NULL, NULL) );

SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/initduringroot",
"should the heuristic be executed multiple times during the root node?",
&heurdata->initduringroot, TRUE, DEFAULT_INITDURINGROOT, NULL, NULL) );
Expand Down

0 comments on commit 5372f6f

Please sign in to comment.