SCIP

    Solving Constraint Integer Programs

    heur_rens.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_rens.c
    26 * @ingroup DEFPLUGINS_HEUR
    27 * @brief LNS heuristic that finds the optimal rounding to a given point
    28 * @author Timo Berthold
    29 */
    30
    31/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
    32
    34#include "scip/heuristics.h"
    35#include "scip/heur_rens.h"
    36#include "scip/pub_event.h"
    37#include "scip/pub_heur.h"
    38#include "scip/pub_message.h"
    39#include "scip/pub_misc.h"
    40#include "scip/pub_sol.h"
    41#include "scip/pub_var.h"
    42#include "scip/scip_branch.h"
    43#include "scip/scip_cons.h"
    44#include "scip/scip_copy.h"
    45#include "scip/scip_event.h"
    46#include "scip/scip_general.h"
    47#include "scip/scip_heur.h"
    48#include "scip/scip_lp.h"
    49#include "scip/scip_mem.h"
    50#include "scip/scip_message.h"
    51#include "scip/scip_nlp.h"
    52#include "scip/scip_nlpi.h"
    53#include "scip/scip_nodesel.h"
    54#include "scip/scip_numerics.h"
    55#include "scip/scip_param.h"
    56#include "scip/scip_prob.h"
    57#include "scip/scip_sol.h"
    58#include "scip/scip_solve.h"
    60#include "scip/scip_timing.h"
    61#include "scip/scip_var.h"
    62
    63
    64/* default values for standard parameters that every primal heuristic has in SCIP */
    65#define HEUR_NAME "rens"
    66#define HEUR_DESC "LNS exploring fractional neighborhood of relaxation's optimum"
    67#define HEUR_DISPCHAR SCIP_HEURDISPCHAR_LNS
    68#define HEUR_PRIORITY -1100000
    69#define HEUR_FREQ 0
    70#define HEUR_FREQOFS 0
    71#define HEUR_MAXDEPTH -1
    72#define HEUR_TIMING SCIP_HEURTIMING_AFTERLPNODE
    73#define HEUR_USESSUBSCIP TRUE /**< does the heuristic use a secondary SCIP instance? */
    74
    75/* default values for RENS-specific plugins */
    76#define DEFAULT_BINARYBOUNDS TRUE /* should general integers get binary bounds [floor(.),ceil(.)] ? */
    77#define DEFAULT_MAXNODES 5000LL /* maximum number of nodes to regard in the subproblem */
    78#define DEFAULT_MINFIXINGRATE 0.5 /* minimum percentage of integer variables that have to be fixed */
    79#define DEFAULT_MINIMPROVE 0.01 /* factor by which RENS should at least improve the incumbent */
    80#define DEFAULT_MINNODES 50LL /* minimum number of nodes to regard in the subproblem */
    81#define DEFAULT_NODESOFS 500LL /* number of nodes added to the contingent of the total nodes */
    82#define DEFAULT_NODESQUOT 0.1 /* subproblem nodes in relation to nodes of the original problem */
    83#define DEFAULT_LPLIMFAC 2.0 /* factor by which the limit on the number of LP depends on the node limit */
    84#define DEFAULT_STARTSOL 'l' /* solution that is used for fixing values */
    85#define STARTSOL_CHOICES "nl" /* possible values for startsol ('l'p relaxation, 'n'lp relaxation) */
    86#define DEFAULT_USELPROWS FALSE /* should subproblem be created out of the rows in the LP rows,
    87 * otherwise, the copy constructors of the constraints handlers are used */
    88#define DEFAULT_COPYCUTS TRUE /* if DEFAULT_USELPROWS is FALSE, then should all active cuts from the cutpool
    89 * of the original scip be copied to constraints of the subscip
    90 */
    91#define DEFAULT_EXTRATIME FALSE /* should the RENS sub-CIP get its own full time limit? This is only
    92 * implemented for testing and not recommended to be used!
    93 */
    94#define DEFAULT_ADDALLSOLS FALSE /* should all subproblem solutions be added to the original SCIP? */
    95
    96#define DEFAULT_FULLSCALE FALSE /* should the RENS sub-CIP be solved with full-scale SCIP settings, including
    97 * techniques that merely work on the dual bound, e.g., cuts? This is only
    98 * implemented for testing and not recommended to be used!
    99 */
    100#define DEFAULT_BESTSOLLIMIT -1 /* limit on number of improving incumbent solutions in sub-CIP */
    101#define DEFAULT_USEUCT FALSE /* should uct node selection be used at the beginning of the search? */
    102
    103/* event handler properties */
    104#define EVENTHDLR_NAME "Rens"
    105#define EVENTHDLR_DESC "LP event handler for " HEUR_NAME " heuristic"
    106
    107/*
    108 * Data structures
    109 */
    110
    111/** primal heuristic data */
    112struct SCIP_HeurData
    113{
    114 SCIP_Longint maxnodes; /**< maximum number of nodes to regard in the subproblem */
    115 SCIP_Longint minnodes; /**< minimum number of nodes to regard in the subproblem */
    116 SCIP_Longint nodesofs; /**< number of nodes added to the contingent of the total nodes */
    117 SCIP_Longint usednodes; /**< nodes already used by RENS in earlier calls */
    118 SCIP_Real minfixingrate; /**< minimum percentage of integer variables that have to be fixed */
    119 SCIP_Real minimprove; /**< factor by which RENS should at least improve the incumbent */
    120 SCIP_Real nodesquot; /**< subproblem nodes in relation to nodes of the original problem */
    121 SCIP_Real nodelimit; /**< the nodelimit employed in the current sub-SCIP, for the event handler*/
    122 SCIP_Real lplimfac; /**< factor by which the limit on the number of LP depends on the node limit */
    123 char startsol; /**< solution used for fixing values ('l'p relaxation, 'n'lp relaxation) */
    124 SCIP_Bool binarybounds; /**< should general integers get binary bounds [floor(.),ceil(.)] ? */
    125 SCIP_Bool uselprows; /**< should subproblem be created out of the rows in the LP rows? */
    126 SCIP_Bool copycuts; /**< if uselprows == FALSE, should all active cuts from cutpool be copied
    127 * to constraints in subproblem? */
    128 SCIP_Bool extratime; /**< should the RENS sub-CIP get its own full time limit? This is only
    129 * implemented for testing and not recommended to be used! */
    130 SCIP_Bool addallsols; /**< should all subproblem solutions be added to the original SCIP? */
    131 SCIP_Bool fullscale; /**< should the RENS sub-CIP be solved with full-scale SCIP settings,
    132 * including techniques that merely work on the dual bound, e.g., cuts?
    133 * This is only implemented for testing and not recommended to be used! */
    134 int bestsollimit; /**< limit on number of improving incumbent solutions in sub-CIP */
    135 SCIP_Bool useuct; /**< should uct node selection be used at the beginning of the search? */
    136};
    138
    139/*
    140 * Local methods
    141 */
    142
    143/** compute the number of initial fixings and check whether the fixing rate exceeds the minimum fixing rate */
    144static
    146 SCIP* scip, /**< SCIP data structure */
    147 SCIP_VAR** fixedvars, /**< array to store source SCIP variables whose copies should be fixed in the sub-SCIP */
    148 SCIP_Real* fixedvals, /**< array to store solution values for variable fixing */
    149 int* nfixedvars, /**< pointer to store the number of fixed variables */
    150 int fixedvarssize, /**< size of the arrays to store fixing variables */
    151 SCIP_Real minfixingrate, /**< percentage of integer variables that have to be fixed */
    152 char* startsol, /**< pointer to solution used for fixing values ('l'p relaxation, 'n'lp relaxation) */
    153 SCIP_Real* fixingrate, /**< percentage of integers that get actually fixed */
    154 SCIP_Bool* success /**< pointer to store whether minimum fixingrate is exceeded */
    155 )
    156{
    157 SCIP_VAR** vars;
    158 int nintvars;
    159 int nbinvars;
    160 int i;
    161
    162 assert(fixedvars != NULL);
    163 assert(fixedvals != NULL);
    164 assert(nfixedvars != NULL);
    165
    166 *fixingrate = 1.0;
    167 *success = FALSE;
    168
    169 /* if there is no NLP relaxation available (e.g., because the presolved problem is linear), use LP relaxation */
    171 {
    172 SCIPdebugMsg(scip, "no NLP present, use LP relaxation instead\n");
    173 (*startsol) = 'l';
    174 }
    175
    176 /* get required variable data */
    177 SCIP_CALL( SCIPgetVarsData(scip, &vars, NULL, &nbinvars, &nintvars, NULL, NULL) );
    178 assert(fixedvarssize >= nbinvars + nintvars);
    179 (*nfixedvars) = 0;
    180
    181 /* try to solve NLP relaxation */
    182 if( (*startsol) == 'n' )
    183 {
    184 SCIP_NLPSOLSTAT stat;
    185
    186 /* only call this function if NLP relaxation is available */
    187 assert(SCIPisNLPConstructed(scip));
    188
    189 SCIPdebugMsg(scip, "try to solve NLP relaxation to obtain fixing values\n");
    190
    191 /* set starting point to LP solution */
    193
    194 /* solve NLP relaxation
    195 * TODO pick some less arbitrary iterlimit
    196 */
    197 SCIP_CALL( SCIPsolveNLP(scip, .iterlimit = 3000) ); /*lint !e666*/
    198
    199 /* get solution status of NLP solver */
    200 stat = SCIPgetNLPSolstat(scip);
    201 *success = (stat == SCIP_NLPSOLSTAT_GLOBOPT) || (stat == SCIP_NLPSOLSTAT_LOCOPT) || stat == (SCIP_NLPSOLSTAT_FEASIBLE);
    202 SCIPdebugMsg(scip, "solving NLP relaxation was %s successful (stat=%d)\n", *success ? "" : "not", stat);
    203
    204 /* it the NLP was not successfully solved we stop the heuristic right away */
    205 if( !(*success) )
    206 return SCIP_OKAY;
    207 }
    208 else
    209 {
    210 assert(*startsol == 'l');
    211 }
    212
    213 /* count the number of variables with integral solution values in the current NLP or LP solution */
    214 for( i = 0; i < nbinvars + nintvars; ++i )
    215 {
    216 SCIP_Real solval;
    217
    218 /* get solution value in the relaxation in question */
    219 solval = (*startsol == 'l') ? SCIPvarGetLPSol(vars[i]) : SCIPvarGetNLPSol(vars[i]);
    220
    221 /* append variable to the buffer storage for integer variables with integer solution values */
    222 if( SCIPisFeasIntegral(scip, solval) )
    223 {
    224 /* fix variables to current LP/NLP solution if it is integral,
    225 * use exact integral value, if the variable is only integral within numerical tolerances
    226 */
    227 solval = SCIPfloor(scip, solval+0.5);
    228 fixedvars[(*nfixedvars)] = vars[i];
    229 fixedvals[(*nfixedvars)] = solval;
    230 (*nfixedvars)++;
    231 }
    232 }
    233
    234 /* abort, if all integer variables were fixed (which should not happen for MIP),
    235 * but frequently happens for MINLPs using an LP relaxation
    236 */
    237 if( (*nfixedvars) == nbinvars + nintvars )
    238 return SCIP_OKAY;
    239
    240 *fixingrate = (*nfixedvars) / (SCIP_Real)(MAX(nbinvars + nintvars, 1));
    241
    242 /* abort, if the amount of fixed variables is insufficient */
    243 if( *fixingrate < minfixingrate )
    244 return SCIP_OKAY;
    245
    246 *success = TRUE;
    247 return SCIP_OKAY;
    248}
    249
    250/** fixes bounds of unfixed integer variables to binary bounds */
    251static
    253 SCIP* scip, /**< original SCIP data structure */
    254 SCIP* subscip, /**< SCIP data structure for the subproblem */
    255 SCIP_VAR** subvars, /**< the variables of the subproblem */
    256 char startsol /**< solution used for fixing values ('l'p relaxation, 'n'lp relaxation) */
    257 )
    258{
    259 SCIP_VAR** vars; /* original SCIP variables */
    260
    261 int nbinvars;
    262 int nintvars;
    263 int i;
    264
    265 assert(scip != NULL);
    266 assert(subscip != NULL);
    267 assert(subvars != NULL);
    268
    269 assert(startsol == 'l' || startsol == 'n');
    270
    271 /* get required variable data */
    272 SCIP_CALL( SCIPgetVarsData(scip, &vars, NULL, &nbinvars, &nintvars, NULL, NULL) );
    273
    274 /* change bounds of integer variables of the subproblem */
    275 for( i = nbinvars; i < nbinvars + nintvars; i++ )
    276 {
    277 SCIP_Real solval;
    278 SCIP_Real lb;
    279 SCIP_Real ub;
    280
    281 if( subvars[i] == NULL )
    282 continue;
    283
    284 /* get the current LP/NLP solution for each variable */
    285 if( startsol == 'l')
    286 solval = SCIPvarGetLPSol(vars[i]);
    287 else
    288 solval = SCIPvarGetNLPSol(vars[i]);
    289
    290 /* restrict bounds to nearest integers if the solution value is not already integer */
    291 if( !SCIPisFeasIntegral(scip, solval) )
    292 {
    293 lb = SCIPfeasFloor(scip, solval);
    294 ub = SCIPfeasCeil(scip, solval);
    295
    296 /* perform the bound change */
    297 SCIP_CALL( SCIPchgVarLbGlobal(subscip, subvars[i], lb) );
    298 SCIP_CALL( SCIPchgVarUbGlobal(subscip, subvars[i], ub) );
    299 }
    300 else
    301 {
    302 /* the variable bounds should be already fixed to this solution value */
    303 assert(SCIPisFeasEQ(scip, SCIPvarGetLbGlobal(subvars[i]), SCIPfloor(scip, solval+0.5)));
    304 assert(SCIPisFeasEQ(scip, SCIPvarGetUbGlobal(subvars[i]), SCIPfloor(scip, solval+0.5)));
    305 }
    306 }
    307
    308 return SCIP_OKAY;
    309}
    310
    312/* ---------------- Callback methods of event handler ---------------- */
    313
    314/* exec the event handler
    315 *
    316 * we interrupt the solution process
    317 */
    318static
    319SCIP_DECL_EVENTEXEC(eventExecRens)
    320{
    321 SCIP_HEURDATA* heurdata;
    322
    323 assert(eventhdlr != NULL);
    324 assert(eventdata != NULL);
    325 assert(event != NULL);
    327
    329
    330 heurdata = (SCIP_HEURDATA*)eventdata;
    331 assert(heurdata != NULL);
    332
    333 /* interrupt solution process of sub-SCIP */
    334 if( SCIPgetNLPs(scip) > heurdata->lplimfac * heurdata->nodelimit )
    335 {
    336 SCIPdebugMsg(scip, "interrupt after %" SCIP_LONGINT_FORMAT " LPs\n",SCIPgetNLPs(scip));
    338 }
    339
    340 return SCIP_OKAY;
    341}
    342
    343/** setup and solve the RENS sub-SCIP */
    344static
    346 SCIP* scip, /**< SCIP data structure */
    347 SCIP* subscip, /**< sub SCIP data structure */
    348 SCIP_RESULT* result, /**< result pointer */
    349 SCIP_HEUR* heur, /**< heuristic data structure */
    350 SCIP_VAR** fixedvars, /**< array of variables that should be fixed */
    351 SCIP_Real* fixedvals, /**< array of fixing values */
    352 int nfixedvars, /**< number of variables that should be fixed */
    353 SCIP_Real intfixingrate, /**< percentage of integer variables fixed */
    354 SCIP_Real minfixingrate, /**< minimum percentage of integer variables that have to be fixed */
    355 SCIP_Real minimprove, /**< factor by which RENS should at least improve the incumbent */
    356 SCIP_Longint maxnodes, /**< maximum number of nodes for the subproblem */
    357 SCIP_Longint nstallnodes, /**< number of stalling nodes for the subproblem */
    358 char startsol, /**< solution used for fixing values ('l'p relaxation, 'n'lp relaxation) */
    359 SCIP_Bool binarybounds, /**< should general integers get binary bounds [floor(.),ceil(.)]? */
    360 SCIP_Bool uselprows /**< should subproblem be created out of the rows in the LP rows? */
    361 )
    362{
    363 SCIP_VAR** vars; /* original problem's variables */
    364 SCIP_VAR** subvars; /* subproblem's variables */
    365 SCIP_HEURDATA* heurdata; /* heuristic data */
    366 SCIP_EVENTHDLR* eventhdlr; /* event handler for LP events */
    367 SCIP_HASHMAP* varmapfw; /* mapping of SCIP variables to sub-SCIP variables */
    368 SCIP_Real cutoff; /* objective cutoff for the subproblem */
    369 SCIP_Real allfixingrate; /* percentage of all variables fixed */
    370 SCIP_Bool success;
    371 int i;
    372 int nvars; /* number of original problem's variables */
    373 SCIP_RETCODE retcode;
    374
    375 assert(scip != NULL);
    376 assert(subscip != NULL);
    377 assert(heur != NULL);
    378 assert(result != NULL);
    379
    380 heurdata = SCIPheurGetData(heur);
    381 assert(heurdata != NULL);
    382
    383 /* get variable data */
    384 SCIP_CALL( SCIPgetVarsData(scip, &vars, &nvars, NULL, NULL, NULL, NULL) );
    385
    386 /* create the variable mapping hash map */
    387 SCIP_CALL( SCIPhashmapCreate(&varmapfw, SCIPblkmem(subscip), nvars) );
    388
    389 /* create a problem copy as sub SCIP */
    390 SCIP_CALL( SCIPcopyLargeNeighborhoodSearch(scip, subscip, varmapfw, "rens", fixedvars, fixedvals, nfixedvars, uselprows,
    391 heurdata->copycuts, &success, NULL) );
    392
    393 eventhdlr = NULL;
    394 /* create event handler for LP events */
    395 SCIP_CALL( SCIPincludeEventhdlrBasic(subscip, &eventhdlr, EVENTHDLR_NAME, EVENTHDLR_DESC, eventExecRens, NULL) );
    396 if( eventhdlr == NULL )
    397 {
    398 SCIPerrorMessage("event handler for " HEUR_NAME " heuristic not found.\n");
    399 return SCIP_PLUGINNOTFOUND;
    400 }
    401
    402 /* copy subproblem variables into the same order as the source SCIP variables */
    403 SCIP_CALL( SCIPallocBufferArray(scip, &subvars, nvars) );
    404 for( i = 0; i < nvars; i++ )
    405 subvars[i] = (SCIP_VAR*) SCIPhashmapGetImage(varmapfw, vars[i]);
    406
    407 /* free hash map */
    408 SCIPhashmapFree(&varmapfw);
    409
    410 /* restrict the integer variables to binary bounds */
    411 if( binarybounds )
    412 {
    413 SCIP_CALL( restrictToBinaryBounds(scip, subscip, subvars, startsol) );
    414 }
    415
    416 SCIPdebugMsg(scip, "RENS subproblem: %d vars, %d cons\n", SCIPgetNVars(subscip), SCIPgetNConss(subscip));
    417
    418 /* do not abort subproblem on CTRL-C */
    419 SCIP_CALL( SCIPsetBoolParam(subscip, "misc/catchctrlc", FALSE) );
    420
    421#ifdef SCIP_DEBUG
    422 /* for debugging, enable full output */
    423 SCIP_CALL( SCIPsetIntParam(subscip, "display/verblevel", 5) );
    424 SCIP_CALL( SCIPsetIntParam(subscip, "display/freq", 100000000) );
    425#else
    426 /* disable statistic timing inside sub SCIP and output to console */
    427 SCIP_CALL( SCIPsetIntParam(subscip, "display/verblevel", 0) );
    428 SCIP_CALL( SCIPsetBoolParam(subscip, "timing/statistictiming", FALSE) );
    429#endif
    430
    431 /* set limits for the subproblem */
    432 SCIP_CALL( SCIPcopyLimits(scip, subscip) );
    433 heurdata->nodelimit = maxnodes;
    434 SCIP_CALL( SCIPsetLongintParam(subscip, "limits/stallnodes", nstallnodes) );
    435 SCIP_CALL( SCIPsetLongintParam(subscip, "limits/nodes", maxnodes) );
    436 SCIP_CALL( SCIPsetIntParam(subscip, "limits/bestsol", heurdata->bestsollimit) );
    437
    438 /* forbid recursive call of heuristics and separators solving sub-SCIPs */
    439 SCIP_CALL( SCIPsetSubscipsOff(subscip, TRUE) );
    440
    441 /* disable expensive techniques that merely work on the dual bound */
    442 if( !heurdata->fullscale )
    443 {
    444 /* disable cutting plane separation */
    446
    447 /* disable expensive presolving */
    449
    450 /* use best estimate node selection */
    451 if( SCIPfindNodesel(subscip, "estimate") != NULL && !SCIPisParamFixed(subscip, "nodeselection/estimate/stdpriority") )
    452 {
    453 SCIP_CALL( SCIPsetIntParam(subscip, "nodeselection/estimate/stdpriority", INT_MAX/4) );
    454 }
    455
    456 /* activate uct node selection at the top of the tree */
    457 if( heurdata->useuct && SCIPfindNodesel(subscip, "uct") != NULL && !SCIPisParamFixed(subscip, "nodeselection/uct/stdpriority") )
    458 {
    459 SCIP_CALL( SCIPsetIntParam(subscip, "nodeselection/uct/stdpriority", INT_MAX/2) );
    460 }
    461
    462 /* use inference branching */
    463 if( SCIPfindBranchrule(subscip, "inference") != NULL && !SCIPisParamFixed(subscip, "branching/inference/priority") )
    464 {
    465 SCIP_CALL( SCIPsetIntParam(subscip, "branching/inference/priority", INT_MAX/4) );
    466 }
    467
    468 /* enable conflict analysis, disable analysis of boundexceeding LPs, and restrict conflict pool */
    469 if( !SCIPisParamFixed(subscip, "conflict/enable") )
    470 {
    471 SCIP_CALL( SCIPsetBoolParam(subscip, "conflict/enable", TRUE) );
    472 }
    473 if( !SCIPisParamFixed(subscip, "conflict/useboundlp") )
    474 {
    475 SCIP_CALL( SCIPsetCharParam(subscip, "conflict/useboundlp", 'o') );
    476 }
    477 if( !SCIPisParamFixed(subscip, "conflict/maxstoresize") )
    478 {
    479 SCIP_CALL( SCIPsetIntParam(subscip, "conflict/maxstoresize", 100) );
    480 }
    481
    482 /* speed up sub-SCIP by not checking dual LP feasibility */
    483 SCIP_CALL( SCIPsetBoolParam(subscip, "lp/checkdualfeas", FALSE) );
    484 }
    485
    486 /* if there is already a solution, add an objective cutoff */
    487 if( SCIPgetNSols(scip) > 0 )
    488 {
    489 SCIP_Real upperbound;
    491
    492 upperbound = SCIPgetUpperbound(scip) - SCIPsumepsilon(scip);
    493
    495 {
    496 cutoff = (1 - minimprove) * SCIPgetUpperbound(scip)
    497 + minimprove * SCIPgetLowerbound(scip);
    498 }
    499 else
    500 {
    501 if( SCIPgetUpperbound(scip) >= 0 )
    502 cutoff = (1 - minimprove) * SCIPgetUpperbound(scip);
    503 else
    504 cutoff = (1 + minimprove) * SCIPgetUpperbound(scip);
    505 }
    506 cutoff = MIN(upperbound, cutoff);
    507 SCIP_CALL( SCIPsetObjlimit(subscip, cutoff) );
    508 }
    509
    510 /* presolve the subproblem */
    511 retcode = SCIPpresolve(subscip);
    512
    513 /* errors in solving the subproblem should not kill the overall solving process;
    514 * hence, the return code is caught and a warning is printed, only in debug mode, SCIP will stop.
    515 */
    516 if( retcode != SCIP_OKAY )
    517 {
    518 SCIPwarningMessage(scip, "Error while presolving subproblem in RENS heuristic; sub-SCIP terminated with code <%d>\n", retcode);
    519 SCIPABORT(); /*lint --e{527}*/
    520 goto TERMINATE;
    521 }
    522
    523 SCIPdebugMsg(scip, "RENS presolved subproblem: %d vars, %d cons, success=%u\n", SCIPgetNVars(subscip), SCIPgetNConss(subscip), success);
    524
    525 allfixingrate = (SCIPgetNOrigVars(subscip) - SCIPgetNVars(subscip)) / (SCIP_Real)SCIPgetNOrigVars(subscip);
    526
    527 /* additional variables added in presolving may lead to the subSCIP having more variables than the original */
    528 allfixingrate = MAX(allfixingrate, 0.0);
    529
    530 /* after presolving, we should have at least reached a certain fixing rate over ALL variables (including continuous)
    531 * to ensure that not only the MIP but also the LP relaxation is easy enough
    532 */
    533 if( allfixingrate >= minfixingrate / 2.0 )
    534 {
    535 SCIP_SOL** subsols;
    536 int nsubsols;
    537
    538 /* catch LP events of sub-SCIP */
    539 assert(eventhdlr != NULL);
    540 SCIP_CALL( SCIPtransformProb(subscip) );
    541 SCIP_CALL( SCIPcatchEvent(subscip, SCIP_EVENTTYPE_LPSOLVED, eventhdlr, (SCIP_EVENTDATA*) heurdata, NULL) );
    542
    543 /* solve the subproblem */
    544 SCIPdebugMsg(scip, "solving subproblem: nstallnodes=%" SCIP_LONGINT_FORMAT ", maxnodes=%" SCIP_LONGINT_FORMAT "\n", nstallnodes, maxnodes);
    545 retcode = SCIPsolve(subscip);
    546
    547 /* drop LP events of sub-SCIP */
    548 SCIP_CALL( SCIPdropEvent(subscip, SCIP_EVENTTYPE_LPSOLVED, eventhdlr, (SCIP_EVENTDATA*) heurdata, -1) );
    549
    550 /* errors in solving the subproblem should not kill the overall solving process;
    551 * hence, the return code is caught and a warning is printed, only in debug mode, SCIP will stop.
    552 */
    553 if( retcode != SCIP_OKAY )
    554 {
    555 SCIPwarningMessage(scip, "Error while solving subproblem in RENS heuristic; sub-SCIP terminated with code <%d>\n", retcode);
    556 SCIPABORT();
    557 goto TERMINATE;
    558 }
    559 else
    560 {
    561 /* transfer variable statistics from sub-SCIP */
    562 SCIP_CALL( SCIPmergeVariableStatistics(subscip, scip, subvars, vars, nvars) );
    563 }
    564
    565 /* print solving statistics of subproblem if we are in SCIP's debug mode */
    567
    568 /* check, whether a solution was found;
    569 * due to numerics, it might happen that not all solutions are feasible -> try all solutions until one was accepted
    570 */
    571 nsubsols = SCIPgetNSols(subscip);
    572 subsols = SCIPgetSols(subscip);
    573 success = FALSE;
    574 for( i = 0; i < nsubsols && (!success || heurdata->addallsols); ++i )
    575 {
    576 SCIP_SOL* newsol;
    577
    578 SCIP_CALL( SCIPtranslateSubSol(scip, subscip, subsols[i], heur, subvars, &newsol) );
    579
    580 SCIP_CALL( SCIPtrySolFree(scip, &newsol, FALSE, FALSE, TRUE, TRUE, TRUE, &success) );
    581 if( success )
    582 *result = SCIP_FOUNDSOL;
    583 }
    584
    585 SCIPstatisticPrintf("RENS statistic: fixed %6.3f integer variables, %6.3f all variables, needed %6.1f seconds, %" SCIP_LONGINT_FORMAT " nodes, solution %10.4f found at node %" SCIP_LONGINT_FORMAT "\n",
    586 intfixingrate, allfixingrate, SCIPgetSolvingTime(subscip), SCIPgetNNodes(subscip), success ? SCIPgetPrimalbound(scip) : SCIPinfinity(scip),
    587 nsubsols > 0 ? SCIPsolGetNodenum(SCIPgetBestSol(subscip)) : -1 );
    588 }
    589 else
    590 {
    591 SCIPstatisticPrintf("RENS statistic: fixed only %6.3f integer variables, %6.3f all variables --> abort \n", intfixingrate, allfixingrate);
    592 }
    593
    594TERMINATE:
    595 /* free sub problem data */
    597
    598 return SCIP_OKAY;
    599}
    600
    601/* ---------------- external methods of RENS heuristic ---------------- */
    602
    603/** main procedure of the RENS heuristic, creates and solves a sub-SCIP */
    605 SCIP* scip, /**< original SCIP data structure */
    606 SCIP_HEUR* heur, /**< heuristic data structure */
    607 SCIP_RESULT* result, /**< result data structure */
    608 SCIP_Real minfixingrate, /**< minimum percentage of integer variables that have to be fixed */
    609 SCIP_Real minimprove, /**< factor by which RENS should at least improve the incumbent */
    610 SCIP_Longint maxnodes, /**< maximum number of nodes for the subproblem */
    611 SCIP_Longint nstallnodes, /**< number of stalling nodes for the subproblem */
    612 char startsol, /**< solution used for fixing values ('l'p relaxation, 'n'lp relaxation) */
    613 SCIP_Bool binarybounds, /**< should general integers get binary bounds [floor(.),ceil(.)]? */
    614 SCIP_Bool uselprows /**< should subproblem be created out of the rows in the LP rows? */
    615 )
    616{
    617 SCIP* subscip; /* the subproblem created by RENS */
    618
    619 SCIP_Real intfixingrate; /* percentage of integer variables fixed */
    620
    621 SCIP_VAR** fixedvars;
    622 SCIP_Real* fixedvals;
    623 int nfixedvars;
    624 int fixedvarssize;
    625 int nbinvars;
    626 int nintvars;
    627
    628 SCIP_Bool success;
    629 SCIP_RETCODE retcode;
    630
    631 assert(scip != NULL);
    632 assert(heur != NULL);
    633 assert(result != NULL);
    634
    635 assert(maxnodes >= 0);
    636 assert(nstallnodes >= 0);
    637
    638 assert(0.0 <= minfixingrate && minfixingrate <= 1.0);
    639 assert(0.0 <= minimprove && minimprove <= 1.0);
    640 assert(startsol == 'l' || startsol == 'n');
    641
    642 *result = SCIP_DIDNOTRUN;
    643
    644 nbinvars = SCIPgetNBinVars(scip);
    645 nintvars = SCIPgetNIntVars(scip);
    646
    647 /* allocate buffer storage to keep fixings for the variables in the sub SCIP */
    648 fixedvarssize = nbinvars + nintvars;
    649 SCIP_CALL( SCIPallocBufferArray(scip, &fixedvars, fixedvarssize) );
    650 SCIP_CALL( SCIPallocBufferArray(scip, &fixedvals, fixedvarssize) );
    651 nfixedvars = 0;
    652
    653 /* compute the number of initial fixings and check if the fixing rate exceeds the minimum fixing rate */
    654 SCIP_CALL( computeFixingrate(scip, fixedvars, fixedvals, &nfixedvars, fixedvarssize, minfixingrate, &startsol, &intfixingrate, &success) );
    655
    656 if( !success )
    657 {
    658 SCIPstatisticPrintf("RENS statistic: fixed only %5.2f integer variables --> abort \n", intfixingrate);
    659 goto TERMINATE;
    660 }
    661
    662 /* check whether there is enough time and memory left */
    663 SCIP_CALL( SCIPcheckCopyLimits(scip, &success) );
    664
    665 if( !success )
    666 goto TERMINATE;
    667
    668 *result = SCIP_DIDNOTFIND;
    669
    670 /* initialize the subproblem */
    671 SCIP_CALL( SCIPcreate(&subscip) );
    672
    673 retcode = setupAndSolveSubscip(scip, subscip, result, heur, fixedvars, fixedvals, nfixedvars, intfixingrate, minfixingrate, minimprove, maxnodes, nstallnodes, startsol, binarybounds, uselprows);
    674
    675 SCIP_CALL( SCIPfree(&subscip) );
    676
    677 SCIP_CALL( retcode );
    678
    679TERMINATE:
    680 /* free buffer storage for variable fixings */
    681 SCIPfreeBufferArray(scip, &fixedvals);
    682 SCIPfreeBufferArray(scip, &fixedvars);
    683
    684 return SCIP_OKAY;
    685}
    687
    688/*
    689 * Callback methods of primal heuristic
    690 */
    691
    692/** copy method for primal heuristic plugins (called when SCIP copies plugins) */
    693static
    694SCIP_DECL_HEURCOPY(heurCopyRens)
    695{ /*lint --e{715}*/
    696 assert(scip != NULL);
    697 assert(heur != NULL);
    698
    700
    701 /* call inclusion method of primal heuristic */
    703
    704 return SCIP_OKAY;
    705}
    706
    707/** destructor of primal heuristic to free user data (called when SCIP is exiting) */
    708static
    709SCIP_DECL_HEURFREE(heurFreeRens)
    710{ /*lint --e{715}*/
    711 SCIP_HEURDATA* heurdata;
    712
    713 assert( heur != NULL );
    714 assert( scip != NULL );
    715
    716 /* get heuristic data */
    717 heurdata = SCIPheurGetData(heur);
    718 assert( heurdata != NULL );
    719
    720 /* free heuristic data */
    722 SCIPheurSetData(heur, NULL);
    723
    724 return SCIP_OKAY;
    725}
    726
    727/** initialization method of primal heuristic (called after problem was transformed) */
    728static
    729SCIP_DECL_HEURINIT(heurInitRens)
    730{ /*lint --e{715}*/
    731 SCIP_HEURDATA* heurdata;
    732
    733 assert( heur != NULL );
    734 assert( scip != NULL );
    735
    736 /* get heuristic data */
    737 heurdata = SCIPheurGetData(heur);
    738 assert( heurdata != NULL );
    739
    740 /* initialize data */
    741 heurdata->usednodes = 0;
    742
    743 return SCIP_OKAY;
    744}
    745
    746
    747/** execution method of primal heuristic */
    748static
    749SCIP_DECL_HEUREXEC(heurExecRens)
    750{ /*lint --e{715}*/
    751 SCIP_HEURDATA* heurdata; /* heuristic's data */
    752 SCIP_Longint nstallnodes; /* number of stalling nodes for the subproblem */
    753
    754 assert( heur != NULL );
    755 assert( scip != NULL );
    756 assert( result != NULL );
    757 assert( SCIPhasCurrentNodeLP(scip) );
    758
    759 *result = SCIP_DELAYED;
    760
    761 /* do not call heuristic of node was already detected to be infeasible */
    762 if( nodeinfeasible )
    763 return SCIP_OKAY;
    764
    765 /* get heuristic data */
    766 heurdata = SCIPheurGetData(heur);
    767 assert( heurdata != NULL );
    768
    769 /* only call heuristic, if an optimal LP solution is at hand */
    770 if( heurdata->startsol == 'l' && SCIPgetLPSolstat(scip) != SCIP_LPSOLSTAT_OPTIMAL )
    771 return SCIP_OKAY;
    772
    773 /* only call heuristic, if the LP objective value is smaller than the cutoff bound */
    774 if( heurdata->startsol == 'l' && SCIPisGE(scip, SCIPgetLPObjval(scip), SCIPgetCutoffbound(scip)) )
    775 return SCIP_OKAY;
    776
    777 /* only continue with some fractional variables */
    778 if( heurdata->startsol == 'l' && SCIPgetNLPBranchCands(scip) == 0 )
    779 return SCIP_OKAY;
    780
    781 /* do not proceed, when we should use the NLP relaxation, but there is no NLP solver included in SCIP */
    782 if( heurdata->startsol == 'n' && SCIPgetNNlpis(scip) == 0 )
    783 return SCIP_OKAY;
    784
    785 *result = SCIP_DIDNOTRUN;
    786
    787 /* calculate the maximal number of branching nodes until heuristic is aborted */
    788 nstallnodes = (SCIP_Longint)(heurdata->nodesquot * SCIPgetNNodes(scip));
    789
    790 /* reward RENS if it succeeded often */
    791 nstallnodes = (SCIP_Longint)(nstallnodes * 3.0 * (SCIPheurGetNBestSolsFound(heur)+1.0)/(SCIPheurGetNCalls(heur) + 1.0));
    792 nstallnodes -= 100 * SCIPheurGetNCalls(heur); /* count the setup costs for the sub-SCIP as 100 nodes */
    793 nstallnodes += heurdata->nodesofs;
    794
    795 /* determine the node limit for the current process */
    796 nstallnodes -= heurdata->usednodes;
    797 nstallnodes = MIN(nstallnodes, heurdata->maxnodes);
    798
    799 /* check whether we have enough nodes left to call subproblem solving */
    800 if( nstallnodes < heurdata->minnodes )
    801 {
    802 SCIPdebugMsg(scip, "skipping RENS: nstallnodes=%" SCIP_LONGINT_FORMAT ", minnodes=%" SCIP_LONGINT_FORMAT "\n", nstallnodes, heurdata->minnodes);
    803 return SCIP_OKAY;
    804 }
    805
    806 if( SCIPisStopped(scip) && !heurdata->extratime )
    807 return SCIP_OKAY;
    808
    809 SCIP_CALL( SCIPapplyRens(scip, heur, result, heurdata->minfixingrate, heurdata->minimprove,
    810 heurdata->maxnodes, nstallnodes, heurdata->startsol, heurdata->binarybounds, heurdata->uselprows) );
    811
    812 return SCIP_OKAY;
    814
    815
    816/*
    817 * primal heuristic specific interface methods
    818 */
    819
    820/** creates the rens primal heuristic and includes it in SCIP */
    822 SCIP* scip /**< SCIP data structure */
    823 )
    824{
    825 SCIP_HEURDATA* heurdata;
    826 SCIP_HEUR* heur;
    827
    828 /* create Rens primal heuristic data */
    829 SCIP_CALL( SCIPallocBlockMemory(scip, &heurdata) );
    830
    831 /* include primal heuristic */
    834 HEUR_MAXDEPTH, HEUR_TIMING, HEUR_USESSUBSCIP, heurExecRens, heurdata) );
    835
    836 assert(heur != NULL);
    837
    838 /* primal heuristic is safe to use in exact solving mode */
    839 SCIPheurMarkExact(heur);
    840
    841 /* set non-NULL pointers to callback methods */
    842 SCIP_CALL( SCIPsetHeurCopy(scip, heur, heurCopyRens) );
    843 SCIP_CALL( SCIPsetHeurFree(scip, heur, heurFreeRens) );
    844 SCIP_CALL( SCIPsetHeurInit(scip, heur, heurInitRens) );
    845
    846 /* add rens primal heuristic parameters */
    847
    848 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/minfixingrate",
    849 "minimum percentage of integer variables that have to be fixable",
    850 &heurdata->minfixingrate, FALSE, DEFAULT_MINFIXINGRATE, 0.0, 1.0, NULL, NULL) );
    851
    852 SCIP_CALL( SCIPaddLongintParam(scip, "heuristics/" HEUR_NAME "/maxnodes",
    853 "maximum number of nodes to regard in the subproblem",
    854 &heurdata->maxnodes, TRUE,DEFAULT_MAXNODES, 0LL, SCIP_LONGINT_MAX, NULL, NULL) );
    855
    856 SCIP_CALL( SCIPaddLongintParam(scip, "heuristics/" HEUR_NAME "/nodesofs",
    857 "number of nodes added to the contingent of the total nodes",
    858 &heurdata->nodesofs, FALSE, DEFAULT_NODESOFS, 0LL, SCIP_LONGINT_MAX, NULL, NULL) );
    859
    860 SCIP_CALL( SCIPaddLongintParam(scip, "heuristics/" HEUR_NAME "/minnodes",
    861 "minimum number of nodes required to start the subproblem",
    862 &heurdata->minnodes, TRUE, DEFAULT_MINNODES, 0LL, SCIP_LONGINT_MAX, NULL, NULL) );
    863
    864 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/nodesquot",
    865 "contingent of sub problem nodes in relation to the number of nodes of the original problem",
    866 &heurdata->nodesquot, FALSE, DEFAULT_NODESQUOT, 0.0, 1.0, NULL, NULL) );
    867
    868 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/minimprove",
    869 "factor by which RENS should at least improve the incumbent",
    870 &heurdata->minimprove, TRUE, DEFAULT_MINIMPROVE, 0.0, 1.0, NULL, NULL) );
    871
    872 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/lplimfac",
    873 "factor by which the limit on the number of LP depends on the node limit",
    874 &heurdata->lplimfac, TRUE, DEFAULT_LPLIMFAC, 1.0, SCIP_REAL_MAX, NULL, NULL) );
    875
    876 SCIP_CALL( SCIPaddCharParam(scip, "heuristics/" HEUR_NAME "/startsol",
    877 "solution that is used for fixing values ('l'p relaxation, 'n'lp relaxation)",
    878 &heurdata->startsol, FALSE, DEFAULT_STARTSOL, STARTSOL_CHOICES, NULL, NULL) );
    879
    880 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/binarybounds",
    881 "should general integers get binary bounds [floor(.),ceil(.)] ?",
    882 &heurdata->binarybounds, TRUE, DEFAULT_BINARYBOUNDS, NULL, NULL) );
    883
    884 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/uselprows",
    885 "should subproblem be created out of the rows in the LP rows?",
    886 &heurdata->uselprows, TRUE, DEFAULT_USELPROWS, NULL, NULL) );
    887
    888 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/copycuts",
    889 "if uselprows == FALSE, should all active cuts from cutpool be copied to constraints in subproblem?",
    890 &heurdata->copycuts, TRUE, DEFAULT_COPYCUTS, NULL, NULL) );
    891
    892 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/extratime",
    893 "should the RENS sub-CIP get its own full time limit? This is only for testing and not recommended!",
    894 &heurdata->extratime, TRUE, DEFAULT_EXTRATIME, NULL, NULL) );
    895
    896 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/addallsols",
    897 "should all subproblem solutions be added to the original SCIP?",
    898 &heurdata->addallsols, TRUE, DEFAULT_ADDALLSOLS, NULL, NULL) );
    899
    900 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/fullscale",
    901 "should the RENS sub-CIP be solved with cuts, conflicts, strong branching,... This is only for testing and not recommended!",
    902 &heurdata->fullscale, TRUE, DEFAULT_FULLSCALE, NULL, NULL) );
    903
    904 SCIP_CALL( SCIPaddIntParam(scip, "heuristics/" HEUR_NAME "/bestsollimit",
    905 "limit on number of improving incumbent solutions in sub-CIP",
    906 &heurdata->bestsollimit, FALSE, DEFAULT_BESTSOLLIMIT, -1, INT_MAX, NULL, NULL) );
    907
    908 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/useuct",
    909 "should uct node selection be used at the beginning of the search?",
    910 &heurdata->useuct, TRUE, DEFAULT_USEUCT, NULL, NULL) );
    911
    912 return SCIP_OKAY;
    913}
    #define NULL
    Definition: def.h:257
    #define SCIP_Longint
    Definition: def.h:150
    #define SCIP_REAL_MAX
    Definition: def.h:167
    #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_LONGINT_FORMAT
    Definition: def.h:157
    #define SCIPABORT()
    Definition: def.h:336
    #define SCIP_LONGINT_MAX
    Definition: def.h:151
    #define SCIP_CALL(x)
    Definition: def.h:364
    SCIP_RETCODE SCIPcheckCopyLimits(SCIP *sourcescip, SCIP_Bool *success)
    Definition: scip_copy.c:3250
    SCIP_RETCODE SCIPmergeVariableStatistics(SCIP *sourcescip, SCIP *targetscip, SCIP_VAR **sourcevars, SCIP_VAR **targetvars, int nvars)
    Definition: scip_copy.c:1255
    SCIP_RETCODE SCIPtranslateSubSol(SCIP *scip, SCIP *subscip, SCIP_SOL *subsol, SCIP_HEUR *heur, SCIP_VAR **subvars, SCIP_SOL **newsol)
    Definition: scip_copy.c:1398
    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 SCIPgetNIntVars(SCIP *scip)
    Definition: scip_prob.c:2340
    SCIP_RETCODE SCIPsetObjlimit(SCIP *scip, SCIP_Real objlimit)
    Definition: scip_prob.c:1661
    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
    int SCIPgetNConss(SCIP *scip)
    Definition: scip_prob.c:3620
    int SCIPgetNOrigVars(SCIP *scip)
    Definition: scip_prob.c:2838
    int SCIPgetNBinVars(SCIP *scip)
    Definition: scip_prob.c:2293
    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 SCIPapplyRens(SCIP *scip, SCIP_HEUR *heur, SCIP_RESULT *result, SCIP_Real minfixingrate, SCIP_Real minimprove, SCIP_Longint maxnodes, SCIP_Longint nstallnodes, char startsol, SCIP_Bool binarybounds, SCIP_Bool uselprows)
    Definition: heur_rens.c:596
    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 SCIPaddCharParam(SCIP *scip, const char *name, const char *desc, char *valueptr, SCIP_Bool isadvanced, char defaultvalue, const char *allowedvalues, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
    Definition: scip_param.c:167
    SCIP_RETCODE SCIPaddIntParam(SCIP *scip, const char *name, const char *desc, int *valueptr, SCIP_Bool isadvanced, int defaultvalue, int minvalue, int maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
    Definition: scip_param.c:83
    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 SCIPsetCharParam(SCIP *scip, const char *name, char value)
    Definition: scip_param.c:661
    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 SCIPincludeHeurRens(SCIP *scip)
    Definition: heur_rens.c:813
    SCIP_BRANCHRULE * SCIPfindBranchrule(SCIP *scip, const char *name)
    Definition: scip_branch.c:304
    int SCIPgetNLPBranchCands(SCIP *scip)
    Definition: scip_branch.c:436
    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
    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_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_Longint SCIPheurGetNBestSolsFound(SCIP_HEUR *heur)
    Definition: heur.c:1613
    SCIP_Longint SCIPheurGetNCalls(SCIP_HEUR *heur)
    Definition: heur.c:1593
    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_Bool SCIPhasCurrentNodeLP(SCIP *scip)
    Definition: scip_lp.c:87
    SCIP_LPSOLSTAT SCIPgetLPSolstat(SCIP *scip)
    Definition: scip_lp.c:174
    SCIP_Real SCIPgetLPObjval(SCIP *scip)
    Definition: scip_lp.c:253
    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 SCIPfreeBlockMemory(scip, ptr)
    Definition: scip_mem.h:108
    #define SCIPallocBlockMemory(scip, ptr)
    Definition: scip_mem.h:89
    int SCIPgetNNlpis(SCIP *scip)
    Definition: scip_nlpi.c:205
    SCIP_Bool SCIPisNLPConstructed(SCIP *scip)
    Definition: scip_nlp.c:110
    SCIP_NLPSOLSTAT SCIPgetNLPSolstat(SCIP *scip)
    Definition: scip_nlp.c:574
    #define SCIPsolveNLP(...)
    Definition: scip_nlp.h:361
    SCIP_RETCODE SCIPsetNLPInitialGuessSol(SCIP *scip, SCIP_SOL *sol)
    Definition: scip_nlp.c:501
    SCIP_NODESEL * SCIPfindNodesel(SCIP *scip, const char *name)
    Definition: scip_nodesel.c:242
    SCIP_SOL * SCIPgetBestSol(SCIP *scip)
    Definition: scip_sol.c:2986
    SCIP_Longint SCIPsolGetNodenum(SCIP_SOL *sol)
    Definition: sol.c:4254
    int SCIPgetNSols(SCIP *scip)
    Definition: scip_sol.c:2887
    SCIP_SOL ** SCIPgetSols(SCIP *scip)
    Definition: scip_sol.c:2936
    SCIP_RETCODE SCIPtrySolFree(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:4114
    SCIP_RETCODE SCIPtransformProb(SCIP *scip)
    Definition: scip_solve.c:232
    SCIP_RETCODE SCIPpresolve(SCIP *scip)
    Definition: scip_solve.c:2425
    SCIP_RETCODE SCIPinterruptSolve(SCIP *scip)
    Definition: scip_solve.c:3561
    SCIP_RETCODE SCIPsolve(SCIP *scip)
    Definition: scip_solve.c:2611
    SCIP_Real SCIPgetPrimalbound(SCIP *scip)
    SCIP_Real SCIPgetUpperbound(SCIP *scip)
    SCIP_Longint SCIPgetNNodes(SCIP *scip)
    SCIP_RETCODE SCIPprintStatistics(SCIP *scip, FILE *file)
    SCIP_Real SCIPgetLowerbound(SCIP *scip)
    SCIP_Longint SCIPgetNLPs(SCIP *scip)
    SCIP_Real SCIPgetCutoffbound(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 SCIPinfinity(SCIP *scip)
    SCIP_Bool SCIPisGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisFeasEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Real SCIPfeasCeil(SCIP *scip, SCIP_Real val)
    SCIP_Real SCIPfloor(SCIP *scip, SCIP_Real val)
    SCIP_Real SCIPfeasFloor(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisFeasIntegral(SCIP *scip, SCIP_Real val)
    SCIP_Real SCIPsumepsilon(SCIP *scip)
    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_Real SCIPvarGetLPSol(SCIP_VAR *var)
    Definition: var.c:24696
    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_Real SCIPvarGetNLPSol(SCIP_VAR *var)
    Definition: var.c:24723
    #define DEFAULT_FULLSCALE
    Definition: heur_rens.c:91
    static SCIP_DECL_HEUREXEC(heurExecRens)
    Definition: heur_rens.c:741
    #define DEFAULT_NODESQUOT
    Definition: heur_rens.c:82
    #define DEFAULT_STARTSOL
    Definition: heur_rens.c:84
    static SCIP_RETCODE setupAndSolveSubscip(SCIP *scip, SCIP *subscip, SCIP_RESULT *result, SCIP_HEUR *heur, SCIP_VAR **fixedvars, SCIP_Real *fixedvals, int nfixedvars, SCIP_Real intfixingrate, SCIP_Real minfixingrate, SCIP_Real minimprove, SCIP_Longint maxnodes, SCIP_Longint nstallnodes, char startsol, SCIP_Bool binarybounds, SCIP_Bool uselprows)
    Definition: heur_rens.c:337
    #define DEFAULT_BINARYBOUNDS
    Definition: heur_rens.c:76
    #define DEFAULT_NODESOFS
    Definition: heur_rens.c:81
    #define DEFAULT_COPYCUTS
    Definition: heur_rens.c:87
    #define DEFAULT_MAXNODES
    Definition: heur_rens.c:77
    #define HEUR_TIMING
    Definition: heur_rens.c:72
    #define DEFAULT_MINNODES
    Definition: heur_rens.c:80
    #define HEUR_FREQOFS
    Definition: heur_rens.c:70
    #define DEFAULT_EXTRATIME
    Definition: heur_rens.c:88
    #define HEUR_DESC
    Definition: heur_rens.c:66
    #define DEFAULT_LPLIMFAC
    Definition: heur_rens.c:83
    static SCIP_DECL_EVENTEXEC(eventExecRens)
    Definition: heur_rens.c:311
    #define DEFAULT_ADDALLSOLS
    Definition: heur_rens.c:89
    #define DEFAULT_MINFIXINGRATE
    Definition: heur_rens.c:78
    #define DEFAULT_USEUCT
    Definition: heur_rens.c:93
    static SCIP_DECL_HEURINIT(heurInitRens)
    Definition: heur_rens.c:721
    #define STARTSOL_CHOICES
    Definition: heur_rens.c:85
    #define HEUR_DISPCHAR
    Definition: heur_rens.c:67
    #define HEUR_MAXDEPTH
    Definition: heur_rens.c:71
    #define HEUR_PRIORITY
    Definition: heur_rens.c:68
    static SCIP_DECL_HEURCOPY(heurCopyRens)
    Definition: heur_rens.c:686
    #define DEFAULT_MINIMPROVE
    Definition: heur_rens.c:79
    #define HEUR_NAME
    Definition: heur_rens.c:65
    #define DEFAULT_USELPROWS
    Definition: heur_rens.c:86
    static SCIP_RETCODE restrictToBinaryBounds(SCIP *scip, SCIP *subscip, SCIP_VAR **subvars, char startsol)
    Definition: heur_rens.c:244
    #define DEFAULT_BESTSOLLIMIT
    Definition: heur_rens.c:92
    static SCIP_DECL_HEURFREE(heurFreeRens)
    Definition: heur_rens.c:701
    #define EVENTHDLR_DESC
    Definition: heur_rens.c:97
    #define HEUR_FREQ
    Definition: heur_rens.c:69
    #define HEUR_USESSUBSCIP
    Definition: heur_rens.c:73
    #define EVENTHDLR_NAME
    Definition: heur_rens.c:96
    static SCIP_RETCODE computeFixingrate(SCIP *scip, SCIP_VAR **fixedvars, SCIP_Real *fixedvals, int *nfixedvars, int fixedvarssize, SCIP_Real minfixingrate, char *startsol, SCIP_Real *fixingrate, SCIP_Bool *success)
    Definition: heur_rens.c:137
    LNS heuristic that finds the optimal rounding to a given point.
    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 SCIPdebug(x)
    Definition: pub_message.h:93
    #define SCIPstatisticPrintf
    Definition: pub_message.h:126
    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
    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 NLPI solver interfaces
    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_LPSOLVED
    Definition: type_event.h:102
    struct SCIP_HeurData SCIP_HEURDATA
    Definition: type_heur.h:77
    @ SCIP_LPSOLSTAT_OPTIMAL
    Definition: type_lp.h:44
    enum SCIP_NlpSolStat SCIP_NLPSOLSTAT
    Definition: type_nlpi.h:168
    @ SCIP_NLPSOLSTAT_FEASIBLE
    Definition: type_nlpi.h:162
    @ SCIP_NLPSOLSTAT_LOCOPT
    Definition: type_nlpi.h:161
    @ SCIP_NLPSOLSTAT_GLOBOPT
    Definition: type_nlpi.h:160
    @ SCIP_PARAMSETTING_OFF
    Definition: type_paramset.h:63
    @ SCIP_PARAMSETTING_FAST
    Definition: type_paramset.h:62
    @ SCIP_DIDNOTRUN
    Definition: type_result.h:42
    @ SCIP_DELAYED
    Definition: type_result.h:43
    @ 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