Scippy

    SCIP

    Solving Constraint Integer Programs

    branch_pscost.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_pscost.c
    26 * @ingroup DEFPLUGINS_BRANCH
    27 * @brief pseudo costs branching rule
    28 * @author Tobias Achterberg
    29 * @author Stefan Vigerske
    30 * @author Krunal Patel
    31 */
    32
    33/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
    34
    36#include "scip/branch_pscost.h"
    37#include "scip/pub_branch.h"
    38#include "scip/pub_message.h"
    39#include "scip/pub_misc.h"
    40#include "scip/pub_misc_sort.h"
    41#include "scip/pub_tree.h"
    42#include "scip/pub_var.h"
    43#include "scip/scip_branch.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"
    49#include "scip/scip_sol.h"
    50#include "scip/scip_tree.h"
    51#include "scip/scip_var.h"
    52#include <string.h>
    53
    54#define BRANCHRULE_NAME "pscost"
    55#define BRANCHRULE_DESC "branching on pseudo cost values"
    56#define BRANCHRULE_PRIORITY 2000
    57#define BRANCHRULE_MAXDEPTH -1
    58#define BRANCHRULE_MAXBOUNDDIST 1.0
    59
    60#define BRANCHRULE_STRATEGIES "dsuv" /**< possible pseudo cost multiplication strategies for branching on external candidates */
    61#define BRANCHRULE_STRATEGY_DEFAULT 'u' /**< default pseudo cost multiplication strategy */
    62#define BRANCHRULE_SCOREMINWEIGHT_DEFAULT 0.8 /**< default weight for minimum of scores of a branching candidate */
    63#define BRANCHRULE_SCOREMAXWEIGHT_DEFAULT 1.3 /**< default weight for maximum of scores of a branching candidate */
    64#define BRANCHRULE_SCORESUMWEIGHT_DEFAULT 0.1 /**< default weight for sum of scores of a branching candidate */
    65#define BRANCHRULE_NCHILDREN_DEFAULT 2 /**< default number of children in n-ary branching */
    66#define BRANCHRULE_NARYMAXDEPTH_DEFAULT -1 /**< default maximal depth where to do n-ary branching */
    67#define BRANCHRULE_NARYMINWIDTH_DEFAULT 0.001 /**< default minimal domain width in children when doing n-ary branching */
    68#define BRANCHRULE_NARYWIDTHFAC_DEFAULT 2.0 /**< default factor of domain width in n-ary branching */
    69#define BRANCHRULE_RANDSEED_DEFAULT 47 /**< initial random seed */
    70#define BRANCHRULE_DISCOUNTFACTOR 0.2 /**< default discount factor for discounted pseudo costs */
    71
    72
    73#define WEIGHTEDSCORING(data, min, max, sum) \
    74 ((data)->scoreminweight * (min) + (data)->scoremaxweight * (max) + (data)->scoresumweight * (sum))
    75
    76/** branching rule data */
    77struct SCIP_BranchruleData
    78{
    79 SCIP_RANDNUMGEN* randnumgen; /**< random number generator */
    80
    81 char strategy; /**< strategy for computing score of external candidates */
    82 SCIP_Real scoreminweight; /**< weight for minimum of scores of a branching candidate */
    83 SCIP_Real scoremaxweight; /**< weight for maximum of scores of a branching candidate */
    84 SCIP_Real scoresumweight; /**< weight for sum of scores of a branching candidate */
    85
    86 char updatestrategy; /**< strategy used to update pseudo costs of continuous variables */
    87
    88 int nchildren; /**< targeted number of children in n-ary branching */
    89 int narymaxdepth; /**< maximal depth where to do n-ary branching, -1 to turn off */
    90 SCIP_Real naryminwidth; /**< minimal domain width in children when doing n-ary branching, relative to global bounds */
    91 SCIP_Real narywidthfactor; /**< factor of domain width in n-ary branching */
    92 SCIP_Real discountfactor; /**< discount factor for discounted pseudo costs.*/
    93};
    94
    95/*
    96 * Local methods
    97 */
    98
    99/** checks if a given branching candidate is better than a previous one and updates the best branching candidate accordingly */
    100static
    102 SCIP* scip, /**< SCIP data structure */
    103 SCIP_BRANCHRULEDATA* branchruledata, /**< branching rule data */
    104 SCIP_VAR** bestvar, /**< best branching candidate */
    105 SCIP_Real* bestbrpoint, /**< branching point for best branching candidate */
    106 SCIP_Real* bestscore, /**< score of best branching candidate */
    107 SCIP_Real* bestrndscore, /**< random score of the best branching candidate */
    108 SCIP_VAR* cand, /**< branching candidate to consider */
    109 SCIP_Real candscoremin, /**< minimal score of branching candidate */
    110 SCIP_Real candscoremax, /**< maximal score of branching candidate */
    111 SCIP_Real candscoresum, /**< sum of scores of branching candidate */
    112 SCIP_Real candrndscore, /**< random score of branching candidate */
    113 SCIP_Real candsol /**< proposed branching point of branching candidate */
    114 )
    115{
    116 SCIP_Real candbrpoint;
    117 SCIP_Real branchscore;
    118
    119 SCIP_Real deltaminus;
    120 SCIP_Real deltaplus;
    121
    122 SCIP_Real pscostdown;
    123 SCIP_Real pscostup;
    124
    125 SCIP_VARTYPE besttype;
    126 SCIP_VARTYPE candtype;
    127
    128 char strategy;
    129
    130 assert(scip != NULL);
    131 assert(branchruledata != NULL);
    132 assert(bestvar != NULL);
    133 assert(bestbrpoint != NULL);
    134 assert(bestscore != NULL);
    135 assert(cand != NULL);
    136
    137 /* a branching variable candidate should either be an active problem variable or a multi-aggregated variable */
    138 assert(SCIPvarIsActive(SCIPvarGetProbvar(cand)) ||
    140
    142 {
    143 /* for a multi-aggregated variable, we call updateBestCandidate function recursively with all variables in the multi-aggregation */
    144 SCIP_VAR** multvars;
    145 int nmultvars;
    146 int i;
    147 SCIP_Bool success;
    148 SCIP_Real multvarlb;
    149 SCIP_Real multvarub;
    150
    151 cand = SCIPvarGetProbvar(cand);
    152 multvars = SCIPvarGetMultaggrVars(cand);
    153 nmultvars = SCIPvarGetMultaggrNVars(cand);
    154
    155 /* if we have a candidate branching point, then first register only aggregation variables
    156 * for which we can compute a corresponding branching point too (see also comments below)
    157 * if this fails, then register all (unfixed) aggregation variables, thereby forgetting about candsol
    158 */
    159 success = FALSE;
    160 if( candsol != SCIP_INVALID ) /*lint !e777*/
    161 {
    162 SCIP_Real* multscalars;
    163 SCIP_Real minact;
    164 SCIP_Real maxact;
    165 SCIP_Real aggrvarsol;
    166 SCIP_Real aggrvarsol1;
    167 SCIP_Real aggrvarsol2;
    168
    169 multscalars = SCIPvarGetMultaggrScalars(cand);
    170
    171 /* for computing the branching point, we need the current bounds of the multi-aggregated variable */
    172 minact = SCIPcomputeVarLbLocal(scip, cand);
    173 maxact = SCIPcomputeVarUbLocal(scip, cand);
    174
    175 for( i = 0; i < nmultvars; ++i )
    176 {
    177 /* skip fixed variables */
    178 multvarlb = SCIPcomputeVarLbLocal(scip, multvars[i]);
    179 multvarub = SCIPcomputeVarUbLocal(scip, multvars[i]);
    180 if( SCIPisEQ(scip, multvarlb, multvarub) )
    181 continue;
    182
    183 assert(multscalars != NULL);
    184 assert(multscalars[i] != 0.0);
    185
    186 /* we cannot ensure that both the upper bound in the left node and the lower bound in the right node
    187 * will be candsol by a clever choice for the branching point of multvars[i],
    188 * but we can try to ensure that at least one of them will be at candsol
    189 */
    190 if( multscalars[i] > 0.0 )
    191 {
    192 /* cand >= candsol
    193 * if multvars[i] >= (candsol - (maxact - multscalars[i] * ub(multvars[i]))) / multscalars[i]
    194 * = (candsol - maxact) / multscalars[i] + ub(multvars[i])
    195 */
    196 aggrvarsol1 = (candsol - maxact) / multscalars[i] + multvarub;
    197
    198 /* cand <= candsol
    199 * if multvars[i] <= (candsol - (minact - multscalar[i] * lb(multvars[i]))) / multscalars[i]
    200 * = (candsol - minact) / multscalars[i] + lb(multvars[i])
    201 */
    202 aggrvarsol2 = (candsol - minact) / multscalars[i] + multvarlb;
    203 }
    204 else
    205 {
    206 /* cand >= candsol
    207 * if multvars[i] <= (candsol - (maxact - multscalars[i] * lb(multvars[i]))) / multscalars[i]
    208 * = (candsol - maxact) / multscalars[i] + lb(multvars[i])
    209 */
    210 aggrvarsol2 = (candsol - maxact) / multscalars[i] + multvarlb;
    211
    212 /* cand <= candsol
    213 * if multvars[i] >= (candsol - (minact - multscalar[i] * ub(multvars[i]))) / multscalars[i]
    214 * = (candsol - minact) / multscalars[i] + ub(multvars[i])
    215 */
    216 aggrvarsol1 = (candsol - minact) / multscalars[i] + multvarub;
    217 }
    218
    219 /* by the above choice, aggrvarsol1 <= ub(multvars[i]) and aggrvarsol2 >= lb(multvars[i])
    220 * if aggrvarsol1 <= lb(multvars[i]) or aggrvarsol2 >= ub(multvars[i]), then choose the other one
    221 * if both are out of bounds, then give up
    222 * if both are inside bounds, then choose the one closer to 0.0 (someone has better idea???)
    223 */
    224 if( SCIPisFeasLE(scip, aggrvarsol1, multvarlb) )
    225 {
    226 if( SCIPisFeasGE(scip, aggrvarsol2, multvarub) )
    227 continue;
    228 else
    229 aggrvarsol = aggrvarsol2;
    230 }
    231 else
    232 {
    233 if( SCIPisFeasGE(scip, aggrvarsol2, multvarub) )
    234 aggrvarsol = aggrvarsol1;
    235 else
    236 aggrvarsol = REALABS(aggrvarsol1) < REALABS(aggrvarsol2) ? aggrvarsol1 : aggrvarsol2;
    237 }
    238 success = TRUE;
    239
    240 SCIP_CALL( updateBestCandidate(scip, branchruledata, bestvar, bestbrpoint, bestscore, bestrndscore,
    241 multvars[i], candscoremin, candscoremax, candscoresum, candrndscore, aggrvarsol) );
    242 }
    243 }
    244
    245 if( !success )
    246 for( i = 0; i < nmultvars; ++i )
    247 {
    248 /* skip fixed variables */
    249 multvarlb = SCIPcomputeVarLbLocal(scip, multvars[i]);
    250 multvarub = SCIPcomputeVarUbLocal(scip, multvars[i]);
    251 if( SCIPisEQ(scip, multvarlb, multvarub) )
    252 continue;
    253
    254 SCIP_CALL( updateBestCandidate(scip, branchruledata, bestvar, bestbrpoint, bestscore, bestrndscore,
    255 multvars[i], candscoremin, candscoremax, candscoresum, candrndscore, SCIP_INVALID) );
    256 }
    257
    258 assert(*bestvar != NULL); /* if all variables were fixed, something is strange */
    259
    260 return SCIP_OKAY;
    261 }
    262
    263 /* select branching point for this variable */
    264 candbrpoint = SCIPgetBranchingPoint(scip, cand, candsol);
    265 assert(candbrpoint >= SCIPvarGetLbLocal(cand));
    266 assert(candbrpoint <= SCIPvarGetUbLocal(cand));
    267
    268 /* we cannot branch on a huge value for a discrete variable, because we simply cannot enumerate such huge integer values in floating point
    269 * arithmetics
    270 */
    271 if( SCIPvarIsIntegral(cand) && (SCIPisHugeValue(scip, candbrpoint) || SCIPisHugeValue(scip, -candbrpoint)) )
    272 return SCIP_OKAY;
    273
    274 assert(!SCIPvarIsIntegral(cand) || !SCIPisIntegral(scip, candbrpoint));
    275
    276 if( !SCIPvarIsIntegral(cand) )
    277 strategy = (branchruledata->strategy == 'u' ? branchruledata->updatestrategy : branchruledata->strategy);
    278 else
    279 strategy = (branchruledata->strategy == 'u' ? 'l' : branchruledata->strategy);
    280
    281 switch( strategy )
    282 {
    283 case 'l':
    284 if( SCIPisInfinity(scip, SCIPgetSolVal(scip, NULL, cand)) || SCIPgetSolVal(scip, NULL, cand) <= SCIPadjustedVarUb(scip, cand, candbrpoint) )
    285 deltaminus = 0.0;
    286 else
    287 deltaminus = SCIPgetSolVal(scip, NULL, cand) - SCIPadjustedVarUb(scip, cand, candbrpoint);
    288 if( SCIPisInfinity(scip, -SCIPgetSolVal(scip, NULL, cand)) || SCIPgetSolVal(scip, NULL, cand) >= SCIPadjustedVarLb(scip, cand, candbrpoint) )
    289 deltaplus = 0.0;
    290 else
    291 deltaplus = SCIPadjustedVarLb(scip, cand, candbrpoint) - SCIPgetSolVal(scip, NULL, cand);
    292 break;
    293
    294 case 'd':
    296 deltaminus = SCIPisInfinity(scip, candscoremax) ? SCIPinfinity(scip) : WEIGHTEDSCORING(branchruledata, candscoremin, candscoremax, candscoresum);
    297 else
    298 deltaminus = SCIPadjustedVarUb(scip, cand, candbrpoint) - SCIPvarGetLbLocal(cand);
    299
    301 deltaplus = SCIPisInfinity(scip, candscoremax) ? SCIPinfinity(scip) : WEIGHTEDSCORING(branchruledata, candscoremin, candscoremax, candscoresum);
    302 else
    303 deltaplus = SCIPvarGetUbLocal(cand) - SCIPadjustedVarLb(scip, cand, candbrpoint);
    304 break;
    305
    306 case 's':
    308 deltaplus = SCIPisInfinity(scip, candscoremax) ? SCIPinfinity(scip) : WEIGHTEDSCORING(branchruledata, candscoremin, candscoremax, candscoresum);
    309 else
    310 deltaplus = SCIPadjustedVarUb(scip, cand, candbrpoint) - SCIPvarGetLbLocal(cand);
    311
    313 deltaminus = SCIPisInfinity(scip, candscoremax) ? SCIPinfinity(scip) : WEIGHTEDSCORING(branchruledata, candscoremin, candscoremax, candscoresum);
    314 else
    315 deltaminus = SCIPvarGetUbLocal(cand) - SCIPadjustedVarLb(scip, cand, candbrpoint);
    316 break;
    317
    318 case 'v':
    319 deltaplus = SCIPisInfinity(scip, candscoremax) ? SCIPinfinity(scip) : WEIGHTEDSCORING(branchruledata, candscoremin, candscoremax, candscoresum);
    320 deltaminus = deltaplus;
    321 break;
    322
    323 default :
    324 SCIPerrorMessage("branching strategy %c unknown\n", strategy);
    325 SCIPABORT();
    326 return SCIP_INVALIDDATA; /*lint !e527*/
    327 }
    328
    329 if( SCIPisInfinity(scip, deltaminus) || SCIPisInfinity(scip, deltaplus) )
    330 {
    331 branchscore = SCIPinfinity(scip);
    332 }
    333 else
    334 {
    335 pscostdown = SCIPgetVarPseudocostVal(scip, cand, -deltaminus);
    336 pscostup = SCIPgetVarPseudocostVal(scip, cand, deltaplus);
    337 branchscore = SCIPgetBranchScore(scip, cand, pscostdown, pscostup);
    338 assert(!SCIPisNegative(scip, branchscore));
    339 }
    340 SCIPdebugMsg(scip, "branching score variable <%s>[%g,%g] = %g; wscore = %g; type=%d bestbrscore=%g\n",
    341 SCIPvarGetName(cand), SCIPvarGetLbLocal(cand), SCIPvarGetUbLocal(cand), branchscore, WEIGHTEDSCORING(branchruledata, candscoremin, candscoremax, candscoresum),
    342 SCIPvarGetType(cand), *bestscore);
    343
    344 if( SCIPisInfinity(scip, branchscore) )
    345 branchscore = 0.9*SCIPinfinity(scip);
    346
    347 if( SCIPisSumGT(scip, branchscore, *bestscore) )
    348 {
    349 (*bestscore) = branchscore;
    350 (*bestrndscore) = candrndscore;
    351 (*bestvar) = cand;
    352 (*bestbrpoint) = candbrpoint;
    353 return SCIP_OKAY;
    354 }
    355
    356 /* if score of candidate is worse than bestscore, stay with best candidate */
    357 if( !SCIPisSumEQ(scip, branchscore, *bestscore) )
    358 return SCIP_OKAY;
    359
    361 {
    362 /* best candidate is unbounded -> we prefer to branch on it */
    364 SCIPrandomGetReal(branchruledata->randnumgen, 0.0, 1.0) <= 0.5
    365 )
    366 {
    367 /* but if the new candidate is also unbounded (thus as good as best candidate),
    368 * then switch to the candidate with 50% probability to reduce performance variability
    369 */
    370 (*bestscore) = branchscore;
    371 (*bestrndscore) = candrndscore;
    372 (*bestvar) = cand;
    373 (*bestbrpoint) = candbrpoint;
    374 }
    375
    376 return SCIP_OKAY;
    377 }
    378
    379 /* best candidate has a finite lower or upper bound -> consider taking the other candidate */
    380
    383 {
    384 /* both candidates are unbounded, but one side may be finite (for bestcand we know there is one)
    385 * take the candidate with the larger bound on the bounded side (hope that this avoids branching on always the same variable)
    386 * this will also prefer unbounded variables over bounded ones
    387 */
    388 if( SCIPvarGetUbLocal(cand) > SCIPvarGetUbLocal(*bestvar) || SCIPvarGetLbLocal(cand) < SCIPvarGetLbLocal(*bestvar) )
    389 {
    390 /* cand is better than bestvar */
    391 (*bestscore) = branchscore;
    392 (*bestrndscore) = candrndscore;
    393 (*bestvar) = cand;
    394 (*bestbrpoint) = candbrpoint;
    395 return SCIP_OKAY;
    396 }
    397
    398 if( SCIPvarGetUbLocal(*bestvar) > SCIPvarGetUbLocal(cand) || SCIPvarGetLbLocal(*bestvar) < SCIPvarGetLbLocal(cand) )
    399 {
    400 /* bestvar is better than cand */
    401 return SCIP_OKAY;
    402 }
    403
    404 /* both are equally good */
    405 }
    406
    407 /* @TODO: handle implied integrality like in relpscost */
    410
    411 if( besttype == candtype )
    412 {
    413 /* if both have the same type, take the one with larger relative diameter */
    415 {
    416 /* cand has larger diameter than bestvar*/
    417 (*bestscore) = branchscore;
    418 (*bestrndscore) = candrndscore;
    419 (*bestvar) = cand;
    420 (*bestbrpoint) = candbrpoint;
    421 return SCIP_OKAY;
    422 }
    423
    425 {
    426 /* bestvar has larger diameter than cand */
    427 return SCIP_OKAY;
    428 }
    429 }
    430
    431 /* take the one with better type ("more discrete") */
    432 if( besttype > candtype )
    433 {
    434 /* cand is more discrete than bestvar */
    435 (*bestscore) = branchscore;
    436 (*bestrndscore) = candrndscore;
    437 (*bestvar) = cand;
    438 (*bestbrpoint) = candbrpoint;
    439 return SCIP_OKAY;
    440 }
    441 if( besttype < candtype )
    442 {
    443 /* bestvar is more discrete than cand */
    444 return SCIP_OKAY;
    445 }
    446
    447 /* cand seems to be as good as the currently best one (bestvar); use the random score as a final tie-breaker */
    448 if( candrndscore >= (*bestrndscore) )
    449 {
    450 (*bestscore) = branchscore;
    451 (*bestrndscore) = candrndscore;
    452 (*bestvar) = cand;
    453 (*bestbrpoint) = candbrpoint;
    454 }
    455
    456 return SCIP_OKAY;
    457}
    458
    459/** selects the branching variable from given candidate array */
    460static
    462 SCIP* scip, /**< SCIP data structure */
    463 SCIP_BRANCHRULE* branchrule, /**< branching rule */
    464 SCIP_VAR** cands, /**< array of branching candidates */
    465 SCIP_Real* candssol, /**< array of candidate solution values */
    466 SCIP_Real* candsscore, /**< array of candidate scores */
    467 int ncands, /**< the number of candidates */
    468 SCIP_VAR** brvar, /**< pointer to store the selected branching candidate or NULL if none */
    469 SCIP_Real* brpoint /**< pointer to store branching point of selected branching variable */
    470 )
    471{ /*lint --e{850}*/
    472 SCIP_BRANCHRULEDATA* branchruledata;
    473
    474 SCIP_VAR* cand;
    475 SCIP_Real candsol;
    476
    477 SCIP_Real bestbranchscore;
    478 SCIP_Real bestrndscore;
    479
    480 SCIP_Real scoremin;
    481 SCIP_Real scoresum;
    482 SCIP_Real scoremax;
    483
    484 SCIP_VAR** candssorted;
    485 int* candsorigidx;
    486
    487 int i;
    488 int j;
    489
    490 assert(brvar != NULL);
    491 assert(brpoint != NULL);
    492
    493 (*brvar) = NULL;
    494 (*brpoint) = SCIP_INVALID;
    495
    496 if( ncands == 0 )
    497 return SCIP_OKAY;
    498
    499 branchruledata = SCIPbranchruleGetData(branchrule);
    500 assert(branchruledata != NULL);
    501
    502 /* sort branching candidates (in a copy), such that same variables are on consecutive positions */
    503 SCIP_CALL( SCIPduplicateBufferArray(scip, &candssorted, cands, ncands) );
    504 SCIP_CALL( SCIPallocBufferArray(scip, &candsorigidx, ncands) );
    505 for( i = 0; i < ncands; ++i )
    506 candsorigidx[i] = i;
    507
    508 SCIPsortPtrInt((void**)candssorted, candsorigidx, SCIPvarComp, ncands);
    509
    510 bestbranchscore = -1.0;
    511 bestrndscore = -1.0;
    512
    513 for( i = 0; i < ncands; ++i )
    514 {
    515 cand = candssorted[i];
    516
    517 /* there should be no fixed branching candidates */
    518 assert(!SCIPisEQ(scip, SCIPvarGetLbLocal(cand), SCIPvarGetUbLocal(cand)));
    519
    520 /* compute min, sum, and max of all registered scores for this variables
    521 * set candsol to a valid value, if someone registered one */
    522 scoremin = candsscore[candsorigidx[i]];
    523 scoresum = scoremin;
    524 scoremax = scoremin;
    525 candsol = candssol[candsorigidx[i]];
    526 for( j = i+1 ; j < ncands && SCIPvarCompare(candssorted[j], cand) == 0; ++j )
    527 {
    528 assert(candsscore[candsorigidx[j]] >= 0.0);
    529 scoresum += candsscore[candsorigidx[j]];
    530 if( candsscore[candsorigidx[j]] < scoremin )
    531 scoremin = candsscore[candsorigidx[j]];
    532 else if( candsscore[candsorigidx[j]] > scoremax )
    533 scoremax = candsscore[candsorigidx[j]];
    534
    535 /* @todo if there are two valid externcandssol available for the same variable, should we take the one closer to the middle of the domain? */
    536 if( SCIPisInfinity(scip, REALABS(candsol)) )
    537 candsol = candssol[candsorigidx[j]];
    538 }
    539 /* set i to last occurrence of cand in candssorted (instead of first one as before), so in next round we look at another variable */
    540 i = j-1;
    541 assert(candssorted[i] == cand);
    542
    543 /* check if new candidate is better than previous candidate (if any) */
    544 SCIP_CALL( updateBestCandidate(scip, branchruledata, brvar, brpoint, &bestbranchscore, &bestrndscore, cand,
    545 scoremin, scoremax, scoresum, SCIPrandomGetReal(branchruledata->randnumgen, 0.0, 1.0), candsol) );
    546 }
    547
    548 /* there were candidates, but no variable was selected; this can only happen if the branching points are huge values
    549 * for all non-continuous variables on which we cannot branch
    550 * @todo delay the node?
    551 */
    552 if( (*brvar) == NULL )
    553 {
    554 SCIPerrorMessage("no branching could be created: all external candidates have huge bounds\n");
    555 return SCIP_BRANCHERROR; /*lint !e527*/
    556 }
    557
    558 /* free buffer arrays */
    559 SCIPfreeBufferArray(scip, &candsorigidx);
    560 SCIPfreeBufferArray(scip, &candssorted);
    561
    562 return SCIP_OKAY;
    563}
    564
    565/*
    566 * Callback methods
    567 */
    568
    569/** copy method for branchrule plugins (called when SCIP copies plugins) */
    570static
    571SCIP_DECL_BRANCHCOPY(branchCopyPscost)
    572{ /*lint --e{715}*/
    573 assert(scip != NULL);
    574 assert(branchrule != NULL);
    575 assert(strcmp(SCIPbranchruleGetName(branchrule), BRANCHRULE_NAME) == 0);
    576
    577 /* call inclusion method of branchrule */
    579
    580 return SCIP_OKAY;
    581}
    582
    583/** destructor of branching rule to free user data (called when SCIP is exiting) */
    584static
    585SCIP_DECL_BRANCHFREE(branchFreePscost)
    586{ /*lint --e{715}*/
    587 SCIP_BRANCHRULEDATA* branchruledata;
    588
    589 /* get branching rule data */
    590 branchruledata = SCIPbranchruleGetData(branchrule);
    591 assert(branchruledata != NULL);
    592
    593 /* free random number generator */
    594 SCIPfreeRandom(scip, &branchruledata->randnumgen);
    595
    596 /* free branching rule data */
    597 SCIPfreeBlockMemory(scip, &branchruledata);
    598 SCIPbranchruleSetData(branchrule, NULL);
    599
    600 return SCIP_OKAY;
    601}
    602
    603/** initialization method of branching rule (called after problem was transformed) */
    604static
    605SCIP_DECL_BRANCHINIT(branchInitPscost)
    606{ /*lint --e{715}*/
    607 SCIP_BRANCHRULEDATA* branchruledata;
    608
    609 /* initialize branching rule data */
    610 branchruledata = SCIPbranchruleGetData(branchrule);
    611 assert(branchruledata != NULL);
    612
    613 SCIPsetRandomSeed(scip, branchruledata->randnumgen, BRANCHRULE_RANDSEED_DEFAULT);
    614
    615 return SCIP_OKAY;
    616}
    617
    618/** branching execution method for fractional LP solutions */
    619static
    620SCIP_DECL_BRANCHEXECLP(branchExeclpPscost)
    621{ /*lint --e{715}*/
    622 SCIP_BRANCHRULEDATA* branchruledata;
    623 SCIP_VAR** lpcands;
    624 SCIP_Real* lpcandssol;
    625 SCIP_Real bestscore;
    626 SCIP_Real bestrootdiff;
    627 int nlpcands;
    628 int bestcand;
    629 int c;
    630
    631 assert(branchrule != NULL);
    632 assert(strcmp(SCIPbranchruleGetName(branchrule), BRANCHRULE_NAME) == 0);
    633 assert(scip != NULL);
    634 assert(result != NULL);
    635
    636 branchruledata = SCIPbranchruleGetData(branchrule);
    637 assert(branchruledata != NULL);
    638
    639 SCIPdebugMsg(scip, "Execlp method of pscost branching\n");
    640
    641 /* get branching candidates */
    642 SCIP_CALL( SCIPgetLPBranchCands(scip, &lpcands, &lpcandssol, NULL, NULL, &nlpcands, NULL) );
    643 assert(nlpcands > 0);
    644
    645 bestcand = -1;
    646 bestscore = -SCIPinfinity(scip);
    647 bestrootdiff = 0.0;
    648 for( c = 0; c < nlpcands; ++c )
    649 {
    650 SCIP_Real score;
    651 SCIP_Real rootsolval;
    652 SCIP_Real rootdiff;
    653
    654 score = SCIPgetVarDPseudocostScore(scip, lpcands[c], lpcandssol[c], branchruledata->discountfactor);
    655 rootsolval = SCIPvarGetRootSol(lpcands[c]);
    656 rootdiff = REALABS(lpcandssol[c] - rootsolval);
    657 if( SCIPisSumGT(scip, score, bestscore) || (SCIPisSumEQ(scip, score, bestscore) && rootdiff > bestrootdiff) )
    658 {
    659 bestcand = c;
    660 bestscore = score;
    661 bestrootdiff = rootdiff;
    662 }
    663 }
    664 assert(0 <= bestcand && bestcand < nlpcands);
    665 assert(!SCIPisFeasIntegral(scip, lpcandssol[bestcand]));
    666 assert(!SCIPisFeasIntegral(scip, SCIPvarGetSol(lpcands[bestcand], TRUE)));
    667
    668 /* perform the branching */
    669 SCIPdebugMsg(scip, " -> %d cands, selected cand %d: variable <%s> (solval=%g, score=%g)\n",
    670 nlpcands, bestcand, SCIPvarGetName(lpcands[bestcand]), lpcandssol[bestcand], bestscore);
    671
    672 /* perform the branching */
    673 SCIP_CALL( SCIPbranchVar(scip, lpcands[bestcand], NULL, NULL, NULL) );
    674 *result = SCIP_BRANCHED;
    675
    676 return SCIP_OKAY;
    677}
    678
    679
    680/** branching execution method for external candidates
    681 *
    682 * @todo extend discounted pseudocosts for non-linear problems
    683 */
    684static
    685SCIP_DECL_BRANCHEXECEXT(branchExecextPscost)
    686{ /*lint --e{715}*/
    687 SCIP_BRANCHRULEDATA* branchruledata;
    688 SCIP_VAR** externcands;
    689 SCIP_Real* externcandssol;
    690 SCIP_Real* externcandsscore;
    691 int nprioexterncands;
    692 SCIP_VAR* brvar;
    693 SCIP_Real brpoint;
    694 int nchildren;
    695
    696 assert(branchrule != NULL);
    697 assert(strcmp(SCIPbranchruleGetName(branchrule), BRANCHRULE_NAME) == 0);
    698 assert(scip != NULL);
    699 assert(result != NULL);
    700
    701 branchruledata = SCIPbranchruleGetData(branchrule);
    702 assert(branchruledata != NULL);
    703
    704 SCIPdebugMsg(scip, "Execext method of pscost branching\n");
    705
    706 /* get branching candidates */
    707 SCIP_CALL( SCIPgetExternBranchCands(scip, &externcands, &externcandssol, &externcandsscore, NULL, &nprioexterncands, NULL, NULL, NULL) );
    708 assert(nprioexterncands > 0);
    709
    710 /* get current update strategy for pseudo costs, if our multiplier rule is 'u' */
    711 if( branchruledata->strategy == 'u' )
    712 {
    713 SCIP_CALL( SCIPgetCharParam(scip, "branching/lpgainnormalize", &branchruledata->updatestrategy) );
    714 }
    715
    716 /* select branching variable */
    717 SCIP_CALL( selectBranchVar(scip, branchrule, externcands, externcandssol, externcandsscore, nprioexterncands, &brvar, &brpoint) );
    718
    719 if( brvar == NULL )
    720 {
    721 /* can happen if all candidates were non-continous variables with huge bounds */
    722 *result = SCIP_DIDNOTFIND;
    723 return SCIP_OKAY;
    724 }
    725
    726 assert(SCIPvarIsActive(SCIPvarGetProbvar(brvar)));
    727
    728 SCIPdebugMsg(scip, "branching on variable <%s>: new intervals: [%g, %g] and [%g, %g]\n",
    729 SCIPvarGetName(brvar), SCIPvarGetLbLocal(brvar), SCIPadjustedVarUb(scip, brvar, brpoint), SCIPadjustedVarLb(scip, brvar, brpoint), SCIPvarGetUbLocal(brvar));
    730
    731 if( branchruledata->nchildren > 2 && SCIPnodeGetDepth(SCIPgetCurrentNode(scip)) <= branchruledata->narymaxdepth )
    732 {
    733 /* do n-ary branching */
    734 SCIP_Real minwidth;
    735
    736 minwidth = 0.0;
    738 minwidth = branchruledata->naryminwidth * (SCIPvarGetUbGlobal(brvar) - SCIPvarGetLbGlobal(brvar));
    739
    740 SCIP_CALL( SCIPbranchVarValNary(scip, brvar, brpoint, branchruledata->nchildren, minwidth, branchruledata->narywidthfactor, &nchildren) );
    741 }
    742 else
    743 {
    744 /* do binary branching */
    745 SCIP_CALL( SCIPbranchVarValNary(scip, brvar, brpoint, 2, 0.0, 1.0, &nchildren) );
    746 }
    747
    748 if( nchildren > 1 )
    749 {
    750 *result = SCIP_BRANCHED;
    751 }
    752 else
    753 {
    754 /* if there are no children, then variable should have been fixed by SCIPbranchVarVal */
    755 assert(SCIPisEQ(scip, SCIPvarGetLbLocal(brvar), SCIPvarGetUbLocal(brvar)));
    756 *result = SCIP_REDUCEDDOM;
    757 }
    758
    759 return SCIP_OKAY;
    760}
    761
    762
    763/*
    764 * branching specific interface methods
    765 */
    766
    767/** creates the pseudo cost branching rule and includes it in SCIP */
    769 SCIP* scip /**< SCIP data structure */
    770 )
    771{
    772 SCIP_BRANCHRULEDATA* branchruledata;
    773 SCIP_BRANCHRULE* branchrule;
    774
    775 /* create pscost branching rule data */
    776 SCIP_CALL( SCIPallocBlockMemory(scip, &branchruledata) );
    777
    778 /* include allfullstrong branching rule */
    781
    782 assert(branchrule != NULL);
    783 /* create a random number generator */
    784 SCIP_CALL( SCIPcreateRandom(scip, &branchruledata->randnumgen,
    786
    787 /* set non-fundamental callbacks via specific setter functions*/
    788 SCIP_CALL( SCIPsetBranchruleCopy(scip, branchrule, branchCopyPscost) );
    789 SCIP_CALL( SCIPsetBranchruleFree(scip, branchrule, branchFreePscost) );
    790 SCIP_CALL( SCIPsetBranchruleInit(scip, branchrule, branchInitPscost) );
    791 SCIP_CALL( SCIPsetBranchruleExecLp(scip, branchrule, branchExeclpPscost) );
    792 SCIP_CALL( SCIPsetBranchruleExecExt(scip, branchrule, branchExecextPscost) );
    793
    794 SCIP_CALL( SCIPaddCharParam(scip, "branching/" BRANCHRULE_NAME "/strategy",
    795 "strategy for utilizing pseudo-costs of external branching candidates (multiply as in pseudo costs 'u'pdate rule, or by 'd'omain reduction, or by domain reduction of 's'ibling, or by 'v'ariable score)",
    796 &branchruledata->strategy, FALSE, BRANCHRULE_STRATEGY_DEFAULT, BRANCHRULE_STRATEGIES, NULL, NULL) );
    797
    798 SCIP_CALL( SCIPaddRealParam(scip, "branching/" BRANCHRULE_NAME "/minscoreweight",
    799 "weight for minimum of scores of a branching candidate when building weighted sum of min/max/sum of scores",
    800 &branchruledata->scoreminweight, TRUE, BRANCHRULE_SCOREMINWEIGHT_DEFAULT, -SCIPinfinity(scip), SCIPinfinity(scip), NULL, NULL) );
    801
    802 SCIP_CALL( SCIPaddRealParam(scip, "branching/" BRANCHRULE_NAME "/maxscoreweight",
    803 "weight for maximum of scores of a branching candidate when building weighted sum of min/max/sum of scores",
    804 &branchruledata->scoremaxweight, TRUE, BRANCHRULE_SCOREMAXWEIGHT_DEFAULT, -SCIPinfinity(scip), SCIPinfinity(scip), NULL, NULL) );
    805
    806 SCIP_CALL( SCIPaddRealParam(scip, "branching/" BRANCHRULE_NAME "/sumscoreweight",
    807 "weight for sum of scores of a branching candidate when building weighted sum of min/max/sum of scores",
    808 &branchruledata->scoresumweight, TRUE, BRANCHRULE_SCORESUMWEIGHT_DEFAULT, -SCIPinfinity(scip), SCIPinfinity(scip), NULL, NULL) );
    809
    810 SCIP_CALL( SCIPaddIntParam(scip, "branching/" BRANCHRULE_NAME "/nchildren",
    811 "number of children to create in n-ary branching",
    812 &branchruledata->nchildren, FALSE, BRANCHRULE_NCHILDREN_DEFAULT, 2, INT_MAX, NULL, NULL) );
    813
    814 SCIP_CALL( SCIPaddIntParam(scip, "branching/" BRANCHRULE_NAME "/narymaxdepth",
    815 "maximal depth where to do n-ary branching, -1 to turn off",
    816 &branchruledata->narymaxdepth, FALSE, BRANCHRULE_NARYMAXDEPTH_DEFAULT, -1, INT_MAX, NULL, NULL) );
    817
    818 SCIP_CALL( SCIPaddRealParam(scip, "branching/" BRANCHRULE_NAME "/naryminwidth",
    819 "minimal domain width in children when doing n-ary branching, relative to global bounds",
    820 &branchruledata->naryminwidth, FALSE, BRANCHRULE_NARYMINWIDTH_DEFAULT, 0.0, 1.0, NULL, NULL) );
    821
    822 SCIP_CALL( SCIPaddRealParam(scip, "branching/" BRANCHRULE_NAME "/narywidthfactor",
    823 "factor of domain width in n-ary branching when creating nodes with increasing distance from branching value",
    824 &branchruledata->narywidthfactor, FALSE, BRANCHRULE_NARYWIDTHFAC_DEFAULT, 1.0, SCIP_REAL_MAX, NULL, NULL) );
    825
    826 SCIP_CALL( SCIPaddRealParam(scip, "branching/" BRANCHRULE_NAME "/discountfactor",
    827 "discount factor for ancestral pseudo costs (0.0: disable discounted pseudo costs)",
    828 &branchruledata->discountfactor, FALSE, BRANCHRULE_DISCOUNTFACTOR, 0.0, 1.0, NULL, NULL) );
    829
    830 return SCIP_OKAY;
    831}
    832
    833/** selects a branching variable, due to pseudo cost, from the given candidate array and returns this variable together
    834 * with a branching point */
    836 SCIP* scip, /**< SCIP data structure */
    837 SCIP_VAR** branchcands, /**< branching candidates */
    838 SCIP_Real* branchcandssol, /**< solution value for the branching candidates */
    839 SCIP_Real* branchcandsscore, /**< array of candidate scores */
    840 int nbranchcands, /**< number of branching candidates */
    841 SCIP_VAR** var, /**< pointer to store the variable to branch on, or NULL if none */
    842 SCIP_Real* brpoint /**< pointer to store the branching point for the branching variable, will be fractional for a discrete variable */
    843 )
    844{
    845 SCIP_BRANCHRULE* branchrule;
    846
    847 assert(scip != NULL);
    848
    849 /* find branching rule */
    851 assert(branchrule != NULL);
    852
    853 /* select branching variable */
    854 SCIP_CALL( selectBranchVar(scip, branchrule, branchcands, branchcandssol, branchcandsscore, nbranchcands, var, brpoint) );
    855
    856 return SCIP_OKAY;
    857}
    #define BRANCHRULE_DESC
    Definition: branch_pscost.c:55
    static SCIP_DECL_BRANCHFREE(branchFreePscost)
    static SCIP_DECL_BRANCHEXECLP(branchExeclpPscost)
    #define BRANCHRULE_NCHILDREN_DEFAULT
    Definition: branch_pscost.c:65
    #define BRANCHRULE_PRIORITY
    Definition: branch_pscost.c:56
    #define BRANCHRULE_DISCOUNTFACTOR
    Definition: branch_pscost.c:70
    static SCIP_DECL_BRANCHEXECEXT(branchExecextPscost)
    #define BRANCHRULE_NARYMAXDEPTH_DEFAULT
    Definition: branch_pscost.c:66
    static SCIP_RETCODE selectBranchVar(SCIP *scip, SCIP_BRANCHRULE *branchrule, SCIP_VAR **cands, SCIP_Real *candssol, SCIP_Real *candsscore, int ncands, SCIP_VAR **brvar, SCIP_Real *brpoint)
    static SCIP_DECL_BRANCHINIT(branchInitPscost)
    #define BRANCHRULE_NAME
    Definition: branch_pscost.c:54
    #define BRANCHRULE_SCOREMAXWEIGHT_DEFAULT
    Definition: branch_pscost.c:63
    static SCIP_RETCODE updateBestCandidate(SCIP *scip, SCIP_BRANCHRULEDATA *branchruledata, SCIP_VAR **bestvar, SCIP_Real *bestbrpoint, SCIP_Real *bestscore, SCIP_Real *bestrndscore, SCIP_VAR *cand, SCIP_Real candscoremin, SCIP_Real candscoremax, SCIP_Real candscoresum, SCIP_Real candrndscore, SCIP_Real candsol)
    #define BRANCHRULE_RANDSEED_DEFAULT
    Definition: branch_pscost.c:69
    #define BRANCHRULE_NARYMINWIDTH_DEFAULT
    Definition: branch_pscost.c:67
    #define WEIGHTEDSCORING(data, min, max, sum)
    Definition: branch_pscost.c:73
    #define BRANCHRULE_NARYWIDTHFAC_DEFAULT
    Definition: branch_pscost.c:68
    #define BRANCHRULE_SCOREMINWEIGHT_DEFAULT
    Definition: branch_pscost.c:62
    #define BRANCHRULE_SCORESUMWEIGHT_DEFAULT
    Definition: branch_pscost.c:64
    static SCIP_DECL_BRANCHCOPY(branchCopyPscost)
    #define BRANCHRULE_STRATEGY_DEFAULT
    Definition: branch_pscost.c:61
    #define BRANCHRULE_STRATEGIES
    Definition: branch_pscost.c:60
    #define BRANCHRULE_MAXDEPTH
    Definition: branch_pscost.c:57
    #define BRANCHRULE_MAXBOUNDDIST
    Definition: branch_pscost.c:58
    pseudo costs branching rule
    #define NULL
    Definition: def.h:248
    #define SCIP_REAL_MAX
    Definition: def.h:158
    #define SCIP_INVALID
    Definition: def.h:178
    #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 SCIPABORT()
    Definition: def.h:327
    #define REALABS(x)
    Definition: def.h:182
    #define SCIP_CALL(x)
    Definition: def.h:355
    SCIP_RETCODE SCIPselectBranchVarPscost(SCIP *scip, SCIP_VAR **branchcands, SCIP_Real *branchcandssol, SCIP_Real *branchcandsscore, int nbranchcands, SCIP_VAR **var, SCIP_Real *brpoint)
    SCIP_RETCODE SCIPincludeBranchrulePscost(SCIP *scip)
    #define SCIPdebugMsg
    Definition: scip_message.h:78
    SCIP_Real SCIPrelDiff(SCIP_Real val1, SCIP_Real val2)
    Definition: misc.c:11162
    SCIP_RETCODE SCIPaddCharParam(SCIP *scip, const char *name, const char *desc, char *valueptr, SCIP_Bool isadvanced, char defaultvalue, const char *allowedvalues, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
    Definition: scip_param.c:167
    SCIP_RETCODE SCIPaddIntParam(SCIP *scip, const char *name, const char *desc, int *valueptr, SCIP_Bool isadvanced, int defaultvalue, int minvalue, int maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
    Definition: scip_param.c:83
    SCIP_RETCODE 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 SCIPgetCharParam(SCIP *scip, const char *name, char *value)
    Definition: scip_param.c:326
    SCIP_RETCODE SCIPsetBranchruleExecExt(SCIP *scip, SCIP_BRANCHRULE *branchrule, SCIP_DECL_BRANCHEXECEXT((*branchexecext)))
    Definition: scip_branch.c:272
    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
    void SCIPbranchruleSetData(SCIP_BRANCHRULE *branchrule, SCIP_BRANCHRULEDATA *branchruledata)
    Definition: branch.c:1896
    SCIP_RETCODE SCIPgetExternBranchCands(SCIP *scip, SCIP_VAR ***externcands, SCIP_Real **externcandssol, SCIP_Real **externcandsscore, int *nexterncands, int *nprioexterncands, int *nprioexternbins, int *nprioexternints, int *nprioexternimpls)
    Definition: scip_branch.c:519
    SCIP_Real SCIPgetBranchingPoint(SCIP *scip, SCIP_VAR *var, SCIP_Real suggestion)
    Definition: scip_branch.c:905
    SCIP_RETCODE SCIPbranchVarValNary(SCIP *scip, SCIP_VAR *var, SCIP_Real val, int n, SCIP_Real minwidth, SCIP_Real widthfactor, int *nchildren)
    Definition: scip_branch.c:1196
    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 SCIPbranchVar(SCIP *scip, SCIP_VAR *var, SCIP_NODE **downchild, SCIP_NODE **eqchild, SCIP_NODE **upchild)
    Definition: scip_branch.c:1058
    SCIP_Real SCIPgetBranchScore(SCIP *scip, SCIP_VAR *var, SCIP_Real downgain, SCIP_Real upgain)
    Definition: scip_branch.c:857
    #define SCIPallocBufferArray(scip, ptr, num)
    Definition: scip_mem.h:124
    #define SCIPfreeBufferArray(scip, ptr)
    Definition: scip_mem.h:136
    #define SCIPduplicateBufferArray(scip, ptr, source, num)
    Definition: scip_mem.h:132
    #define SCIPfreeBlockMemory(scip, ptr)
    Definition: scip_mem.h:108
    #define SCIPallocBlockMemory(scip, ptr)
    Definition: scip_mem.h:89
    int SCIPnodeGetDepth(SCIP_NODE *node)
    Definition: tree.c:8493
    SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
    Definition: scip_sol.c:1765
    SCIP_Bool SCIPisFeasGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Real SCIPinfinity(SCIP *scip)
    SCIP_Bool SCIPisIntegral(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisHugeValue(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisFeasLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisSumEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisFeasIntegral(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisNegative(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisSumGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_NODE * SCIPgetCurrentNode(SCIP *scip)
    Definition: scip_tree.c:91
    SCIP_Real SCIPvarGetSol(SCIP_VAR *var, SCIP_Bool getlpval)
    Definition: var.c:19007
    SCIP_Bool SCIPvarIsActive(SCIP_VAR *var)
    Definition: var.c:23642
    SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
    Definition: var.c:23386
    SCIP_Bool SCIPvarIsImpliedIntegral(SCIP_VAR *var)
    Definition: var.c:23498
    SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
    Definition: var.c:24268
    SCIP_VAR * SCIPvarGetProbvar(SCIP_VAR *var)
    Definition: var.c:17550
    SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
    Definition: var.c:23453
    SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
    Definition: var.c:24142
    const char * SCIPvarGetName(SCIP_VAR *var)
    Definition: var.c:23267
    SCIP_Real SCIPgetVarDPseudocostScore(SCIP *scip, SCIP_VAR *var, SCIP_Real solval, SCIP_Real discountfac)
    Definition: scip_var.c:11570
    SCIP_Real SCIPadjustedVarUb(SCIP *scip, SCIP_VAR *var, SCIP_Real ub)
    Definition: scip_var.c:5634
    SCIP_Real SCIPvarGetRootSol(SCIP_VAR *var)
    Definition: var.c:19115
    SCIP_Real SCIPgetVarPseudocostVal(SCIP *scip, SCIP_VAR *var, SCIP_Real solvaldelta)
    Definition: scip_var.c:11188
    SCIP_Real SCIPadjustedVarLb(SCIP *scip, SCIP_VAR *var, SCIP_Real lb)
    Definition: scip_var.c:5570
    SCIP_Bool SCIPvarIsIntegral(SCIP_VAR *var)
    Definition: var.c:23490
    SCIP_VAR ** SCIPvarGetMultaggrVars(SCIP_VAR *var)
    Definition: var.c:23806
    int SCIPvarGetMultaggrNVars(SCIP_VAR *var)
    Definition: var.c:23794
    SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
    Definition: var.c:24234
    SCIP_Real SCIPcomputeVarLbLocal(SCIP *scip, SCIP_VAR *var)
    Definition: scip_var.c:8417
    SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
    Definition: var.c:24120
    int SCIPvarCompare(SCIP_VAR *var1, SCIP_VAR *var2)
    Definition: var.c:17274
    SCIP_Real SCIPcomputeVarUbLocal(SCIP *scip, SCIP_VAR *var)
    Definition: scip_var.c:8462
    SCIP_Real * SCIPvarGetMultaggrScalars(SCIP_VAR *var)
    Definition: var.c:23818
    void SCIPfreeRandom(SCIP *scip, SCIP_RANDNUMGEN **randnumgen)
    void SCIPsetRandomSeed(SCIP *scip, SCIP_RANDNUMGEN *randnumgen, unsigned int seed)
    SCIP_Real SCIPrandomGetReal(SCIP_RANDNUMGEN *randnumgen, SCIP_Real minrandval, SCIP_Real maxrandval)
    Definition: misc.c:10245
    SCIP_RETCODE SCIPcreateRandom(SCIP *scip, SCIP_RANDNUMGEN **randnumgen, unsigned int initialseed, SCIP_Bool useglobalseed)
    void SCIPsortPtrInt(void **ptrarray, int *intarray, SCIP_DECL_SORTPTRCOMP((*ptrcomp)), int len)
    memory allocation routines
    public methods for branching rules
    public methods for message output
    #define SCIPerrorMessage
    Definition: pub_message.h:64
    public data structures and miscellaneous methods
    methods for sorting joint arrays of various types
    public methods for branch and bound tree
    public methods for problem variables
    public methods for branching rule plugins and branching
    public methods for memory management
    public methods for message handling
    public methods for numerical tolerances
    public methods for SCIP parameter handling
    public methods for random numbers
    public methods for solutions
    public methods for the branch-and-bound tree
    public methods for SCIP variables
    struct SCIP_BranchruleData SCIP_BRANCHRULEDATA
    Definition: type_branch.h:57
    @ SCIP_REDUCEDDOM
    Definition: type_result.h:51
    @ SCIP_DIDNOTFIND
    Definition: type_result.h:44
    @ SCIP_BRANCHED
    Definition: type_result.h:54
    @ SCIP_BRANCHERROR
    Definition: type_retcode.h:60
    @ SCIP_INVALIDDATA
    Definition: type_retcode.h:52
    @ SCIP_OKAY
    Definition: type_retcode.h:42
    enum SCIP_Retcode SCIP_RETCODE
    Definition: type_retcode.h:63
    #define SCIP_DEPRECATED_VARTYPE_IMPLINT
    Definition: type_var.h:79
    @ SCIP_VARSTATUS_MULTAGGR
    Definition: type_var.h:56
    enum SCIP_Vartype SCIP_VARTYPE
    Definition: type_var.h:73