Scippy

    SCIP

    Solving Constraint Integer Programs

    branch_vanillafullstrong.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 branch_vanillafullstrong.c
    26 * @ingroup DEFPLUGINS_BRANCH
    27 * @brief vanilla full strong LP branching rule
    28 * @author Tobias Achterberg
    29 * @author Maxime Gasse
    30 */
    31
    32/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
    33
    36#include "scip/pub_branch.h"
    37#include "scip/pub_message.h"
    38#include "scip/pub_tree.h"
    39#include "scip/pub_var.h"
    40#include "scip/scip_branch.h"
    41#include "scip/scip_exact.h"
    42#include "scip/scip_general.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"
    50#include "scip/scip_tree.h"
    51#include "scip/scip_var.h"
    52#include <string.h>
    53
    54
    55#define BRANCHRULE_NAME "vanillafullstrong"
    56#define BRANCHRULE_DESC "vanilla full strong branching"
    57#define BRANCHRULE_PRIORITY -2000
    58#define BRANCHRULE_MAXDEPTH -1
    59#define BRANCHRULE_MAXBOUNDDIST 1.0
    60
    61#define DEFAULT_INTEGRALCANDS FALSE /**< should integral variables in the current LP solution be considered as
    62 * branching candidates ? */
    63#define DEFAULT_SCOREALL FALSE /**< should strong branching scores be computed for all candidates, or can
    64 * we early stop when a variable has infinite score ? */
    65#define DEFAULT_IDEMPOTENT FALSE /**< should strong branching side-effects be prevented (e.g., domain
    66 * changes, stat updates etc.) ? */
    67#define DEFAULT_COLLECTSCORES FALSE /**< should strong branching scores be collected ? */
    68#define DEFAULT_DONOTBRANCH FALSE /**< should branching be done ? */
    69
    70
    71/** branching rule data */
    72struct SCIP_BranchruleData
    73{
    74 SCIP_Bool integralcands; /**< should integral variables in the current LP solution be considered
    75 * as branching candidates ? */
    76 SCIP_Bool scoreall; /**< should strong branching scores be computed for all candidates, or
    77 * can we early stop when a node is detected infeasible ? */
    78 SCIP_Bool idempotent; /**< should strong branching side-effects be prevented (e.g., domain
    79 * changes, stat updates etc.) ? */
    80 SCIP_Bool collectscores; /**< should strong branching scores be collected ? */
    81 SCIP_Bool donotbranch; /**< should branching be done ? */
    82 SCIP_VAR** cands; /**< candidate variables */
    83 SCIP_Real* candscores; /**< candidate scores */
    84 int ncands; /**< number of candidates */
    85 int npriocands; /**< number of priority candidates */
    86 int bestcand; /**< best branching candidate */
    87 int candcapacity; /**< capacity of candidate arrays */
    88};
    89
    90
    91/*
    92 * local methods
    93 */
    94
    95
    96/** selects a variable from a set of candidates by strong branching */
    97static
    99 SCIP* scip, /**< SCIP data structure */
    100 SCIP_VAR** cands, /**< branching candidates */
    101 int ncands, /**< number of branching candidates */
    102 int npriocands, /**< number of branching candidates with highest priority */
    103 SCIP_Bool scoreall, /**< should strong branching scores be computed for all candidates, or can
    104 * we early stop when a node is detected infeasible ? */
    105 SCIP_Bool idempotent, /**< should strong branching side-effects be prevented (e.g., domain
    106 * changes, stat updates etc.) ? */
    107 SCIP_Real* scores, /**< candidate scores */
    108 int* bestcand, /**< best candidate for branching */
    109 SCIP_Real* bestdown, /**< objective value of the down branch for bestcand */
    110 SCIP_Real* bestup, /**< objective value of the up branch for bestcand */
    111 SCIP_Real* bestscore, /**< score for bestcand */
    112 SCIP_Bool* bestdownvalid, /**< is bestdown a valid dual bound for the down branch? */
    113 SCIP_Bool* bestupvalid, /**< is bestup a valid dual bound for the up branch? */
    114 SCIP_Real* provedbound /**< proved dual bound for current subtree */
    115 )
    116{ /*lint --e{715}*/
    117 SCIP_Real lpobjval;
    118 int nsbcalls;
    119 int c;
    120
    121 assert(scip != NULL);
    122 assert(cands != NULL);
    123 assert(bestcand != NULL);
    124 assert(bestdown != NULL);
    125 assert(bestup != NULL);
    126 assert(bestscore != NULL);
    127 assert(bestdownvalid != NULL);
    128 assert(bestupvalid != NULL);
    129 assert(provedbound != NULL);
    130 assert(ncands > 0);
    131
    132 /* get current LP objective bound of the local sub problem and global cutoff bound */
    133 lpobjval = SCIPgetLPObjval(scip);
    134 *provedbound = lpobjval;
    135
    136 *bestcand = 0;
    137 *bestdown = lpobjval;
    138 *bestup = lpobjval;
    139 *bestdownvalid = FALSE;
    140 *bestupvalid = FALSE;
    141 *bestscore = -SCIPinfinity(scip);
    142
    143 if( scores != NULL )
    144 for( c = 0; c < ncands; ++c )
    145 scores[c] = -SCIPinfinity(scip);
    146
    147 /* if only one candidate exists, choose this one without applying strong branching; also, when SCIP is about to be
    148 * stopped, all strongbranching evaluations will be aborted anyway, thus we can return immediately
    149 */
    150 if( (!scoreall && ncands == 1) || SCIPisStopped(scip) )
    151 return SCIP_OKAY;
    152
    153 /* this assert may not hold if SCIP is stopped, thus we only check it here */
    155
    156 /* initialize strong branching without propagation */
    158
    159 /* compute strong branching scores */
    160 nsbcalls = 0;
    161 for( c = 0; c < ncands ; ++c )
    162 {
    163 SCIP_VAR* var;
    164 SCIP_Real val;
    165 SCIP_Bool integral;
    166 SCIP_Real down, up;
    167 SCIP_Real downgain, upgain;
    168 SCIP_Bool downvalid, upvalid;
    169 SCIP_Bool downinf, upinf;
    170 SCIP_Bool downconflict, upconflict;
    171 SCIP_Bool lperror;
    172 SCIP_Real gains[3];
    173 SCIP_Real score;
    174
    175 var = cands[c];
    176 assert(var != NULL);
    177
    178 val = SCIPvarGetLPSol(var);
    179 integral = SCIPisFeasIntegral(scip, val);
    180
    181 up = -SCIPinfinity(scip);
    182 down = -SCIPinfinity(scip);
    183
    184 SCIPdebugMsg(scip, "applying vanilla strong branching on variable <%s> with solution %g\n",
    185 SCIPvarGetName(var), val);
    186
    187 /* apply strong branching */
    188 if( integral )
    189 {
    190 SCIP_CALL( SCIPgetVarStrongbranchInt(scip, cands[c], INT_MAX, idempotent,
    191 &down, &up, &downvalid, &upvalid, &downinf, &upinf, &downconflict, &upconflict, &lperror) );
    192 }
    193 else
    194 {
    195 SCIP_CALL( SCIPgetVarStrongbranchFrac(scip, cands[c], INT_MAX, idempotent,
    196 &down, &up, &downvalid, &upvalid, &downinf, &upinf, &downconflict, &upconflict, &lperror) );
    197 }
    198 nsbcalls++;
    199
    200 /* check for an error in strong branching */
    201 if( lperror )
    202 {
    204 "(node %" SCIP_LONGINT_FORMAT ") error in strong branching call for variable <%s> with solution %g\n",
    205 SCIPgetNNodes(scip), SCIPvarGetName(var), val);
    206 break;
    207 }
    208
    209 /* evaluate strong branching */
    210 down = MAX(down, lpobjval);
    211 up = MAX(up, lpobjval);
    212 downgain = down - lpobjval;
    213 upgain = up - lpobjval;
    214
    215 assert(!SCIPallColsInLP(scip) || SCIPisExact(scip) || !downvalid || downinf == SCIPisGE(scip, down, SCIPgetCutoffbound(scip)));
    216 assert(!SCIPallColsInLP(scip) || SCIPisExact(scip) || !upvalid || upinf == SCIPisGE(scip, up, SCIPgetCutoffbound(scip)));
    217 assert(downinf || !downconflict);
    218 assert(upinf || !upconflict);
    219
    220 if( !idempotent )
    221 {
    222 /* display node information line */
    223 if( SCIPgetDepth(scip) == 0 && nsbcalls % 100 == 0 )
    224 {
    226 }
    227 /* update variable pseudo cost values */
    228 if( !downinf && downvalid )
    229 {
    230 SCIP_CALL( SCIPupdateVarPseudocost(scip, var, integral ? -1.0 : 0.0 - SCIPfrac(scip, val), downgain, 1.0) );
    231 }
    232 if( !upinf && upvalid )
    233 {
    234 SCIP_CALL( SCIPupdateVarPseudocost(scip, var, integral ? +1.0 : 1.0 - SCIPfrac(scip, val), upgain, 1.0) );
    235 }
    236 }
    237
    238 /* compute strong branching score */
    239 gains[0] = downgain;
    240 gains[1] = upgain;
    241 gains[2] = 0.0;
    242 score = SCIPgetBranchScoreMultiple(scip, var, integral ? 3 : 2, gains);
    243
    244 /* collect scores if requested */
    245 if( scores != NULL )
    246 scores[c] = score;
    247
    248 /* check for a better score */
    249 if( score > *bestscore )
    250 {
    251 *bestcand = c;
    252 *bestdown = down;
    253 *bestup = up;
    254 *bestdownvalid = downvalid;
    255 *bestupvalid = upvalid;
    256 *bestscore = score;
    257 }
    258
    259 SCIPdebugMsg(scip, " -> cand %d/%d (prio:%d) var <%s> (solval=%g, downgain=%g, upgain=%g, score=%g) -- best: <%s> (%g)\n",
    260 c, ncands, npriocands, SCIPvarGetName(var), val, downgain, upgain, score,
    261 SCIPvarGetName(cands[*bestcand]), *bestscore);
    262
    263 /* node is infeasible -> early stopping (highest score) */
    264 if( !integral && !scoreall && downinf && upinf )
    265 {
    266 /* we should only detect infeasibility if the LP is a valid relaxation */
    267 assert(SCIPallColsInLP(scip));
    268 assert(!SCIPisExact(scip));
    269 assert(*bestcand == c);
    270
    271 SCIPdebugMsg(scip, " -> variable <%s> is infeasible in both directions\n", SCIPvarGetName(var));
    272 break;
    273 }
    274 }
    275
    276 /* end strong branching */
    278
    279 /* update proved bound */
    280 if( *bestdownvalid && *bestupvalid && !SCIPisFeasIntegral(scip, SCIPvarGetLPSol(cands[*bestcand])) )
    281 {
    282 SCIP_Real minbound = MIN(*bestdown, *bestup);
    283
    284 *provedbound = MAX(*provedbound, minbound);
    285 }
    286
    287 return SCIP_OKAY;
    288}
    289
    290/*
    291 * Callback methods
    292 */
    293
    294/** copy method for branchrule plugins (called when SCIP copies plugins) */
    295static
    296SCIP_DECL_BRANCHCOPY(branchCopyVanillafullstrong)
    297{ /*lint --e{715}*/
    298 assert(scip != NULL);
    299 assert(branchrule != NULL);
    300 assert(strcmp(SCIPbranchruleGetName(branchrule), BRANCHRULE_NAME) == 0);
    301
    302 /* call inclusion method of branchrule */
    304
    305 return SCIP_OKAY;
    306}
    307
    308/** destructor of branching rule to free user data (called when SCIP is exiting) */
    309static
    310SCIP_DECL_BRANCHFREE(branchFreeVanillafullstrong)
    311{ /*lint --e{715}*/
    312 SCIP_BRANCHRULEDATA* branchruledata;
    313
    314 /* free branching rule data */
    315 branchruledata = SCIPbranchruleGetData(branchrule);
    316 assert(branchruledata != NULL);
    317
    318 SCIPfreeBlockMemoryNull(scip, &branchruledata);
    319
    320 return SCIP_OKAY;
    321}
    322
    323/** initialization method of branching rule (called after problem was transformed) */
    324static
    325SCIP_DECL_BRANCHINIT(branchInitVanillafullstrong)
    326{ /*lint --e{715}*/
    327#ifndef NDEBUG
    328 SCIP_BRANCHRULEDATA* branchruledata;
    329
    330 /* initialize branching rule data */
    331 branchruledata = SCIPbranchruleGetData(branchrule);
    332#endif
    333 assert(branchruledata != NULL);
    334 assert(branchruledata->candscores == NULL);
    335 assert(branchruledata->cands == NULL);
    336
    337 return SCIP_OKAY;
    338}
    339
    340/** deinitialization method of branching rule (called before transformed problem is freed) */
    341static
    342SCIP_DECL_BRANCHEXIT(branchExitVanillafullstrong)
    343{ /*lint --e{715}*/
    344 SCIP_BRANCHRULEDATA* branchruledata;
    345
    346 /* initialize branching rule data */
    347 branchruledata = SCIPbranchruleGetData(branchrule);
    348 assert(branchruledata != NULL);
    349
    350 /* free candidate arrays if any */
    351 if( branchruledata->candscores != NULL )
    352 {
    353 SCIPfreeBlockMemoryArrayNull(scip, &branchruledata->candscores, branchruledata->candcapacity);
    354 }
    355 if( branchruledata->cands != NULL )
    356 {
    357 SCIPfreeBlockMemoryArrayNull(scip, &branchruledata->cands, branchruledata->candcapacity);
    358 }
    359
    360 branchruledata->candcapacity = -1;
    361 branchruledata->ncands = -1;
    362 branchruledata->npriocands = -1;
    363 branchruledata->bestcand = -1;
    364
    365 return SCIP_OKAY;
    366}
    367
    368/** branching execution method */
    369static
    370SCIP_DECL_BRANCHEXECLP(branchExeclpVanillafullstrong)
    371{ /*lint --e{715}*/
    372 SCIP_BRANCHRULEDATA* branchruledata;
    373 SCIP_Real bestdown;
    374 SCIP_Real bestup;
    375 SCIP_Real bestscore;
    376 SCIP_Real provedbound;
    377 SCIP_Bool bestdownvalid;
    378 SCIP_Bool bestupvalid;
    379 SCIP_VAR** cands;
    380 int ncands;
    381 int npriocands;
    382 int i;
    383
    384 assert(branchrule != NULL);
    385 assert(strcmp(SCIPbranchruleGetName(branchrule), BRANCHRULE_NAME) == 0);
    386 assert(scip != NULL);
    387 assert(result != NULL);
    388
    389 SCIPdebugMsg(scip, "Execlp method of vanilla fullstrong branching\n");
    390
    391 *result = SCIP_DIDNOTRUN;
    392
    393 /* get branching rule data */
    394 branchruledata = SCIPbranchruleGetData(branchrule);
    395 assert(branchruledata != NULL);
    396
    397 /* get branching candidates, either all non-fixed variables or only the
    398 * fractional ones */
    399 if( branchruledata->integralcands )
    400 {
    401 SCIP_CALL( SCIPgetPseudoBranchCands(scip, &cands, &ncands, &npriocands) );
    402 }
    403 else
    404 {
    405 SCIP_CALL( SCIPgetLPBranchCands(scip, &cands, NULL, NULL, &ncands, &npriocands, NULL) );
    406 }
    407
    408 assert(ncands > 0);
    409 assert(npriocands > 0);
    410
    411 /* increase candidate arrays capacity if needed */
    412 if( ncands > branchruledata->candcapacity )
    413 {
    414 /* free previously allocated arrays if any */
    415 if( branchruledata->candscores != NULL)
    416 {
    417 SCIPfreeBlockMemoryArrayNull(scip, &branchruledata->candscores, branchruledata->candcapacity);
    418 branchruledata->candscores = NULL;
    419 }
    420 if( branchruledata->cands != NULL)
    421 {
    422 SCIPfreeBlockMemoryArrayNull(scip, &branchruledata->cands, branchruledata->candcapacity);
    423 branchruledata->cands = NULL;
    424 }
    425
    426 /* update capacity */
    427 branchruledata->candcapacity = SCIPgetNBinVars(scip) + SCIPgetNIntVars(scip) + SCIPgetNImplVars(scip);
    428 }
    429 assert(branchruledata->candcapacity >= ncands);
    430
    431 /* allocate new candidate arrays if needed */
    432 if( branchruledata->cands == NULL )
    433 {
    434 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &branchruledata->cands, branchruledata->candcapacity) );
    435 }
    436 if( branchruledata->candscores == NULL && branchruledata->collectscores )
    437 {
    438 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &branchruledata->candscores, branchruledata->candcapacity) );
    439 }
    440
    441 /* copy candidates */
    442 branchruledata->ncands = ncands;
    443 branchruledata->npriocands = npriocands;
    444
    445 for( i = 0; i < ncands; i++ )
    446 branchruledata->cands[i] = cands[i];
    447
    448 SCIP_CALL( runVanillaStrongBranching(scip, branchruledata->cands, branchruledata->ncands, branchruledata->npriocands,
    449 branchruledata->scoreall, branchruledata->idempotent, branchruledata->candscores,
    450 &branchruledata->bestcand, &bestdown, &bestup, &bestscore, &bestdownvalid,
    451 &bestupvalid, &provedbound) );
    452
    453 if( !branchruledata->donotbranch )
    454 {
    455 assert(0 <= branchruledata->bestcand && branchruledata->bestcand < branchruledata->ncands);
    456
    457 if( SCIPisGE(scip, provedbound, SCIPgetCutoffbound(scip)) )
    458 {
    459 SCIPdebugMsg(scip, " -> variable <%s> is infeasible in both directions\n",
    460 SCIPvarGetName(branchruledata->cands[branchruledata->bestcand]));
    461
    462 *result = SCIP_CUTOFF;
    463 }
    464 else
    465 {
    466 SCIP_VAR* var;
    467 SCIP_Real val;
    468 SCIP_NODE* downchild;
    469 SCIP_NODE* eqchild;
    470 SCIP_NODE* upchild;
    471 SCIP_Bool allcolsinlp;
    472 SCIP_Bool exactsolve;
    473
    474 /* check, if we want to solve the problem exactly, meaning that strong branching information is not useful
    475 * for cutting off sub problems and improving lower bounds of children
    476 */
    477 exactsolve = SCIPisExact(scip);
    478
    479 /* check, if all existing columns are in LP, and thus the strong branching results give lower bounds */
    480 allcolsinlp = SCIPallColsInLP(scip);
    481
    482 if( !branchruledata->idempotent && allcolsinlp && !exactsolve )
    483 {
    485 }
    486
    487 assert(SCIPisLT(scip, provedbound, SCIPgetCutoffbound(scip)));
    488
    489 var = branchruledata->cands[branchruledata->bestcand];
    490 val = SCIPvarGetLPSol(var);
    491
    492 /* perform the branching */
    493 SCIPdebugMsg(scip, " -> %d candidates, selected candidate %d: variable <%s>[%g,%g] (solval=%g, down=%g, up=%g, score=%g)\n",
    494 branchruledata->ncands, branchruledata->bestcand, SCIPvarGetName(var), SCIPvarGetLbLocal(var),
    495 SCIPvarGetUbLocal(var), val, bestdown, bestup, bestscore);
    496 SCIP_CALL( SCIPbranchVarVal(scip, var, val, &downchild, &eqchild, &upchild) );
    497
    498 /* update the lower bounds in the children */
    499 if( !branchruledata->idempotent && allcolsinlp && !exactsolve )
    500 {
    501 if( downchild != NULL && bestdownvalid )
    502 {
    503 SCIP_CALL( SCIPupdateNodeLowerbound(scip, downchild, bestdown) );
    504 SCIPdebugMsg(scip, " -> down child's lowerbound: %g\n", SCIPnodeGetLowerbound(downchild));
    505 }
    506 if( upchild != NULL && bestupvalid )
    507 {
    508 SCIP_CALL( SCIPupdateNodeLowerbound(scip, upchild, bestup) );
    509 SCIPdebugMsg(scip, " -> up child's lowerbound: %g\n", SCIPnodeGetLowerbound(upchild));
    510 }
    511 }
    512
    513 *result = SCIP_BRANCHED;
    514 }
    515 }
    516
    517 return SCIP_OKAY;
    518}
    519
    520
    521/*
    522 * branching specific interface methods
    523 */
    524
    525/** creates the vanilla full strong LP branching rule and includes it in SCIP */
    527 SCIP* scip /**< SCIP data structure */
    528 )
    529{
    530 SCIP_BRANCHRULEDATA* branchruledata;
    531 SCIP_BRANCHRULE* branchrule;
    532
    533 /* create fullstrong branching rule data */
    534 SCIP_CALL( SCIPallocBlockMemory(scip, &branchruledata) );
    535 branchruledata->cands = NULL;
    536 branchruledata->candscores = NULL;
    537 branchruledata->candcapacity = -1;
    538 branchruledata->ncands = -1;
    539 branchruledata->npriocands = -1;
    540 branchruledata->bestcand = -1;
    541
    542 /* include branching rule */
    545
    546 assert(branchrule != NULL);
    547
    548 /* set non-fundamental callbacks via specific setter functions*/
    549 SCIP_CALL( SCIPsetBranchruleCopy(scip, branchrule, branchCopyVanillafullstrong) );
    550 SCIP_CALL( SCIPsetBranchruleFree(scip, branchrule, branchFreeVanillafullstrong) );
    551 SCIP_CALL( SCIPsetBranchruleInit(scip, branchrule, branchInitVanillafullstrong) );
    552 SCIP_CALL( SCIPsetBranchruleExit(scip, branchrule, branchExitVanillafullstrong) );
    553 SCIP_CALL( SCIPsetBranchruleExecLp(scip, branchrule, branchExeclpVanillafullstrong) );
    554
    555 /* fullstrong branching rule parameters */
    557 "branching/vanillafullstrong/integralcands",
    558 "should integral variables in the current LP solution be considered as branching candidates?",
    559 &branchruledata->integralcands, FALSE, DEFAULT_INTEGRALCANDS, NULL, NULL) );
    561 "branching/vanillafullstrong/idempotent",
    562 "should strong branching side-effects be prevented (e.g., domain changes, stat updates etc.)?",
    563 &branchruledata->idempotent, FALSE, DEFAULT_IDEMPOTENT, NULL, NULL) );
    565 "branching/vanillafullstrong/scoreall",
    566 "should strong branching scores be computed for all candidates, or can we early stop when a variable has infinite score?",
    567 &branchruledata->scoreall, TRUE, DEFAULT_SCOREALL, NULL, NULL) );
    569 "branching/vanillafullstrong/collectscores",
    570 "should strong branching scores be collected?",
    571 &branchruledata->collectscores, TRUE, DEFAULT_COLLECTSCORES, NULL, NULL) );
    573 "branching/vanillafullstrong/donotbranch",
    574 "should candidates only be scored, but no branching be performed?",
    575 &branchruledata->donotbranch, TRUE, DEFAULT_DONOTBRANCH, NULL, NULL) );
    576
    577 return SCIP_OKAY;
    578}
    579
    580
    581/** recovers candidate variables and their scores from last vanilla full strong branching call */
    583 SCIP* scip, /**< SCIP data structure */
    584 SCIP_VAR*** cands, /**< pointer to store candidate variables; or NULL */
    585 SCIP_Real** candscores, /**< pointer to store candidate scores; or NULL */
    586 int* ncands, /**< pointer to store number of candidates; or NULL */
    587 int* npriocands, /**< pointer to store number of priority candidates; or NULL */
    588 int* bestcand /**< pointer to store best branching candidate; or NULL */
    589 )
    590{
    591 SCIP_BRANCHRULEDATA* branchruledata;
    592 SCIP_BRANCHRULE* branchrule;
    593
    594 assert(scip != NULL);
    595
    597 assert( branchrule != NULL );
    598 branchruledata = SCIPbranchruleGetData(branchrule);
    599 assert( branchruledata != NULL );
    600
    601 if( cands )
    602 {
    603 *cands = branchruledata->cands;
    604 }
    605 if( candscores && branchruledata->collectscores )
    606 {
    607 *candscores = branchruledata->candscores;
    608 }
    609 if( ncands )
    610 {
    611 *ncands = branchruledata->ncands;
    612 }
    613 if( npriocands )
    614 {
    615 *npriocands = branchruledata->npriocands;
    616 }
    617 if( bestcand )
    618 {
    619 *bestcand = branchruledata->bestcand;
    620 }
    621
    622 return SCIP_OKAY;
    623}
    #define BRANCHRULE_DESC
    #define DEFAULT_IDEMPOTENT
    #define BRANCHRULE_PRIORITY
    SCIP_RETCODE SCIPgetVanillafullstrongData(SCIP *scip, SCIP_VAR ***cands, SCIP_Real **candscores, int *ncands, int *npriocands, int *bestcand)
    #define DEFAULT_SCOREALL
    #define BRANCHRULE_NAME
    static SCIP_DECL_BRANCHCOPY(branchCopyVanillafullstrong)
    static SCIP_RETCODE runVanillaStrongBranching(SCIP *scip, SCIP_VAR **cands, int ncands, int npriocands, SCIP_Bool scoreall, SCIP_Bool idempotent, SCIP_Real *scores, int *bestcand, SCIP_Real *bestdown, SCIP_Real *bestup, SCIP_Real *bestscore, SCIP_Bool *bestdownvalid, SCIP_Bool *bestupvalid, SCIP_Real *provedbound)
    #define DEFAULT_INTEGRALCANDS
    #define DEFAULT_DONOTBRANCH
    static SCIP_DECL_BRANCHFREE(branchFreeVanillafullstrong)
    static SCIP_DECL_BRANCHEXIT(branchExitVanillafullstrong)
    static SCIP_DECL_BRANCHEXECLP(branchExeclpVanillafullstrong)
    static SCIP_DECL_BRANCHINIT(branchInitVanillafullstrong)
    #define BRANCHRULE_MAXDEPTH
    #define DEFAULT_COLLECTSCORES
    #define BRANCHRULE_MAXBOUNDDIST
    vanilla full strong LP branching rule
    #define NULL
    Definition: def.h:248
    #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_LONGINT_FORMAT
    Definition: def.h:148
    #define SCIP_CALL(x)
    Definition: def.h:355
    SCIP_RETCODE SCIPincludeBranchruleVanillafullstrong(SCIP *scip)
    SCIP_Bool SCIPisStopped(SCIP *scip)
    Definition: scip_general.c:759
    int SCIPgetNIntVars(SCIP *scip)
    Definition: scip_prob.c:2340
    int SCIPgetNImplVars(SCIP *scip)
    Definition: scip_prob.c:2387
    int SCIPgetNBinVars(SCIP *scip)
    Definition: scip_prob.c:2293
    SCIP_RETCODE SCIPupdateNodeLowerbound(SCIP *scip, SCIP_NODE *node, SCIP_Real newbound)
    Definition: scip_prob.c:4354
    SCIP_RETCODE SCIPupdateLocalLowerbound(SCIP *scip, SCIP_Real newbound)
    Definition: scip_prob.c:4289
    void SCIPverbMessage(SCIP *scip, SCIP_VERBLEVEL msgverblevel, FILE *file, const char *formatstr,...)
    Definition: scip_message.c:225
    #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 SCIPsetBranchruleExit(SCIP *scip, SCIP_BRANCHRULE *branchrule, SCIP_DECL_BRANCHEXIT((*branchexit)))
    Definition: scip_branch.c:208
    SCIP_RETCODE SCIPsetBranchruleExecLp(SCIP *scip, SCIP_BRANCHRULE *branchrule, SCIP_DECL_BRANCHEXECLP((*branchexeclp)))
    Definition: scip_branch.c:256
    SCIP_BRANCHRULE * SCIPfindBranchrule(SCIP *scip, const char *name)
    Definition: scip_branch.c:304
    SCIP_RETCODE SCIPsetBranchruleCopy(SCIP *scip, SCIP_BRANCHRULE *branchrule, SCIP_DECL_BRANCHCOPY((*branchcopy)))
    Definition: scip_branch.c:160
    SCIP_RETCODE SCIPincludeBranchruleBasic(SCIP *scip, SCIP_BRANCHRULE **branchruleptr, const char *name, const char *desc, int priority, int maxdepth, SCIP_Real maxbounddist, SCIP_BRANCHRULEDATA *branchruledata)
    Definition: scip_branch.c:123
    const char * SCIPbranchruleGetName(SCIP_BRANCHRULE *branchrule)
    Definition: branch.c:2018
    SCIP_BRANCHRULEDATA * SCIPbranchruleGetData(SCIP_BRANCHRULE *branchrule)
    Definition: branch.c:1886
    SCIP_RETCODE SCIPsetBranchruleFree(SCIP *scip, SCIP_BRANCHRULE *branchrule, SCIP_DECL_BRANCHFREE((*branchfree)))
    Definition: scip_branch.c:176
    SCIP_RETCODE SCIPsetBranchruleInit(SCIP *scip, SCIP_BRANCHRULE *branchrule, SCIP_DECL_BRANCHINIT((*branchinit)))
    Definition: scip_branch.c:192
    SCIP_RETCODE SCIPbranchVarVal(SCIP *scip, SCIP_VAR *var, SCIP_Real val, SCIP_NODE **downchild, SCIP_NODE **eqchild, SCIP_NODE **upchild)
    Definition: scip_branch.c:1134
    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 SCIPgetPseudoBranchCands(SCIP *scip, SCIP_VAR ***pseudocands, int *npseudocands, int *npriopseudocands)
    Definition: scip_branch.c:741
    SCIP_Real SCIPgetBranchScoreMultiple(SCIP *scip, SCIP_VAR *var, int nchildren, SCIP_Real *gains)
    Definition: scip_branch.c:880
    SCIP_Bool SCIPisExact(SCIP *scip)
    Definition: scip_exact.c:193
    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 SCIPallocBlockMemoryArray(scip, ptr, num)
    Definition: scip_mem.h:93
    #define SCIPfreeBlockMemoryArrayNull(scip, ptr, num)
    Definition: scip_mem.h:111
    #define SCIPfreeBlockMemoryNull(scip, ptr)
    Definition: scip_mem.h:109
    #define SCIPallocBlockMemory(scip, ptr)
    Definition: scip_mem.h:89
    SCIP_Real SCIPnodeGetLowerbound(SCIP_NODE *node)
    Definition: tree.c:8503
    SCIP_Longint SCIPgetNNodes(SCIP *scip)
    SCIP_Real SCIPgetCutoffbound(SCIP *scip)
    SCIP_RETCODE SCIPprintDisplayLine(SCIP *scip, FILE *file, SCIP_VERBLEVEL verblevel, SCIP_Bool endline)
    SCIP_Real SCIPinfinity(SCIP *scip)
    SCIP_Bool SCIPisGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisFeasIntegral(SCIP *scip, SCIP_Real val)
    SCIP_Real SCIPfrac(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    int SCIPgetDepth(SCIP *scip)
    Definition: scip_tree.c:672
    SCIP_RETCODE SCIPgetVarStrongbranchFrac(SCIP *scip, SCIP_VAR *var, int itlim, SCIP_Bool idempotent, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, SCIP_Bool *downinf, SCIP_Bool *upinf, SCIP_Bool *downconflict, SCIP_Bool *upconflict, SCIP_Bool *lperror)
    Definition: scip_var.c:3664
    SCIP_RETCODE SCIPgetVarStrongbranchInt(SCIP *scip, SCIP_VAR *var, int itlim, SCIP_Bool idempotent, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, SCIP_Bool *downinf, SCIP_Bool *upinf, SCIP_Bool *downconflict, SCIP_Bool *upconflict, SCIP_Bool *lperror)
    Definition: scip_var.c:4478
    SCIP_RETCODE SCIPendStrongbranch(SCIP *scip)
    Definition: scip_var.c:3488
    SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
    Definition: var.c:24268
    const char * SCIPvarGetName(SCIP_VAR *var)
    Definition: var.c:23267
    SCIP_Real SCIPvarGetLPSol(SCIP_VAR *var)
    Definition: var.c:24664
    SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
    Definition: var.c:24234
    SCIP_RETCODE SCIPupdateVarPseudocost(SCIP *scip, SCIP_VAR *var, SCIP_Real solvaldelta, SCIP_Real objdelta, SCIP_Real weight)
    Definition: scip_var.c:11122
    SCIP_RETCODE SCIPstartStrongbranch(SCIP *scip, SCIP_Bool enablepropagation)
    Definition: scip_var.c:3430
    memory allocation routines
    public methods for branching rules
    public methods for message output
    public methods for branch and bound tree
    public methods for problem variables
    public methods for branching rule plugins and branching
    public methods for exact solving
    general public methods
    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 querying solving statistics
    public methods for the branch-and-bound tree
    public methods for SCIP variables
    struct SCIP_BranchruleData SCIP_BRANCHRULEDATA
    Definition: type_branch.h:57
    @ SCIP_LPSOLSTAT_OPTIMAL
    Definition: type_lp.h:44
    @ SCIP_VERBLEVEL_HIGH
    Definition: type_message.h:61
    @ SCIP_DIDNOTRUN
    Definition: type_result.h:42
    @ SCIP_CUTOFF
    Definition: type_result.h:48
    @ SCIP_BRANCHED
    Definition: type_result.h:54
    @ SCIP_OKAY
    Definition: type_retcode.h:42
    enum SCIP_Retcode SCIP_RETCODE
    Definition: type_retcode.h:63