SCIP

    Solving Constraint Integer Programs

    heur_adaptivediving.c
    Go to the documentation of this file.
    1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    2/* */
    3/* This file is part of the program and library */
    4/* SCIP --- Solving Constraint Integer Programs */
    5/* */
    6/* Copyright (c) 2002-2026 Zuse Institute Berlin (ZIB) */
    7/* */
    8/* Licensed under the Apache License, Version 2.0 (the "License"); */
    9/* you may not use this file except in compliance with the License. */
    10/* You may obtain a copy of the License at */
    11/* */
    12/* http://www.apache.org/licenses/LICENSE-2.0 */
    13/* */
    14/* Unless required by applicable law or agreed to in writing, software */
    15/* distributed under the License is distributed on an "AS IS" BASIS, */
    16/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
    17/* See the License for the specific language governing permissions and */
    18/* limitations under the License. */
    19/* */
    20/* You should have received a copy of the Apache-2.0 license */
    21/* along with SCIP; see the file LICENSE. If not visit scipopt.org. */
    22/* */
    23/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    24
    25/**@file heur_adaptivediving.c
    26 * @ingroup DEFPLUGINS_HEUR
    27 * @brief diving heuristic that selects adaptively between the existing, public dive sets
    28 * @author Gregor Hendel
    29 */
    30
    31/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
    32
    34#include "scip/heuristics.h"
    35#include "scip/scipdefplugins.h"
    36
    37#define HEUR_NAME "adaptivediving"
    38#define HEUR_DESC "diving heuristic that selects adaptively between the existing, public divesets"
    39#define HEUR_DISPCHAR SCIP_HEURDISPCHAR_DIVING
    40#define HEUR_PRIORITY -70000
    41#define HEUR_FREQ 5
    42#define HEUR_FREQOFS 3
    43#define HEUR_MAXDEPTH -1
    44#define HEUR_TIMING SCIP_HEURTIMING_AFTERLPPLUNGE
    45#define HEUR_USESSUBSCIP FALSE /**< does the heuristic use a secondary SCIP instance? */
    46
    47#define DIVESETS_INITIALSIZE 10
    48#define DEFAULT_INITIALSEED 13
    49
    50/*
    51 * Default parameter settings
    52 */
    53#define DEFAULT_SELTYPE 'w'
    54#define DEFAULT_SCORETYPE 'c' /**< score parameter for selection: minimize either average 'n'odes, LP 'i'terations,
    55 * backtrack/'c'onflict ratio, 'd'epth, 1 / 's'olutions, or
    56 * 1 / solutions'u'ccess */
    57#define DEFAULT_USEADAPTIVECONTEXT FALSE
    58#define DEFAULT_SELCONFIDENCECOEFF 10.0 /**< coefficient c to decrease initial confidence (calls + 1.0) / (calls + c) in scores */
    59#define DEFAULT_EPSILON 1.0 /**< parameter that increases probability of exploration among divesets (only active if seltype is 'e') */
    60#define DEFAULT_MAXLPITERQUOT 0.15 /**< maximal fraction of diving LP iterations compared to node LP iterations */
    61#define DEFAULT_MAXLPITEROFS 1500L /**< additional number of allowed LP iterations */
    62#define DEFAULT_BESTSOLWEIGHT 10.0 /**< weight of incumbent solutions compared to other solutions in computation of LP iteration limit */
    63
    64/* locally defined heuristic data */
    65struct SCIP_HeurData
    66{
    67 /* data structures used internally */
    68 SCIP_SOL* sol; /**< working solution */
    69 SCIP_RANDNUMGEN* randnumgen; /**< random number generator for selection */
    70 SCIP_DIVESET** divesets; /**< publicly available divesets from diving heuristics */
    71 int ndivesets; /**< number of publicly available divesets from diving heuristics */
    72 int divesetssize; /**< array size for divesets array */
    73 int lastselection; /**< stores the last selected diveset when the heuristics was run */
    74 /* user parameters */
    75 SCIP_Real epsilon; /**< parameter that increases probability of exploration among divesets (only active if seltype is 'e') */
    76 SCIP_Real selconfidencecoeff; /**< coefficient c to decrease initial confidence (calls + 1.0) / (calls + c) in scores */
    77 SCIP_Real maxlpiterquot; /**< maximal fraction of diving LP iterations compared to node LP iterations */
    78 SCIP_Longint maxlpiterofs; /**< additional number of allowed LP iterations */
    79 SCIP_Real bestsolweight; /**< weight of incumbent solutions compared to other solutions in computation of LP iteration limit */
    80 char seltype; /**< selection strategy: (e)psilon-greedy, (w)eighted distribution, (n)ext diving */
    81 char scoretype; /**< score parameter for selection: minimize either average 'n'odes, LP 'i'terations,
    82 * backtrack/'c'onflict ratio, 'd'epth, 1 / 's'olutions, or
    83 * 1 / solutions'u'ccess */
    84 SCIP_Bool useadaptivecontext; /**< should the heuristic use its own statistics, or shared statistics? */
    85};
    86
    87/*
    88 * local methods
    89 */
    90
    91
    92/** get the selection score for this dive set */
    93static
    95 SCIP_DIVESET* diveset, /**< diving settings data structure */
    96 SCIP_HEURDATA* heurdata, /**< heuristic data */
    97 SCIP_DIVECONTEXT divecontext, /**< context for diving statistics */
    98 SCIP_Real* scoreptr /**< pointer to store the score */
    99 )
    100{
    101 SCIP_Real confidence;
    102
    103 assert(scoreptr != NULL);
    104
    105 /* compute confidence scalar (converges towards 1 with increasing number of calls) */
    106 confidence = (SCIPdivesetGetNCalls(diveset, divecontext) + 1.0) /
    107 (SCIPdivesetGetNCalls(diveset, divecontext) + heurdata->selconfidencecoeff);
    108
    109 switch (heurdata->scoretype) {
    110 case 'n': /* min average nodes */
    111 *scoreptr = confidence * SCIPdivesetGetNProbingNodes(diveset, divecontext) / (SCIPdivesetGetNCalls(diveset, divecontext) + 1.0);
    112 break;
    113 case 'i': /* min avg LP iterations */
    114 *scoreptr = confidence * SCIPdivesetGetNLPIterations(diveset, divecontext) / (SCIPdivesetGetNCalls(diveset, divecontext) + 1.0);
    115 break;
    116 case 'c': /* min backtrack / conflict ratio (the current default) */
    117 *scoreptr = confidence * (SCIPdivesetGetNBacktracks(diveset, divecontext)) / (SCIPdivesetGetNConflicts(diveset, divecontext) + 10.0);
    118 break;
    119 case 'd': /* minimum average depth */
    120 *scoreptr = SCIPdivesetGetAvgDepth(diveset, divecontext) * confidence;
    121 break;
    122 case 's': /* maximum number of solutions */
    123 *scoreptr = confidence / (SCIPdivesetGetNSols(diveset, divecontext) + 1.0);
    124 break;
    125 case 'u': /* maximum solution success (which weighs best solutions higher) */
    126 *scoreptr = confidence / (SCIPdivesetGetSolSuccess(diveset, divecontext) + 1.0);
    127 break;
    128 default:
    129 SCIPerrorMessage("Unsupported scoring parameter '%c'\n", heurdata->scoretype);
    130 SCIPABORT();
    131 *scoreptr = SCIP_INVALID;
    133 }
    134
    135 return SCIP_OKAY;
    136}
    137
    138/*
    139 * Callback methods
    140 */
    141
    142/** copy method for primal heuristic plugins (called when SCIP copies plugins) */
    143static
    144SCIP_DECL_HEURCOPY(heurCopyAdaptivediving)
    145{ /*lint --e{715}*/
    146 assert(scip != NULL);
    147 assert(heur != NULL);
    148
    150
    151 /* call inclusion method of primal heuristic */
    153
    154 return SCIP_OKAY;
    155}
    156
    157/** destructor of primal heuristic to free user data (called when SCIP is exiting) */
    158static
    159SCIP_DECL_HEURFREE(heurFreeAdaptivediving) /*lint --e{715}*/
    160{ /*lint --e{715}*/
    161 SCIP_HEURDATA* heurdata;
    162
    163 assert(heur != NULL);
    164 assert(scip != NULL);
    165
    167
    168 /* free heuristic data */
    169 heurdata = SCIPheurGetData(heur);
    170 assert(heurdata != NULL);
    171
    172 if( heurdata->divesets != NULL )
    173 {
    174 SCIPfreeBlockMemoryArray(scip, &heurdata->divesets, heurdata->divesetssize);
    175 }
    176
    177 SCIPfreeRandom(scip, &heurdata->randnumgen);
    178
    179 SCIPfreeMemory(scip, &heurdata);
    180 SCIPheurSetData(heur, NULL);
    181
    182 return SCIP_OKAY;
    183}
    184
    185/** find publicly available divesets and store them */
    186static
    188 SCIP* scip, /**< SCIP data structure */
    189 SCIP_HEUR* heur, /**< the heuristic */
    190 SCIP_HEURDATA* heurdata /**< heuristic data */
    191 )
    192{
    193 int h;
    194 SCIP_HEUR** heurs;
    195
    196 assert(scip != NULL);
    197 assert(heur != NULL);
    198 assert(heurdata != NULL);
    199
    200 heurs = SCIPgetHeurs(scip);
    201
    202 heurdata->divesetssize = DIVESETS_INITIALSIZE;
    203 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &heurdata->divesets, heurdata->divesetssize) );
    204 heurdata->ndivesets = 0;
    205
    206 for( h = 0; h < SCIPgetNHeurs(scip); ++h )
    207 {
    208 int d;
    209 assert(heurs[h] != NULL);
    210
    211 /* loop over divesets of this heuristic and check whether they are public */
    212 for( d = 0; d < SCIPheurGetNDivesets(heurs[h]); ++d )
    213 {
    214 SCIP_DIVESET* diveset = SCIPheurGetDivesets(heurs[h])[d];
    215 if( SCIPdivesetIsPublic(diveset) )
    216 {
    217 SCIPdebugMsg(scip, "Found publicly available diveset %s\n", SCIPdivesetGetName(diveset));
    218
    219 if( heurdata->ndivesets == heurdata->divesetssize )
    220 {
    221 int newsize = 2 * heurdata->divesetssize;
    222 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &heurdata->divesets, heurdata->divesetssize, newsize) );
    223 heurdata->divesetssize = newsize;
    224 }
    225 heurdata->divesets[heurdata->ndivesets++] = diveset;
    226 }
    227 else
    228 {
    229 SCIPdebugMsg(scip, "Skipping private diveset %s\n", SCIPdivesetGetName(diveset));
    230 }
    231 }
    232 }
    233 return SCIP_OKAY;
    234}
    235
    236/** initialization method of primal heuristic (called after problem was transformed) */
    237static
    238SCIP_DECL_HEURINIT(heurInitAdaptivediving) /*lint --e{715}*/
    239{ /*lint --e{715}*/
    240 SCIP_HEURDATA* heurdata;
    241
    242 assert(heur != NULL);
    243
    245
    246 /* get and reset heuristic data */
    247 heurdata = SCIPheurGetData(heur);
    248 heurdata->lastselection = -1;
    249 if( heurdata->divesets != NULL )
    250 {
    251 /* we clear the list of collected divesets to ensure reproducability and consistent state across multiple runs
    252 * within the same SCIP data structure */
    253 SCIPfreeBlockMemoryArray(scip, &heurdata->divesets, heurdata->divesetssize);
    254 assert(heurdata->divesets == NULL);
    255 }
    256
    257 assert(heurdata != NULL);
    258
    259 /* create working solution */
    260 SCIP_CALL( SCIPcreateSol(scip, &heurdata->sol, heur) );
    261
    262 /* initialize random seed; use problem dimensions to vary initial order between different instances */
    263 SCIPsetRandomSeed(scip, heurdata->randnumgen,
    265
    266 return SCIP_OKAY;
    267}
    268
    269
    270/** deinitialization method of primal heuristic (called before transformed problem is freed) */
    271static
    272SCIP_DECL_HEUREXIT(heurExitAdaptivediving) /*lint --e{715}*/
    273{ /*lint --e{715}*/
    274 SCIP_HEURDATA* heurdata;
    275
    276 assert(heur != NULL);
    277
    279
    280 /* get heuristic data */
    281 heurdata = SCIPheurGetData(heur);
    282 assert(heurdata != NULL);
    283
    284 /* free working solution */
    285 SCIP_CALL( SCIPfreeSol(scip, &heurdata->sol) );
    286
    287 return SCIP_OKAY;
    288}
    289
    290/*
    291 * heuristic specific interface methods
    292 */
    293
    294/** get LP iteration limit for diving */
    295static
    297 SCIP* scip, /**< SCIP data structure */
    298 SCIP_HEUR* heur, /**< the heuristic */
    299 SCIP_HEURDATA* heurdata /**< heuristic data */
    300 )
    301{
    302 SCIP_Real nsolsfound = SCIPheurGetNSolsFound(heur) + heurdata->bestsolweight * SCIPheurGetNBestSolsFound(heur);
    304 SCIP_Longint ncalls = SCIPheurGetNCalls(heur);
    305
    306 SCIP_Longint nlpiterationsdive = 0;
    307 SCIP_Longint lpiterlimit;
    308 int i;
    309
    310 assert(scip != NULL);
    311 assert(heur != NULL);
    312 assert(heurdata != NULL);
    313
    314 /* loop over the divesets and collect their individual iterations */
    315 for( i = 0; i < heurdata->ndivesets; ++i )
    316 {
    317 nlpiterationsdive += SCIPdivesetGetNLPIterations(heurdata->divesets[i], SCIP_DIVECONTEXT_ADAPTIVE);
    318 }
    319
    320 /* compute the iteration limit */
    321 lpiterlimit = (SCIP_Longint)(heurdata->maxlpiterquot * (nsolsfound+1.0)/(ncalls+1.0) * nlpiterations);
    322 lpiterlimit += heurdata->maxlpiterofs;
    323 lpiterlimit -= nlpiterationsdive;
    324
    325 return lpiterlimit;
    326}
    327
    328#ifdef SCIP_DEBUG
    329/** print array for debug purpose */
    330static
    331void printRealArray(
    332 char* strbuf, /**< string buffer array */
    333 SCIP_Real* elems, /**< array elements */
    334 int nelems /**< number of elements */
    335 )
    336{
    337 int c;
    338
    339 for( c = 0; c < nelems; ++c )
    340 strbuf += sprintf(strbuf, "%.4f ", elems[c]);
    341}
    342#endif
    343
    344/** sample from a distribution defined by weights */ /*lint -e715*/
    345static
    347 SCIP* scip, /**< SCIP data structure */
    348 SCIP_RANDNUMGEN* rng, /**< random number generator */
    349 SCIP_Real* weights, /**< weights of a ground set that define the sampling distribution */
    350 int nweights /**< number of elements in the ground set */
    351 )
    352{
    353 SCIP_Real weightsum;
    354 SCIP_Real randomnr;
    355 int w;
    356#ifdef SCIP_DEBUG
    357 char strbuf[SCIP_MAXSTRLEN];
    358 printRealArray(strbuf, weights, nweights);
    359 SCIPdebugMsg(scip, "Weights: %s\n", strbuf);
    360#endif
    361
    362 weightsum = 0.0;
    363 /* collect sum of weights */
    364 for( w = 0; w < nweights; ++w )
    365 {
    366 weightsum += weights[w];
    367 }
    368 assert(weightsum > 0);
    369
    370 randomnr = SCIPrandomGetReal(rng, 0.0, weightsum);
    371
    372 weightsum = 0.0;
    373 /* choose first element i such that the weight sum exceeds the random number */
    374 for( w = 0; w < nweights - 1; ++w )
    375 {
    376 weightsum += weights[w];
    377
    378 if( weightsum >= randomnr )
    379 break;
    380 }
    381 assert(w < nweights);
    382 assert(weights[w] > 0.0);
    383
    384 return w;
    385}
    386
    387/** select the diving method to apply */
    388static
    390 SCIP* scip, /**< SCIP data structure */
    391 SCIP_HEUR* heur, /**< the heuristic */
    392 SCIP_HEURDATA* heurdata, /**< heuristic data */
    393 int* selection /**< selection made */
    394 )
    395{
    396 SCIP_Bool* methodunavailable;
    397 SCIP_DIVESET** divesets;
    398 int ndivesets;
    399 int d;
    400 SCIP_RANDNUMGEN* rng;
    401 SCIP_DIVECONTEXT divecontext;
    402 SCIP_Real* weights;
    403 SCIP_Real epsilon_t;
    404
    405 divesets = heurdata->divesets;
    406 ndivesets = heurdata->ndivesets;
    407 assert(ndivesets > 0);
    408 assert(divesets != NULL);
    409
    410 SCIP_CALL( SCIPallocClearBufferArray(scip, &methodunavailable, ndivesets) );
    411
    412 divecontext = heurdata->useadaptivecontext ? SCIP_DIVECONTEXT_ADAPTIVE : SCIP_DIVECONTEXT_TOTAL;
    413
    414 /* check availability of divesets */
    415 for( d = 0; d < heurdata->ndivesets; ++d )
    416 {
    417 SCIP_Bool available;
    418 SCIP_CALL( SCIPisDivesetAvailable(scip, heurdata->divesets[d], &available) );
    419 methodunavailable[d] = ! available;
    420 }
    421
    422 *selection = -1;
    423
    424 rng = heurdata->randnumgen;
    425 assert(rng != NULL);
    426
    427 switch (heurdata->seltype) {
    428 case 'e':
    429 epsilon_t = heurdata->epsilon * sqrt(ndivesets / (SCIPheurGetNCalls(heur) + 1.0));
    430 epsilon_t = MAX(epsilon_t, 0.05);
    431
    432 /* select one of the available methods at random */
    433 if( epsilon_t >= 1.0 || SCIPrandomGetReal(rng, 0.0, 1.0) < epsilon_t )
    434 {
    435 do
    436 {
    437 *selection = SCIPrandomGetInt(rng, 0, ndivesets - 1);
    438 }
    439 while( methodunavailable[*selection] );
    440 }
    441 else
    442 {
    443 SCIP_Real bestscore = SCIP_REAL_MAX;
    444 for( d = 0; d < heurdata->ndivesets; ++d )
    445 {
    446 SCIP_Real score;
    447
    448 if( methodunavailable[d] )
    449 continue;
    450
    451 SCIP_CALL( divesetGetSelectionScore(divesets[d], heurdata, divecontext, &score) );
    452
    453 if( score < bestscore )
    454 {
    455 bestscore = score;
    456 *selection = d;
    457 }
    458 }
    459 }
    460 break;
    461 case 'w':
    462 SCIP_CALL( SCIPallocBufferArray(scip, &weights, ndivesets) );
    463
    464 /* initialize weights as inverse of the score + a small positive epsilon */
    465 for( d = 0; d < ndivesets; ++d )
    466 {
    467 SCIP_Real score;
    468
    469 SCIP_CALL( divesetGetSelectionScore(divesets[d], heurdata, divecontext, &score) );
    470
    471 weights[d] = methodunavailable[d] ? 0.0 : 1 / (score + 1e-4);
    472 }
    473
    474 *selection = sampleWeighted(scip, rng, weights, ndivesets);
    475
    476 SCIPfreeBufferArray(scip, &weights);
    477 break;
    478 case 'n':
    479 /* continue from last selection and stop at the next available method */
    480 *selection = heurdata->lastselection;
    481
    482 do
    483 {
    484 *selection = (*selection + 1) % ndivesets;
    485 }
    486 while( methodunavailable[*selection] );
    487 heurdata->lastselection = *selection;
    488 break;
    489 default:
    490 SCIPerrorMessage("Error: Unknown selection method %c\n", heurdata->seltype);
    491
    492 return SCIP_INVALIDDATA;
    493 }
    494
    495 assert(*selection >= 0 && *selection < ndivesets);
    496 SCIPfreeBufferArray(scip, &methodunavailable);
    497
    498 return SCIP_OKAY;
    499}
    500
    501/** execution method of primal heuristic */
    502static
    503SCIP_DECL_HEUREXEC(heurExecAdaptivediving) /*lint --e{715}*/
    504{ /*lint --e{715}*/
    505 SCIP_HEURDATA* heurdata;
    506 SCIP_DIVESET* diveset;
    507 SCIP_DIVESET** divesets;
    508 SCIP_Longint lpiterlimit;
    509 int selection;
    510
    511 assert(heur != NULL);
    512 assert(scip != NULL);
    513 assert(result != NULL);
    514 assert(SCIPhasCurrentNodeLP(scip));
    515
    517
    518 heurdata = SCIPheurGetData(heur);
    519 if( heurdata->divesets == NULL )
    520 {
    521 SCIP_CALL( findAndStoreDivesets(scip, heur, heurdata) );
    522 }
    523
    524 divesets = heurdata->divesets;
    525 assert(divesets != NULL);
    526 assert(heurdata->ndivesets > 0);
    527
    528 SCIPdebugMsg(scip, "heurExecAdaptivediving: depth %d sols %d inf %u node %lld (last dive at %lld)\n",
    531 nodeinfeasible,
    534 );
    535
    536 *result = SCIP_DELAYED;
    537
    538 /* do not call heuristic in node that was already detected to be infeasible */
    539 if( nodeinfeasible )
    540 return SCIP_OKAY;
    541
    542 /* only call heuristic, if an optimal LP solution is at hand */
    544 return SCIP_OKAY;
    545
    546 /* only call heuristic, if the LP objective value is smaller than the cutoff bound */
    548 return SCIP_OKAY;
    549
    550 /* only call heuristic, if the LP solution is basic (which allows fast resolve in diving) */
    551 if( !SCIPisLPSolBasic(scip) )
    552 return SCIP_OKAY;
    553
    554 /* don't dive two times at the same node */
    556 {
    557 SCIPdebugMsg(scip, "already dived at node here\n");
    558
    559 return SCIP_OKAY;
    560 }
    561
    562 *result = SCIP_DIDNOTRUN;
    563
    564 lpiterlimit = getLPIterlimit(scip, heur, heurdata);
    565
    566 if( lpiterlimit <= 0 )
    567 return SCIP_OKAY;
    568
    569 /* select the next diving strategy based on previous success */
    570 SCIP_CALL( selectDiving(scip, heur, heurdata, &selection) );
    571 assert(selection >= 0 && selection < heurdata->ndivesets);
    572
    573 diveset = divesets[selection];
    574 assert(diveset != NULL);
    575
    576 SCIPdebugMsg(scip, "Selected diveset %s\n", SCIPdivesetGetName(diveset));
    577
    578 SCIP_CALL( SCIPperformGenericDivingAlgorithm(scip, diveset, heurdata->sol, heur, result, nodeinfeasible,
    579 lpiterlimit, -1, -1.0, SCIP_DIVECONTEXT_ADAPTIVE) );
    580
    581 if( *result == SCIP_FOUNDSOL )
    582 {
    583 SCIPdebugMsg(scip, "Solution found by diveset %s\n", SCIPdivesetGetName(diveset));
    584 }
    585
    586 return SCIP_OKAY;
    587}
    588
    589/** creates the adaptivediving heuristic and includes it in SCIP */
    591 SCIP* scip /**< SCIP data structure */
    592 )
    593{
    594 SCIP_RETCODE retcode;
    595 SCIP_HEURDATA* heurdata;
    596 SCIP_HEUR* heur;
    597
    598 /* create adaptivediving data */
    599 heurdata = NULL;
    600 SCIP_CALL( SCIPallocMemory(scip, &heurdata) );
    601
    602 heurdata->divesets = NULL;
    603 heurdata->ndivesets = 0;
    604 heurdata->divesetssize = -1;
    605
    606 SCIP_CALL_TERMINATE( retcode, SCIPcreateRandom(scip, &heurdata->randnumgen, DEFAULT_INITIALSEED, TRUE), TERMINATE );
    607
    608 /* include adaptive diving primal heuristic */
    611 HEUR_MAXDEPTH, HEUR_TIMING, HEUR_USESSUBSCIP, heurExecAdaptivediving, heurdata) );
    612
    613 assert(heur != NULL);
    614
    615 /* primal heuristic is safe to use in exact solving mode */
    616 SCIPheurMarkExact(heur);
    617
    618 /* set non-NULL pointers to callback methods */
    619 SCIP_CALL( SCIPsetHeurCopy(scip, heur, heurCopyAdaptivediving) );
    620 SCIP_CALL( SCIPsetHeurFree(scip, heur, heurFreeAdaptivediving) );
    621 SCIP_CALL( SCIPsetHeurInit(scip, heur, heurInitAdaptivediving) );
    622 SCIP_CALL( SCIPsetHeurExit(scip, heur, heurExitAdaptivediving) );
    623
    624 /* add parameters */
    625 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/epsilon",
    626 "parameter that increases probability of exploration among divesets (only active if seltype is 'e')",
    627 &heurdata->epsilon, FALSE, DEFAULT_EPSILON, 0.0, SCIP_REAL_MAX, NULL, NULL) );
    628
    629 SCIP_CALL( SCIPaddCharParam(scip, "heuristics/" HEUR_NAME "/scoretype",
    630 "score parameter for selection: minimize either average 'n'odes, LP 'i'terations,"
    631 "backtrack/'c'onflict ratio, 'd'epth, 1 / 's'olutions, or 1 / solutions'u'ccess",
    632 &heurdata->scoretype, FALSE, DEFAULT_SCORETYPE, "cdinsu", NULL, NULL) );
    633
    634 SCIP_CALL( SCIPaddCharParam(scip, "heuristics/" HEUR_NAME "/seltype",
    635 "selection strategy: (e)psilon-greedy, (w)eighted distribution, (n)ext diving",
    636 &heurdata->seltype, FALSE, DEFAULT_SELTYPE, "enw", NULL, NULL) );
    637
    638 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/useadaptivecontext",
    639 "should the heuristic use its own statistics, or shared statistics?", &heurdata->useadaptivecontext, TRUE,
    641
    642 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/selconfidencecoeff",
    643 "coefficient c to decrease initial confidence (calls + 1.0) / (calls + c) in scores",
    644 &heurdata->selconfidencecoeff, FALSE, DEFAULT_SELCONFIDENCECOEFF, 1.0, (SCIP_Real)INT_MAX, NULL, NULL) );
    645
    646 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/maxlpiterquot",
    647 "maximal fraction of diving LP iterations compared to node LP iterations",
    648 &heurdata->maxlpiterquot, FALSE, DEFAULT_MAXLPITERQUOT, 0.0, SCIP_REAL_MAX, NULL, NULL) );
    649
    650 SCIP_CALL( SCIPaddLongintParam(scip, "heuristics/" HEUR_NAME "/maxlpiterofs",
    651 "additional number of allowed LP iterations",
    652 &heurdata->maxlpiterofs, FALSE, DEFAULT_MAXLPITEROFS, 0L, (SCIP_Longint)INT_MAX, NULL, NULL) );
    653
    654 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/bestsolweight",
    655 "weight of incumbent solutions compared to other solutions in computation of LP iteration limit",
    656 &heurdata->bestsolweight, FALSE, DEFAULT_BESTSOLWEIGHT, 0.0, SCIP_REAL_MAX, NULL, NULL) );
    657
    658TERMINATE:
    659 if( retcode != SCIP_OKAY )
    660 {
    661 SCIPfreeMemory(scip, &heurdata);
    662 return retcode;
    663 }
    664
    665 return SCIP_OKAY;
    666}
    SCIP_VAR * h
    Definition: circlepacking.c:68
    SCIP_VAR * w
    Definition: circlepacking.c:67
    #define NULL
    Definition: def.h:257
    #define SCIP_MAXSTRLEN
    Definition: def.h:278
    #define SCIP_Longint
    Definition: def.h:150
    #define SCIP_REAL_MAX
    Definition: def.h:167
    #define SCIP_INVALID
    Definition: def.h:187
    #define SCIP_Bool
    Definition: def.h:100
    #define SCIP_STRINGEQ(name, reference, retcode)
    Definition: def.h:454
    #define SCIP_Real
    Definition: def.h:165
    #define TRUE
    Definition: def.h:102
    #define FALSE
    Definition: def.h:103
    #define MAX(x, y)
    Definition: def.h:229
    #define SCIP_CALL_TERMINATE(retcode, x, TERM)
    Definition: def.h:385
    #define SCIPABORT()
    Definition: def.h:336
    #define SCIP_CALL(x)
    Definition: def.h:364
    int SCIPgetNOrigConss(SCIP *scip)
    Definition: scip_prob.c:3712
    int SCIPgetNOrigVars(SCIP *scip)
    Definition: scip_prob.c:2838
    #define SCIPdebugMsg
    Definition: scip_message.h:78
    SCIP_RETCODE SCIPaddLongintParam(SCIP *scip, const char *name, const char *desc, SCIP_Longint *valueptr, SCIP_Bool isadvanced, SCIP_Longint defaultvalue, SCIP_Longint minvalue, SCIP_Longint maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
    Definition: scip_param.c:111
    SCIP_RETCODE SCIPaddCharParam(SCIP *scip, const char *name, const char *desc, char *valueptr, SCIP_Bool isadvanced, char defaultvalue, const char *allowedvalues, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
    Definition: scip_param.c:167
    SCIP_RETCODE SCIPaddRealParam(SCIP *scip, const char *name, const char *desc, SCIP_Real *valueptr, SCIP_Bool isadvanced, SCIP_Real defaultvalue, SCIP_Real minvalue, SCIP_Real maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
    Definition: scip_param.c:139
    SCIP_RETCODE SCIPaddBoolParam(SCIP *scip, const char *name, const char *desc, SCIP_Bool *valueptr, SCIP_Bool isadvanced, SCIP_Bool defaultvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
    Definition: scip_param.c:57
    SCIP_Bool SCIPdivesetIsPublic(SCIP_DIVESET *diveset)
    Definition: heur.c:764
    SCIP_Longint SCIPdivesetGetNBacktracks(SCIP_DIVESET *diveset, SCIP_DIVECONTEXT divecontext)
    Definition: heur.c:615
    SCIP_Longint SCIPdivesetGetNSols(SCIP_DIVESET *diveset, SCIP_DIVECONTEXT divecontext)
    Definition: heur.c:641
    SCIP_Longint SCIPdivesetGetNConflicts(SCIP_DIVESET *diveset, SCIP_DIVECONTEXT divecontext)
    Definition: heur.c:628
    SCIP_Real SCIPdivesetGetAvgDepth(SCIP_DIVESET *diveset, SCIP_DIVECONTEXT divecontext)
    Definition: heur.c:537
    SCIP_Longint SCIPdivesetGetNLPIterations(SCIP_DIVESET *diveset, SCIP_DIVECONTEXT divecontext)
    Definition: heur.c:589
    SCIP_Longint SCIPdivesetGetSolSuccess(SCIP_DIVESET *diveset, SCIP_DIVECONTEXT divecontext)
    Definition: heur.c:471
    const char * SCIPdivesetGetName(SCIP_DIVESET *diveset)
    Definition: heur.c:445
    SCIP_RETCODE SCIPisDivesetAvailable(SCIP *scip, SCIP_DIVESET *diveset, SCIP_Bool *available)
    Definition: scip_heur.c:368
    int SCIPdivesetGetNCalls(SCIP_DIVESET *diveset, SCIP_DIVECONTEXT divecontext)
    Definition: heur.c:485
    SCIP_Longint SCIPdivesetGetNProbingNodes(SCIP_DIVESET *diveset, SCIP_DIVECONTEXT divecontext)
    Definition: heur.c:602
    SCIP_RETCODE SCIPsetHeurCopy(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEURCOPY((*heurcopy)))
    Definition: scip_heur.c:167
    SCIP_HEURDATA * SCIPheurGetData(SCIP_HEUR *heur)
    Definition: heur.c:1368
    SCIP_RETCODE SCIPincludeHeurBasic(SCIP *scip, SCIP_HEUR **heur, const char *name, const char *desc, char dispchar, int priority, int freq, int freqofs, int maxdepth, SCIP_HEURTIMING timingmask, SCIP_Bool usessubscip, SCIP_DECL_HEUREXEC((*heurexec)), SCIP_HEURDATA *heurdata)
    Definition: scip_heur.c:122
    SCIP_HEUR ** SCIPgetHeurs(SCIP *scip)
    Definition: scip_heur.c:276
    SCIP_RETCODE SCIPsetHeurFree(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEURFREE((*heurfree)))
    Definition: scip_heur.c:183
    SCIP_Longint SCIPheurGetNSolsFound(SCIP_HEUR *heur)
    Definition: heur.c:1603
    SCIP_RETCODE SCIPsetHeurExit(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEUREXIT((*heurexit)))
    Definition: scip_heur.c:215
    SCIP_Longint SCIPheurGetNBestSolsFound(SCIP_HEUR *heur)
    Definition: heur.c:1613
    int SCIPgetNHeurs(SCIP *scip)
    Definition: scip_heur.c:287
    SCIP_Longint SCIPheurGetNCalls(SCIP_HEUR *heur)
    Definition: heur.c:1593
    int SCIPheurGetNDivesets(SCIP_HEUR *heur)
    Definition: heur.c:1675
    void SCIPheurMarkExact(SCIP_HEUR *heur)
    Definition: heur.c:1457
    SCIP_RETCODE SCIPsetHeurInit(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEURINIT((*heurinit)))
    Definition: scip_heur.c:199
    const char * SCIPheurGetName(SCIP_HEUR *heur)
    Definition: heur.c:1467
    SCIP_DIVESET ** SCIPheurGetDivesets(SCIP_HEUR *heur)
    Definition: heur.c:1665
    void SCIPheurSetData(SCIP_HEUR *heur, SCIP_HEURDATA *heurdata)
    Definition: heur.c:1378
    SCIP_Longint SCIPgetLastDivenode(SCIP *scip)
    Definition: scip_lp.c:2710
    SCIP_Bool SCIPhasCurrentNodeLP(SCIP *scip)
    Definition: scip_lp.c:87
    SCIP_LPSOLSTAT SCIPgetLPSolstat(SCIP *scip)
    Definition: scip_lp.c:174
    SCIP_Real SCIPgetLPObjval(SCIP *scip)
    Definition: scip_lp.c:253
    SCIP_Bool SCIPisLPSolBasic(SCIP *scip)
    Definition: scip_lp.c:673
    #define SCIPfreeBlockMemoryArray(scip, ptr, num)
    Definition: scip_mem.h:110
    #define SCIPallocClearBufferArray(scip, ptr, num)
    Definition: scip_mem.h:126
    #define SCIPallocBufferArray(scip, ptr, num)
    Definition: scip_mem.h:124
    #define SCIPallocMemory(scip, ptr)
    Definition: scip_mem.h:60
    #define SCIPfreeBufferArray(scip, ptr)
    Definition: scip_mem.h:136
    #define SCIPfreeMemory(scip, ptr)
    Definition: scip_mem.h:78
    #define SCIPallocBlockMemoryArray(scip, ptr, num)
    Definition: scip_mem.h:93
    #define SCIPreallocBlockMemoryArray(scip, ptr, oldnum, newnum)
    Definition: scip_mem.h:99
    SCIP_RETCODE SCIPcreateSol(SCIP *scip, SCIP_SOL **sol, SCIP_HEUR *heur)
    Definition: scip_sol.c:514
    SCIP_RETCODE SCIPfreeSol(SCIP *scip, SCIP_SOL **sol)
    Definition: scip_sol.c:1250
    int SCIPgetNSols(SCIP *scip)
    Definition: scip_sol.c:2887
    SCIP_Longint SCIPgetNNodes(SCIP *scip)
    SCIP_Longint SCIPgetNNodeLPIterations(SCIP *scip)
    SCIP_Real SCIPgetCutoffbound(SCIP *scip)
    SCIP_RETCODE SCIPperformGenericDivingAlgorithm(SCIP *scip, SCIP_DIVESET *diveset, SCIP_SOL *worksol, SCIP_HEUR *heur, SCIP_RESULT *result, SCIP_Bool nodeinfeasible, SCIP_Longint iterlim, int nodelimit, SCIP_Real lpresolvedomchgquot, SCIP_DIVECONTEXT divecontext)
    Definition: heuristics.c:221
    SCIP_Bool SCIPisGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    int SCIPgetDepth(SCIP *scip)
    Definition: scip_tree.c:672
    void SCIPfreeRandom(SCIP *scip, SCIP_RANDNUMGEN **randnumgen)
    void SCIPsetRandomSeed(SCIP *scip, SCIP_RANDNUMGEN *randnumgen, unsigned int seed)
    SCIP_Real SCIPrandomGetReal(SCIP_RANDNUMGEN *randnumgen, SCIP_Real minrandval, SCIP_Real maxrandval)
    Definition: misc.c:10245
    SCIP_RETCODE SCIPcreateRandom(SCIP *scip, SCIP_RANDNUMGEN **randnumgen, unsigned int initialseed, SCIP_Bool useglobalseed)
    int SCIPrandomGetInt(SCIP_RANDNUMGEN *randnumgen, int minrandval, int maxrandval)
    Definition: misc.c:10223
    static SCIP_Longint getLPIterlimit(SCIP *scip, SCIP_HEUR *heur, SCIP_HEURDATA *heurdata)
    static SCIP_RETCODE divesetGetSelectionScore(SCIP_DIVESET *diveset, SCIP_HEURDATA *heurdata, SCIP_DIVECONTEXT divecontext, SCIP_Real *scoreptr)
    #define DEFAULT_INITIALSEED
    static SCIP_DECL_HEURFREE(heurFreeAdaptivediving)
    static SCIP_DECL_HEUREXIT(heurExitAdaptivediving)
    #define HEUR_TIMING
    static SCIP_DECL_HEURCOPY(heurCopyAdaptivediving)
    static int sampleWeighted(SCIP *scip, SCIP_RANDNUMGEN *rng, SCIP_Real *weights, int nweights)
    static SCIP_RETCODE findAndStoreDivesets(SCIP *scip, SCIP_HEUR *heur, SCIP_HEURDATA *heurdata)
    #define DEFAULT_MAXLPITERQUOT
    #define HEUR_FREQOFS
    #define HEUR_DESC
    #define DEFAULT_USEADAPTIVECONTEXT
    SCIP_RETCODE SCIPincludeHeurAdaptivediving(SCIP *scip)
    #define DEFAULT_SCORETYPE
    #define DEFAULT_SELCONFIDENCECOEFF
    static SCIP_DECL_HEURINIT(heurInitAdaptivediving)
    #define DIVESETS_INITIALSIZE
    #define HEUR_DISPCHAR
    #define DEFAULT_EPSILON
    #define HEUR_MAXDEPTH
    #define HEUR_PRIORITY
    #define DEFAULT_MAXLPITEROFS
    #define DEFAULT_SELTYPE
    #define HEUR_NAME
    static SCIP_DECL_HEUREXEC(heurExecAdaptivediving)
    #define HEUR_FREQ
    #define HEUR_USESSUBSCIP
    static SCIP_RETCODE selectDiving(SCIP *scip, SCIP_HEUR *heur, SCIP_HEURDATA *heurdata, int *selection)
    #define DEFAULT_BESTSOLWEIGHT
    diving heuristic that selects adaptively between the existing, public dive sets
    methods commonly used by primal heuristics
    #define SCIPerrorMessage
    Definition: pub_message.h:64
    default SCIP plugins
    SCIP_SOL * sol
    Definition: struct_heur.h:71
    enum SCIP_DiveContext SCIP_DIVECONTEXT
    Definition: type_heur.h:73
    struct SCIP_HeurData SCIP_HEURDATA
    Definition: type_heur.h:77
    @ SCIP_DIVECONTEXT_TOTAL
    Definition: type_heur.h:68
    @ SCIP_DIVECONTEXT_ADAPTIVE
    Definition: type_heur.h:70
    @ SCIP_LPSOLSTAT_OPTIMAL
    Definition: type_lp.h:44
    @ SCIP_DIDNOTRUN
    Definition: type_result.h:42
    @ SCIP_DELAYED
    Definition: type_result.h:43
    @ SCIP_FOUNDSOL
    Definition: type_result.h:56
    @ SCIP_INVALIDDATA
    Definition: type_retcode.h:52
    @ SCIP_PARAMETERWRONGVAL
    Definition: type_retcode.h:57
    @ SCIP_OKAY
    Definition: type_retcode.h:42
    @ SCIP_INVALIDCALL
    Definition: type_retcode.h:51
    enum SCIP_Retcode SCIP_RETCODE
    Definition: type_retcode.h:63