Scippy

    SCIP

    Solving Constraint Integer Programs

    heur_proximity.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-2025 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_proximity.c
    26 * @ingroup DEFPLUGINS_HEUR
    27 * @brief improvement heuristic which uses an auxiliary objective instead of the original objective function which
    28 * is itself added as a constraint to a sub-SCIP instance. The heuristic was presented by Matteo Fischetti
    29 * and Michele Monaci.
    30 * @author Gregor Hendel
    31 */
    32
    33/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
    34
    36#include "scip/cons_linear.h"
    37#include "scip/heuristics.h"
    38#include "scip/heur_proximity.h"
    39#include "scip/pub_event.h"
    40#include "scip/pub_heur.h"
    41#include "scip/pub_message.h"
    42#include "scip/pub_misc.h"
    43#include "scip/pub_sol.h"
    44#include "scip/pub_var.h"
    45#include "scip/scip_branch.h"
    46#include "scip/scip_cons.h"
    47#include "scip/scip_copy.h"
    48#include "scip/scip_event.h"
    49#include "scip/scip_exact.h"
    50#include "scip/scip_general.h"
    51#include "scip/scip_heur.h"
    52#include "scip/scip_lp.h"
    53#include "scip/scip_mem.h"
    54#include "scip/scip_message.h"
    55#include "scip/scip_nlp.h"
    56#include "scip/scip_nodesel.h"
    57#include "scip/scip_numerics.h"
    58#include "scip/scip_param.h"
    59#include "scip/scip_prob.h"
    60#include "scip/scip_sol.h"
    61#include "scip/scip_solve.h"
    63#include "scip/scip_timing.h"
    64#include "scip/scip_var.h"
    65#include <string.h>
    66
    67#define HEUR_NAME "proximity"
    68#define HEUR_DESC "heuristic trying to improve the incumbent by an auxiliary proximity objective function"
    69#define HEUR_DISPCHAR SCIP_HEURDISPCHAR_LNS
    70#define HEUR_PRIORITY -2000000
    71#define HEUR_FREQ -1
    72#define HEUR_FREQOFS 0
    73#define HEUR_MAXDEPTH -1
    74#define HEUR_TIMING SCIP_HEURTIMING_AFTERNODE
    75#define HEUR_USESSUBSCIP TRUE /**< does the heuristic use a secondary SCIP instance? */
    76
    77/* event handler properties */
    78#define EVENTHDLR_NAME "Proximity"
    79#define EVENTHDLR_DESC "LP event handler for " HEUR_NAME " heuristic"
    80
    81/* default values for proximity-specific parameters */
    82/* todo refine these values */
    83#define DEFAULT_MAXNODES 10000LL /**< maximum number of nodes to regard in the subproblem */
    84#define DEFAULT_MINIMPROVE 0.02 /**< factor by which proximity should at least improve the incumbent */
    85#define DEFAULT_MINGAP 0.01 /**< minimum primal-dual gap for which the heuristic is executed */
    86#define DEFAULT_MINNODES 1LL /**< minimum number of nodes to regard in the subproblem */
    87#define DEFAULT_MINLPITERS 200LL /**< minimum number of LP iterations to perform in one sub-mip */
    88#define DEFAULT_MAXLPITERS 100000LL /**< maximum number of LP iterations to be performed in the subproblem */
    89#define DEFAULT_NODESOFS 50LL /**< number of nodes added to the contingent of the total nodes */
    90#define DEFAULT_WAITINGNODES 100LL /**< default waiting nodes since last incumbent before heuristic is executed */
    91#define DEFAULT_NODESQUOT 0.1 /**< default quotient of sub-MIP nodes with respect to number of processed nodes*/
    92#define DEFAULT_USELPROWS FALSE /**< should subproblem be constructed based on LP row information? */
    93#define DEFAULT_BINVARQUOT 0.1 /**< default threshold for percentage of binary variables required to start */
    94#define DEFAULT_RESTART TRUE /**< should the heuristic immediately run again on its newly found solution? */
    95#define DEFAULT_USEFINALLP FALSE /**< should the heuristic solve a final LP in case of continuous objective variables? */
    96#define DEFAULT_LPITERSQUOT 0.2 /**< default quotient of sub-MIP LP iterations with respect to LP iterations so far */
    97#define DEFAULT_USEUCT FALSE /**< should uct node selection be used at the beginning of the search? */
    98
    99/*
    100 * Data structures
    101 */
    102
    103/** primal heuristic data */
    104struct SCIP_HeurData
    105{
    106 SCIP_Longint maxnodes; /**< maximum number of nodes to regard in the subproblem */
    107 SCIP_Longint minnodes; /**< minimum number of nodes to regard in the subproblem */
    108 SCIP_Longint maxlpiters; /**< maximum number of LP iterations to be performed in the subproblem */
    109 SCIP_Longint nusedlpiters; /**< number of actually performed LP iterations */
    110 SCIP_Longint minlpiters; /**< minimum number of LP iterations to perform in one sub-mip */
    111 SCIP_Longint nodesofs; /**< number of nodes added to the contingent of the total nodes */
    112 SCIP_Longint usednodes; /**< nodes already used by proximity in earlier calls */
    113 SCIP_Longint waitingnodes; /**< waiting nodes since last incumbent before heuristic is executed */
    114 SCIP_Real lpitersquot; /**< quotient of sub-MIP LP iterations with respect to LP iterations so far */
    115 SCIP_Real minimprove; /**< factor by which proximity should at least improve the incumbent */
    116 SCIP_Real mingap; /**< minimum primal-dual gap for which the heuristic is executed */
    117 SCIP_Real nodesquot; /**< quotient of sub-MIP nodes with respect to number of processed nodes */
    118 SCIP_Real binvarquot; /**< threshold for percantage of binary variables required to start */
    119
    120 SCIP* subscip; /**< the subscip used by the heuristic */
    121 SCIP_HASHMAP* varmapfw; /**< map between scip variables and subscip variables */
    122 SCIP_VAR** subvars; /**< variables in subscip */
    123 SCIP_CONS* objcons; /**< the objective cutoff constraint of the subproblem */
    124
    125 int nsubvars; /**< the number of subvars */
    126 int lastsolidx; /**< index of last solution on which the heuristic was processed */
    127 int subprobidx; /**< counter for the subproblem index to be solved by proximity */
    128
    129 SCIP_Bool uselprows; /**< should subproblem be constructed based on LP row information? */
    130 SCIP_Bool restart; /**< should the heuristic immediately run again on its newly found solution? */
    131 SCIP_Bool usefinallp; /**< should the heuristic solve a final LP in case of continuous objective variables? */
    132 SCIP_Bool useuct; /**< should uct node selection be used at the beginning of the search? */
    133};
    134
    135
    136/*
    137 * Local methods
    138 */
    139
    140/** optimizes the continuous variables in an LP diving by fixing all integer variables to the given solution values */
    141static
    143 SCIP* scip, /**< SCIP data structure */
    144 SCIP_SOL* sol, /**< candidate solution for which continuous variables should be optimized */
    145 SCIP_Bool* success /**< was the dive successful? */
    146 )
    147{
    148 SCIP_VAR** vars;
    149 SCIP_RETCODE retstat;
    150
    151 int v;
    152 int nvars;
    153 int ncontvars;
    154 int nintvars;
    155
    156 SCIP_Bool lperror;
    157 SCIP_Bool requiresnlp;
    158
    159 assert(success != NULL);
    160
    161 SCIP_CALL( SCIPgetVarsData(scip, &vars, &nvars, NULL, NULL, NULL, &ncontvars) );
    162
    163 nintvars = nvars - ncontvars;
    164
    165 /**@todo in case of an MINLP, if SCIPisNLPConstructed() is TRUE rather solve the NLP instead of the LP */
    166 requiresnlp = SCIPisNLPConstructed(scip);
    167 if( requiresnlp || ncontvars == 0 )
    168 return SCIP_OKAY;
    169
    170 /* start diving to calculate the LP relaxation */
    172
    173 /* set the bounds of the variables: fixed for integers, global bounds for continuous */
    174 for( v = 0; v < nvars; ++v )
    175 {
    177 {
    178 SCIP_CALL( SCIPchgVarLbDive(scip, vars[v], SCIPvarGetLbGlobal(vars[v])) );
    179 SCIP_CALL( SCIPchgVarUbDive(scip, vars[v], SCIPvarGetUbGlobal(vars[v])) );
    180 }
    181 }
    182
    183 /* apply this after global bounds to not cause an error with intermediate empty domains */
    184 for( v = 0; v < nintvars; ++v )
    185 {
    187 {
    188 SCIP_Real solval;
    189
    190 solval = SCIPgetSolVal(scip, sol, vars[v]);
    191 SCIP_CALL( SCIPchgVarLbDive(scip, vars[v], solval) );
    192 SCIP_CALL( SCIPchgVarUbDive(scip, vars[v], solval) );
    193 }
    194 }
    195
    196 /* solve LP */
    197 SCIPdebugMsg(scip, " -> old LP iterations: %" SCIP_LONGINT_FORMAT "\n", SCIPgetNLPIterations(scip));
    198
    199 /* Errors in the LP solver should not kill the overall solving process, if the LP is just needed for a heuristic.
    200 * Hence in optimized mode, the return code is caught and a warning is printed, only in debug mode, SCIP will stop.
    201 */
    202 retstat = SCIPsolveDiveLP(scip, -1, &lperror, NULL);
    203 if( retstat != SCIP_OKAY )
    204 {
    205#ifdef NDEBUG
    206 SCIPwarningMessage(scip, "Error while solving LP in Proximity heuristic; LP solve terminated with code <%d>\n",retstat);
    207#else
    208 SCIP_CALL( retstat );
    209#endif
    210 }
    211
    212 SCIPdebugMsg(scip, " -> new LP iterations: %" SCIP_LONGINT_FORMAT "\n", SCIPgetNLPIterations(scip));
    213 SCIPdebugMsg(scip, " -> error=%u, status=%d\n", lperror, SCIPgetLPSolstat(scip));
    214 if( !lperror && SCIPgetLPSolstat(scip) == SCIP_LPSOLSTAT_OPTIMAL )
    215 {
    217
    218 /* in exact mode we have to end diving prior to trying the solution */
    219 if( SCIPisExact(scip) )
    220 {
    223 }
    224
    225 SCIP_CALL( SCIPtrySol(scip, sol, FALSE, FALSE, TRUE, TRUE, TRUE, success) );
    226 }
    227
    228 /* terminate diving mode */
    229 if( SCIPinDive(scip) )
    230 {
    232 }
    233
    234 return SCIP_OKAY;
    235}
    236
    237/** creates a new solution for the original problem by copying the solution of the subproblem */
    238static
    240 SCIP* scip, /**< original SCIP data structure */
    241 SCIP* subscip, /**< SCIP structure of the subproblem */
    242 SCIP_VAR** subvars, /**< the variables of the subproblem */
    243 SCIP_HEUR* heur, /**< proximity heuristic structure */
    244 SCIP_SOL* subsol, /**< solution of the subproblem */
    245 SCIP_Bool usefinallp, /**< should continuous variables be optimized by a final LP */
    246 SCIP_Bool* success /**< used to store whether new solution was found or not */
    247 )
    248{
    249 SCIP_VAR** vars; /* the original problem's variables */
    250 int nvars; /* the original problem's number of variables */
    251 int ncontvars; /* the original problem's number of continuous variables */
    252 SCIP_Real* subsolvals; /* solution values of the subproblem */
    253 SCIP_SOL* newsol; /* solution to be created for the original problem */
    254 int i;
    255
    256 assert(scip != NULL);
    257 assert(subscip != NULL);
    258 assert(subvars != NULL);
    259 assert(subsol != NULL);
    260 assert(success != NULL);
    261
    262 /* get variables' data */
    263 SCIP_CALL( SCIPgetVarsData(scip, &vars, &nvars, NULL, NULL, NULL, &ncontvars) );
    264
    265 SCIP_CALL( SCIPallocBufferArray(scip, &subsolvals, nvars) );
    266
    267 /* copy the solution */
    268 for( i = 0; i < nvars; ++i )
    269 {
    270 if( subvars[i] == NULL )
    271 subsolvals[i] = MIN(MAX(0.0, SCIPvarGetLbLocal(vars[i])), SCIPvarGetUbLocal(vars[i])); /*lint !e666*/
    272 else
    273 subsolvals[i] = SCIPgetSolVal(subscip, subsol, subvars[i]);
    274 }
    275
    276 /* create new solution for the original problem */
    277 SCIP_CALL( SCIPcreateSol(scip, &newsol, heur) );
    278 SCIP_CALL( SCIPsetSolVals(scip, newsol, nvars, vars, subsolvals) );
    279
    280 *success = FALSE;
    281
    282 /* solve an LP with all integer variables fixed to improve solution quality */
    283 if( ncontvars > 0 && usefinallp && SCIPisLPConstructed(scip) )
    284 {
    285 int v;
    286 int ncontobjvars = 0; /* does the problem instance have continuous variables with nonzero objective coefficients? */
    287 SCIP_Real sumofobjsquares = 0.0;
    288
    289 /* check if continuous variables with nonzero objective coefficient are present */
    290 for( v = nvars - 1; v >= nvars - ncontvars; --v )
    291 {
    292 SCIP_VAR* var;
    293
    294 var = vars[v];
    295 assert(vars[v] != NULL);
    296 assert(!SCIPvarIsIntegral(var));
    297
    299 {
    300 ++ncontobjvars;
    301 sumofobjsquares += SCIPvarGetObj(var) * SCIPvarGetObj(var);
    302 }
    303 }
    304
    305 SCIPstatisticMessage(" Continuous Objective variables: %d, Euclidean OBJ: %g total, %g continuous\n", ncontobjvars, SCIPgetObjNorm(scip), sumofobjsquares);
    306
    307 /* solve a final LP to optimize solution values of continuous problem variables */
    308 SCIPstatisticMessage("Solution Value before LP resolve: %g\n", SCIPgetSolOrigObj(scip, newsol));
    309 SCIP_CALL( solveLp(scip, newsol, success) );
    310
    311 /* if the LP solve was not successful, reset the solution */
    312 if( !*success )
    313 {
    314 for( v = nvars - 1; v >= nvars - ncontvars; --v )
    315 {
    316 SCIP_CALL( SCIPsetSolVal(scip, newsol, vars[v], subsolvals[v]) );
    317 }
    318 }
    319 }
    320
    321 /* try to add new solution to SCIP and free it immediately */
    322 if( !*success )
    323 {
    324 SCIP_CALL( SCIPtrySol(scip, newsol, FALSE, FALSE, TRUE, TRUE, TRUE, success) );
    325 }
    326 SCIP_CALL( SCIPfreeSol(scip, &newsol) );
    327
    328 SCIPfreeBufferArray(scip, &subsolvals);
    329
    330 return SCIP_OKAY;
    331}
    332
    333/** sets solving parameters for the subproblem created by the heuristic */
    334static
    336 SCIP_HEURDATA* heurdata, /**< heuristic data structure */
    337 SCIP* subscip /**< copied SCIP data structure */
    338 )
    339{
    340 assert(subscip != NULL);
    341
    342 /* do not abort subproblem on CTRL-C */
    343 SCIP_CALL( SCIPsetBoolParam(subscip, "misc/catchctrlc", FALSE) );
    344
    345#ifdef SCIP_DEBUG
    346 /* for debugging, enable full output */
    347 SCIP_CALL( SCIPsetIntParam(subscip, "display/verblevel", 5) );
    348 SCIP_CALL( SCIPsetIntParam(subscip, "display/freq", 100000000) );
    349#else
    350 /* disable statistic timing inside sub SCIP and output to console */
    351 SCIP_CALL( SCIPsetIntParam(subscip, "display/verblevel", 0) );
    352 SCIP_CALL( SCIPsetBoolParam(subscip, "timing/statistictiming", FALSE) );
    353#endif
    354
    355 /* forbid recursive call of heuristics and separators solving sub-SCIPs */
    356 SCIP_CALL( SCIPsetSubscipsOff(subscip, TRUE) );
    357
    358 /* use restart dfs node selection */
    359 if( SCIPfindNodesel(subscip, "restartdfs") != NULL && !SCIPisParamFixed(subscip, "nodeselection/restartdfs/stdpriority") )
    360 {
    361 SCIP_CALL( SCIPsetIntParam(subscip, "nodeselection/restartdfs/stdpriority", INT_MAX/4) );
    362 }
    363
    364 /* activate uct node selection at the top of the tree */
    365 if( heurdata->useuct && SCIPfindNodesel(subscip, "uct") != NULL && !SCIPisParamFixed(subscip, "nodeselection/uct/stdpriority") )
    366 {
    367 SCIP_CALL( SCIPsetIntParam(subscip, "nodeselection/uct/stdpriority", INT_MAX/2) );
    368 }
    369
    370 /* disable expensive presolving
    371 * todo maybe presolving can be entirely turned off here - parameter???
    372 */
    374
    375 /* SCIP_CALL( SCIPsetPresolving(scip, SCIP_PARAMSETTING_OFF, TRUE) ); */
    376 if( !SCIPisParamFixed(subscip, "presolving/maxrounds") )
    377 {
    378 SCIP_CALL( SCIPsetIntParam(subscip, "presolving/maxrounds", 50) );
    379 }
    380
    381 /* disable cutting plane separation */
    383
    384 /* todo: check branching rule in sub-SCIP */
    385 if( SCIPfindBranchrule(subscip, "inference") != NULL && !SCIPisParamFixed(subscip, "branching/inference/priority") )
    386 {
    387 SCIP_CALL( SCIPsetIntParam(subscip, "branching/inference/priority", INT_MAX/4) );
    388 }
    389
    390 /* disable feasibility pump and fractional diving */
    391 if( !SCIPisParamFixed(subscip, "heuristics/feaspump/freq") )
    392 {
    393 SCIP_CALL( SCIPsetIntParam(subscip, "heuristics/feaspump/freq", -1) );
    394 }
    395 if( !SCIPisParamFixed(subscip, "heuristics/fracdiving/freq") )
    396 {
    397 SCIP_CALL( SCIPsetIntParam(subscip, "heuristics/fracdiving/freq", -1) );
    398 }
    399
    400 /* todo check if
    401 * SCIP_CALL( SCIPsetEmphasis(subscip, SCIP_PARAMEMPHASIS_FEASIBILITY, TRUE) );
    402 * improves performance */
    403
    404 return SCIP_OKAY;
    405}
    406
    407/** frees the subproblem */
    408static
    410 SCIP* scip, /**< SCIP data structure */
    411 SCIP_HEURDATA* heurdata /**< heuristic data */
    412 )
    413{
    414 /* free remaining memory from heuristic execution */
    415 if( heurdata->subscip != NULL )
    416 {
    417 assert(heurdata->varmapfw != NULL);
    418 assert(heurdata->subvars != NULL);
    419 assert(heurdata->objcons != NULL);
    420
    421 SCIPdebugMsg(scip, "Freeing subproblem of proximity heuristic\n");
    422 SCIPfreeBlockMemoryArray(scip, &heurdata->subvars, heurdata->nsubvars);
    423 SCIPhashmapFree(&heurdata->varmapfw);
    424 SCIP_CALL( SCIPreleaseCons(heurdata->subscip, &heurdata->objcons) );
    425 SCIP_CALL( SCIPfree(&heurdata->subscip) );
    426
    427 heurdata->subscip = NULL;
    428 heurdata->varmapfw = NULL;
    429 heurdata->subvars = NULL;
    430 heurdata->objcons = NULL;
    431 }
    432 return SCIP_OKAY;
    433}
    434
    435/* ---------------- Callback methods of event handler ---------------- */
    436
    437/** exec the event handler
    438 *
    439 * We interrupt the solution process.
    440 */
    441static
    442SCIP_DECL_EVENTEXEC(eventExecProximity)
    443{
    444 SCIP_HEURDATA* heurdata;
    445
    446 assert(eventhdlr != NULL);
    447 assert(eventdata != NULL);
    448 assert(strcmp(SCIPeventhdlrGetName(eventhdlr), EVENTHDLR_NAME) == 0);
    449 assert(event != NULL);
    451
    452 heurdata = (SCIP_HEURDATA*)eventdata;
    453 assert(heurdata != NULL);
    454
    455 /* interrupt solution process of sub-SCIP
    456 * todo adjust interruption limit */
    457 if( SCIPgetLPSolstat(scip) == SCIP_LPSOLSTAT_ITERLIMIT || SCIPgetNLPIterations(scip) >= heurdata->maxlpiters )
    458 {
    460 }
    461
    462 return SCIP_OKAY;
    463}
    464
    465
    466/* ---------------- Callback methods of primal heuristic ---------------- */
    467
    468/** copy method for primal heuristic plugins (called when SCIP copies plugins) */
    469static
    470SCIP_DECL_HEURCOPY(heurCopyProximity)
    471{ /*lint --e{715}*/
    472 assert(scip != NULL);
    473 assert(heur != NULL);
    474 assert(strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0);
    475
    476 /* call inclusion method of primal heuristic */
    478
    479 return SCIP_OKAY;
    480}
    481
    482/** destructor of primal heuristic to free user data (called when SCIP is exiting) */
    483static
    484SCIP_DECL_HEURFREE(heurFreeProximity)
    485{ /*lint --e{715}*/
    486 SCIP_HEURDATA* heurdata;
    487
    488 assert( heur != NULL );
    489 assert( scip != NULL );
    490
    491 /* get heuristic data */
    492 heurdata = SCIPheurGetData(heur);
    493 assert( heurdata != NULL );
    494
    495 /* free heuristic data */
    496 SCIPfreeBlockMemory(scip, &heurdata);
    497 SCIPheurSetData(heur, NULL);
    498
    499 return SCIP_OKAY;
    500}
    501
    502
    503/** initialization method of primal heuristic (called after problem was transformed) */
    504static
    505SCIP_DECL_HEURINIT(heurInitProximity)
    506{ /*lint --e{715}*/
    507 SCIP_HEURDATA* heurdata;
    508
    509 assert( heur != NULL );
    510 assert( scip != NULL );
    511
    512 /* get heuristic data */
    513 heurdata = SCIPheurGetData(heur);
    514 assert( heurdata != NULL );
    515
    516 /* initialize data */
    517 heurdata->usednodes = 0LL;
    518 heurdata->lastsolidx = -1;
    519 heurdata->nusedlpiters = 0LL;
    520 heurdata->subprobidx = 0;
    521
    522 heurdata->subscip = NULL;
    523 heurdata->varmapfw = NULL;
    524 heurdata->subvars = NULL;
    525 heurdata->objcons = NULL;
    526
    527 heurdata->nsubvars = 0;
    528
    529 return SCIP_OKAY;
    530}
    531
    532/** solution process exiting method of proximity heuristic */
    533static
    534SCIP_DECL_HEUREXITSOL(heurExitsolProximity)
    535{
    536 SCIP_HEURDATA* heurdata;
    537
    538 assert( heur != NULL );
    539 assert( scip != NULL );
    540
    541 /* get heuristic data */
    542 heurdata = SCIPheurGetData(heur);
    543 assert( heurdata != NULL );
    544
    545 SCIP_CALL( deleteSubproblem(scip, heurdata) );
    546
    547 assert(heurdata->subscip == NULL && heurdata->varmapfw == NULL && heurdata->subvars == NULL && heurdata->objcons == NULL);
    548
    549 return SCIP_OKAY;
    550}
    551
    552/** execution method of primal heuristic */
    553static
    554SCIP_DECL_HEUREXEC(heurExecProximity)
    555{ /*lint --e{715}*/
    556 SCIP_HEURDATA* heurdata; /* heuristic's data */
    557 SCIP_Longint nnodes; /* number of stalling nodes for the subproblem */
    558 SCIP_Longint nlpiters; /* lp iteration limit for the subproblem */
    559 SCIP_Bool foundsol = FALSE;
    560
    561 assert(heur != NULL);
    562 assert(scip != NULL);
    563 assert(result != NULL);
    564
    565 *result = SCIP_DIDNOTRUN;
    566
    567 /* get heuristic data */
    568 heurdata = SCIPheurGetData(heur);
    569 assert(heurdata != NULL);
    570
    571 /* do not run heuristic when there are only few binary varables */
    572 if( SCIPgetNBinVars(scip) < heurdata->binvarquot * SCIPgetNVars(scip) )
    573 return SCIP_OKAY;
    574
    575 /* calculate branching node limit for sub problem */
    576 /* todo maybe treat root node differently */
    577 nnodes = (SCIP_Longint) (heurdata->nodesquot * SCIPgetNNodes(scip));
    578 nnodes += heurdata->nodesofs;
    579
    580 /* determine the node and LP iteration limit for the solve of the sub-SCIP */
    581 nnodes -= heurdata->usednodes;
    582 nnodes = MIN(nnodes, heurdata->maxnodes);
    583
    584 nlpiters = (SCIP_Longint) (heurdata->lpitersquot * SCIPgetNRootFirstLPIterations(scip));
    585 nlpiters = MIN(nlpiters, heurdata->maxlpiters);
    586
    587 /* check whether we have enough nodes left to call subproblem solving */
    588 if( nnodes < heurdata->minnodes )
    589 {
    590 SCIPdebugMsg(scip, "skipping proximity: nnodes=%" SCIP_LONGINT_FORMAT ", minnodes=%" SCIP_LONGINT_FORMAT "\n", nnodes, heurdata->minnodes);
    591 return SCIP_OKAY;
    592 }
    593
    594 /* do not run proximity, if the problem does not have an objective function anyway */
    595 if( SCIPgetNObjVars(scip) == 0 )
    596 {
    597 SCIPdebugMsg(scip, "skipping proximity: pure feasibility problem anyway\n");
    598 return SCIP_OKAY;
    599 }
    600
    601 do
    602 {
    603 /* main loop of proximity: in every iteration, a new subproblem is set up and solved until no improved solution
    604 * is found or one of the heuristic limits on nodes or LP iterations is hit
    605 * heuristic performs only one iteration if restart parameter is set to FALSE
    606 */
    607 SCIP_Longint nusednodes = 0LL;
    608 SCIP_Longint nusedlpiters = 0LL;
    609
    610 nlpiters = MAX(nlpiters, heurdata->minlpiters);
    611
    612 /* define and solve the proximity subproblem */
    613 SCIP_CALL( SCIPapplyProximity(scip, heur, result, heurdata->minimprove, nnodes, nlpiters, &nusednodes, &nusedlpiters, FALSE) );
    614
    615 /* adjust node limit and LP iteration limit for future iterations */
    616 assert(nusednodes <= nnodes);
    617 heurdata->usednodes += nusednodes;
    618 nnodes -= nusednodes;
    619
    620 nlpiters -= nusedlpiters;
    621 heurdata->nusedlpiters += nusedlpiters;
    622
    623 /* memorize if a new solution has been found in at least one iteration */
    624 if( *result == SCIP_FOUNDSOL )
    625 foundsol = TRUE;
    626 }
    627 while( *result == SCIP_FOUNDSOL && heurdata->restart && !SCIPisStopped(scip) && nnodes > 0 );
    628
    629 /* reset result pointer if solution has been found in previous iteration */
    630 if( foundsol )
    631 *result = SCIP_FOUNDSOL;
    632
    633 /* free the occupied memory */
    634 if( heurdata->subscip != NULL )
    635 {
    636 /* just for testing the library method, in debug mode, we call the wrapper method for the actual delete method */
    637#ifndef NDEBUG
    639#else
    640 SCIP_CALL( deleteSubproblem(scip, heurdata) );
    641#endif
    642 }
    643 return SCIP_OKAY;
    644}
    645
    646
    647/*
    648 * primal heuristic specific interface methods
    649 */
    650
    651/** frees the sub-MIP created by proximity */
    653 SCIP* scip /** SCIP data structure */
    654 )
    655{
    656 SCIP_HEUR* heur;
    657 SCIP_HEURDATA* heurdata;
    658
    659 assert(scip != NULL);
    660
    661 heur = SCIPfindHeur(scip, HEUR_NAME);
    662 assert(heur != NULL);
    663
    664 heurdata = SCIPheurGetData(heur);
    665 if( heurdata != NULL )
    666 {
    667 SCIP_CALL( deleteSubproblem(scip, heurdata) );
    668 }
    669
    670 return SCIP_OKAY;
    671}
    672
    673/** main procedure of the proximity heuristic, creates and solves a sub-SCIP
    674 *
    675 * @note The method can be applied in an iterative way, keeping the same subscip in between. If the @p freesubscip
    676 * parameter is set to FALSE, the heuristic will keep the subscip data structures. Always set this parameter
    677 * to TRUE, or call SCIPdeleteSubproblemProximity() afterwards.
    678 */
    680 SCIP* scip, /**< original SCIP data structure */
    681 SCIP_HEUR* heur, /**< heuristic data structure */
    682 SCIP_RESULT* result, /**< result data structure */
    683 SCIP_Real minimprove, /**< factor by which proximity should at least improve the incumbent */
    684 SCIP_Longint nnodes, /**< node limit for the subproblem */
    685 SCIP_Longint nlpiters, /**< LP iteration limit for the subproblem */
    686 SCIP_Longint* nusednodes, /**< pointer to store number of used nodes in subscip */
    687 SCIP_Longint* nusedlpiters, /**< pointer to store number of used LP iterations in subscip */
    688 SCIP_Bool freesubscip /**< should the created sub-MIP be freed at the end of the method? */
    689 )
    690{
    691 SCIP* subscip; /* the subproblem created by proximity */
    692 SCIP_HASHMAP* varmapfw; /* mapping of SCIP variables to sub-SCIP variables */
    693 SCIP_VAR** vars; /* original problem's variables */
    694 SCIP_VAR** subvars; /* subproblem's variables */
    695 SCIP_HEURDATA* heurdata; /* heuristic's private data structure */
    696 SCIP_EVENTHDLR* eventhdlr; /* event handler for LP events */
    697
    698 SCIP_SOL* incumbent;
    699 SCIP_CONS* objcons;
    700 SCIP_Longint iterlim;
    701
    702 SCIP_Real large;
    703 SCIP_Real inf;
    704
    705 SCIP_Real bestobj;
    706 SCIP_Real objcutoff;
    707 SCIP_Real lowerbound;
    708
    709 int nvars; /* number of original problem's variables */
    710 int nfixedvars;
    711 int nsubsols;
    712 int solidx;
    713 int i;
    714
    715 SCIP_Bool valid;
    716 SCIP_Bool success;
    717
    718 assert(scip != NULL);
    719 assert(heur != NULL);
    720 assert(result != NULL);
    721
    722 assert(nnodes >= 0);
    723 assert(0.0 <= minimprove && minimprove <= 1.0);
    724
    725 *result = SCIP_DIDNOTRUN;
    726
    727 /* get heuristic data */
    728 heurdata = SCIPheurGetData(heur);
    729 assert(heurdata != NULL);
    730
    731 /* only call the heuristic if we have an incumbent */
    732 if( SCIPgetNSolsFound(scip) == 0 )
    733 return SCIP_OKAY;
    734
    735 /* do not use heuristic on problems without binary variables */
    736 if( SCIPgetNBinVars(scip) == 0 )
    737 return SCIP_OKAY;
    738
    739 incumbent = SCIPgetBestSol(scip);
    740 assert(incumbent != NULL);
    741
    742 /* make sure that the incumbent is valid for the transformed space, otherwise terminate */
    743 if( SCIPsolIsOriginal(incumbent) )
    744 return SCIP_OKAY;
    745
    746 solidx = SCIPsolGetIndex(incumbent);
    747
    748 if( heurdata->lastsolidx == solidx )
    749 return SCIP_OKAY;
    750
    751 /* only call heuristic, if the best solution does not come from trivial heuristic */
    752 if( SCIPsolGetHeur(incumbent) != NULL && strcmp(SCIPheurGetName(SCIPsolGetHeur(incumbent)), "trivial") == 0 )
    753 return SCIP_OKAY;
    754
    755 /* waitingnodes parameter defines the minimum number of nodes to wait before a new incumbent is processed */
    756 if( SCIPgetNNodes(scip) > 1 && SCIPgetNNodes(scip) - SCIPsolGetNodenum(incumbent) < heurdata->waitingnodes )
    757 return SCIP_OKAY;
    758
    759 bestobj = SCIPgetSolTransObj(scip, incumbent);
    760 lowerbound = SCIPgetLowerbound(scip);
    761
    762 /* use knowledge about integrality of objective to round up lower bound */
    764 {
    765 SCIPdebugMsg(scip, " Rounding up lower bound: %f --> %f \n", lowerbound, SCIPfeasCeil(scip, lowerbound));
    766 lowerbound = SCIPfeasCeil(scip, lowerbound);
    767 }
    768
    769 /* do not trigger heuristic if primal and dual bound are already close together */
    770 if( SCIPisFeasLE(scip, bestobj, lowerbound) || SCIPgetGap(scip) <= heurdata->mingap )
    771 return SCIP_OKAY;
    772
    773 /* calculate the minimum improvement for a heuristic solution in terms of the distance between incumbent objective
    774 * and the lower bound */
    775 if( SCIPisInfinity(scip, REALABS(lowerbound)) )
    776 {
    777 if( SCIPisZero(scip, bestobj) )
    778 objcutoff = bestobj - 1;
    779 else
    780 objcutoff = (1 - minimprove) * bestobj;
    781 }
    782 else
    783 objcutoff = minimprove * lowerbound + (1 - minimprove) * (bestobj);
    784
    785 /* use integrality of the objective function to round down (and thus strengthen) the objective cutoff */
    787 objcutoff = SCIPfeasFloor(scip, objcutoff);
    788
    789 if( SCIPisFeasLT(scip, objcutoff, lowerbound) )
    790 objcutoff = lowerbound;
    791
    792 /* exit execution if the right hand side of the objective constraint does not change (suggests that the heuristic
    793 * was not successful in a previous iteration) */
    794 if( heurdata->objcons != NULL && SCIPisFeasEQ(scip, SCIPgetRhsLinear(heurdata->subscip, heurdata->objcons), objcutoff) )
    795 return SCIP_OKAY;
    796
    797 /* check whether there is enough time and memory left */
    799
    800 if( ! valid )
    801 return SCIP_OKAY;
    802
    803 *result = SCIP_DIDNOTFIND;
    804
    805 heurdata->lastsolidx = solidx;
    806
    807 /* get variable data */
    808 SCIP_CALL( SCIPgetVarsData(scip, &vars, &nvars, NULL, NULL, NULL, NULL) );
    809
    810 /* create a subscip and copy the original scip instance into it */
    811 if( heurdata->subscip == NULL )
    812 {
    813 assert(heurdata->varmapfw == NULL);
    814 assert(heurdata->objcons == NULL);
    815
    816 /* initialize the subproblem */
    817 SCIP_CALL( SCIPcreate(&subscip) );
    818
    819 /* create the variable mapping hash map */
    820 SCIP_CALL( SCIPhashmapCreate(&varmapfw, SCIPblkmem(subscip), nvars) );
    821 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &subvars, nvars) );
    822
    823 /* copy complete SCIP instance */
    824 valid = FALSE;
    825
    826 /* create a problem copy as sub SCIP */
    827 SCIP_CALL( SCIPcopyLargeNeighborhoodSearch(scip, subscip, varmapfw, "proximity", NULL, NULL, 0, heurdata->uselprows, TRUE,
    828 &success, &valid) );
    829
    830 SCIPdebugMsg(scip, "Copying the SCIP instance was %s complete.\n", valid ? "" : "not ");
    831
    832 /* create event handler for LP events */
    833 eventhdlr = NULL;
    834 SCIP_CALL( SCIPincludeEventhdlrBasic(subscip, &eventhdlr, EVENTHDLR_NAME, EVENTHDLR_DESC, eventExecProximity, NULL) );
    835 if( eventhdlr == NULL )
    836 {
    837 SCIPerrorMessage("event handler for " HEUR_NAME " heuristic not found.\n");
    838 return SCIP_PLUGINNOTFOUND;
    839 }
    840
    841 /* set up parameters for the copied instance */
    842 SCIP_CALL( setupSubproblem(heurdata, subscip) );
    843
    844 /* create the objective constraint in the sub scip, first without variables and values which will be added later */
    845 SCIP_CALL( SCIPcreateConsBasicLinear(subscip, &objcons, "objbound_of_origscip", 0, NULL, NULL, -SCIPinfinity(subscip), SCIPinfinity(subscip)) );
    846
    847 /* determine large value to set variable bounds to, safe-guard to avoid fixings to infinite values */
    848 large = SCIPinfinity(scip);
    849 if( !SCIPisInfinity(scip, 0.1 / SCIPfeastol(scip)) )
    850 large = 0.1 / SCIPfeastol(scip);
    851 inf = SCIPinfinity(subscip);
    852
    853 /* get variable image and change objective to proximity function (Manhattan distance) in sub-SCIP */
    854 for( i = 0; i < nvars; i++ )
    855 {
    856 SCIP_Real adjustedbound;
    857 SCIP_Real lb;
    858 SCIP_Real ub;
    859
    860 subvars[i] = (SCIP_VAR*) SCIPhashmapGetImage(varmapfw, vars[i]);
    861
    862 if( subvars[i] == NULL )
    863 continue;
    864
    865 SCIP_CALL( SCIPchgVarObj(subscip, subvars[i], 0.0) );
    866
    867 lb = SCIPvarGetLbGlobal(subvars[i]);
    868 ub = SCIPvarGetUbGlobal(subvars[i]);
    869
    870 /* adjust infinite bounds in order to avoid that variables with non-zero objective
    871 * get fixed to infinite value in proximity subproblem
    872 */
    873 if( SCIPisInfinity(subscip, ub) )
    874 {
    875 adjustedbound = MAX(large, lb + large);
    876 adjustedbound = MIN(adjustedbound, inf);
    877 SCIP_CALL( SCIPchgVarUbGlobal(subscip, subvars[i], adjustedbound) );
    878 }
    879 if( SCIPisInfinity(subscip, -lb) )
    880 {
    881 adjustedbound = MIN(-large, ub - large);
    882 adjustedbound = MAX(adjustedbound, -inf);
    883 SCIP_CALL( SCIPchgVarLbGlobal(subscip, subvars[i], adjustedbound) );
    884 }
    885
    886 /* add all nonzero objective coefficients to the objective constraint */
    887 if( !SCIPisFeasZero(subscip, SCIPvarGetObj(vars[i])) )
    888 {
    889 SCIP_CALL( SCIPaddCoefLinear(subscip, objcons, subvars[i], SCIPvarGetObj(vars[i])) );
    890 }
    891 }
    892
    893 /* add objective constraint to the subscip */
    894 SCIP_CALL( SCIPaddCons(subscip, objcons) );
    895 }
    896 else
    897 {
    898 /* the instance, event handler, hash map and variable array were already copied in a previous iteration
    899 * and stored in heuristic data
    900 */
    901 assert(heurdata->varmapfw != NULL);
    902 assert(heurdata->subvars != NULL);
    903 assert(heurdata->objcons != NULL);
    904
    905 subscip = heurdata->subscip;
    906 varmapfw = heurdata->varmapfw;
    907 subvars = heurdata->subvars;
    908 objcons = heurdata->objcons;
    909
    910 eventhdlr = SCIPfindEventhdlr(subscip, EVENTHDLR_NAME);
    911 assert(eventhdlr != NULL);
    912 }
    913
    914 SCIP_CALL( SCIPchgRhsLinear(subscip, objcons, objcutoff) );
    915
    916 for( i = 0; i < SCIPgetNBinVars(scip); ++i )
    917 {
    918 SCIP_Real solval;
    919
    920 if( subvars[i] == NULL )
    921 continue;
    922
    923 /* objective coefficients are only set for binary variables of the problem */
    924 assert(SCIPvarIsBinary(subvars[i]));
    925
    926 solval = SCIPgetSolVal(scip, incumbent, vars[i]);
    927 assert(SCIPisFeasGE(scip, solval, 0.0));
    928 assert(SCIPisFeasLE(scip, solval, 1.0));
    929 assert(SCIPisFeasIntegral(scip, solval));
    930
    931 if( solval < 0.5 )
    932 {
    933 SCIP_CALL( SCIPchgVarObj(subscip, subvars[i], 1.0) );
    934 }
    935 else
    936 {
    937 SCIP_CALL( SCIPchgVarObj(subscip, subvars[i], -1.0) );
    938 }
    939 }
    940
    941 /* set limits for the subproblem */
    942 SCIP_CALL( SCIPcopyLimits(scip, subscip) );
    943 SCIP_CALL( SCIPsetLongintParam(subscip, "limits/nodes", nnodes) );
    944 SCIP_CALL( SCIPsetIntParam(subscip, "limits/solutions", 1) );
    945
    946 /* restrict LP iterations */
    947 /* todo set iterations limit depending on the number of iterations of the original problem root */
    948 iterlim = nlpiters;
    949 SCIP_CALL( SCIPsetLongintParam(subscip, "lp/iterlim", MAX(1, iterlim / MIN(10, nnodes))) );
    950 SCIP_CALL( SCIPsetLongintParam(subscip, "lp/rootiterlim", iterlim) );
    951
    952 /* catch LP events of sub-SCIP */
    953 SCIP_CALL( SCIPtransformProb(subscip) );
    954 SCIP_CALL( SCIPcatchEvent(subscip, SCIP_EVENTTYPE_NODESOLVED, eventhdlr, (SCIP_EVENTDATA*) heurdata, NULL) );
    955
    956 SCIPstatisticMessage("solving subproblem at Node: %" SCIP_LONGINT_FORMAT " "
    957 "nnodes: %" SCIP_LONGINT_FORMAT " "
    958 "iterlim: %" SCIP_LONGINT_FORMAT "\n", SCIPgetNNodes(scip), nnodes, iterlim);
    959
    960 /* solve the subproblem with all previously adjusted parameters */
    961 nfixedvars = SCIPgetNFixedVars(subscip);
    962
    963 SCIP_CALL( SCIPpresolve(subscip) );
    964
    965 nfixedvars = SCIPgetNFixedVars(subscip) - nfixedvars;
    966 assert(nfixedvars >= 0);
    967 SCIPstatisticMessage("presolve fixings %d: %d\n", ++(heurdata->subprobidx), nfixedvars);
    968
    969 /* errors in solving the subproblem should not kill the overall solving process;
    970 * hence, the return code is caught and a warning is printed, only in debug mode, SCIP will stop.
    971 */
    972 SCIP_CALL_ABORT( SCIPsolve(subscip) );
    973
    974 /* print solving statistics of subproblem if we are in SCIP's debug mode */
    976 SCIPstatisticMessage("solve of subscip %d:"
    977 "usednodes: %" SCIP_LONGINT_FORMAT " "
    978 "lp iters: %" SCIP_LONGINT_FORMAT " "
    979 "root iters: %" SCIP_LONGINT_FORMAT " "
    980 "Presolving Time: %.2f\n", heurdata->subprobidx,
    982
    983 SCIPstatisticMessage("Solving Time %d: %.2f\n", heurdata->subprobidx, SCIPgetSolvingTime(subscip) );
    984
    985 /* drop LP events of sub-SCIP */
    986 SCIP_CALL( SCIPdropEvent(subscip, SCIP_EVENTTYPE_NODESOLVED, eventhdlr, (SCIP_EVENTDATA*) heurdata, -1) );
    987
    988 /* keep track of relevant information for future runs of heuristic */
    989 if( nusednodes != NULL )
    990 *nusednodes = SCIPgetNNodes(subscip);
    991 if( nusedlpiters != NULL )
    992 *nusedlpiters = SCIPgetNLPIterations(subscip);
    993
    994 /* check whether a solution was found */
    995 nsubsols = SCIPgetNSols(subscip);
    996 incumbent = SCIPgetBestSol(subscip);
    997 assert(nsubsols == 0 || incumbent != NULL);
    998
    999 SCIPstatisticMessage("primal bound before subproblem %d: %g\n", heurdata->subprobidx, SCIPgetPrimalbound(scip));
    1000 if( nsubsols > 0 )
    1001 {
    1002 /* try to translate the sub problem solution to the original scip instance */
    1003 success = FALSE;
    1004 SCIP_CALL( createNewSol(scip, subscip, subvars, heur, incumbent, heurdata->usefinallp, &success) );
    1005
    1006 if( success )
    1007 *result = SCIP_FOUNDSOL;
    1008 }
    1009 SCIPstatisticMessage("primal bound after subproblem %d: %g\n", heurdata->subprobidx, SCIPgetPrimalbound(scip));
    1010
    1011 /* free the transformed subproblem data */
    1012 SCIP_CALL( SCIPfreeTransform(subscip) );
    1013
    1014 /* save subproblem in heuristic data for subsequent runs if it has been successful, otherwise free subproblem */
    1015 heurdata->subscip = subscip;
    1016 heurdata->varmapfw = varmapfw;
    1017 heurdata->subvars = subvars;
    1018 heurdata->objcons = objcons;
    1019 heurdata->nsubvars = nvars;
    1020
    1021 /* delete the sub problem */
    1022 if( freesubscip )
    1023 {
    1024 SCIP_CALL( deleteSubproblem(scip, heurdata) );
    1025 }
    1026
    1027 return SCIP_OKAY;
    1028}
    1029
    1030
    1031/** creates the proximity primal heuristic and includes it in SCIP */
    1033 SCIP* scip /**< SCIP data structure */
    1034 )
    1035{
    1036 SCIP_HEURDATA* heurdata;
    1037 SCIP_HEUR* heur = NULL;
    1038
    1039 /* create heuristic data */
    1040 SCIP_CALL( SCIPallocBlockMemory(scip, &heurdata) );
    1041
    1042 /* include primal heuristic */
    1045 HEUR_MAXDEPTH, HEUR_TIMING, HEUR_USESSUBSCIP, heurExecProximity, heurdata) );
    1046 assert(heur != NULL);
    1047
    1048 /* primal heuristic is safe to use in exact solving mode */
    1049 SCIPheurMarkExact(heur);
    1050
    1051 /* set non-NULL pointers to callback methods */
    1052 SCIP_CALL( SCIPsetHeurCopy(scip, heur, heurCopyProximity) );
    1053 SCIP_CALL( SCIPsetHeurFree(scip, heur, heurFreeProximity) );
    1054 SCIP_CALL( SCIPsetHeurInit(scip, heur, heurInitProximity) );
    1055 SCIP_CALL( SCIPsetHeurExitsol(scip, heur, heurExitsolProximity) );
    1056
    1057 /* add proximity primal heuristic parameters */
    1058 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/uselprows",
    1059 "should subproblem be constructed based on LP row information?",
    1060 &heurdata->uselprows, TRUE, DEFAULT_USELPROWS, NULL, NULL) );
    1061
    1062 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/restart",
    1063 "should the heuristic immediately run again on its newly found solution?",
    1064 &heurdata->restart, TRUE, DEFAULT_RESTART, NULL, NULL) );
    1065
    1066 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/usefinallp",
    1067 "should the heuristic solve a final LP in case of continuous objective variables?",
    1068 &heurdata->usefinallp, TRUE, DEFAULT_USEFINALLP, NULL, NULL) );
    1069
    1070 SCIP_CALL( SCIPaddLongintParam(scip, "heuristics/" HEUR_NAME "/maxnodes",
    1071 "maximum number of nodes to regard in the subproblem",
    1072 &heurdata->maxnodes, TRUE,DEFAULT_MAXNODES, 0LL, SCIP_LONGINT_MAX, NULL, NULL) );
    1073
    1074 SCIP_CALL( SCIPaddLongintParam(scip, "heuristics/" HEUR_NAME "/nodesofs",
    1075 "number of nodes added to the contingent of the total nodes",
    1076 &heurdata->nodesofs, TRUE, DEFAULT_NODESOFS, 0LL, SCIP_LONGINT_MAX, NULL, NULL) );
    1077
    1078 SCIP_CALL( SCIPaddLongintParam(scip, "heuristics/" HEUR_NAME "/minnodes",
    1079 "minimum number of nodes required to start the subproblem",
    1080 &heurdata->minnodes, TRUE, DEFAULT_MINNODES, 0LL, SCIP_LONGINT_MAX, NULL, NULL) );
    1081
    1082 SCIP_CALL( SCIPaddLongintParam(scip, "heuristics/" HEUR_NAME "/maxlpiters",
    1083 "maximum number of LP iterations to be performed in the subproblem",
    1084 &heurdata->maxlpiters, TRUE, DEFAULT_MAXLPITERS, -1LL, SCIP_LONGINT_MAX, NULL, NULL) );
    1085
    1086 SCIP_CALL( SCIPaddLongintParam(scip, "heuristics/" HEUR_NAME "/minlpiters",
    1087 "minimum number of LP iterations performed in subproblem",
    1088 &heurdata->minlpiters, TRUE, DEFAULT_MINLPITERS, 0LL, SCIP_LONGINT_MAX, NULL, NULL) );
    1089
    1090 SCIP_CALL( SCIPaddLongintParam(scip, "heuristics/" HEUR_NAME "/waitingnodes",
    1091 "waiting nodes since last incumbent before heuristic is executed",
    1092 &heurdata->waitingnodes, TRUE, DEFAULT_WAITINGNODES, 0LL, SCIP_LONGINT_MAX, NULL, NULL) );
    1093
    1094 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/minimprove",
    1095 "factor by which proximity should at least improve the incumbent",
    1096 &heurdata->minimprove, TRUE, DEFAULT_MINIMPROVE, 0.0, 1.0, NULL, NULL) );
    1097
    1098 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/nodesquot",
    1099 "sub-MIP node limit w.r.t number of original nodes",
    1100 &heurdata->nodesquot, TRUE, DEFAULT_NODESQUOT, 0.0, SCIPinfinity(scip), NULL, NULL) );
    1101
    1102 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/binvarquot",
    1103 "threshold for percentage of binary variables required to start",
    1104 &heurdata->binvarquot, TRUE, DEFAULT_BINVARQUOT, 0.0, 1.0, NULL, NULL) );
    1105
    1106 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/lpitersquot",
    1107 "quotient of sub-MIP LP iterations with respect to LP iterations so far",
    1108 &heurdata->lpitersquot, TRUE, DEFAULT_LPITERSQUOT, 0.0, 1.0, NULL, NULL) );
    1109
    1110 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/mingap",
    1111 "minimum primal-dual gap for which the heuristic is executed",
    1112 &heurdata->mingap, TRUE, DEFAULT_MINGAP, 0.0, SCIPinfinity(scip), NULL, NULL) );
    1113
    1114 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/useuct",
    1115 "should uct node selection be used at the beginning of the search?",
    1116 &heurdata->useuct, TRUE, DEFAULT_USEUCT, NULL, NULL) );
    1117
    1118 return SCIP_OKAY;
    1119}
    Constraint handler for linear constraints in their most general form, .
    #define NULL
    Definition: def.h:248
    #define SCIP_Longint
    Definition: def.h:141
    #define SCIP_Bool
    Definition: def.h:91
    #define MIN(x, y)
    Definition: def.h:224
    #define SCIP_Real
    Definition: def.h:156
    #define TRUE
    Definition: def.h:93
    #define FALSE
    Definition: def.h:94
    #define MAX(x, y)
    Definition: def.h:220
    #define SCIP_CALL_ABORT(x)
    Definition: def.h:334
    #define SCIP_LONGINT_FORMAT
    Definition: def.h:148
    #define REALABS(x)
    Definition: def.h:182
    #define SCIP_LONGINT_MAX
    Definition: def.h:142
    #define SCIP_CALL(x)
    Definition: def.h:355
    #define nnodes
    Definition: gastrans.c:74
    SCIP_Real SCIPgetRhsLinear(SCIP *scip, SCIP_CONS *cons)
    SCIP_RETCODE SCIPchgRhsLinear(SCIP *scip, SCIP_CONS *cons, SCIP_Real rhs)
    SCIP_RETCODE SCIPaddCoefLinear(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real val)
    SCIP_RETCODE SCIPcreateConsBasicLinear(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_Real *vals, SCIP_Real lhs, SCIP_Real rhs)
    SCIP_RETCODE SCIPcheckCopyLimits(SCIP *sourcescip, SCIP_Bool *success)
    Definition: scip_copy.c:3249
    SCIP_RETCODE SCIPcopyLimits(SCIP *sourcescip, SCIP *targetscip)
    Definition: scip_copy.c:3292
    SCIP_Bool SCIPisStopped(SCIP *scip)
    Definition: scip_general.c:759
    SCIP_RETCODE SCIPfree(SCIP **scip)
    Definition: scip_general.c:402
    SCIP_RETCODE SCIPcreate(SCIP **scip)
    Definition: scip_general.c:370
    int SCIPgetNObjVars(SCIP *scip)
    Definition: scip_prob.c:2616
    SCIP_RETCODE SCIPgetVarsData(SCIP *scip, SCIP_VAR ***vars, int *nvars, int *nbinvars, int *nintvars, int *nimplvars, int *ncontvars)
    Definition: scip_prob.c:2115
    int SCIPgetNVars(SCIP *scip)
    Definition: scip_prob.c:2246
    SCIP_RETCODE SCIPaddCons(SCIP *scip, SCIP_CONS *cons)
    Definition: scip_prob.c:3274
    SCIP_Real SCIPgetObjNorm(SCIP *scip)
    Definition: scip_prob.c:1880
    int SCIPgetNFixedVars(SCIP *scip)
    Definition: scip_prob.c:2705
    int SCIPgetNBinVars(SCIP *scip)
    Definition: scip_prob.c:2293
    SCIP_Bool SCIPisObjIntegral(SCIP *scip)
    Definition: scip_prob.c:1801
    void SCIPhashmapFree(SCIP_HASHMAP **hashmap)
    Definition: misc.c:3095
    void * SCIPhashmapGetImage(SCIP_HASHMAP *hashmap, void *origin)
    Definition: misc.c:3284
    SCIP_RETCODE SCIPhashmapCreate(SCIP_HASHMAP **hashmap, BMS_BLKMEM *blkmem, int mapsize)
    Definition: misc.c:3061
    #define SCIPdebugMsg
    Definition: scip_message.h:78
    void SCIPwarningMessage(SCIP *scip, const char *formatstr,...)
    Definition: scip_message.c:120
    SCIP_RETCODE SCIPdeleteSubproblemProximity(SCIP *scip)
    SCIP_RETCODE SCIPapplyProximity(SCIP *scip, SCIP_HEUR *heur, SCIP_RESULT *result, SCIP_Real minimprove, SCIP_Longint nnodes, SCIP_Longint nlpiters, SCIP_Longint *nusednodes, SCIP_Longint *nusedlpiters, SCIP_Bool freesubscip)
    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_Bool SCIPisParamFixed(SCIP *scip, const char *name)
    Definition: scip_param.c:219
    SCIP_RETCODE SCIPsetLongintParam(SCIP *scip, const char *name, SCIP_Longint value)
    Definition: scip_param.c:545
    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 SCIPsetIntParam(SCIP *scip, const char *name, int value)
    Definition: scip_param.c:487
    SCIP_RETCODE SCIPsetSubscipsOff(SCIP *scip, SCIP_Bool quiet)
    Definition: scip_param.c:904
    SCIP_RETCODE SCIPsetPresolving(SCIP *scip, SCIP_PARAMSETTING paramsetting, SCIP_Bool quiet)
    Definition: scip_param.c:956
    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_RETCODE SCIPsetBoolParam(SCIP *scip, const char *name, SCIP_Bool value)
    Definition: scip_param.c:429
    SCIP_RETCODE SCIPsetSeparating(SCIP *scip, SCIP_PARAMSETTING paramsetting, SCIP_Bool quiet)
    Definition: scip_param.c:985
    SCIP_RETCODE SCIPincludeHeurProximity(SCIP *scip)
    SCIP_BRANCHRULE * SCIPfindBranchrule(SCIP *scip, const char *name)
    Definition: scip_branch.c:304
    SCIP_RETCODE SCIPreleaseCons(SCIP *scip, SCIP_CONS **cons)
    Definition: scip_cons.c:1173
    SCIP_RETCODE SCIPincludeEventhdlrBasic(SCIP *scip, SCIP_EVENTHDLR **eventhdlrptr, const char *name, const char *desc, SCIP_DECL_EVENTEXEC((*eventexec)), SCIP_EVENTHDLRDATA *eventhdlrdata)
    Definition: scip_event.c:111
    SCIP_EVENTHDLR * SCIPfindEventhdlr(SCIP *scip, const char *name)
    Definition: scip_event.c:241
    const char * SCIPeventhdlrGetName(SCIP_EVENTHDLR *eventhdlr)
    Definition: event.c:396
    SCIP_EVENTTYPE SCIPeventGetType(SCIP_EVENT *event)
    Definition: event.c:1194
    SCIP_RETCODE SCIPcatchEvent(SCIP *scip, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int *filterpos)
    Definition: scip_event.c:293
    SCIP_RETCODE SCIPdropEvent(SCIP *scip, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int filterpos)
    Definition: scip_event.c:333
    SCIP_Bool SCIPisExact(SCIP *scip)
    Definition: scip_exact.c:193
    SCIP_RETCODE SCIPsetHeurExitsol(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEUREXITSOL((*heurexitsol)))
    Definition: scip_heur.c:247
    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_RETCODE SCIPsetHeurFree(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEURFREE((*heurfree)))
    Definition: scip_heur.c:183
    SCIP_HEUR * SCIPfindHeur(SCIP *scip, const char *name)
    Definition: scip_heur.c:263
    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
    void SCIPheurSetData(SCIP_HEUR *heur, SCIP_HEURDATA *heurdata)
    Definition: heur.c:1378
    SCIP_RETCODE SCIPchgVarLbDive(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
    Definition: scip_lp.c:2384
    SCIP_RETCODE SCIPchgVarUbDive(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
    Definition: scip_lp.c:2416
    SCIP_RETCODE SCIPstartDive(SCIP *scip)
    Definition: scip_lp.c:2206
    SCIP_RETCODE SCIPsolveDiveLP(SCIP *scip, int itlim, SCIP_Bool *lperror, SCIP_Bool *cutoff)
    Definition: scip_lp.c:2643
    SCIP_RETCODE SCIPendDive(SCIP *scip)
    Definition: scip_lp.c:2255
    SCIP_Bool SCIPinDive(SCIP *scip)
    Definition: scip_lp.c:2740
    SCIP_Bool SCIPisLPConstructed(SCIP *scip)
    Definition: scip_lp.c:105
    SCIP_LPSOLSTAT SCIPgetLPSolstat(SCIP *scip)
    Definition: scip_lp.c:174
    #define SCIPfreeBlockMemoryArray(scip, ptr, num)
    Definition: scip_mem.h:110
    BMS_BLKMEM * SCIPblkmem(SCIP *scip)
    Definition: scip_mem.c:57
    #define SCIPallocBufferArray(scip, ptr, num)
    Definition: scip_mem.h:124
    #define SCIPfreeBufferArray(scip, ptr)
    Definition: scip_mem.h:136
    #define SCIPallocBlockMemoryArray(scip, ptr, num)
    Definition: scip_mem.h:93
    #define SCIPfreeBlockMemory(scip, ptr)
    Definition: scip_mem.h:108
    #define SCIPallocBlockMemory(scip, ptr)
    Definition: scip_mem.h:89
    SCIP_Bool SCIPisNLPConstructed(SCIP *scip)
    Definition: scip_nlp.c:110
    SCIP_NODESEL * SCIPfindNodesel(SCIP *scip, const char *name)
    Definition: scip_nodesel.c:242
    SCIP_SOL * SCIPgetBestSol(SCIP *scip)
    Definition: scip_sol.c:2981
    SCIP_RETCODE SCIPcreateSol(SCIP *scip, SCIP_SOL **sol, SCIP_HEUR *heur)
    Definition: scip_sol.c:516
    SCIP_RETCODE SCIPfreeSol(SCIP *scip, SCIP_SOL **sol)
    Definition: scip_sol.c:1252
    SCIP_Longint SCIPsolGetNodenum(SCIP_SOL *sol)
    Definition: sol.c:4239
    int SCIPgetNSols(SCIP *scip)
    Definition: scip_sol.c:2882
    SCIP_HEUR * SCIPsolGetHeur(SCIP_SOL *sol)
    Definition: sol.c:4259
    SCIP_RETCODE SCIPunlinkSol(SCIP *scip, SCIP_SOL *sol)
    Definition: scip_sol.c:1506
    SCIP_Bool SCIPsolIsOriginal(SCIP_SOL *sol)
    Definition: sol.c:4140
    int SCIPsolGetIndex(SCIP_SOL *sol)
    Definition: sol.c:4290
    SCIP_RETCODE SCIPsetSolVals(SCIP *scip, SCIP_SOL *sol, int nvars, SCIP_VAR **vars, SCIP_Real *vals)
    Definition: scip_sol.c:1662
    SCIP_RETCODE SCIPtrySol(SCIP *scip, SCIP_SOL *sol, SCIP_Bool printreason, SCIP_Bool completely, SCIP_Bool checkbounds, SCIP_Bool checkintegrality, SCIP_Bool checklprows, SCIP_Bool *stored)
    Definition: scip_sol.c:4012
    SCIP_RETCODE SCIPlinkLPSol(SCIP *scip, SCIP_SOL *sol)
    Definition: scip_sol.c:1295
    SCIP_Real SCIPgetSolOrigObj(SCIP *scip, SCIP_SOL *sol)
    Definition: scip_sol.c:1892
    SCIP_RETCODE SCIPsetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var, SCIP_Real val)
    Definition: scip_sol.c:1571
    SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
    Definition: scip_sol.c:1765
    SCIP_Real SCIPgetSolTransObj(SCIP *scip, SCIP_SOL *sol)
    Definition: scip_sol.c:2005
    SCIP_RETCODE SCIPtransformProb(SCIP *scip)
    Definition: scip_solve.c:232
    SCIP_RETCODE SCIPpresolve(SCIP *scip)
    Definition: scip_solve.c:2449
    SCIP_RETCODE SCIPfreeTransform(SCIP *scip)
    Definition: scip_solve.c:3462
    SCIP_RETCODE SCIPinterruptSolve(SCIP *scip)
    Definition: scip_solve.c:3548
    SCIP_RETCODE SCIPsolve(SCIP *scip)
    Definition: scip_solve.c:2635
    SCIP_Longint SCIPgetNSolsFound(SCIP *scip)
    SCIP_Real SCIPgetPrimalbound(SCIP *scip)
    SCIP_Real SCIPgetGap(SCIP *scip)
    SCIP_Longint SCIPgetNNodes(SCIP *scip)
    SCIP_RETCODE SCIPprintStatistics(SCIP *scip, FILE *file)
    SCIP_Real SCIPgetLowerbound(SCIP *scip)
    SCIP_Longint SCIPgetNRootLPIterations(SCIP *scip)
    SCIP_Longint SCIPgetNRootFirstLPIterations(SCIP *scip)
    SCIP_Longint SCIPgetNLPIterations(SCIP *scip)
    SCIP_RETCODE SCIPcopyLargeNeighborhoodSearch(SCIP *sourcescip, SCIP *subscip, SCIP_HASHMAP *varmap, const char *suffix, SCIP_VAR **fixedvars, SCIP_Real *fixedvals, int nfixedvars, SCIP_Bool uselprows, SCIP_Bool copycuts, SCIP_Bool *success, SCIP_Bool *valid)
    Definition: heuristics.c:953
    SCIP_Real SCIPgetSolvingTime(SCIP *scip)
    Definition: scip_timing.c:378
    SCIP_Real SCIPgetPresolvingTime(SCIP *scip)
    Definition: scip_timing.c:442
    SCIP_Bool SCIPisFeasGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Real SCIPinfinity(SCIP *scip)
    SCIP_Bool SCIPisFeasEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Real SCIPfeasCeil(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisFeasZero(SCIP *scip, SCIP_Real val)
    SCIP_Real SCIPfeasFloor(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisFeasLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisFeasLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisFeasIntegral(SCIP *scip, SCIP_Real val)
    SCIP_Real SCIPfeastol(SCIP *scip)
    SCIP_Bool SCIPisZero(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPvarIsBinary(SCIP_VAR *var)
    Definition: var.c:23478
    SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
    Definition: var.c:23386
    SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
    Definition: var.c:24268
    SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
    Definition: var.c:23900
    SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
    Definition: var.c:24142
    SCIP_RETCODE SCIPchgVarLbGlobal(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
    Definition: scip_var.c:6141
    SCIP_Bool SCIPvarIsIntegral(SCIP_VAR *var)
    Definition: var.c:23490
    SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
    Definition: var.c:24234
    SCIP_RETCODE SCIPchgVarUbGlobal(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
    Definition: scip_var.c:6230
    SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
    Definition: var.c:24120
    SCIP_RETCODE SCIPchgVarObj(SCIP *scip, SCIP_VAR *var, SCIP_Real newobj)
    Definition: scip_var.c:5372
    static SCIP_RETCODE solveLp(SCIP *scip, SCIP_SOL *sol, SCIP_Bool *success)
    static SCIP_DECL_HEURINIT(heurInitProximity)
    #define DEFAULT_RESTART
    #define DEFAULT_NODESQUOT
    static SCIP_RETCODE createNewSol(SCIP *scip, SCIP *subscip, SCIP_VAR **subvars, SCIP_HEUR *heur, SCIP_SOL *subsol, SCIP_Bool usefinallp, SCIP_Bool *success)
    #define DEFAULT_BINVARQUOT
    #define DEFAULT_NODESOFS
    #define DEFAULT_MINGAP
    #define DEFAULT_USEFINALLP
    #define DEFAULT_MAXNODES
    static SCIP_RETCODE setupSubproblem(SCIP_HEURDATA *heurdata, SCIP *subscip)
    #define HEUR_TIMING
    #define DEFAULT_MINNODES
    #define HEUR_FREQOFS
    #define HEUR_DESC
    #define DEFAULT_WAITINGNODES
    #define DEFAULT_USEUCT
    static SCIP_RETCODE deleteSubproblem(SCIP *scip, SCIP_HEURDATA *heurdata)
    static SCIP_DECL_HEUREXITSOL(heurExitsolProximity)
    #define HEUR_DISPCHAR
    #define HEUR_MAXDEPTH
    #define HEUR_PRIORITY
    #define DEFAULT_MINIMPROVE
    #define HEUR_NAME
    #define DEFAULT_USELPROWS
    #define DEFAULT_LPITERSQUOT
    static SCIP_DECL_HEUREXEC(heurExecProximity)
    #define EVENTHDLR_DESC
    #define HEUR_FREQ
    #define DEFAULT_MAXLPITERS
    static SCIP_DECL_HEURCOPY(heurCopyProximity)
    #define HEUR_USESSUBSCIP
    static SCIP_DECL_HEURFREE(heurFreeProximity)
    #define EVENTHDLR_NAME
    static SCIP_DECL_EVENTEXEC(eventExecProximity)
    #define DEFAULT_MINLPITERS
    improvement heuristic which uses an auxiliary objective instead of the original objective function wh...
    methods commonly used by primal heuristics
    memory allocation routines
    public methods for managing events
    public methods for primal heuristics
    public methods for message output
    #define SCIPerrorMessage
    Definition: pub_message.h:64
    #define SCIPstatisticMessage
    Definition: pub_message.h:123
    #define SCIPdebug(x)
    Definition: pub_message.h:93
    public data structures and miscellaneous methods
    public methods for primal CIP solutions
    public methods for problem variables
    public methods for branching rule plugins and branching
    public methods for constraint handler plugins and constraints
    public methods for problem copies
    public methods for event handler plugins and event handlers
    public methods for exact solving
    general public methods
    public methods for primal heuristic plugins and divesets
    public methods for the LP relaxation, rows and columns
    public methods for memory management
    public methods for message handling
    public methods for nonlinear relaxation
    public methods for node selector plugins
    public methods for numerical tolerances
    public methods for SCIP parameter handling
    public methods for global and local (sub)problems
    public methods for solutions
    public solving methods
    public methods for querying solving statistics
    public methods for timing
    public methods for SCIP variables
    struct SCIP_EventData SCIP_EVENTDATA
    Definition: type_event.h:179
    #define SCIP_EVENTTYPE_NODESOLVED
    Definition: type_event.h:138
    struct SCIP_HeurData SCIP_HEURDATA
    Definition: type_heur.h:77
    @ SCIP_LPSOLSTAT_OPTIMAL
    Definition: type_lp.h:44
    @ SCIP_LPSOLSTAT_ITERLIMIT
    Definition: type_lp.h:48
    @ SCIP_PARAMSETTING_OFF
    Definition: type_paramset.h:63
    @ SCIP_PARAMSETTING_FAST
    Definition: type_paramset.h:62
    @ SCIP_DIDNOTRUN
    Definition: type_result.h:42
    @ SCIP_DIDNOTFIND
    Definition: type_result.h:44
    @ SCIP_FOUNDSOL
    Definition: type_result.h:56
    enum SCIP_Result SCIP_RESULT
    Definition: type_result.h:61
    @ SCIP_PLUGINNOTFOUND
    Definition: type_retcode.h:54
    @ SCIP_OKAY
    Definition: type_retcode.h:42
    enum SCIP_Retcode SCIP_RETCODE
    Definition: type_retcode.h:63
    @ SCIP_VARSTATUS_COLUMN
    Definition: type_var.h:53