Scippy

    SCIP

    Solving Constraint Integer Programs

    heur_ofins.c
    Go to the documentation of this file.
    1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    2/* */
    3/* This file is part of the program and library */
    4/* SCIP --- Solving Constraint Integer Programs */
    5/* */
    6/* Copyright (c) 2002-2025 Zuse Institute Berlin (ZIB) */
    7/* */
    8/* Licensed under the Apache License, Version 2.0 (the "License"); */
    9/* you may not use this file except in compliance with the License. */
    10/* You may obtain a copy of the License at */
    11/* */
    12/* http://www.apache.org/licenses/LICENSE-2.0 */
    13/* */
    14/* Unless required by applicable law or agreed to in writing, software */
    15/* distributed under the License is distributed on an "AS IS" BASIS, */
    16/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
    17/* See the License for the specific language governing permissions and */
    18/* limitations under the License. */
    19/* */
    20/* You should have received a copy of the Apache-2.0 license */
    21/* along with SCIP; see the file LICENSE. If not visit scipopt.org. */
    22/* */
    23/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    24
    25/**@file heur_ofins.c
    26 * @ingroup DEFPLUGINS_HEUR
    27 * @brief OFINS - Objective Function Induced Neighborhood Search - a primal heuristic for reoptimization
    28 * @author Jakob Witzig
    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_ofins.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_copy.h"
    44#include "scip/scip_event.h"
    45#include "scip/scip_general.h"
    46#include "scip/scip_heur.h"
    47#include "scip/scip_mem.h"
    48#include "scip/scip_message.h"
    49#include "scip/scip_nodesel.h"
    50#include "scip/scip_numerics.h"
    51#include "scip/scip_param.h"
    52#include "scip/scip_prob.h"
    53#include "scip/scip_sol.h"
    54#include "scip/scip_solve.h"
    56#include "scip/scip_timing.h"
    57#include <string.h>
    58
    59#define HEUR_NAME "ofins"
    60#define HEUR_DESC "primal heuristic for reoptimization, objective function induced neighborhood search"
    61#define HEUR_DISPCHAR SCIP_HEURDISPCHAR_LNS
    62#define HEUR_PRIORITY 60000
    63#define HEUR_FREQ 0
    64#define HEUR_FREQOFS 0
    65#define HEUR_MAXDEPTH 0
    66#define HEUR_TIMING SCIP_HEURTIMING_BEFORENODE
    67#define HEUR_USESSUBSCIP TRUE /**< does the heuristic use a secondary SCIP instance? */
    68
    69/* default values for OFINS-specific plugins */
    70#define DEFAULT_MAXNODES 5000LL /**< maximum number of nodes to regard in the subproblem */
    71#define DEFAULT_MAXCHGRATE 0.50 /**< maximum percentage of changed objective coefficients */
    72#define DEFAULT_COPYCUTS TRUE /**< if DEFAULT_USELPROWS is FALSE, then should all active cuts from the cutpool
    73 * of the original scip be copied to constraints of the subscip */
    74#define DEFAULT_MAXCHANGE 0.04 /**< maximal rate of change per coefficient to get fixed */
    75#define DEFAULT_MINIMPROVE 0.01 /**< factor by which OFINS should at least improve the incumbent */
    76#define DEFAULT_ADDALLSOLS FALSE /**< should all subproblem solutions be added to the original SCIP? */
    77#define DEFAULT_MINNODES 50LL /**< minimum number of nodes to regard in the subproblem */
    78#define DEFAULT_NODESOFS 500LL /**< number of nodes added to the contingent of the total nodes */
    79#define DEFAULT_NODESQUOT 0.1 /**< subproblem nodes in relation to nodes of the original problem */
    80#define DEFAULT_LPLIMFAC 2.0 /**< factor by which the limit on the number of LP depends on the node limit */
    81
    82/* event handler properties */
    83#define EVENTHDLR_NAME "Ofins"
    84#define EVENTHDLR_DESC "LP event handler for " HEUR_NAME " heuristic"
    85
    86
    87/** primal heuristic data */
    88struct SCIP_HeurData
    89{
    90 SCIP_Real maxchangerate; /**< maximal rate of changed coefficients in the objective function */
    91 SCIP_Longint maxnodes; /**< maximum number of nodes to regard in the subproblem */
    92 SCIP_Bool copycuts; /**< should all active cuts from cutpool be copied to constraints in subproblem? */
    93 SCIP_Bool addallsols; /**< should all subproblem solutions be added to the original SCIP? */
    94 SCIP_Longint minnodes; /**< minimum number of nodes to regard in the subproblem */
    95 SCIP_Longint nodesofs; /**< number of nodes added to the contingent of the total nodes */
    96 SCIP_Real maxchange; /**< maximal rate of change per coefficient to get fixed */
    97 SCIP_Real minimprove; /**< factor by which OFINS should at least improve the incumbent */
    98 SCIP_Real nodesquot; /**< subproblem nodes in relation to nodes of the original problem */
    99 SCIP_Real nodelimit; /**< the nodelimit employed in the current sub-SCIP, for the event handler*/
    100 SCIP_Real lplimfac; /**< factor by which the limit on the number of LP depends on the node limit */
    101};
    102
    103/* ---------------- Callback methods of event handler ---------------- */
    104
    105/* exec the event handler
    106 *
    107 * we interrupt the solution process
    108 */
    109static
    110SCIP_DECL_EVENTEXEC(eventExecOfins)
    111{
    112 SCIP_HEURDATA* heurdata;
    113
    114 assert(eventhdlr != NULL);
    115 assert(eventdata != NULL);
    116 assert(strcmp(SCIPeventhdlrGetName(eventhdlr), EVENTHDLR_NAME) == 0);
    117 assert(event != NULL);
    119
    120 heurdata = (SCIP_HEURDATA*)eventdata;
    121 assert(heurdata != NULL);
    122
    123 /* interrupt solution process of sub-SCIP */
    124 if( SCIPgetNLPs(scip) > heurdata->lplimfac * heurdata->nodelimit )
    125 {
    126 SCIPdebugMsg(scip, "interrupt after %" SCIP_LONGINT_FORMAT " LPs\n",SCIPgetNLPs(scip));
    128 }
    129
    130 return SCIP_OKAY;
    131}
    132
    133/* setup and solve the sub-SCIP */
    134static
    136 SCIP* scip, /**< original SCIP data structure */
    137 SCIP* subscip, /**< sub-SCIP data structure */
    138 SCIP_HEUR* heur, /**< heuristic data structure */
    139 SCIP_HEURDATA* heurdata, /**< euristic's private data structure */
    140 SCIP_RESULT* result, /**< result data structure */
    141 SCIP_Longint nstallnodes, /**< number of stalling nodes for the subproblem */
    142 SCIP_Bool* chgcoeffs /**< array of changed coefficients */
    143
    144 )
    145{
    146 SCIP_HASHMAP* varmapfw;
    147 SCIP_VAR** vars;
    148 SCIP_VAR** subvars;
    149 SCIP_EVENTHDLR* eventhdlr;
    150
    151 SCIP_SOL* sol;
    152 SCIP_VAR** fixedvars;
    153 SCIP_Real* fixedvals;
    154 int nfixedvars;
    155
    156 int nvars;
    157 int nintvars;
    158 int i;
    159
    160 SCIP_SOL** subsols;
    161 int nsubsols = 0;
    162
    163 SCIP_Bool success;
    164 SCIP_RETCODE retcode;
    165 SCIP_STATUS status;
    166
    167 assert(scip != NULL);
    168 assert(subscip != NULL);
    169 assert(heur != NULL);
    170 assert(heurdata != NULL);
    171 assert(result != NULL);
    172 assert(chgcoeffs != NULL);
    173
    174 SCIPdebugMsg(scip, "+---+ Start OFINS heuristic +---+\n");
    175
    176 /* get variable data */
    177 vars = SCIPgetVars(scip);
    178 nvars = SCIPgetNVars(scip);
    179
    180 /* create the variable mapping hash map */
    181 SCIP_CALL( SCIPhashmapCreate(&varmapfw, SCIPblkmem(subscip), nvars) );
    182
    183 /* get optimal solution of the last iteration */
    185
    186 /* if the solution is NULL the last problem was infeasible */
    187 if( sol == NULL )
    188 return SCIP_OKAY;
    189
    191 SCIP_CALL( SCIPallocBufferArray(scip, &fixedvars, nvars) );
    192 SCIP_CALL( SCIPallocBufferArray(scip, &fixedvals, nvars) );
    193
    194 /* determine variables to fix in the sub-SCIP */
    195 nfixedvars = 0;
    196 for( i = 0; i < nintvars; i++ )
    197 {
    198 if( !chgcoeffs[i] )
    199 {
    200 fixedvars[nfixedvars] = vars[i];
    201 fixedvals[nfixedvars] = SCIPgetSolVal(scip, sol, vars[i]);
    202 ++nfixedvars;
    203 }
    204 }
    205
    206 /* create a problem copy as sub SCIP */
    207 SCIP_CALL( SCIPcopyLargeNeighborhoodSearch(scip, subscip, varmapfw, "ofins", fixedvars, fixedvals, nfixedvars, FALSE,
    208 FALSE, &success, NULL) );
    209 assert(success);
    210
    211 SCIPfreeBufferArrayNull(scip, &fixedvals);
    212 SCIPfreeBufferArrayNull(scip, &fixedvars);
    213
    214 /* create event handler for LP events */
    215 eventhdlr = NULL;
    216 SCIP_CALL( SCIPincludeEventhdlrBasic(subscip, &eventhdlr, EVENTHDLR_NAME, EVENTHDLR_DESC, eventExecOfins, NULL) );
    217 if( eventhdlr == NULL )
    218 {
    219 SCIPerrorMessage("event handler for " HEUR_NAME " heuristic not found.\n");
    220 return SCIP_PLUGINNOTFOUND;
    221 }
    222
    223 SCIP_CALL( SCIPallocBufferArray(scip, &subvars, nvars) );
    224 for( i = 0; i < nvars; i++ )
    225 subvars[i] = (SCIP_VAR*) SCIPhashmapGetImage(varmapfw, vars[i]);
    226
    227 /* free hash map */
    228 SCIPhashmapFree(&varmapfw);
    229
    230 /* set an objective limit */
    231 SCIPdebugMsg(scip, "set objective limit of %g to sub-SCIP\n", SCIPgetUpperbound(scip));
    233
    234 SCIPdebugMsg(scip, "OFINS subproblem: %d vars, %d cons\n", SCIPgetNVars(subscip), SCIPgetNConss(subscip));
    235
    236 /* do not abort subproblem on CTRL-C */
    237 SCIP_CALL( SCIPsetBoolParam(subscip, "misc/catchctrlc", FALSE) );
    238
    239#ifdef SCIP_DEBUG
    240 /* for debugging, enable full output */
    241 SCIP_CALL( SCIPsetIntParam(subscip, "display/verblevel", 5) );
    242 SCIP_CALL( SCIPsetIntParam(subscip, "display/freq", 100000000) );
    243#else
    244 /* disable statistic timing inside sub SCIP and output to console */
    245 SCIP_CALL( SCIPsetIntParam(subscip, "display/verblevel", 0) );
    246 SCIP_CALL( SCIPsetBoolParam(subscip, "timing/statistictiming", FALSE) );
    247#endif
    248
    249 /* set limits for the subproblem */
    250 SCIP_CALL( SCIPcopyLimits(scip, subscip) );
    251 heurdata->nodelimit = heurdata->maxnodes;
    252 SCIP_CALL( SCIPsetLongintParam(subscip, "limits/stallnodes", nstallnodes) );
    253 SCIP_CALL( SCIPsetLongintParam(subscip, "limits/nodes", heurdata->maxnodes) );
    254
    255 /* forbid recursive call of heuristics and separators solving sub-SCIPs */
    256 SCIP_CALL( SCIPsetSubscipsOff(subscip, TRUE) );
    257
    258 /* disable cutting plane separation */
    260
    261 /* disable expensive presolving */
    263
    264 /* use best estimate node selection */
    265 if( SCIPfindNodesel(subscip, "estimate") != NULL && !SCIPisParamFixed(subscip, "nodeselection/estimate/stdpriority") )
    266 {
    267 SCIP_CALL( SCIPsetIntParam(subscip, "nodeselection/estimate/stdpriority", INT_MAX/4) );
    268 }
    269
    270 /* use inference branching */
    271 if( SCIPfindBranchrule(subscip, "inference") != NULL && !SCIPisParamFixed(subscip, "branching/inference/priority") )
    272 {
    273 SCIP_CALL( SCIPsetIntParam(subscip, "branching/inference/priority", INT_MAX/4) );
    274 }
    275
    276 /* disable conflict analysis */
    277 if( !SCIPisParamFixed(subscip, "conflict/enable") )
    278 {
    279 SCIP_CALL( SCIPsetBoolParam(subscip, "conflict/enable", FALSE) );
    280 }
    281
    282 /* speed up sub-SCIP by not checking dual LP feasibility */
    283 SCIP_CALL( SCIPsetBoolParam(subscip, "lp/checkdualfeas", FALSE) );
    284
    285 /* presolve the subproblem */
    286 retcode = SCIPpresolve(subscip);
    287
    288 /* errors in solving the subproblem should not kill the overall solving process;
    289 * hence, the return code is caught and a warning is printed, only in debug mode, SCIP will stop.
    290 */
    291 if( retcode != SCIP_OKAY )
    292 {
    293 SCIPwarningMessage(scip, "Error while presolving subproblem in %s heuristic; sub-SCIP terminated with code <%d>\n", HEUR_NAME, retcode);
    294
    295 SCIPABORT(); /*lint --e{527}*/
    296
    297 /* free */
    298 SCIPfreeBufferArray(scip, &subvars);
    299 return SCIP_OKAY;
    300 }
    301
    302 SCIPdebugMsg(scip, "%s presolved subproblem: %d vars, %d cons\n", HEUR_NAME, SCIPgetNVars(subscip), SCIPgetNConss(subscip));
    303
    304 assert(eventhdlr != NULL);
    305
    306 SCIP_CALL( SCIPtransformProb(subscip) );
    307 SCIP_CALL( SCIPcatchEvent(subscip, SCIP_EVENTTYPE_LPSOLVED, eventhdlr, (SCIP_EVENTDATA*) heurdata, NULL) );
    308
    309 /* solve the subproblem */
    310 SCIPdebugMsg(scip, "solving subproblem: nstallnodes=%" SCIP_LONGINT_FORMAT ", maxnodes=%" SCIP_LONGINT_FORMAT "\n", nstallnodes, heurdata->maxnodes);
    311
    312 /* errors in solving the subproblem should not kill the overall solving process;
    313 * hence, the return code is caught and a warning is printed, only in debug mode, SCIP will stop.
    314 */
    315 SCIP_CALL_ABORT( SCIPsolve(subscip) );
    316
    317 SCIP_CALL( SCIPdropEvent(subscip, SCIP_EVENTTYPE_LPSOLVED, eventhdlr, (SCIP_EVENTDATA*) heurdata, -1) );
    318
    319 /* print solving statistics of subproblem if we are in SCIP's debug mode */
    321
    322 status = SCIPgetStatus(subscip);
    323
    324 switch (status) {
    326 break;
    329 {
    330 /* transfer the primal ray from the sub-SCIP to the main SCIP */
    331 if( SCIPhasPrimalRay(subscip) )
    332 {
    333 SCIP_SOL* primalray;
    334
    335 SCIP_CALL( SCIPcreateSol(scip, &primalray, heur) );
    336
    337 /* transform the ray into the space of the source scip */
    338 for( i = 0; i < nvars; i++ )
    339 {
    340 SCIP_CALL( SCIPsetSolVal(scip, primalray, vars[i],
    341 subvars[i] != NULL ? SCIPgetPrimalRayVal(subscip, subvars[i]) : 0.0) );
    342 }
    343
    344 SCIPdebug( SCIP_CALL( SCIPprintRay(scip, primalray, 0, FALSE) ); );
    345
    346 /* update the primal ray of the source scip */
    347 SCIP_CALL( SCIPupdatePrimalRay(scip, primalray) );
    348 SCIP_CALL( SCIPfreeSol(scip, &primalray) );
    349
    350 *result = SCIP_UNBOUNDED;
    351 }
    352
    353 break;
    354 }
    355 default:
    356 /* check, whether a solution was found;
    357 * due to numerics, it might happen that not all solutions are feasible -> try all solutions until one was accepted
    358 */
    359 nsubsols = SCIPgetNSols(subscip);
    360 subsols = SCIPgetSols(subscip);
    361 success = FALSE;
    362 for( i = 0; i < nsubsols && (!success || heurdata->addallsols); i++ )
    363 {
    364 SCIP_SOL* newsol;
    365
    366 SCIP_CALL( SCIPtranslateSubSol(scip, subscip, subsols[i], heur, subvars, &newsol) );
    367
    368 /* try to add new solution to scip and free it immediately */
    369 SCIP_CALL( SCIPtrySolFree(scip, &newsol, FALSE, FALSE, TRUE, TRUE, TRUE, &success) );
    370
    371 if( success )
    372 *result = SCIP_FOUNDSOL;
    373 }
    374 break;
    375 } /*lint !e788*/
    376
    377 SCIPstatisticPrintf("%s statistic: fixed %6.3f integer variables, needed %6.1f seconds, %" SCIP_LONGINT_FORMAT " nodes, solution %10.4f found at node %" SCIP_LONGINT_FORMAT "\n",
    378 HEUR_NAME, 0.0, SCIPgetSolvingTime(subscip), SCIPgetNNodes(subscip), success ? SCIPgetPrimalbound(scip) : SCIPinfinity(scip),
    379 nsubsols > 0 ? SCIPsolGetNodenum(SCIPgetBestSol(subscip)) : -1 );
    380
    381 /* free subproblem */
    382 SCIPfreeBufferArray(scip, &subvars);
    383
    384 return SCIP_OKAY;
    385}
    386
    387/** main procedure of the OFINS heuristic, creates and solves a sub-SCIP */
    388static
    390 SCIP* scip, /**< original SCIP data structure */
    391 SCIP_HEUR* heur, /**< heuristic data structure */
    392 SCIP_HEURDATA* heurdata, /**< euristic's private data structure */
    393 SCIP_RESULT* result, /**< result data structure */
    394 SCIP_Longint nstallnodes, /**< number of stalling nodes for the subproblem */
    395 SCIP_Bool* chgcoeffs /**< array of changed coefficients */
    396 )
    397{
    398 SCIP* subscip;
    399 SCIP_RETCODE retcode;
    400 SCIP_Bool success;
    401
    402 assert(scip != NULL);
    403 assert(heur != NULL);
    404 assert(heurdata != NULL);
    405 assert(result != NULL);
    406 assert(chgcoeffs != NULL);
    407
    408 *result = SCIP_DIDNOTRUN;
    409
    410 /* check whether there is enough time and memory left */
    411 SCIP_CALL( SCIPcheckCopyLimits(scip, &success) );
    412
    413 if( !success )
    414 return SCIP_OKAY;
    415
    416 *result = SCIP_DIDNOTFIND;
    417
    418 /* do not run, if no solution was found */
    420 return SCIP_OKAY;
    421
    422 /* initialize the subproblem */
    423 SCIP_CALL( SCIPcreate(&subscip) );
    424
    425 retcode = setupAndSolve(scip, subscip, heur, heurdata, result, nstallnodes, chgcoeffs);
    426
    427 SCIP_CALL( SCIPfree(&subscip) );
    428
    429 SCIP_CALL( retcode );
    430
    431 return SCIP_OKAY;
    432}
    433
    434
    435
    436
    437/*
    438 * Callback methods of primal heuristic
    439 */
    440
    441/** copy method for primal heuristic plugins (called when SCIP copies plugins) */
    442static
    443SCIP_DECL_HEURCOPY(heurCopyOfins)
    444{ /*lint --e{715}*/
    445 assert(scip != NULL);
    446 assert(heur != NULL);
    447 assert(strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0);
    448
    449 /* call inclusion method of primal heuristic */
    451
    452 return SCIP_OKAY;
    453}
    454
    455/** destructor of primal heuristic to free user data (called when SCIP is exiting) */
    456static
    457SCIP_DECL_HEURFREE(heurFreeOfins)
    458{ /*lint --e{715}*/
    459 SCIP_HEURDATA* heurdata;
    460
    461 assert(heur != NULL);
    462 assert(scip != NULL);
    463
    464 /* get heuristic data */
    465 heurdata = SCIPheurGetData(heur);
    466 assert(heurdata != NULL);
    467
    468 /* free heuristic data */
    469 SCIPfreeBlockMemory(scip, &heurdata);
    470 SCIPheurSetData(heur, NULL);
    471
    472 return SCIP_OKAY;
    473}
    474
    475/** execution method of primal heuristic */
    476static
    477SCIP_DECL_HEUREXEC(heurExecOfins)
    478{/*lint --e{715}*/
    479 SCIP_HEURDATA* heurdata;
    480 SCIP_VAR** vars;
    481 SCIP_Bool* chgcoeffs;
    482 SCIP_Longint nstallnodes;
    483 int nchgcoefs;
    484 int nvars;
    485 int v;
    486
    487 assert( scip != NULL );
    488 assert( heur != NULL );
    489 assert( result != NULL );
    490
    491 /* only call heuristic if reoptimization is enabled */
    493 {
    494 *result = SCIP_DIDNOTRUN;
    495 return SCIP_OKAY;
    496 }
    497
    498 *result = SCIP_DELAYED;
    499
    500 /* only call the heuristic if we are in run >= 2 */
    501 if( SCIPgetNReoptRuns(scip) <= 1 )
    502 return SCIP_OKAY;
    503
    504 /* do not call heuristic if node was already detected to be infeasible */
    505 if( nodeinfeasible )
    506 return SCIP_OKAY;
    507
    508 *result = SCIP_DIDNOTRUN;
    509
    510 if( SCIPisStopped(scip) )
    511 return SCIP_OKAY;
    512
    513 /* get heuristic data */
    514 heurdata = SCIPheurGetData(heur);
    515 assert( heurdata != NULL );
    516
    517 /* calculate the maximal number of branching nodes until heuristic is aborted */
    518 nstallnodes = (SCIP_Longint)(heurdata->nodesquot * SCIPgetNNodes(scip));
    519
    520 /* reward OFINS if it succeeded often */
    521 nstallnodes = (SCIP_Longint)(nstallnodes * 3.0 * (SCIPheurGetNBestSolsFound(heur)+1.0)/(SCIPheurGetNCalls(heur) + 1.0));
    522 nstallnodes -= 100 * SCIPheurGetNCalls(heur); /* count the setup costs for the sub-SCIP as 100 nodes */
    523 nstallnodes += heurdata->nodesofs;
    524
    525 /* determine the node limit for the current process */
    526 nstallnodes = MIN(nstallnodes, heurdata->maxnodes);
    527
    528 /* check whether we have enough nodes left to call subproblem solving */
    529 if( nstallnodes < heurdata->minnodes )
    530 {
    531 SCIPdebugMsg(scip, "skipping OFINS: nstallnodes=%" SCIP_LONGINT_FORMAT ", minnodes=%" SCIP_LONGINT_FORMAT "\n", nstallnodes, heurdata->minnodes);
    532 return SCIP_OKAY;
    533 }
    534
    535 /* get variable data and check which coefficient has changed */
    536 vars = SCIPgetVars(scip);
    538 nchgcoefs = 0;
    539
    540 SCIP_CALL( SCIPallocBufferArray(scip, &chgcoeffs, nvars) );
    541
    542 for( v = 0; v < nvars; v++ )
    543 {
    544 SCIP_Real newcoef;
    545 SCIP_Real oldcoef;
    546 SCIP_Real newcoefabs;
    547 SCIP_Real oldcoefabs;
    548 SCIP_Real frac;
    549
    550 /* we only want to count variables that are unfixed after the presolving */
    551 assert(SCIPvarGetStatus(vars[v]) != SCIP_VARSTATUS_ORIGINAL);
    552 assert(SCIPvarIsActive(vars[v]));
    553
    556 newcoefabs = REALABS(newcoef);
    557 oldcoefabs = REALABS(oldcoef);
    558
    559 /* if both coefficients are zero nothing has changed */
    560 if( SCIPisZero(scip, newcoef) && SCIPisZero(scip, oldcoef) )
    561 {
    562 frac = 0;
    563 }
    564 /* if exactly one coefficient is zero, the other need to be close to zero */
    565 else if( SCIPisZero(scip, newcoef) || SCIPisZero(scip, oldcoef) )
    566 {
    567 assert(SCIPisZero(scip, newcoef) != SCIPisZero(scip, oldcoef));
    568 if( !SCIPisZero(scip, newcoef) )
    569 frac = MIN(1, newcoefabs);
    570 else
    571 frac = MIN(1, oldcoefabs);
    572 }
    573 /* if both coefficients have the same sign we calculate the quotient
    574 * MIN(newcoefabs, oldcoefabs)/MAX(newcoefabs, oldcoefabs)
    575 */
    576 else if( SCIPisPositive(scip, newcoef) == SCIPisPositive(scip, oldcoef) )
    577 {
    578 frac = 1.0 - MIN(newcoefabs, oldcoefabs)/MAX(newcoefabs, oldcoefabs);
    579 }
    580 /* if both coefficients have a different sign, we set frac = 1 */
    581 else
    582 {
    583 assert((SCIPisPositive(scip, newcoef) && SCIPisNegative(scip, oldcoef))
    584 || (SCIPisNegative(scip, newcoef) && SCIPisPositive(scip, oldcoef)));
    585
    586 frac = 1;
    587 }
    588
    589 if( frac > heurdata->maxchange )
    590 {
    591 chgcoeffs[v] = TRUE;
    592 nchgcoefs++;
    593 }
    594 else
    595 chgcoeffs[v] = FALSE;
    596 }
    597
    598 SCIPdebugMsg(scip, "%d (rate %.4f) changed coefficients\n", nchgcoefs, nchgcoefs/((SCIP_Real)nvars));
    599
    600 /* we only want to run the heuristic if there at least 3 changed coefficients.
    601 * if the number of changed coefficients is 2 the trivialnegation heuristic will construct an
    602 * optimal solution without solving a MIP.
    603 */
    604 if( nchgcoefs < 3 )
    605 goto TERMINATE;
    606
    607 /* run the heuristic if not too many coefficients have changed */
    608 if( nchgcoefs/((SCIP_Real)nvars) > heurdata->maxchangerate )
    609 goto TERMINATE;
    610
    611 SCIP_CALL( applyOfins(scip, heur, heurdata, result, nstallnodes, chgcoeffs) );
    612
    613 TERMINATE:
    614 SCIPfreeBufferArray(scip, &chgcoeffs);
    615
    616 return SCIP_OKAY;
    617}
    618
    619
    620/*
    621 * primal heuristic specific interface methods
    622 */
    623
    624/** creates the ofins primal heuristic and includes it in SCIP */
    626 SCIP* scip /**< SCIP data structure */
    627 )
    628{
    629 SCIP_HEURDATA* heurdata;
    630 SCIP_HEUR* heur;
    631
    632 /* create ofins primal heuristic data */
    633 SCIP_CALL( SCIPallocBlockMemory(scip, &heurdata) );
    634 assert(heurdata != NULL);
    635
    636 /* include primal heuristic */
    639 HEUR_MAXDEPTH, HEUR_TIMING, HEUR_USESSUBSCIP, heurExecOfins, heurdata) );
    640
    641 assert(heur != NULL);
    642
    643 /* primal heuristic is safe to use in exact solving mode */
    644 SCIPheurMarkExact(heur);
    645
    646 /* set non fundamental callbacks via setter functions */
    647 SCIP_CALL( SCIPsetHeurCopy(scip, heur, heurCopyOfins) );
    648 SCIP_CALL( SCIPsetHeurFree(scip, heur, heurFreeOfins) );
    649
    650 /* add ofins primal heuristic parameters */
    651
    652 SCIP_CALL( SCIPaddLongintParam(scip, "heuristics/" HEUR_NAME "/maxnodes",
    653 "maximum number of nodes to regard in the subproblem",
    654 &heurdata->maxnodes, TRUE, DEFAULT_MAXNODES, 0LL, SCIP_LONGINT_MAX, NULL, NULL) );
    655
    656 SCIP_CALL( SCIPaddLongintParam(scip, "heuristics/" HEUR_NAME "/minnodes",
    657 "minimum number of nodes required to start the subproblem",
    658 &heurdata->minnodes, TRUE, DEFAULT_MINNODES, 0LL, SCIP_LONGINT_MAX, NULL, NULL) );
    659
    660 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/maxchangerate",
    661 "maximal rate of changed coefficients",
    662 &heurdata->maxchangerate, FALSE, DEFAULT_MAXCHGRATE, 0.0, 1.0, NULL, NULL) );
    663
    664 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/maxchange",
    665 "maximal rate of change per coefficient to get fixed",
    666 &heurdata->maxchange, FALSE, DEFAULT_MAXCHANGE, 0.0, 1.0, NULL, NULL) );
    667
    668 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/copycuts",
    669 "should all active cuts from cutpool be copied to constraints in subproblem?",
    670 &heurdata->copycuts, TRUE, DEFAULT_COPYCUTS, NULL, NULL) );
    671
    672 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/addallsols",
    673 "should all subproblem solutions be added to the original SCIP?",
    674 &heurdata->addallsols, TRUE, DEFAULT_ADDALLSOLS, NULL, NULL) );
    675
    676 SCIP_CALL( SCIPaddLongintParam(scip, "heuristics/" HEUR_NAME "/nodesofs",
    677 "number of nodes added to the contingent of the total nodes",
    678 &heurdata->nodesofs, FALSE, DEFAULT_NODESOFS, 0LL, SCIP_LONGINT_MAX, NULL, NULL) );
    679
    680 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/nodesquot",
    681 "contingent of sub problem nodes in relation to the number of nodes of the original problem",
    682 &heurdata->nodesquot, FALSE, DEFAULT_NODESQUOT, 0.0, 1.0, NULL, NULL) );
    683
    684 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/minimprove",
    685 "factor by which RENS should at least improve the incumbent",
    686 &heurdata->minimprove, TRUE, DEFAULT_MINIMPROVE, 0.0, 1.0, NULL, NULL) );
    687
    688 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/lplimfac",
    689 "factor by which the limit on the number of LP depends on the node limit",
    690 &heurdata->lplimfac, TRUE, DEFAULT_LPLIMFAC, 1.0, SCIP_REAL_MAX, NULL, NULL) );
    691
    692 return SCIP_OKAY;
    693}
    #define NULL
    Definition: def.h:248
    #define SCIP_Longint
    Definition: def.h:141
    #define SCIP_REAL_MAX
    Definition: def.h:158
    #define SCIP_Bool
    Definition: def.h:91
    #define MIN(x, y)
    Definition: def.h:224
    #define SCIP_Real
    Definition: def.h:156
    #define TRUE
    Definition: def.h:93
    #define FALSE
    Definition: def.h:94
    #define MAX(x, y)
    Definition: def.h:220
    #define SCIP_CALL_ABORT(x)
    Definition: def.h:334
    #define SCIP_LONGINT_FORMAT
    Definition: def.h:148
    #define SCIPABORT()
    Definition: def.h:327
    #define REALABS(x)
    Definition: def.h:182
    #define SCIP_LONGINT_MAX
    Definition: def.h:142
    #define SCIP_CALL(x)
    Definition: def.h:355
    SCIP_RETCODE SCIPcheckCopyLimits(SCIP *sourcescip, SCIP_Bool *success)
    Definition: scip_copy.c:3249
    SCIP_RETCODE SCIPtranslateSubSol(SCIP *scip, SCIP *subscip, SCIP_SOL *subsol, SCIP_HEUR *heur, SCIP_VAR **subvars, SCIP_SOL **newsol)
    Definition: scip_copy.c:1397
    SCIP_RETCODE SCIPcopyLimits(SCIP *sourcescip, SCIP *targetscip)
    Definition: scip_copy.c:3292
    SCIP_Bool SCIPisStopped(SCIP *scip)
    Definition: scip_general.c:759
    SCIP_RETCODE SCIPfree(SCIP **scip)
    Definition: scip_general.c:402
    SCIP_RETCODE SCIPcreate(SCIP **scip)
    Definition: scip_general.c:370
    SCIP_STATUS SCIPgetStatus(SCIP *scip)
    Definition: scip_general.c:562
    int SCIPgetNIntVars(SCIP *scip)
    Definition: scip_prob.c:2340
    int SCIPgetNImplVars(SCIP *scip)
    Definition: scip_prob.c:2387
    SCIP_RETCODE SCIPsetObjlimit(SCIP *scip, SCIP_Real objlimit)
    Definition: scip_prob.c:1661
    int SCIPgetNVars(SCIP *scip)
    Definition: scip_prob.c:2246
    int SCIPgetNConss(SCIP *scip)
    Definition: scip_prob.c:3620
    SCIP_VAR ** SCIPgetVars(SCIP *scip)
    Definition: scip_prob.c:2201
    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 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 SCIPincludeHeurOfins(SCIP *scip)
    Definition: heur_ofins.c:625
    SCIP_BRANCHRULE * SCIPfindBranchrule(SCIP *scip, const char *name)
    Definition: scip_branch.c:304
    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
    const char * SCIPheurGetName(SCIP_HEUR *heur)
    Definition: heur.c:1467
    void SCIPheurSetData(SCIP_HEUR *heur, SCIP_HEURDATA *heurdata)
    Definition: heur.c:1378
    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 SCIPfreeBufferArrayNull(scip, ptr)
    Definition: scip_mem.h:137
    #define SCIPallocBlockMemory(scip, ptr)
    Definition: scip_mem.h:89
    SCIP_NODESEL * SCIPfindNodesel(SCIP *scip, const char *name)
    Definition: scip_nodesel.c:242
    SCIP_SOL * SCIPgetReoptLastOptSol(SCIP *scip)
    Definition: scip_solve.c:3248
    SCIP_RETCODE SCIPgetReoptOldObjCoef(SCIP *scip, SCIP_VAR *var, int run, SCIP_Real *objcoef)
    Definition: scip_solve.c:3275
    SCIP_Bool SCIPisReoptEnabled(SCIP *scip)
    Definition: scip_solve.c:3616
    SCIP_SOL * SCIPgetBestSol(SCIP *scip)
    Definition: scip_sol.c:2981
    SCIP_RETCODE SCIPcreateSol(SCIP *scip, SCIP_SOL **sol, SCIP_HEUR *heur)
    Definition: scip_sol.c:516
    SCIP_RETCODE SCIPfreeSol(SCIP *scip, SCIP_SOL **sol)
    Definition: scip_sol.c:1252
    SCIP_RETCODE SCIPprintRay(SCIP *scip, SCIP_SOL *sol, FILE *file, SCIP_Bool printzeros)
    Definition: scip_sol.c:2845
    SCIP_Longint SCIPsolGetNodenum(SCIP_SOL *sol)
    Definition: sol.c:4239
    int SCIPgetNSols(SCIP *scip)
    Definition: scip_sol.c:2882
    SCIP_Real SCIPgetPrimalRayVal(SCIP *scip, SCIP_VAR *var)
    Definition: scip_sol.c:4445
    SCIP_SOL ** SCIPgetSols(SCIP *scip)
    Definition: scip_sol.c:2931
    SCIP_Bool SCIPhasPrimalRay(SCIP *scip)
    Definition: scip_sol.c:4427
    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:4109
    SCIP_RETCODE SCIPsetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var, SCIP_Real val)
    Definition: scip_sol.c:1571
    SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
    Definition: scip_sol.c:1765
    SCIP_RETCODE SCIPupdatePrimalRay(SCIP *scip, SCIP_SOL *primalray)
    Definition: scip_sol.c:4473
    SCIP_RETCODE SCIPtransformProb(SCIP *scip)
    Definition: scip_solve.c:232
    SCIP_RETCODE SCIPpresolve(SCIP *scip)
    Definition: scip_solve.c:2449
    SCIP_RETCODE SCIPinterruptSolve(SCIP *scip)
    Definition: scip_solve.c:3548
    SCIP_RETCODE SCIPsolve(SCIP *scip)
    Definition: scip_solve.c:2635
    SCIP_Real SCIPgetPrimalbound(SCIP *scip)
    SCIP_Real SCIPgetUpperbound(SCIP *scip)
    SCIP_Longint SCIPgetNNodes(SCIP *scip)
    SCIP_RETCODE SCIPprintStatistics(SCIP *scip, FILE *file)
    SCIP_Longint SCIPgetNLPs(SCIP *scip)
    int SCIPgetNReoptRuns(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 SCIPisPositive(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisNegative(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisZero(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPvarIsActive(SCIP_VAR *var)
    Definition: var.c:23642
    SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
    Definition: var.c:23386
    #define DEFAULT_MAXCHGRATE
    Definition: heur_ofins.c:71
    #define DEFAULT_MAXCHANGE
    Definition: heur_ofins.c:74
    #define DEFAULT_NODESQUOT
    Definition: heur_ofins.c:79
    #define DEFAULT_NODESOFS
    Definition: heur_ofins.c:78
    #define DEFAULT_COPYCUTS
    Definition: heur_ofins.c:72
    #define DEFAULT_MAXNODES
    Definition: heur_ofins.c:70
    #define HEUR_TIMING
    Definition: heur_ofins.c:66
    #define DEFAULT_MINNODES
    Definition: heur_ofins.c:77
    #define HEUR_FREQOFS
    Definition: heur_ofins.c:64
    static SCIP_DECL_EVENTEXEC(eventExecOfins)
    Definition: heur_ofins.c:110
    #define HEUR_DESC
    Definition: heur_ofins.c:60
    #define DEFAULT_LPLIMFAC
    Definition: heur_ofins.c:80
    static SCIP_RETCODE setupAndSolve(SCIP *scip, SCIP *subscip, SCIP_HEUR *heur, SCIP_HEURDATA *heurdata, SCIP_RESULT *result, SCIP_Longint nstallnodes, SCIP_Bool *chgcoeffs)
    Definition: heur_ofins.c:135
    #define DEFAULT_ADDALLSOLS
    Definition: heur_ofins.c:76
    static SCIP_DECL_HEURCOPY(heurCopyOfins)
    Definition: heur_ofins.c:443
    #define HEUR_DISPCHAR
    Definition: heur_ofins.c:61
    #define HEUR_MAXDEPTH
    Definition: heur_ofins.c:65
    #define HEUR_PRIORITY
    Definition: heur_ofins.c:62
    #define DEFAULT_MINIMPROVE
    Definition: heur_ofins.c:75
    #define HEUR_NAME
    Definition: heur_ofins.c:59
    static SCIP_DECL_HEURFREE(heurFreeOfins)
    Definition: heur_ofins.c:457
    static SCIP_RETCODE applyOfins(SCIP *scip, SCIP_HEUR *heur, SCIP_HEURDATA *heurdata, SCIP_RESULT *result, SCIP_Longint nstallnodes, SCIP_Bool *chgcoeffs)
    Definition: heur_ofins.c:389
    #define EVENTHDLR_DESC
    Definition: heur_ofins.c:84
    #define HEUR_FREQ
    Definition: heur_ofins.c:63
    static SCIP_DECL_HEUREXEC(heurExecOfins)
    Definition: heur_ofins.c:477
    #define HEUR_USESSUBSCIP
    Definition: heur_ofins.c:67
    #define EVENTHDLR_NAME
    Definition: heur_ofins.c:83
    OFINS - Objective Function Induced Neighborhood Search - a primal heuristic for reoptimization.
    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 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 memory management
    public methods for message handling
    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
    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_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_UNBOUNDED
    Definition: type_result.h:47
    @ SCIP_FOUNDSOL
    Definition: type_result.h:56
    enum SCIP_Result SCIP_RESULT
    Definition: type_result.h:61
    @ SCIP_PLUGINNOTFOUND
    Definition: type_retcode.h:54
    @ SCIP_OKAY
    Definition: type_retcode.h:42
    enum SCIP_Retcode SCIP_RETCODE
    Definition: type_retcode.h:63
    @ SCIP_STATUS_UNBOUNDED
    Definition: type_stat.h:45
    @ SCIP_STATUS_INFORUNBD
    Definition: type_stat.h:46
    @ SCIP_STATUS_INFEASIBLE
    Definition: type_stat.h:44
    enum SCIP_Status SCIP_STATUS
    Definition: type_stat.h:64
    @ SCIP_VARSTATUS_ORIGINAL
    Definition: type_var.h:51