Scippy

    SCIP

    Solving Constraint Integer Programs

    heur_simplerounding.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_simplerounding.c
    26 * @ingroup DEFPLUGINS_HEUR
    27 * @brief simple and fast LP rounding heuristic
    28 * @author Tobias Achterberg
    29 * @author Marc Pfetsch
    30 *
    31 * The heuristic also tries to round relaxation solutions if available.
    32 */
    33
    34/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
    35
    38#include "scip/pub_heur.h"
    39#include "scip/pub_message.h"
    40#include "scip/pub_var.h"
    41#include "scip/scip_branch.h"
    42#include "scip/scip_heur.h"
    43#include "scip/scip_lp.h"
    44#include "scip/scip_mem.h"
    45#include "scip/scip_message.h"
    46#include "scip/scip_numerics.h"
    47#include "scip/scip_param.h"
    48#include "scip/scip_prob.h"
    49#include "scip/scip_sol.h"
    51#include "scip/scip_var.h"
    52#include <string.h>
    53
    54#define HEUR_NAME "simplerounding"
    55#define HEUR_DESC "simple and fast LP rounding heuristic"
    56#define HEUR_DISPCHAR SCIP_HEURDISPCHAR_ROUNDING
    57#define HEUR_PRIORITY -30
    58#define HEUR_FREQ 1
    59#define HEUR_FREQOFS 0
    60#define HEUR_MAXDEPTH -1
    61#define HEUR_TIMING SCIP_HEURTIMING_DURINGLPLOOP | SCIP_HEURTIMING_DURINGPRICINGLOOP
    62#define HEUR_USESSUBSCIP FALSE /**< does the heuristic use a secondary SCIP instance? */
    63
    64#define DEFAULT_ONCEPERNODE FALSE /**< should the heuristic only be called once per node? */
    65
    66/* locally defined heuristic data */
    67struct SCIP_HeurData
    68{
    69 SCIP_SOL* sol; /**< working solution */
    70 SCIP_Longint lastlp; /**< last LP number where the heuristic was applied */
    71 int nroundablevars; /**< number of variables that can be rounded (-1 if not yet calculated) */
    72 SCIP_Bool oncepernode; /**< should the heuristic only be called once per node? */
    73};
    74
    75
    76/*
    77 * Local methods
    78 */
    79
    80/** perform rounding */
    81static
    83 SCIP* scip, /**< SCIP main data structure */
    84 SCIP_SOL* sol, /**< solution to round */
    85 SCIP_VAR** cands, /**< candidate variables */
    86 SCIP_Real* candssol, /**< solutions of candidate variables */
    87 int ncands, /**< number of candidates */
    88 SCIP_RESULT* result /**< pointer to store the result of the heuristic call */
    89 )
    90{
    91 int nunroundableimplints = 0;
    92 int c;
    93
    94 /* round all roundable fractional variables as long as no unroundable variable was found */
    95 for( c = 0; c < ncands; ++c )
    96 {
    97 SCIP_VAR* var;
    98 SCIP_Real oldsolval;
    99 SCIP_Real newsolval;
    100 SCIP_Bool mayrounddown;
    101 SCIP_Bool mayroundup;
    102
    103 oldsolval = candssol[c];
    104 assert( ! SCIPisFeasIntegral(scip, oldsolval) );
    105 var = cands[c];
    106 assert( SCIPvarGetStatus(var) == SCIP_VARSTATUS_COLUMN );
    107 mayrounddown = SCIPvarMayRoundDown(var);
    108 mayroundup = SCIPvarMayRoundUp(var);
    109 SCIPdebugMsg(scip, "simple rounding heuristic: var <%s>, val=%g, rounddown=%u, roundup=%u\n",
    110 SCIPvarGetName(var), oldsolval, mayrounddown, mayroundup);
    111
    112 /* choose rounding direction */
    113 if ( mayrounddown && mayroundup )
    114 {
    115 /* we can round in both directions: round in objective function direction */
    116 if ( SCIPvarGetObj(var) >= 0.0 )
    117 newsolval = SCIPfeasFloor(scip, oldsolval);
    118 else
    119 newsolval = SCIPfeasCeil(scip, oldsolval);
    120 }
    121 else if ( mayrounddown )
    122 newsolval = SCIPfeasFloor(scip, oldsolval);
    123 else if ( mayroundup )
    124 newsolval = SCIPfeasCeil(scip, oldsolval);
    125 else if( SCIPvarIsImpliedIntegral(var) )
    126 {
    127 ++nunroundableimplints;
    128 continue;
    129 }
    130 else
    131 break;
    132
    133 /* store new solution value */
    134 SCIP_CALL( SCIPsetSolVal(scip, sol, var, newsolval) );
    135 }
    136
    137 /* check, if rounding was successful */
    138 if( c == ncands )
    139 {
    140 SCIP_Bool stored;
    141 SCIP_Bool checklprows;
    142
    143 /* unroundable implied integral variables are adjusted, LP rows must be checked afterwards */
    144 if( nunroundableimplints > 0 )
    145 {
    147 checklprows = TRUE;
    148 }
    149 else
    150 checklprows = FALSE;
    151
    152 if( SCIPallColsInLP(scip) )
    153 {
    154 /* check solution for feasibility, and add it to solution store if possible
    155 * integrality need not be checked, because all fractional
    156 * variables were already moved in feasible direction to the next integer
    157 *
    158 * feasibility of LP rows must be checked again at the presence of
    159 * unroundable implied integral variables with fractional LP solution value
    160 */
    161 SCIP_CALL( SCIPtrySol(scip, sol, FALSE, FALSE, FALSE, FALSE, checklprows, &stored) );
    162 }
    163 else
    164 {
    165 /* if there are variables which are not present in the LP, e.g., for
    166 * column generation, we need to check their bounds
    167 */
    168 SCIP_CALL( SCIPtrySol(scip, sol, FALSE, FALSE, TRUE, FALSE, checklprows, &stored) );
    169 }
    170
    171 if( stored )
    172 {
    173#ifdef SCIP_DEBUG
    174 SCIPdebugMsg(scip, "found feasible rounded solution:\n");
    176#endif
    177 *result = SCIP_FOUNDSOL;
    178 }
    179 }
    180 return SCIP_OKAY;
    181}
    182
    183/** perform LP-rounding */
    184static
    186 SCIP* scip, /**< SCIP main data structure */
    187 SCIP_HEURDATA* heurdata, /**< heuristic data */
    188 SCIP_HEURTIMING heurtiming, /**< heuristic timing mask */
    189 SCIP_RESULT* result /**< pointer to store the result of the heuristic call */
    190 )
    191{
    192 SCIP_SOL* sol;
    193 SCIP_VAR** lpcands;
    194 SCIP_Real* lpcandssol;
    195 SCIP_Longint nlps;
    196 int nlpcands;
    197 int nfracimplvars;
    198
    199 /* only call heuristic, if an optimal LP solution is at hand */
    201 return SCIP_OKAY;
    202
    203 /* only call heuristic, if the LP objective value is smaller than the cutoff bound */
    205 return SCIP_OKAY;
    206
    207 /* get fractional variables, that should be integral */
    208 SCIP_CALL( SCIPgetLPBranchCands(scip, &lpcands, &lpcandssol, NULL, &nlpcands, NULL, &nfracimplvars) );
    209
    210 /* only call heuristic, if LP solution is fractional; except we are called during pricing, in this case we
    211 * want to detect a (mixed) integer (LP) solution which is primal feasible
    212 */
    213 if ( nlpcands == 0 && heurtiming != SCIP_HEURTIMING_DURINGPRICINGLOOP )
    214 return SCIP_OKAY;
    215
    216 /* don't call heuristic, if there are more fractional variables than roundable ones. We do not consider
    217 * fractional continuous implied integer variables here, because simple rounding may adjust those separately,
    218 * even if they aren't roundable
    219 */
    220 if ( nlpcands > heurdata->nroundablevars )
    221 return SCIP_OKAY;
    222
    223 /* get the working solution from heuristic's local data */
    224 sol = heurdata->sol;
    225 assert( sol != NULL );
    226
    227 /* copy the current LP solution to the working solution */
    229
    230 /* don't call heuristic, if we have already processed the current LP solution */
    231 nlps = SCIPgetNLPs(scip);
    232 if( nlps == heurdata->lastlp )
    233 return SCIP_OKAY;
    234 heurdata->lastlp = nlps;
    235
    236 /* perform simple rounding */
    237 SCIPdebugMsg(scip, "executing simple LP-rounding heuristic, fractionals: %d + %d\n", nlpcands, nfracimplvars);
    238 SCIP_CALL( performSimpleRounding(scip, sol, lpcands, lpcandssol, nlpcands + nfracimplvars, result) );
    239
    240 return SCIP_OKAY;
    241}
    242
    243/** perform relaxation solution rounding */
    244static
    246 SCIP* scip, /**< SCIP main data structure */
    247 SCIP_HEURDATA* heurdata, /**< heuristic data */
    248 SCIP_RESULT* result /**< pointer to store the result of the heuristic call */
    249 )
    250{
    251 SCIP_VAR** vars;
    252 SCIP_VAR** relaxcands;
    253 SCIP_SOL* sol;
    254 SCIP_Real* relaxcandssol;
    255 int nrelaxcands = 0;
    256 int nbinvars;
    257 int nintvars;
    258 int nimplvars;
    259 int nintegervars;
    260 int ndiscretevars;
    261 int v;
    262
    263 /* do not call heuristic if no relaxation solution is available */
    265 return SCIP_OKAY;
    266
    267 /* get integral variables */
    268 SCIP_CALL( SCIPgetVarsData(scip, &vars, NULL, &nbinvars, &nintvars, &nimplvars, NULL) );
    269 nintegervars = nbinvars + nintvars;
    270 ndiscretevars = nintegervars + nimplvars;
    271
    272 /* get storage */
    273 SCIP_CALL( SCIPallocBufferArray(scip, &relaxcands, ndiscretevars) );
    274 SCIP_CALL( SCIPallocBufferArray(scip, &relaxcandssol, ndiscretevars) );
    275
    276 /* get fractional non-implied integral variables */
    277 for( v = 0; v < nintegervars; ++v )
    278 {
    279 SCIP_Real val;
    280
    281 val = SCIPgetRelaxSolVal(scip, vars[v]);
    282 if( !SCIPisFeasIntegral(scip, val) )
    283 {
    284 relaxcands[nrelaxcands] = vars[v];
    285 relaxcandssol[nrelaxcands++] = val;
    286 }
    287 }
    288
    289 /* don't call heuristic, if there are more fractional variables than roundable ones. We explicitly
    290 * do not consider implied integral variables with fractional relaxation solution here
    291 * because they may be feasibly adjusted, although they are not roundable
    292 */
    293 if( nrelaxcands > heurdata->nroundablevars )
    294 {
    295 SCIPfreeBufferArray(scip, &relaxcands);
    296 SCIPfreeBufferArray(scip, &relaxcandssol);
    297 return SCIP_OKAY;
    298 }
    299
    300 /* collect implied integral variables with fractional solution value */
    301 for( v = nintegervars; v < ndiscretevars; ++v )
    302 {
    303 SCIP_Real val;
    304
    305 val = SCIPgetRelaxSolVal(scip, vars[v]);
    306 if( !SCIPisFeasIntegral(scip, val) )
    307 {
    308 relaxcands[nrelaxcands] = vars[v];
    309 relaxcandssol[nrelaxcands++] = val;
    310 }
    311 }
    312
    313 /* get the working solution from heuristic's local data */
    314 sol = heurdata->sol;
    315 assert( sol != NULL );
    316
    317 /* copy the current relaxation solution to the working solution */
    319
    320 /* perform simple rounding */
    321 SCIPdebugMsg(scip, "executing simple rounding heuristic on relaxation solution: %d fractionals\n", nrelaxcands);
    322 SCIP_CALL( performSimpleRounding(scip, sol, relaxcands, relaxcandssol, nrelaxcands, result) );
    323
    324 /* free storage */
    325 SCIPfreeBufferArray(scip, &relaxcands);
    326 SCIPfreeBufferArray(scip, &relaxcandssol);
    327
    328 return SCIP_OKAY;
    329}
    330
    331
    332/*
    333 * Callback methods
    334 */
    335
    336/** copy method for primal heuristic plugins (called when SCIP copies plugins) */
    337static
    338SCIP_DECL_HEURCOPY(heurCopySimplerounding)
    339{ /*lint --e{715}*/
    340 assert(scip != NULL);
    341 assert(heur != NULL);
    342 assert(strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0);
    343
    344 /* call inclusion method of primal heuristic */
    346
    347 return SCIP_OKAY;
    348}
    349
    350/** destructor of primal heuristic to free user data (called when SCIP is exiting) */
    351static
    352SCIP_DECL_HEURFREE(heurFreeSimplerounding) /*lint --e{715}*/
    353{ /*lint --e{715}*/
    354 SCIP_HEURDATA* heurdata;
    355
    356 assert(heur != NULL);
    357 assert(strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0);
    358 assert(scip != NULL);
    359
    360 /* free heuristic data */
    361 heurdata = SCIPheurGetData(heur);
    362 assert(heurdata != NULL);
    363 SCIPfreeBlockMemory(scip, &heurdata);
    364 SCIPheurSetData(heur, NULL);
    365
    366 return SCIP_OKAY;
    367}
    368
    369
    370/** initialization method of primal heuristic (called after problem was transformed) */
    371static
    372SCIP_DECL_HEURINIT(heurInitSimplerounding) /*lint --e{715}*/
    373{ /*lint --e{715}*/
    374 SCIP_HEURDATA* heurdata;
    375
    376 assert(strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0);
    377 heurdata = SCIPheurGetData(heur);
    378 assert(heurdata != NULL);
    379
    380 /* create heuristic data */
    381 SCIP_CALL( SCIPcreateSol(scip, &heurdata->sol, heur) );
    382 heurdata->lastlp = -1;
    383 heurdata->nroundablevars = -1;
    384
    385 return SCIP_OKAY;
    386}
    387
    388
    389/** deinitialization method of primal heuristic (called before transformed problem is freed) */
    390static
    391SCIP_DECL_HEUREXIT(heurExitSimplerounding) /*lint --e{715}*/
    392{ /*lint --e{715}*/
    393 SCIP_HEURDATA* heurdata;
    394
    395 assert(strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0);
    396
    397 /* free heuristic data */
    398 heurdata = SCIPheurGetData(heur);
    399 assert(heurdata != NULL);
    400 SCIP_CALL( SCIPfreeSol(scip, &heurdata->sol) );
    401
    402 return SCIP_OKAY;
    403}
    404
    405
    406/** solving process initialization method of primal heuristic (called when branch and bound process is about to begin) */
    407static
    408SCIP_DECL_HEURINITSOL(heurInitsolSimplerounding)
    409{
    410 SCIP_HEURDATA* heurdata;
    411
    412 assert(strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0);
    413
    414 heurdata = SCIPheurGetData(heur);
    415 assert(heurdata != NULL);
    416 heurdata->lastlp = -1;
    417
    418 /* change the heuristic's timingmask, if it should be called only once per node */
    419 if( heurdata->oncepernode )
    421
    422 return SCIP_OKAY;
    423}
    424
    425
    426/** solving process deinitialization method of primal heuristic (called before branch and bound process data is freed) */
    427static
    428SCIP_DECL_HEUREXITSOL(heurExitsolSimplerounding)
    429{
    430 /* reset the timing mask to its default value */
    432
    433 return SCIP_OKAY;
    434}
    435
    436
    437/** execution method of primal heuristic */
    438static
    439SCIP_DECL_HEUREXEC(heurExecSimplerounding) /*lint --e{715}*/
    440{ /*lint --e{715}*/
    441 SCIP_HEURDATA* heurdata;
    442 int nbinintvars;
    443
    444 assert(SCIPhasCurrentNodeLP(scip));
    445 assert(strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0);
    446 assert(result != NULL);
    447
    448 *result = SCIP_DIDNOTRUN;
    449
    450 /* get nonimplied integral variable number */
    451 nbinintvars = SCIPgetNBinVars(scip) + SCIPgetNIntVars(scip);
    452
    453 /* only call heuristic if there are integral variables */
    454 if( nbinintvars == 0 )
    455 return SCIP_OKAY;
    456
    457 /* get heuristic data */
    458 heurdata = SCIPheurGetData(heur);
    459 assert(heurdata != NULL);
    460
    461 /* only call heuristic if there are roundable variables; except we are called during pricing, in this case we
    462 * want to detect a (mixed) integer (LP) solution which is primal feasible
    463 */
    464 if( heurtiming != SCIP_HEURTIMING_DURINGPRICINGLOOP && heurdata->nroundablevars == 0 )
    465 return SCIP_OKAY;
    466
    467 /* only call heuristic if an optimal LP solution or a relaxation solution is available */
    469 return SCIP_OKAY;
    470
    471 /* only call heuristic if the LP objective value is smaller than the cutoff bound */
    473 return SCIP_OKAY;
    474
    475 /* only call heuristic if the current LP solution is not already processed or a relaxation solution is available */
    476 if( SCIPgetNLPs(scip) == heurdata->lastlp && !SCIPisRelaxSolValid(scip) )
    477 return SCIP_OKAY;
    478
    479 /* on our first call or after each pricing round, calculate the number of roundable variables */
    480 if( heurtiming == SCIP_HEURTIMING_DURINGPRICINGLOOP || heurdata->nroundablevars == -1 )
    481 {
    482 SCIP_VAR** vars;
    483 int i;
    484
    485 heurdata->nroundablevars = 0;
    486 vars = SCIPgetVars(scip);
    487
    488 for( i = 0; i < nbinintvars; ++i )
    489 {
    490 if( SCIPvarMayRoundDown(vars[i]) || SCIPvarMayRoundUp(vars[i]) )
    491 ++heurdata->nroundablevars;
    492 }
    493
    494 /* only call heuristic if there are roundable variables; except we are called during pricing, in this case we
    495 * want to detect a (mixed) integer (LP) solution which is primal feasible
    496 */
    497 if( heurtiming != SCIP_HEURTIMING_DURINGPRICINGLOOP && heurdata->nroundablevars == 0 )
    498 return SCIP_OKAY;
    499 }
    500
    501 *result = SCIP_DIDNOTFIND;
    502
    503 /* try to round LP solution */
    504 SCIP_CALL( performLPSimpleRounding(scip, heurdata, heurtiming, result) );
    505
    506 /* try to round relaxation solution */
    507 SCIP_CALL( performRelaxSimpleRounding(scip, heurdata, result) );
    508
    509 return SCIP_OKAY;
    510}
    511
    512/*
    513 * heuristic specific interface methods
    514 */
    515
    516/** creates the simple rounding heuristic and includes it in SCIP */
    518 SCIP* scip /**< SCIP data structure */
    519 )
    520{
    521 SCIP_HEURDATA* heurdata;
    522 SCIP_HEUR* heur;
    523
    524 /* create heuristic data */
    525 SCIP_CALL( SCIPallocBlockMemory(scip, &heurdata) );
    526
    527 /* include primal heuristic */
    530 HEUR_MAXDEPTH, HEUR_TIMING, HEUR_USESSUBSCIP, heurExecSimplerounding, heurdata) );
    531 assert(heur != NULL);
    532
    533 /* primal heuristic is safe to use in exact solving mode */
    534 SCIPheurMarkExact(heur);
    535
    536 /* set non-NULL pointers to callback methods */
    537 SCIP_CALL( SCIPsetHeurCopy(scip, heur, heurCopySimplerounding) );
    538 SCIP_CALL( SCIPsetHeurInit(scip, heur, heurInitSimplerounding) );
    539 SCIP_CALL( SCIPsetHeurExit(scip, heur, heurExitSimplerounding) );
    540 SCIP_CALL( SCIPsetHeurInitsol(scip, heur, heurInitsolSimplerounding) );
    541 SCIP_CALL( SCIPsetHeurExitsol(scip, heur, heurExitsolSimplerounding) );
    542 SCIP_CALL( SCIPsetHeurFree(scip, heur, heurFreeSimplerounding) );
    543
    544 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/oncepernode",
    545 "should the heuristic only be called once per node?",
    546 &heurdata->oncepernode, TRUE, DEFAULT_ONCEPERNODE, NULL, NULL) );
    547
    548 return SCIP_OKAY;
    549}
    #define NULL
    Definition: def.h:248
    #define SCIP_Longint
    Definition: def.h:141
    #define SCIP_Bool
    Definition: def.h:91
    #define SCIP_Real
    Definition: def.h:156
    #define TRUE
    Definition: def.h:93
    #define FALSE
    Definition: def.h:94
    #define SCIP_CALL(x)
    Definition: def.h:355
    int SCIPgetNIntVars(SCIP *scip)
    Definition: scip_prob.c:2340
    SCIP_RETCODE SCIPgetVarsData(SCIP *scip, SCIP_VAR ***vars, int *nvars, int *nbinvars, int *nintvars, int *nimplvars, int *ncontvars)
    Definition: scip_prob.c:2115
    SCIP_VAR ** SCIPgetVars(SCIP *scip)
    Definition: scip_prob.c:2201
    int SCIPgetNBinVars(SCIP *scip)
    Definition: scip_prob.c:2293
    #define SCIPdebugMsg
    Definition: scip_message.h:78
    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 SCIPincludeHeurSimplerounding(SCIP *scip)
    SCIP_RETCODE SCIPgetLPBranchCands(SCIP *scip, SCIP_VAR ***lpcands, SCIP_Real **lpcandssol, SCIP_Real **lpcandsfrac, int *nlpcands, int *npriolpcands, int *nfracimplvars)
    Definition: scip_branch.c:402
    SCIP_RETCODE SCIPsetHeurExitsol(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEUREXITSOL((*heurexitsol)))
    Definition: scip_heur.c:247
    SCIP_RETCODE SCIPsetHeurCopy(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEURCOPY((*heurcopy)))
    Definition: scip_heur.c:167
    SCIP_HEURDATA * SCIPheurGetData(SCIP_HEUR *heur)
    Definition: heur.c:1368
    SCIP_RETCODE SCIPincludeHeurBasic(SCIP *scip, SCIP_HEUR **heur, const char *name, const char *desc, char dispchar, int priority, int freq, int freqofs, int maxdepth, SCIP_HEURTIMING timingmask, SCIP_Bool usessubscip, SCIP_DECL_HEUREXEC((*heurexec)), SCIP_HEURDATA *heurdata)
    Definition: scip_heur.c:122
    SCIP_RETCODE SCIPsetHeurFree(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEURFREE((*heurfree)))
    Definition: scip_heur.c:183
    SCIP_RETCODE SCIPsetHeurExit(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEUREXIT((*heurexit)))
    Definition: scip_heur.c:215
    void SCIPheurSetTimingmask(SCIP_HEUR *heur, SCIP_HEURTIMING timingmask)
    Definition: heur.c:1507
    SCIP_RETCODE SCIPsetHeurInitsol(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEURINITSOL((*heurinitsol)))
    Definition: scip_heur.c:231
    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_Bool SCIPallColsInLP(SCIP *scip)
    Definition: scip_lp.c:655
    SCIP_Real SCIPgetLPObjval(SCIP *scip)
    Definition: scip_lp.c:253
    #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
    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 SCIPprintSol(SCIP *scip, SCIP_SOL *sol, FILE *file, SCIP_Bool printzeros)
    Definition: scip_sol.c:2349
    SCIP_RETCODE SCIPadjustImplicitSolVals(SCIP *scip, SCIP_SOL *sol, SCIP_Bool uselprows)
    Definition: scip_sol.c:2305
    SCIP_RETCODE SCIPlinkRelaxSol(SCIP *scip, SCIP_SOL *sol)
    Definition: scip_sol.c:1388
    SCIP_RETCODE SCIPtrySol(SCIP *scip, SCIP_SOL *sol, SCIP_Bool printreason, SCIP_Bool completely, SCIP_Bool checkbounds, SCIP_Bool checkintegrality, SCIP_Bool checklprows, SCIP_Bool *stored)
    Definition: scip_sol.c:4012
    SCIP_RETCODE SCIPlinkLPSol(SCIP *scip, SCIP_SOL *sol)
    Definition: scip_sol.c:1295
    SCIP_RETCODE SCIPsetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var, SCIP_Real val)
    Definition: scip_sol.c:1571
    SCIP_Longint SCIPgetNLPs(SCIP *scip)
    SCIP_Real SCIPgetCutoffbound(SCIP *scip)
    SCIP_Bool SCIPisGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Real SCIPfeasCeil(SCIP *scip, SCIP_Real val)
    SCIP_Real SCIPfeasFloor(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisFeasIntegral(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPvarMayRoundUp(SCIP_VAR *var)
    Definition: var.c:4484
    SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
    Definition: var.c:23386
    SCIP_Bool SCIPvarIsImpliedIntegral(SCIP_VAR *var)
    Definition: var.c:23498
    SCIP_Bool SCIPvarMayRoundDown(SCIP_VAR *var)
    Definition: var.c:4473
    SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
    Definition: var.c:23900
    const char * SCIPvarGetName(SCIP_VAR *var)
    Definition: var.c:23267
    SCIP_Real SCIPgetRelaxSolVal(SCIP *scip, SCIP_VAR *var)
    Definition: scip_var.c:3347
    SCIP_Bool SCIPisRelaxSolValid(SCIP *scip)
    Definition: scip_var.c:3281
    static SCIP_DECL_HEURFREE(heurFreeSimplerounding)
    #define HEUR_TIMING
    static SCIP_DECL_HEUREXITSOL(heurExitsolSimplerounding)
    #define HEUR_FREQOFS
    #define HEUR_DESC
    #define DEFAULT_ONCEPERNODE
    static SCIP_DECL_HEURCOPY(heurCopySimplerounding)
    static SCIP_DECL_HEURINITSOL(heurInitsolSimplerounding)
    #define HEUR_DISPCHAR
    #define HEUR_MAXDEPTH
    static SCIP_RETCODE performSimpleRounding(SCIP *scip, SCIP_SOL *sol, SCIP_VAR **cands, SCIP_Real *candssol, int ncands, SCIP_RESULT *result)
    #define HEUR_PRIORITY
    #define HEUR_NAME
    static SCIP_RETCODE performLPSimpleRounding(SCIP *scip, SCIP_HEURDATA *heurdata, SCIP_HEURTIMING heurtiming, SCIP_RESULT *result)
    static SCIP_DECL_HEUREXEC(heurExecSimplerounding)
    static SCIP_DECL_HEURINIT(heurInitSimplerounding)
    #define HEUR_FREQ
    static SCIP_RETCODE performRelaxSimpleRounding(SCIP *scip, SCIP_HEURDATA *heurdata, SCIP_RESULT *result)
    #define HEUR_USESSUBSCIP
    static SCIP_DECL_HEUREXIT(heurExitSimplerounding)
    Simple and fast LP rounding heuristic.
    memory allocation routines
    public methods for primal heuristics
    public methods for message output
    public methods for problem variables
    public methods for branching rule plugins and branching
    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 numerical tolerances
    public methods for SCIP parameter handling
    public methods for global and local (sub)problems
    public methods for solutions
    public methods for querying solving statistics
    public methods for SCIP variables
    struct SCIP_HeurData SCIP_HEURDATA
    Definition: type_heur.h:77
    @ SCIP_LPSOLSTAT_OPTIMAL
    Definition: type_lp.h:44
    @ SCIP_DIDNOTRUN
    Definition: type_result.h:42
    @ SCIP_DIDNOTFIND
    Definition: type_result.h:44
    @ SCIP_FOUNDSOL
    Definition: type_result.h:56
    enum SCIP_Result SCIP_RESULT
    Definition: type_result.h:61
    @ SCIP_OKAY
    Definition: type_retcode.h:42
    enum SCIP_Retcode SCIP_RETCODE
    Definition: type_retcode.h:63
    #define SCIP_HEURTIMING_DURINGPRICINGLOOP
    Definition: type_timing.h:91
    unsigned int SCIP_HEURTIMING
    Definition: type_timing.h:103
    #define SCIP_HEURTIMING_AFTERLPNODE
    Definition: type_timing.h:83
    @ SCIP_VARSTATUS_COLUMN
    Definition: type_var.h:53