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-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_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
    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(event != NULL);
    450
    452
    453 heurdata = (SCIP_HEURDATA*)eventdata;
    454 assert(heurdata != NULL);
    455
    456 /* interrupt solution process of sub-SCIP
    457 * todo adjust interruption limit */
    458 if( SCIPgetLPSolstat(scip) == SCIP_LPSOLSTAT_ITERLIMIT || SCIPgetNLPIterations(scip) >= heurdata->maxlpiters )
    459 {
    461 }
    462
    463 return SCIP_OKAY;
    464}
    465
    466
    467/* ---------------- Callback methods of primal heuristic ---------------- */
    468
    469/** copy method for primal heuristic plugins (called when SCIP copies plugins) */
    470static
    471SCIP_DECL_HEURCOPY(heurCopyProximity)
    472{ /*lint --e{715}*/
    473 assert(scip != NULL);
    474 assert(heur != NULL);
    475
    477
    478 /* call inclusion method of primal heuristic */
    480
    481 return SCIP_OKAY;
    482}
    483
    484/** destructor of primal heuristic to free user data (called when SCIP is exiting) */
    485static
    486SCIP_DECL_HEURFREE(heurFreeProximity)
    487{ /*lint --e{715}*/
    488 SCIP_HEURDATA* heurdata;
    489
    490 assert( heur != NULL );
    491 assert( scip != NULL );
    492
    493 /* get heuristic data */
    494 heurdata = SCIPheurGetData(heur);
    495 assert( heurdata != NULL );
    496
    497 /* free heuristic data */
    498 SCIPfreeBlockMemory(scip, &heurdata);
    499 SCIPheurSetData(heur, NULL);
    500
    501 return SCIP_OKAY;
    502}
    503
    504
    505/** initialization method of primal heuristic (called after problem was transformed) */
    506static
    507SCIP_DECL_HEURINIT(heurInitProximity)
    508{ /*lint --e{715}*/
    509 SCIP_HEURDATA* heurdata;
    510
    511 assert( heur != NULL );
    512 assert( scip != NULL );
    513
    514 /* get heuristic data */
    515 heurdata = SCIPheurGetData(heur);
    516 assert( heurdata != NULL );
    517
    518 /* initialize data */
    519 heurdata->usednodes = 0LL;
    520 heurdata->lastsolidx = -1;
    521 heurdata->nusedlpiters = 0LL;
    522 heurdata->subprobidx = 0;
    523
    524 heurdata->subscip = NULL;
    525 heurdata->varmapfw = NULL;
    526 heurdata->subvars = NULL;
    527 heurdata->objcons = NULL;
    528
    529 heurdata->nsubvars = 0;
    530
    531 return SCIP_OKAY;
    532}
    533
    534/** solution process exiting method of proximity heuristic */
    535static
    536SCIP_DECL_HEUREXITSOL(heurExitsolProximity)
    537{
    538 SCIP_HEURDATA* heurdata;
    539
    540 assert( heur != NULL );
    541 assert( scip != NULL );
    542
    543 /* get heuristic data */
    544 heurdata = SCIPheurGetData(heur);
    545 assert( heurdata != NULL );
    546
    547 SCIP_CALL( deleteSubproblem(scip, heurdata) );
    548
    549 assert(heurdata->subscip == NULL && heurdata->varmapfw == NULL && heurdata->subvars == NULL && heurdata->objcons == NULL);
    550
    551 return SCIP_OKAY;
    552}
    553
    554/** execution method of primal heuristic */
    555static
    556SCIP_DECL_HEUREXEC(heurExecProximity)
    557{ /*lint --e{715}*/
    558 SCIP_HEURDATA* heurdata; /* heuristic's data */
    559 SCIP_Longint nnodes; /* number of stalling nodes for the subproblem */
    560 SCIP_Longint nlpiters; /* lp iteration limit for the subproblem */
    561 SCIP_Bool foundsol = FALSE;
    562
    563 assert(heur != NULL);
    564 assert(scip != NULL);
    565 assert(result != NULL);
    566
    567 *result = SCIP_DIDNOTRUN;
    568
    569 /* get heuristic data */
    570 heurdata = SCIPheurGetData(heur);
    571 assert(heurdata != NULL);
    572
    573 /* do not run heuristic when there are only few binary varables */
    574 if( SCIPgetNBinVars(scip) < heurdata->binvarquot * SCIPgetNVars(scip) )
    575 return SCIP_OKAY;
    576
    577 /* calculate branching node limit for sub problem */
    578 /* todo maybe treat root node differently */
    579 nnodes = (SCIP_Longint) (heurdata->nodesquot * SCIPgetNNodes(scip));
    580 nnodes += heurdata->nodesofs;
    581
    582 /* determine the node and LP iteration limit for the solve of the sub-SCIP */
    583 nnodes -= heurdata->usednodes;
    584 nnodes = MIN(nnodes, heurdata->maxnodes);
    585
    586 nlpiters = (SCIP_Longint) (heurdata->lpitersquot * SCIPgetNRootFirstLPIterations(scip));
    587 nlpiters = MIN(nlpiters, heurdata->maxlpiters);
    588
    589 /* check whether we have enough nodes left to call subproblem solving */
    590 if( nnodes < heurdata->minnodes )
    591 {
    592 SCIPdebugMsg(scip, "skipping proximity: nnodes=%" SCIP_LONGINT_FORMAT ", minnodes=%" SCIP_LONGINT_FORMAT "\n", nnodes, heurdata->minnodes);
    593 return SCIP_OKAY;
    594 }
    595
    596 /* do not run proximity, if the problem does not have an objective function anyway */
    597 if( SCIPgetNObjVars(scip) == 0 )
    598 {
    599 SCIPdebugMsg(scip, "skipping proximity: pure feasibility problem anyway\n");
    600 return SCIP_OKAY;
    601 }
    602
    603 do
    604 {
    605 /* main loop of proximity: in every iteration, a new subproblem is set up and solved until no improved solution
    606 * is found or one of the heuristic limits on nodes or LP iterations is hit
    607 * heuristic performs only one iteration if restart parameter is set to FALSE
    608 */
    609 SCIP_Longint nusednodes = 0LL;
    610 SCIP_Longint nusedlpiters = 0LL;
    611
    612 nlpiters = MAX(nlpiters, heurdata->minlpiters);
    613
    614 /* define and solve the proximity subproblem */
    615 SCIP_CALL( SCIPapplyProximity(scip, heur, result, heurdata->minimprove, nnodes, nlpiters, &nusednodes, &nusedlpiters, FALSE) );
    616
    617 /* adjust node limit and LP iteration limit for future iterations */
    618 assert(nusednodes <= nnodes);
    619 heurdata->usednodes += nusednodes;
    620 nnodes -= nusednodes;
    621
    622 nlpiters -= nusedlpiters;
    623 heurdata->nusedlpiters += nusedlpiters;
    624
    625 /* memorize if a new solution has been found in at least one iteration */
    626 if( *result == SCIP_FOUNDSOL )
    627 foundsol = TRUE;
    628 }
    629 while( *result == SCIP_FOUNDSOL && heurdata->restart && !SCIPisStopped(scip) && nnodes > 0 );
    630
    631 /* reset result pointer if solution has been found in previous iteration */
    632 if( foundsol )
    633 *result = SCIP_FOUNDSOL;
    634
    635 /* free the occupied memory */
    636 if( heurdata->subscip != NULL )
    637 {
    638 /* just for testing the library method, in debug mode, we call the wrapper method for the actual delete method */
    639#ifndef NDEBUG
    641#else
    642 SCIP_CALL( deleteSubproblem(scip, heurdata) );
    643#endif
    644 }
    645 return SCIP_OKAY;
    646}
    647
    648
    649/*
    650 * primal heuristic specific interface methods
    651 */
    652
    653/** frees the sub-MIP created by proximity */
    655 SCIP* scip /** SCIP data structure */
    656 )
    657{
    658 SCIP_HEUR* heur;
    659 SCIP_HEURDATA* heurdata;
    660
    661 assert(scip != NULL);
    662
    663 heur = SCIPfindHeur(scip, HEUR_NAME);
    664 assert(heur != NULL);
    665
    666 heurdata = SCIPheurGetData(heur);
    667 if( heurdata != NULL )
    668 {
    669 SCIP_CALL( deleteSubproblem(scip, heurdata) );
    670 }
    671
    672 return SCIP_OKAY;
    673}
    674
    675/** main procedure of the proximity heuristic, creates and solves a sub-SCIP
    676 *
    677 * @note The method can be applied in an iterative way, keeping the same subscip in between. If the @p freesubscip
    678 * parameter is set to FALSE, the heuristic will keep the subscip data structures. Always set this parameter
    679 * to TRUE, or call SCIPdeleteSubproblemProximity() afterwards.
    680 */
    682 SCIP* scip, /**< original SCIP data structure */
    683 SCIP_HEUR* heur, /**< heuristic data structure */
    684 SCIP_RESULT* result, /**< result data structure */
    685 SCIP_Real minimprove, /**< factor by which proximity should at least improve the incumbent */
    686 SCIP_Longint nnodes, /**< node limit for the subproblem */
    687 SCIP_Longint nlpiters, /**< LP iteration limit for the subproblem */
    688 SCIP_Longint* nusednodes, /**< pointer to store number of used nodes in subscip */
    689 SCIP_Longint* nusedlpiters, /**< pointer to store number of used LP iterations in subscip */
    690 SCIP_Bool freesubscip /**< should the created sub-MIP be freed at the end of the method? */
    691 )
    692{
    693 SCIP* subscip; /* the subproblem created by proximity */
    694 SCIP_HASHMAP* varmapfw; /* mapping of SCIP variables to sub-SCIP variables */
    695 SCIP_VAR** vars; /* original problem's variables */
    696 SCIP_VAR** subvars; /* subproblem's variables */
    697 SCIP_HEURDATA* heurdata; /* heuristic's private data structure */
    698 SCIP_EVENTHDLR* eventhdlr; /* event handler for LP events */
    699
    700 SCIP_SOL* incumbent;
    701 SCIP_CONS* objcons;
    702 SCIP_Longint iterlim;
    703
    704 SCIP_Real large;
    705 SCIP_Real inf;
    706
    707 SCIP_Real bestobj;
    708 SCIP_Real objcutoff;
    709 SCIP_Real lowerbound;
    710
    711 int nvars; /* number of original problem's variables */
    712 int nfixedvars;
    713 int nsubsols;
    714 int solidx;
    715 int i;
    716
    717 SCIP_Bool valid;
    718 SCIP_Bool success;
    719
    720 assert(scip != NULL);
    721 assert(heur != NULL);
    722 assert(result != NULL);
    723
    724 assert(nnodes >= 0);
    725 assert(0.0 <= minimprove && minimprove <= 1.0);
    726
    727 *result = SCIP_DIDNOTRUN;
    728
    729 /* get heuristic data */
    730 heurdata = SCIPheurGetData(heur);
    731 assert(heurdata != NULL);
    732
    733 /* only call the heuristic if we have an incumbent */
    734 if( SCIPgetNSolsFound(scip) == 0 )
    735 return SCIP_OKAY;
    736
    737 /* do not use heuristic on problems without binary variables */
    738 if( SCIPgetNBinVars(scip) == 0 )
    739 return SCIP_OKAY;
    740
    741 incumbent = SCIPgetBestSol(scip);
    742 assert(incumbent != NULL);
    743
    744 /* make sure that the incumbent is valid for the transformed space, otherwise terminate */
    745 if( SCIPsolIsOriginal(incumbent) )
    746 return SCIP_OKAY;
    747
    748 solidx = SCIPsolGetIndex(incumbent);
    749
    750 if( heurdata->lastsolidx == solidx )
    751 return SCIP_OKAY;
    752
    753 /* only call heuristic, if the best solution does not come from trivial heuristic */
    754 if( SCIPsolGetHeur(incumbent) != NULL && strcmp(SCIPheurGetName(SCIPsolGetHeur(incumbent)), "trivial") == 0 )
    755 return SCIP_OKAY;
    756
    757 /* waitingnodes parameter defines the minimum number of nodes to wait before a new incumbent is processed */
    758 if( SCIPgetNNodes(scip) > 1 && SCIPgetNNodes(scip) - SCIPsolGetNodenum(incumbent) < heurdata->waitingnodes )
    759 return SCIP_OKAY;
    760
    761 bestobj = SCIPgetSolTransObj(scip, incumbent);
    762 lowerbound = SCIPgetLowerbound(scip);
    763
    764 /* use knowledge about integrality of objective to round up lower bound */
    766 {
    767 SCIPdebugMsg(scip, " Rounding up lower bound: %f --> %f \n", lowerbound, SCIPfeasCeil(scip, lowerbound));
    768 lowerbound = SCIPfeasCeil(scip, lowerbound);
    769 }
    770
    771 /* do not trigger heuristic if primal and dual bound are already close together */
    772 if( SCIPisFeasLE(scip, bestobj, lowerbound) || SCIPgetGap(scip) <= heurdata->mingap )
    773 return SCIP_OKAY;
    774
    775 /* calculate the minimum improvement for a heuristic solution in terms of the distance between incumbent objective
    776 * and the lower bound */
    777 if( SCIPisInfinity(scip, REALABS(lowerbound)) )
    778 {
    779 if( SCIPisZero(scip, bestobj) )
    780 objcutoff = bestobj - 1;
    781 else
    782 objcutoff = (1 - minimprove) * bestobj;
    783 }
    784 else
    785 objcutoff = minimprove * lowerbound + (1 - minimprove) * (bestobj);
    786
    787 /* use integrality of the objective function to round down (and thus strengthen) the objective cutoff */
    789 objcutoff = SCIPfeasFloor(scip, objcutoff);
    790
    791 if( SCIPisFeasLT(scip, objcutoff, lowerbound) )
    792 objcutoff = lowerbound;
    793
    794 /* exit execution if the right hand side of the objective constraint does not change (suggests that the heuristic
    795 * was not successful in a previous iteration) */
    796 if( heurdata->objcons != NULL && SCIPisFeasEQ(scip, SCIPgetRhsLinear(heurdata->subscip, heurdata->objcons), objcutoff) )
    797 return SCIP_OKAY;
    798
    799 /* check whether there is enough time and memory left */
    801
    802 if( ! valid )
    803 return SCIP_OKAY;
    804
    805 *result = SCIP_DIDNOTFIND;
    806
    807 heurdata->lastsolidx = solidx;
    808
    809 /* get variable data */
    810 SCIP_CALL( SCIPgetVarsData(scip, &vars, &nvars, NULL, NULL, NULL, NULL) );
    811
    812 /* create a subscip and copy the original scip instance into it */
    813 if( heurdata->subscip == NULL )
    814 {
    815 assert(heurdata->varmapfw == NULL);
    816 assert(heurdata->objcons == NULL);
    817
    818 /* initialize the subproblem */
    819 SCIP_CALL( SCIPcreate(&subscip) );
    820
    821 /* create the variable mapping hash map */
    822 SCIP_CALL( SCIPhashmapCreate(&varmapfw, SCIPblkmem(subscip), nvars) );
    823 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &subvars, nvars) );
    824
    825 /* copy complete SCIP instance */
    826 valid = FALSE;
    827
    828 /* create a problem copy as sub SCIP */
    829 SCIP_CALL( SCIPcopyLargeNeighborhoodSearch(scip, subscip, varmapfw, "proximity", NULL, NULL, 0, heurdata->uselprows, TRUE,
    830 &success, &valid) );
    831
    832 SCIPdebugMsg(scip, "Copying the SCIP instance was %s complete.\n", valid ? "" : "not ");
    833
    834 /* create event handler for LP events */
    835 eventhdlr = NULL;
    836 SCIP_CALL( SCIPincludeEventhdlrBasic(subscip, &eventhdlr, EVENTHDLR_NAME, EVENTHDLR_DESC, eventExecProximity, NULL) );
    837 if( eventhdlr == NULL )
    838 {
    839 SCIPerrorMessage("event handler for " HEUR_NAME " heuristic not found.\n");
    840 return SCIP_PLUGINNOTFOUND;
    841 }
    842
    843 /* set up parameters for the copied instance */
    844 SCIP_CALL( setupSubproblem(heurdata, subscip) );
    845
    846 /* create the objective constraint in the sub scip, first without variables and values which will be added later */
    847 SCIP_CALL( SCIPcreateConsBasicLinear(subscip, &objcons, "objbound_of_origscip", 0, NULL, NULL, -SCIPinfinity(subscip), SCIPinfinity(subscip)) );
    848
    849 /* determine large value to set variable bounds to, safe-guard to avoid fixings to infinite values */
    850 large = SCIPinfinity(scip);
    851 if( !SCIPisInfinity(scip, 0.1 / SCIPfeastol(scip)) )
    852 large = 0.1 / SCIPfeastol(scip);
    853 inf = SCIPinfinity(subscip);
    854
    855 /* get variable image and change objective to proximity function (Manhattan distance) in sub-SCIP */
    856 for( i = 0; i < nvars; i++ )
    857 {
    858 SCIP_Real adjustedbound;
    859 SCIP_Real lb;
    860 SCIP_Real ub;
    861
    862 subvars[i] = (SCIP_VAR*) SCIPhashmapGetImage(varmapfw, vars[i]);
    863
    864 if( subvars[i] == NULL )
    865 continue;
    866
    867 SCIP_CALL( SCIPchgVarObj(subscip, subvars[i], 0.0) );
    868
    869 lb = SCIPvarGetLbGlobal(subvars[i]);
    870 ub = SCIPvarGetUbGlobal(subvars[i]);
    871
    872 /* adjust infinite bounds in order to avoid that variables with non-zero objective
    873 * get fixed to infinite value in proximity subproblem
    874 */
    875 if( SCIPisInfinity(subscip, ub) )
    876 {
    877 adjustedbound = MAX(large, lb + large);
    878 adjustedbound = MIN(adjustedbound, inf);
    879 SCIP_CALL( SCIPchgVarUbGlobal(subscip, subvars[i], adjustedbound) );
    880 }
    881 if( SCIPisInfinity(subscip, -lb) )
    882 {
    883 adjustedbound = MIN(-large, ub - large);
    884 adjustedbound = MAX(adjustedbound, -inf);
    885 SCIP_CALL( SCIPchgVarLbGlobal(subscip, subvars[i], adjustedbound) );
    886 }
    887
    888 /* add all nonzero objective coefficients to the objective constraint */
    889 if( !SCIPisFeasZero(subscip, SCIPvarGetObj(vars[i])) )
    890 {
    891 SCIP_CALL( SCIPaddCoefLinear(subscip, objcons, subvars[i], SCIPvarGetObj(vars[i])) );
    892 }
    893 }
    894
    895 /* add objective constraint to the subscip */
    896 SCIP_CALL( SCIPaddCons(subscip, objcons) );
    897 }
    898 else
    899 {
    900 /* the instance, event handler, hash map and variable array were already copied in a previous iteration
    901 * and stored in heuristic data
    902 */
    903 assert(heurdata->varmapfw != NULL);
    904 assert(heurdata->subvars != NULL);
    905 assert(heurdata->objcons != NULL);
    906
    907 subscip = heurdata->subscip;
    908 varmapfw = heurdata->varmapfw;
    909 subvars = heurdata->subvars;
    910 objcons = heurdata->objcons;
    911
    912 eventhdlr = SCIPfindEventhdlr(subscip, EVENTHDLR_NAME);
    913 assert(eventhdlr != NULL);
    914 }
    915
    916 SCIP_CALL( SCIPchgRhsLinear(subscip, objcons, objcutoff) );
    917
    918 for( i = 0; i < SCIPgetNBinVars(scip); ++i )
    919 {
    920 SCIP_Real solval;
    921
    922 if( subvars[i] == NULL )
    923 continue;
    924
    925 /* objective coefficients are only set for binary variables of the problem */
    926 assert(SCIPvarIsBinary(subvars[i]));
    927
    928 solval = SCIPgetSolVal(scip, incumbent, vars[i]);
    929 assert(SCIPisFeasGE(scip, solval, 0.0));
    930 assert(SCIPisFeasLE(scip, solval, 1.0));
    931 assert(SCIPisFeasIntegral(scip, solval));
    932
    933 if( solval < 0.5 )
    934 {
    935 SCIP_CALL( SCIPchgVarObj(subscip, subvars[i], 1.0) );
    936 }
    937 else
    938 {
    939 SCIP_CALL( SCIPchgVarObj(subscip, subvars[i], -1.0) );
    940 }
    941 }
    942
    943 /* set limits for the subproblem */
    944 SCIP_CALL( SCIPcopyLimits(scip, subscip) );
    945 SCIP_CALL( SCIPsetLongintParam(subscip, "limits/nodes", nnodes) );
    946 SCIP_CALL( SCIPsetIntParam(subscip, "limits/solutions", 1) );
    947
    948 /* restrict LP iterations */
    949 /* todo set iterations limit depending on the number of iterations of the original problem root */
    950 iterlim = nlpiters;
    951 SCIP_CALL( SCIPsetLongintParam(subscip, "lp/iterlim", MAX(1, iterlim / MIN(10, nnodes))) );
    952 SCIP_CALL( SCIPsetLongintParam(subscip, "lp/rootiterlim", iterlim) );
    953
    954 /* catch LP events of sub-SCIP */
    955 SCIP_CALL( SCIPtransformProb(subscip) );
    956 SCIP_CALL( SCIPcatchEvent(subscip, SCIP_EVENTTYPE_NODESOLVED, eventhdlr, (SCIP_EVENTDATA*) heurdata, NULL) );
    957
    958 SCIPstatisticMessage("solving subproblem at Node: %" SCIP_LONGINT_FORMAT " "
    959 "nnodes: %" SCIP_LONGINT_FORMAT " "
    960 "iterlim: %" SCIP_LONGINT_FORMAT "\n", SCIPgetNNodes(scip), nnodes, iterlim);
    961
    962 /* solve the subproblem with all previously adjusted parameters */
    963 nfixedvars = SCIPgetNFixedVars(subscip);
    964
    965 SCIP_CALL( SCIPpresolve(subscip) );
    966
    967 nfixedvars = SCIPgetNFixedVars(subscip) - nfixedvars;
    968 assert(nfixedvars >= 0);
    969 SCIPstatisticMessage("presolve fixings %d: %d\n", ++(heurdata->subprobidx), nfixedvars);
    970
    971 /* errors in solving the subproblem should not kill the overall solving process;
    972 * hence, the return code is caught and a warning is printed, only in debug mode, SCIP will stop.
    973 */
    974 SCIP_CALL_ABORT( SCIPsolve(subscip) );
    975
    976 /* print solving statistics of subproblem if we are in SCIP's debug mode */
    978 SCIPstatisticMessage("solve of subscip %d:"
    979 "usednodes: %" SCIP_LONGINT_FORMAT " "
    980 "lp iters: %" SCIP_LONGINT_FORMAT " "
    981 "root iters: %" SCIP_LONGINT_FORMAT " "
    982 "Presolving Time: %.2f\n", heurdata->subprobidx,
    984
    985 SCIPstatisticMessage("Solving Time %d: %.2f\n", heurdata->subprobidx, SCIPgetSolvingTime(subscip) );
    986
    987 /* drop LP events of sub-SCIP */
    988 SCIP_CALL( SCIPdropEvent(subscip, SCIP_EVENTTYPE_NODESOLVED, eventhdlr, (SCIP_EVENTDATA*) heurdata, -1) );
    989
    990 /* keep track of relevant information for future runs of heuristic */
    991 if( nusednodes != NULL )
    992 *nusednodes = SCIPgetNNodes(subscip);
    993 if( nusedlpiters != NULL )
    994 *nusedlpiters = SCIPgetNLPIterations(subscip);
    995
    996 /* check whether a solution was found */
    997 nsubsols = SCIPgetNSols(subscip);
    998 incumbent = SCIPgetBestSol(subscip);
    999 assert(nsubsols == 0 || incumbent != NULL);
    1000
    1001 SCIPstatisticMessage("primal bound before subproblem %d: %g\n", heurdata->subprobidx, SCIPgetPrimalbound(scip));
    1002 if( nsubsols > 0 )
    1003 {
    1004 /* try to translate the sub problem solution to the original scip instance */
    1005 success = FALSE;
    1006 SCIP_CALL( createNewSol(scip, subscip, subvars, heur, incumbent, heurdata->usefinallp, &success) );
    1007
    1008 if( success )
    1009 *result = SCIP_FOUNDSOL;
    1010 }
    1011 SCIPstatisticMessage("primal bound after subproblem %d: %g\n", heurdata->subprobidx, SCIPgetPrimalbound(scip));
    1012
    1013 /* free the transformed subproblem data */
    1014 SCIP_CALL( SCIPfreeTransform(subscip) );
    1015
    1016 /* save subproblem in heuristic data for subsequent runs if it has been successful, otherwise free subproblem */
    1017 heurdata->subscip = subscip;
    1018 heurdata->varmapfw = varmapfw;
    1019 heurdata->subvars = subvars;
    1020 heurdata->objcons = objcons;
    1021 heurdata->nsubvars = nvars;
    1022
    1023 /* delete the sub problem */
    1024 if( freesubscip )
    1025 {
    1026 SCIP_CALL( deleteSubproblem(scip, heurdata) );
    1027 }
    1028
    1029 return SCIP_OKAY;
    1030}
    1031
    1032
    1033/** creates the proximity primal heuristic and includes it in SCIP */
    1035 SCIP* scip /**< SCIP data structure */
    1036 )
    1037{
    1038 SCIP_HEURDATA* heurdata;
    1039 SCIP_HEUR* heur = NULL;
    1040
    1041 /* create heuristic data */
    1042 SCIP_CALL( SCIPallocBlockMemory(scip, &heurdata) );
    1043
    1044 /* include primal heuristic */
    1047 HEUR_MAXDEPTH, HEUR_TIMING, HEUR_USESSUBSCIP, heurExecProximity, heurdata) );
    1048 assert(heur != NULL);
    1049
    1050 /* primal heuristic is safe to use in exact solving mode */
    1051 SCIPheurMarkExact(heur);
    1052
    1053 /* set non-NULL pointers to callback methods */
    1054 SCIP_CALL( SCIPsetHeurCopy(scip, heur, heurCopyProximity) );
    1055 SCIP_CALL( SCIPsetHeurFree(scip, heur, heurFreeProximity) );
    1056 SCIP_CALL( SCIPsetHeurInit(scip, heur, heurInitProximity) );
    1057 SCIP_CALL( SCIPsetHeurExitsol(scip, heur, heurExitsolProximity) );
    1058
    1059 /* add proximity primal heuristic parameters */
    1060 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/uselprows",
    1061 "should subproblem be constructed based on LP row information?",
    1062 &heurdata->uselprows, TRUE, DEFAULT_USELPROWS, NULL, NULL) );
    1063
    1064 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/restart",
    1065 "should the heuristic immediately run again on its newly found solution?",
    1066 &heurdata->restart, TRUE, DEFAULT_RESTART, NULL, NULL) );
    1067
    1068 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/usefinallp",
    1069 "should the heuristic solve a final LP in case of continuous objective variables?",
    1070 &heurdata->usefinallp, TRUE, DEFAULT_USEFINALLP, NULL, NULL) );
    1071
    1072 SCIP_CALL( SCIPaddLongintParam(scip, "heuristics/" HEUR_NAME "/maxnodes",
    1073 "maximum number of nodes to regard in the subproblem",
    1074 &heurdata->maxnodes, TRUE,DEFAULT_MAXNODES, 0LL, SCIP_LONGINT_MAX, NULL, NULL) );
    1075
    1076 SCIP_CALL( SCIPaddLongintParam(scip, "heuristics/" HEUR_NAME "/nodesofs",
    1077 "number of nodes added to the contingent of the total nodes",
    1078 &heurdata->nodesofs, TRUE, DEFAULT_NODESOFS, 0LL, SCIP_LONGINT_MAX, NULL, NULL) );
    1079
    1080 SCIP_CALL( SCIPaddLongintParam(scip, "heuristics/" HEUR_NAME "/minnodes",
    1081 "minimum number of nodes required to start the subproblem",
    1082 &heurdata->minnodes, TRUE, DEFAULT_MINNODES, 0LL, SCIP_LONGINT_MAX, NULL, NULL) );
    1083
    1084 SCIP_CALL( SCIPaddLongintParam(scip, "heuristics/" HEUR_NAME "/maxlpiters",
    1085 "maximum number of LP iterations to be performed in the subproblem",
    1086 &heurdata->maxlpiters, TRUE, DEFAULT_MAXLPITERS, -1LL, SCIP_LONGINT_MAX, NULL, NULL) );
    1087
    1088 SCIP_CALL( SCIPaddLongintParam(scip, "heuristics/" HEUR_NAME "/minlpiters",
    1089 "minimum number of LP iterations performed in subproblem",
    1090 &heurdata->minlpiters, TRUE, DEFAULT_MINLPITERS, 0LL, SCIP_LONGINT_MAX, NULL, NULL) );
    1091
    1092 SCIP_CALL( SCIPaddLongintParam(scip, "heuristics/" HEUR_NAME "/waitingnodes",
    1093 "waiting nodes since last incumbent before heuristic is executed",
    1094 &heurdata->waitingnodes, TRUE, DEFAULT_WAITINGNODES, 0LL, SCIP_LONGINT_MAX, NULL, NULL) );
    1095
    1096 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/minimprove",
    1097 "factor by which proximity should at least improve the incumbent",
    1098 &heurdata->minimprove, TRUE, DEFAULT_MINIMPROVE, 0.0, 1.0, NULL, NULL) );
    1099
    1100 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/nodesquot",
    1101 "sub-MIP node limit w.r.t number of original nodes",
    1102 &heurdata->nodesquot, TRUE, DEFAULT_NODESQUOT, 0.0, SCIPinfinity(scip), NULL, NULL) );
    1103
    1104 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/binvarquot",
    1105 "threshold for percentage of binary variables required to start",
    1106 &heurdata->binvarquot, TRUE, DEFAULT_BINVARQUOT, 0.0, 1.0, NULL, NULL) );
    1107
    1108 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/lpitersquot",
    1109 "quotient of sub-MIP LP iterations with respect to LP iterations so far",
    1110 &heurdata->lpitersquot, TRUE, DEFAULT_LPITERSQUOT, 0.0, 1.0, NULL, NULL) );
    1111
    1112 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/mingap",
    1113 "minimum primal-dual gap for which the heuristic is executed",
    1114 &heurdata->mingap, TRUE, DEFAULT_MINGAP, 0.0, SCIPinfinity(scip), NULL, NULL) );
    1115
    1116 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/useuct",
    1117 "should uct node selection be used at the beginning of the search?",
    1118 &heurdata->useuct, TRUE, DEFAULT_USEUCT, NULL, NULL) );
    1119
    1120 return SCIP_OKAY;
    1121}
    Constraint handler for linear constraints in their most general form, .
    #define NULL
    Definition: def.h:257
    #define SCIP_Longint
    Definition: def.h:150
    #define SCIP_Bool
    Definition: def.h:100
    #define MIN(x, y)
    Definition: def.h:233
    #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_ABORT(x)
    Definition: def.h:343
    #define SCIP_LONGINT_FORMAT
    Definition: def.h:157
    #define REALABS(x)
    Definition: def.h:191
    #define SCIP_LONGINT_MAX
    Definition: def.h:151
    #define SCIP_CALL(x)
    Definition: def.h:364
    #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:3250
    SCIP_RETCODE SCIPcopyLimits(SCIP *sourcescip, SCIP *targetscip)
    Definition: scip_copy.c:3293
    SCIP_Bool SCIPisStopped(SCIP *scip)
    Definition: scip_general.c:767
    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:2986
    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
    SCIP_Longint SCIPsolGetNodenum(SCIP_SOL *sol)
    Definition: sol.c:4254
    int SCIPgetNSols(SCIP *scip)
    Definition: scip_sol.c:2887
    SCIP_HEUR * SCIPsolGetHeur(SCIP_SOL *sol)
    Definition: sol.c:4274
    SCIP_RETCODE SCIPunlinkSol(SCIP *scip, SCIP_SOL *sol)
    Definition: scip_sol.c:1504
    SCIP_Bool SCIPsolIsOriginal(SCIP_SOL *sol)
    Definition: sol.c:4155
    int SCIPsolGetIndex(SCIP_SOL *sol)
    Definition: sol.c:4305
    SCIP_RETCODE SCIPsetSolVals(SCIP *scip, SCIP_SOL *sol, int nvars, SCIP_VAR **vars, SCIP_Real *vals)
    Definition: scip_sol.c:1660
    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:4017
    SCIP_RETCODE SCIPlinkLPSol(SCIP *scip, SCIP_SOL *sol)
    Definition: scip_sol.c:1293
    SCIP_Real SCIPgetSolOrigObj(SCIP *scip, SCIP_SOL *sol)
    Definition: scip_sol.c:1890
    SCIP_RETCODE SCIPsetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var, SCIP_Real val)
    Definition: scip_sol.c:1569
    SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
    Definition: scip_sol.c:1763
    SCIP_Real SCIPgetSolTransObj(SCIP *scip, SCIP_SOL *sol)
    Definition: scip_sol.c:2003
    SCIP_RETCODE SCIPtransformProb(SCIP *scip)
    Definition: scip_solve.c:232
    SCIP_RETCODE SCIPpresolve(SCIP *scip)
    Definition: scip_solve.c:2425
    SCIP_RETCODE SCIPfreeTransform(SCIP *scip)
    Definition: scip_solve.c:3475
    SCIP_RETCODE SCIPinterruptSolve(SCIP *scip)
    Definition: scip_solve.c:3561
    SCIP_RETCODE SCIPsolve(SCIP *scip)
    Definition: scip_solve.c:2611
    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:23510
    SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
    Definition: var.c:23418
    SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
    Definition: var.c:24300
    SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
    Definition: var.c:23932
    SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
    Definition: var.c:24174
    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:23522
    SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
    Definition: var.c:24266
    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:24152
    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
    @ SCIP_INVALIDCALL
    Definition: type_retcode.h:51
    enum SCIP_Retcode SCIP_RETCODE
    Definition: type_retcode.h:63
    @ SCIP_VARSTATUS_COLUMN
    Definition: type_var.h:53