Scippy

    SCIP

    Solving Constraint Integer Programs

    branch_relpscost.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_relpscost.c
    26 * @ingroup DEFPLUGINS_BRANCH
    27 * @brief reliable pseudo costs branching rule
    28 * @author Tobias Achterberg
    29 * @author Timo Berthold
    30 * @author Gerald Gamrath
    31 * @author Gioni Mexi
    32 * @author Marc Pfetsch
    33 * @author Krunal Patel
    34 */
    35
    36/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
    37
    40#include "scip/treemodel.h"
    41#include "scip/cons_and.h"
    42#include "scip/pub_branch.h"
    43#include "scip/pub_cons.h"
    44#include "scip/scip_exact.h"
    45#include "scip/pub_message.h"
    46#include "scip/pub_misc.h"
    47#include "scip/pub_sol.h"
    48#include "scip/pub_tree.h"
    49#include "scip/pub_var.h"
    50#include "scip/scip_branch.h"
    51#include "scip/scip_cons.h"
    52#include "scip/scip_general.h"
    53#include "scip/scip_lp.h"
    54#include "scip/scip_mem.h"
    55#include "scip/scip_message.h"
    56#include "scip/scip_nlp.h"
    57#include "scip/scip_numerics.h"
    58#include "scip/scip_param.h"
    59#include "scip/scip_prob.h"
    61#include "scip/scip_sol.h"
    63#include "scip/scip_tree.h"
    64#include "scip/scip_var.h"
    65#include "scip/prop_symmetry.h"
    66#include "scip/symmetry.h"
    67#include <string.h>
    68
    69#define BRANCHRULE_NAME "relpscost"
    70#define BRANCHRULE_DESC "reliability branching on pseudo cost values"
    71#define BRANCHRULE_PRIORITY 10000
    72#define BRANCHRULE_MAXDEPTH -1
    73#define BRANCHRULE_MAXBOUNDDIST 1.0
    74
    75#define DEFAULT_CONFLICTWEIGHT 0.01 /**< weight in score calculations for conflict score */
    76#define DEFAULT_CONFLENGTHWEIGHT 0.0 /**< weight in score calculations for conflict length score*/
    77#define DEFAULT_INFERENCEWEIGHT 0.0001 /**< weight in score calculations for inference score */
    78#define DEFAULT_CUTOFFWEIGHT 0.0001 /**< weight in score calculations for cutoff score */
    79#define DEFAULT_GMIAVGEFFWEIGHT 0.0 /**< weight in score calculations of average GMI cut normed efficacies */
    80#define DEFAULT_GMILASTEFFWEIGHT 0.00001 /**< weight in score calculations of last GMI cut normed efficacy */
    81#define DEFAULT_PSCOSTWEIGHT 1.0 /**< weight in score calculations for pseudo cost score */
    82#define DEFAULT_NLSCOREWEIGHT 0.1 /**< weight in score calculations for nlcount score */
    83#define DEFAULT_MINRELIABLE 1.0 /**< minimal value for minimum pseudo cost size to regard pseudo cost value as reliable */
    84#define DEFAULT_MAXRELIABLE 5.0 /**< maximal value for minimum pseudo cost size to regard pseudo cost value as reliable */
    85#define DEFAULT_SBITERQUOT 0.5 /**< maximal fraction of strong branching LP iterations compared to normal iterations */
    86#define DEFAULT_DYNAMICLOOKAHEADQUOT 0.6 /**< apply dynamic lookahead after this fraction maxlookahead is reached */
    87#define DEFAULT_SBITEROFS 100000 /**< additional number of allowed strong branching LP iterations */
    88#define DEFAULT_MAXLOOKAHEAD 9 /**< maximal number of further variables evaluated without better score */
    89#define DEFAULT_INITCAND 100 /**< maximal number of candidates initialized with strong branching per node */
    90#define DEFAULT_INITITER 0 /**< iteration limit for strong branching initialization of pseudo cost entries (0: auto) */
    91#define DEFAULT_MAXBDCHGS 5 /**< maximal number of bound tightenings before the node is reevaluated (-1: unlimited) */
    92#define DEFAULT_MAXPROPROUNDS -2 /**< maximum number of propagation rounds to be performed during strong branching
    93 * before solving the LP (-1: no limit, -2: parameter settings) */
    94#define DEFAULT_PROBINGBOUNDS TRUE /**< should valid bounds be identified in a probing-like fashion during strong
    95 * branching (only with propagation)? */
    96#define DEFAULT_USERELERRORFORRELIABILITY FALSE /**< should reliability be based on relative errors? */
    97#define DEFAULT_LOWERRORTOL 0.05 /**< lowest tolerance beneath which relative errors are reliable */
    98#define DEFAULT_HIGHERRORTOL 1.0 /**< highest tolerance beneath which relative errors are reliable */
    99#define DEFAULT_USEHYPTESTFORRELIABILITY FALSE /**< should the strong branching decision be based on a hypothesis test? */
    100#define DEFAULT_USEDYNAMICCONFIDENCE FALSE /**< should the confidence level be adjusted dynamically? */
    101#define DEFAULT_STORESEMIINITCOSTS FALSE /**< should strong branching result be considered for pseudo costs if the other direction was infeasible? */
    102#define DEFAULT_USESBLOCALINFO FALSE /**< should the scoring function use only local cutoff and inference information obtained for strong branching candidates? */
    103#define DEFAULT_CONFIDENCELEVEL 2 /**< The confidence level for statistical methods, between 0 (Min) and 4 (Max). */
    104#define DEFAULT_SKIPBADINITCANDS TRUE /**< should branching rule skip candidates that have a low probability to be
    105 * better than the best strong-branching or pseudo-candidate? */
    106#define DEFAULT_STARTRANDSEED 5 /**< start random seed for random number generation */
    107#define DEFAULT_DYNAMICLOOKAHEAD FALSE /**< should we use a dynamic lookahead based on a tree size estimation of further strong branchings? */
    108#define DEFAULT_MINSAMPLESIZE 10 /**< minimum sample size to estimate the tree size for dynamic lookahead */
    109#define DEFAULT_DYNAMICLOOKDISTRIBUTION 1 /**< which distribution should be used for dynamic lookahead? 0=exponential, 1=Pareto, 2=log-normal */
    110#define DEFAULT_RANDINITORDER FALSE /**< should slight perturbation of scores be used to break ties in the prior scores? */
    111#define DEFAULT_USESMALLWEIGHTSITLIM FALSE /**< should smaller weights be used for pseudo cost updates after hitting the LP iteration limit? */
    112#define DEFAULT_DYNAMICWEIGHTS TRUE /**< should the weights of the branching rule be adjusted dynamically during solving based
    113 * infeasible and objective leaf counters? */
    114#define DEFAULT_DEGENERACYAWARE 1 /**< should degeneracy be taken into account to update weights and skip strong branching? (0: off, 1: after root, 2: always)*/
    115
    116/* symmetry handling */
    117#define DEFAULT_FILTERCANDSSYM FALSE /**< Use symmetry to filter branching candidates? */
    118#define DEFAULT_TRANSSYMPSCOST FALSE /**< Transfer pscost information to symmetric variables if filtering is performed? */
    119
    120/* distribution to use for lookahead strong branching */
    121#define EXPONENTIALDISTRIBUTION 0
    122#define PARETODISTRIBUTION 1
    123#define LOGNORMALDISTRIBUTION 2
    124
    125/* shift for geometric mean of left and right gains */
    126#define GEOMMEANSHIFT 0.01
    127/* maximum gain with which we update the estimated left and right dual gains */
    128#define MAXGAINTHRESHOLD 1e15
    129/* minimum considered expected dual gain and probability for lookahead strong branching */
    130#define MINGAINTHRESHOLD 1e-5
    131
    132/* discounted pseudo cost */
    133#define BRANCHRULE_DISCOUNTFACTOR 0.2 /**< default discount factor for discounted pseudo costs.*/
    134
    135/** branching rule data */
    136struct SCIP_BranchruleData
    137{
    138 SCIP_Real conflictweight; /**< weight in score calculations for conflict score */
    139 SCIP_Real conflengthweight; /**< weight in score calculations for conflict length score */
    140 SCIP_Real inferenceweight; /**< weight in score calculations for inference score */
    141 SCIP_Real cutoffweight; /**< weight in score calculations for cutoff score */
    142 SCIP_Real gmiavgeffweight; /**< weight in score calculations of average GMI normed cut efficacies */
    143 SCIP_Real gmilasteffweight; /**< weight in score calculations of last GMI cut normalized efficacy */
    144 SCIP_Real pscostweight; /**< weight in score calculations for pseudo cost score */
    145 SCIP_Real nlscoreweight; /**< weight in score calculations for nlcount score */
    146 SCIP_Real minreliable; /**< minimal value for minimum pseudo cost size to regard pseudo cost value as reliable */
    147 SCIP_Real maxreliable; /**< maximal value for minimum pseudo cost size to regard pseudo cost value as reliable */
    148 SCIP_Real sbiterquot; /**< maximal fraction of strong branching LP iterations compared to normal iterations */
    149 SCIP_Real meandualgain; /**< mean dual gain of all strong branchings */
    150 SCIP_Real currmeandualgain; /**< current mean dual gain in current node */
    151 SCIP_Real maxmeangain; /**< maximal dual gain of all strong branchings */
    152 SCIP_Real minmeangain; /**< minimal dual gain of all strong branchings */
    153 SCIP_Real sumlogmeangains; /**< sum of logarithms of all means of the dual gains */
    154 SCIP_Real logstdevgain; /**< logarithm of the standard deviation of the means of the dual gains */
    155 SCIP_Real nzerogains; /**< number of zero dual gains */
    156 int currndualgains; /**< number of dual gains used in the computation of the mean from current node */
    157 int sbiterofs; /**< additional number of allowed strong branching LP iterations */
    158 int maxlookahead; /**< maximal number of further variables evaluated without better score */
    159 int initcand; /**< maximal number of candidates initialized with strong branching per node */
    160 int inititer; /**< iteration limit for strong branching initialization of pseudo cost entries (0: auto) */
    161 int maxbdchgs; /**< maximal number of bound tightenings before the node is reevaluated (-1: unlimited) */
    162 int maxproprounds; /**< maximum number of propagation rounds to be performed during strong branching
    163 * before solving the LP (-1: no limit, -2: parameter settings) */
    164 SCIP_Bool probingbounds; /**< should valid bounds be identified in a probing-like fashion during strong
    165 * branching (only with propagation)? */
    166 SCIP_Bool userelerrorforreliability; /**< should reliability be based on relative errors? */
    167 SCIP_Real lowerrortol; /**< lowest tolerance beneath which relative errors are reliable */
    168 SCIP_Real higherrortol; /**< highest tolerance beneath which relative errors are reliable */
    169 SCIP_Bool usehyptestforreliability; /**< should the strong branching decision be based on a hypothesis test? */
    170 SCIP_Bool usedynamicconfidence; /**< should the confidence level be adjusted dynamically? */
    171 SCIP_Bool storesemiinitcosts; /**< should strong branching result be considered for pseudo costs if the
    172 * other direction was infeasible? */
    173 SCIP_Bool usesblocalinfo; /**< should the scoring function disregard cutoffs for variable if sb-lookahead was feasible ? */
    174 SCIP_Bool skipbadinitcands; /**< should branching rule skip candidates that have a low probability to be
    175 * better than the best strong-branching or pseudo-candidate? */
    176 SCIP_Bool dynamicweights; /**< should the weights of the branching rule be adjusted dynamically during
    177 * solving based on objective and infeasible leaf counters? */
    178 SCIP_Real dynamiclookaheadquot; /**< apply dynamic lookahead after this fraction maxlookahead is reached */
    179 SCIP_Bool dynamiclookahead; /**< should we use a dynamic lookahead based on a tree size estimation of further strong branchings? */
    180 int dynamiclookdistribution; /**< which distribution should be used for dynamic lookahead? 0=exponential, 1=Pareto, 2=log-normal */
    181 int minsamplesize; /**< minimum sample size to estimate the tree size for dynamic lookahead */
    182 int degeneracyaware; /**< should degeneracy be taken into account to update weights and skip strong branching? (0: off, 1: after root, 2: always) */
    183 int confidencelevel; /**< The confidence level for statistical methods, between 0 (Min) and 4 (Max). */
    184 int* nlcount; /**< array to store nonlinear count values */
    185 int nlcountsize; /**< length of nlcount array */
    186 int nlcountmax; /**< maximum entry in nlcount array or 1 if NULL */
    187 SCIP_Bool randinitorder; /**< should slight perturbation of scores be used to break ties in the prior scores? */
    188 SCIP_RANDNUMGEN* randnumgen; /**< random number generator */
    189 int startrandseed; /**< start random seed for random number generation */
    190 SCIP_Bool usesmallweightsitlim; /**< should smaller weights be used for pseudo cost updates after hitting the LP iteration limit? */
    191 SCIP_TREEMODEL* treemodel; /**< Parameters for the Treemodel branching rules */
    192
    193 /* for symmetry */
    194 SCIP_Bool filtercandssym; /**< Use symmetry to filter branching candidates? */
    195 SCIP_Bool transsympscost; /**< Transfer pscost information to symmetric variables? */
    196
    197 SCIP_Bool nosymmetry; /**< No symmetry present? */
    198 int* orbits; /**< array of non-trivial orbits */
    199 int* orbitbegins; /**< array containing begin positions of new orbits in orbits array */
    200 int norbits; /**< pointer to number of orbits currently stored in orbits */
    201 int* varorbitmap; /**< array for storing indices of the containing orbit for each variable */
    202 int* orbitrep; /**< representative variable of each orbit */
    203 SCIP_VAR** permvars; /**< variables on which permutations act */
    204 int npermvars; /**< number of variables for permutations */
    205 SCIP_HASHMAP* permvarmap; /**< map of variables to indices in permvars array */
    206
    207 /* for discounted pseudo costs */
    208 SCIP_Real discountfactor; /**< discount factor for discounted pseudo costs.*/
    209};
    210
    211/*
    212 * local methods
    213 */
    214
    215/** initialize orbits */
    216static
    218 SCIP* scip, /**< SCIP data structure */
    219 SCIP_BRANCHRULEDATA* branchruledata /**< branching rule data */
    220 )
    221{
    222 int** permstrans = NULL;
    223 int* components = NULL;
    224 int* componentbegins = NULL;
    225 int* vartocomponent = NULL;
    226 int ncomponents = 0;
    227 int nperms = -1;
    228
    229 assert( scip != NULL );
    230 assert( branchruledata != NULL );
    231 assert( branchruledata->filtercandssym );
    232
    233 /* exit if no symmetry or orbits already available */
    234 if( branchruledata->nosymmetry || branchruledata->orbits != NULL )
    235 return SCIP_OKAY;
    236
    237 assert( branchruledata->orbitbegins == NULL );
    238 assert( branchruledata->varorbitmap == NULL );
    239 assert( branchruledata->orbitrep == NULL );
    240
    241 /* obtain symmetry including permutations */
    242 SCIP_CALL( SCIPgetSymmetry(scip, &branchruledata->npermvars, &branchruledata->permvars, &branchruledata->permvarmap,
    243 &nperms, NULL, &permstrans, NULL, NULL, &components, &componentbegins, &vartocomponent, &ncomponents) );
    244
    245 /* turn off symmetry handling if there is no symmetry or the number of variables is not equal */
    246 if( nperms <= 0 || branchruledata->npermvars != SCIPgetNVars(scip) )
    247 {
    248 branchruledata->nosymmetry = TRUE;
    249 return SCIP_OKAY;
    250 }
    251 assert( branchruledata->permvars != NULL );
    252 assert( branchruledata->permvarmap != NULL );
    253 assert( branchruledata->npermvars > 0 );
    254 assert( permstrans != NULL );
    255 assert( components != NULL );
    256 assert( componentbegins != NULL );
    257 assert( vartocomponent != NULL );
    258 assert( ncomponents > 0 );
    259
    260 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &branchruledata->orbits, branchruledata->npermvars) );
    261 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &branchruledata->orbitbegins, branchruledata->npermvars) );
    262 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &branchruledata->varorbitmap, branchruledata->npermvars) );
    263 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &branchruledata->orbitrep, branchruledata->npermvars) );
    264
    265 /* Compute orbits on all variables, since this might help for branching and this computation is only done once. */
    266 SCIP_CALL( SCIPcomputeOrbitsComponentsSym(scip, branchruledata->npermvars, permstrans, nperms,
    267 components, componentbegins, vartocomponent, ncomponents,
    268 branchruledata->orbits, branchruledata->orbitbegins, &branchruledata->norbits, branchruledata->varorbitmap) );
    269 assert( branchruledata->norbits < branchruledata->npermvars );
    270
    271 return SCIP_OKAY;
    272}
    273
    274/** filter out symmetric variables from branching variables */
    275static
    277 SCIP* scip, /**< SCIP data structure */
    278 SCIP_BRANCHRULEDATA* branchruledata, /**< branching rule data */
    279 SCIP_VAR** origbranchcands, /**< original branching candidates */
    280 SCIP_Real* origbranchcandssol, /**< original solution value for the branching candidates */
    281 SCIP_Real* origbranchcandsfrac,/**< original fractional part of the branching candidates */
    282 int norigbranchcands, /**< original number of branching candidates */
    283 SCIP_VAR** branchcands, /**< branching candidates */
    284 SCIP_Real* branchcandssol, /**< solution value for the branching candidates */
    285 SCIP_Real* branchcandsfrac, /**< fractional part of the branching candidates */
    286 int* branchorbitidx, /**< array of indices of orbit of branching candidates */
    287 int* nbranchcands /**< pointer to store number of branching candidates */
    288 )
    289{
    290 int i;
    291
    292 assert( scip != NULL );
    293 assert( branchruledata != NULL );
    294 assert( origbranchcands != NULL );
    295 assert( origbranchcandssol != NULL );
    296 assert( origbranchcandsfrac != NULL );
    297 assert( branchcands != NULL );
    298 assert( branchcandssol != NULL );
    299 assert( branchcandsfrac != NULL );
    300 assert( nbranchcands != NULL );
    301
    302 assert( ! branchruledata->nosymmetry );
    303 assert( branchruledata->orbitbegins != NULL );
    304 assert( branchruledata->orbits != NULL );
    305 assert( branchruledata->permvarmap != NULL );
    306 assert( branchruledata->varorbitmap != NULL );
    307 assert( branchruledata->orbitrep != NULL );
    308 assert( branchruledata->norbits < branchruledata->npermvars );
    309
    310 /* init representatives (used to see whether variable is the first in an orbit) */
    311 for( i = 0; i < branchruledata->norbits; ++i )
    312 branchruledata->orbitrep[i] = -1;
    313
    314 /* loop through branching variables, determine orbit and whether they are the first ones */
    315 *nbranchcands = 0;
    316 for( i = 0; i < norigbranchcands; ++i )
    317 {
    318 int orbitidx = -1;
    319 int varidx;
    320
    321 varidx = SCIPhashmapGetImageInt(branchruledata->permvarmap, (void*) origbranchcands[i]);
    322 if( varidx != INT_MAX )
    323 {
    324 assert( 0 <= varidx && varidx < branchruledata->npermvars );
    325 orbitidx = branchruledata->varorbitmap[varidx];
    326 }
    327 assert( -1 <= orbitidx && orbitidx < branchruledata->norbits );
    328
    329 /* Check whether the variable is not present (can happen if variable was added after computing symmetries or is in
    330 * a singleton orbit). */
    331 if( orbitidx == -1 )
    332 {
    333 branchcands[*nbranchcands] = origbranchcands[i];
    334 branchcandssol[*nbranchcands] = origbranchcandssol[i];
    335 branchcandsfrac[*nbranchcands] = origbranchcandsfrac[i];
    336 branchorbitidx[*nbranchcands] = -1;
    337 ++(*nbranchcands);
    338 }
    339 else if( branchruledata->orbitrep[orbitidx] == -1 )
    340 {
    341 /* if variable is the first in a nontrivial orbit */
    342 assert( 0 <= varidx && varidx < branchruledata->npermvars );
    343 branchruledata->orbitrep[orbitidx] = varidx;
    344 branchcands[*nbranchcands] = origbranchcands[i];
    345 branchcandssol[*nbranchcands] = origbranchcandssol[i];
    346 branchcandsfrac[*nbranchcands] = origbranchcandsfrac[i];
    347 branchorbitidx[*nbranchcands] = orbitidx;
    348 ++(*nbranchcands);
    349 }
    350 }
    351
    352 SCIPdebugMsg(scip, "Filtered out %d variables by symmetry.\n", norigbranchcands - *nbranchcands);
    353
    354 return SCIP_OKAY;
    355}
    356
    357/** updates the pseudo costs of the given variable and all its symmetric variables */
    358static
    360 SCIP* scip, /**< SCIP data structure */
    361 SCIP_BRANCHRULEDATA* branchruledata, /**< branching rule data */
    362 SCIP_VAR* branchvar, /**< branching variable candidate */
    363 int* branchorbitidx, /**< array of orbit indices */
    364 int branchvaridx, /**< index of variable in branchorbitidx */
    365 SCIP_Real solvaldelta, /**< difference of variable's new LP value - old LP value */
    366 SCIP_Real objdelta, /**< difference of new LP's objective value - old LP's objective value */
    367 SCIP_Real weight /**< weight in (0,1] of this update in pseudo cost sum */
    368 )
    369{
    370 int orbitidx;
    371 int j;
    372 SCIP_Bool useancpscost;
    373
    374 assert( scip != NULL );
    375 assert( branchruledata != NULL );
    376
    377 /* update the discounted pseudo cost of the current node branched variable */
    378 SCIP_CALL( SCIPgetBoolParam(scip, "branching/collectancpscost", &useancpscost) );
    379 if( useancpscost )
    380 {
    381 SCIP_NODE* currentnode;
    382
    383 currentnode = SCIPgetFocusNode(scip);
    384 if( SCIPnodeGetDepth(currentnode) > 0 )
    385 {
    386 SCIP_DOMCHG* domchange;
    387 SCIP_BOUNDCHG* boundchg;
    388 int nboundchgs;
    389 SCIP_VAR* var;
    390 int i;
    391 SCIP_Real parentlpsolval;
    392 SCIP_Real parentsolvedelta;
    393
    394 domchange = SCIPnodeGetDomchg(currentnode);
    395 nboundchgs = SCIPdomchgGetNBoundchgs(domchange);
    396 for( i = 0; i < nboundchgs; ++i )
    397 {
    398 boundchg = SCIPdomchgGetBoundchg(domchange, i);
    399 var = SCIPboundchgGetVar(boundchg);
    400 assert(var != NULL);
    401
    403 {
    404 parentlpsolval = SCIPboundchgGetLPSolVal(boundchg);
    405 if( parentlpsolval >= SCIP_INVALID )
    406 continue;
    407 parentsolvedelta = SCIPboundchgGetNewbound(boundchg) - parentlpsolval;
    408 SCIP_CALL( SCIPupdateVarAncPseudocost(scip, var, parentsolvedelta, objdelta, weight) );
    409 }
    410 }
    411 }
    412 }
    413
    414 if( branchruledata->nosymmetry || ! branchruledata->transsympscost || branchorbitidx == NULL )
    415 {
    416 /* use original update function */
    417 SCIP_CALL( SCIPupdateVarPseudocost(scip, branchvar, solvaldelta, objdelta, weight) );
    418 return SCIP_OKAY;
    419 }
    420
    421 assert( branchruledata->orbitbegins != NULL );
    422 assert( branchruledata->orbits != NULL );
    423 assert( 0 <= branchvaridx && branchvaridx < branchruledata->npermvars );
    424
    425 orbitidx = branchorbitidx[branchvaridx];
    426 if( orbitidx < 0 )
    427 {
    428 /* only update given variable */
    429 SCIP_CALL( SCIPupdateVarPseudocost(scip, branchvar, solvaldelta, objdelta, weight) );
    430 return SCIP_OKAY;
    431 }
    432 assert( 0 <= orbitidx && orbitidx < branchruledata->norbits );
    433
    434 /* loop through orbit containing variable and update pseudo costs for all variables */
    435 for( j = branchruledata->orbitbegins[orbitidx]; j < branchruledata->orbitbegins[orbitidx+1]; ++j )
    436 {
    437 SCIP_VAR* var;
    438 int idx;
    439
    440 idx = branchruledata->orbits[j];
    441 assert( 0 <= idx && idx < branchruledata->npermvars );
    442
    443 var = branchruledata->permvars[idx];
    444 assert( var != NULL );
    445
    446 if( SCIPvarIsActive(var) )
    447 {
    448 SCIP_CALL( SCIPupdateVarPseudocost(scip, var, solvaldelta, objdelta, weight) );
    449 }
    450 }
    451
    452 return SCIP_OKAY;
    453}
    454
    455/**! [SnippetCodeStyleDeclaration] */
    456
    457/** counts number of nonlinear constraints in which each variable appears */
    458static
    460 SCIP* scip, /**< SCIP data structure */
    461 int* nlcount, /**< pointer to array for storing count values */
    462 int nlcountsize, /**< buffer for storing length of nlcount array */
    463 int* nlcountmax /**< buffer for storing maximum value in nlcount array */
    464 )
    465{
    466 SCIP_CONSHDLR* andconshdlr;
    467 SCIP_VAR** vars;
    468 int nvars;
    469 int i;
    470
    471/**! [SnippetCodeStyleDeclaration] */
    472
    473 assert(scip != NULL);
    474 assert(nlcount != NULL);
    475 assert(nlcountmax != NULL);
    476
    477 SCIP_CALL( SCIPgetVarsData(scip, &vars, &nvars, NULL, NULL, NULL, NULL) );
    478 assert(nlcountsize >= nvars);
    479
    480 /* get nonlinearity for constraints in NLP */
    482 {
    483 assert(SCIPgetNNLPVars(scip) == nvars);
    485 }
    486 else
    487 {
    488 BMSclearMemoryArray(nlcount, nvars);
    489 }
    490
    491 /* increase counters for and constraints */
    492 andconshdlr = SCIPfindConshdlr(scip, "and");
    493 if( andconshdlr != NULL )
    494 {
    495 int c;
    496
    497 for( c = 0; c < SCIPconshdlrGetNActiveConss(andconshdlr); ++c )
    498 {
    499 SCIP_CONS* andcons;
    500 SCIP_VAR** andvars;
    501 SCIP_VAR* andres;
    502 int probindex;
    503 int nandvars;
    504 int v;
    505
    506 /* get constraint and variables */
    507 andcons = SCIPconshdlrGetConss(andconshdlr)[c];
    508 nandvars = SCIPgetNVarsAnd(scip, andcons);
    509 andvars = SCIPgetVarsAnd(scip, andcons);
    510 andres = SCIPgetResultantAnd(scip, andcons);
    511
    512 /* get active index of resultant */
    513 probindex = SCIPvarGetProbindex(SCIPvarGetProbvar(andres));
    514
    515 /* the resultant might be deleted */
    516 if( probindex >= 0 )
    517 ++nlcount[probindex];
    518
    519 /**! [SnippetCodeStyleIfFor] */
    520 for( v = 0; v < nandvars; ++v )
    521 {
    522 /* get active index of operator */
    523 probindex = SCIPvarGetProbindex(SCIPvarGetProbvar(andvars[v]));
    524
    525 /* the operator might be deleted */
    526 if( probindex >= 0 )
    527 ++nlcount[probindex];
    528 }
    529 /**! [SnippetCodeStyleIfFor] */
    530 }
    531 }
    532
    533 /* compute maximum count value */
    534 *nlcountmax = 1;
    535 for( i = 0; i < nvars; ++i )
    536 {
    537 if( *nlcountmax < nlcount[i] )
    538 *nlcountmax = nlcount[i];
    539 }
    540
    541 return SCIP_OKAY;
    542}
    543
    544static
    546 SCIP* scip, /**< SCIP data structure */
    547 SCIP_BRANCHRULEDATA* branchruledata /**< branching rule data */
    548 )
    549{
    550 int nvars;
    551
    552 assert(scip != NULL);
    553 assert(branchruledata != NULL);
    554
    555 nvars = SCIPgetNVars(scip);
    556
    557 /**@todo test whether we want to apply this as if problem has only and constraints */
    558 /**@todo update changes in and constraints */
    559 if( branchruledata->nlscoreweight > 0.0 ) /* && SCIPisNLPConstructed(scip) */
    560 {
    561 if( branchruledata->nlcount == NULL )
    562 {
    563 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &branchruledata->nlcount, nvars) );
    564 branchruledata->nlcountsize = nvars;
    565
    566 SCIP_CALL( countNonlinearities(scip, branchruledata->nlcount, branchruledata->nlcountsize, &branchruledata->nlcountmax) );
    567 }
    568 else if( branchruledata->nlcountsize < nvars )
    569 {
    570 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &branchruledata->nlcount, branchruledata->nlcountsize, nvars) );
    571 /**@todo should we update nlcounts for new variables? */
    572 BMSclearMemoryArray(&(branchruledata->nlcount[branchruledata->nlcountsize]), nvars - branchruledata->nlcountsize); /*lint !e866*/
    573 branchruledata->nlcountsize = nvars;
    574 }
    575 assert(branchruledata->nlcount != NULL);
    576 assert(branchruledata->nlcountsize == nvars);
    577 assert(branchruledata->nlcountmax >= 1);
    578 }
    579 else
    580 {
    581 SCIPfreeBlockMemoryArrayNull(scip, &branchruledata->nlcount, branchruledata->nlcountsize);
    582 branchruledata->nlcountsize = 0;
    583 branchruledata->nlcountmax = 1;
    584 }
    585
    586 return SCIP_OKAY;
    587}
    588
    589
    590/** calculates nlscore value between 0 and 1 */
    591static
    593 SCIP* scip, /**< SCIP data structure */
    594 int* nlcount, /**< array to store count values */
    595 int nlcountmax, /**< maximum value in nlcount array */
    596 int probindex /**< index of branching candidate */
    597 )
    598{
    599 if( nlcountmax >= 1 && nlcount != NULL )
    600 {
    601 SCIP_Real nlscore;
    602
    603 assert(scip != NULL);
    604 assert(probindex >= 0);
    605 assert(probindex < SCIPgetNVars(scip));
    606
    607 nlscore = nlcount[probindex] / (SCIP_Real)nlcountmax;
    608
    609 assert(nlscore >= 0.0);
    610 assert(nlscore <= 1.0);
    611 return nlscore;
    612 }
    613 else
    614 return 0.0;
    615}
    616
    617/** calculates an overall score value for the given individual score values */
    618static
    620 SCIP* scip, /**< SCIP data structure */
    621 SCIP_BRANCHRULEDATA* branchruledata, /**< branching rule data */
    622 SCIP_Real conflictscore, /**< conflict score of current variable */
    623 SCIP_Real avgconflictscore, /**< average conflict score */
    624 SCIP_Real conflengthscore, /**< conflict length score of current variable */
    625 SCIP_Real avgconflengthscore, /**< average conflict length score */
    626 SCIP_Real inferencescore, /**< inference score of current variable */
    627 SCIP_Real avginferencescore, /**< average inference score */
    628 SCIP_Real cutoffscore, /**< cutoff score of current variable */
    629 SCIP_Real avgcutoffscore, /**< average cutoff score */
    630 SCIP_Real gmieffscore, /**< normalized-eff of avg GMI cuts from row when var was frac and basic */
    631 SCIP_Real lastgmieffscore, /**< last normalized gmieffscore when var was frac and basic */
    632 SCIP_Real pscostscore, /**< pscost score of current variable */
    633 SCIP_Real avgpscostscore, /**< average pscost score */
    634 SCIP_Real nlscore, /**< nonlinear score of current variable between 0 and 1 */
    635 SCIP_Real frac, /**< fractional value of variable in current solution */
    636 SCIP_Real degeneracyfactor /**< factor to apply because of degeneracy */
    637 )
    638{
    639 SCIP_Real score;
    640 SCIP_Real dynamicfactor;
    641
    642 assert(branchruledata != NULL);
    643 assert(0.0 < frac && frac < 1.0);
    644
    645 if( branchruledata->dynamicweights )
    646 {
    647 dynamicfactor = (SCIPgetNInfeasibleLeaves(scip) + 1.0) / (SCIPgetNObjlimLeaves(scip) + 1.0);
    648 }
    649 else
    650 dynamicfactor = 1.0;
    651
    652 dynamicfactor *= degeneracyfactor;
    653
    654 score = dynamicfactor * (branchruledata->conflictweight * (1.0 - 1.0/(1.0+conflictscore/avgconflictscore))
    655 + branchruledata->conflengthweight * (1.0 - 1.0/(1.0+conflengthscore/avgconflengthscore))
    656 + branchruledata->inferenceweight * (1.0 - 1.0/(1.0+inferencescore/avginferencescore))
    657 + branchruledata->cutoffweight * (1.0 - 1.0/(1.0+cutoffscore/avgcutoffscore))
    658 + branchruledata->gmiavgeffweight * gmieffscore + branchruledata->gmilasteffweight * lastgmieffscore)
    659 + branchruledata->pscostweight / dynamicfactor * (1.0 - 1.0/(1.0+pscostscore/avgpscostscore))
    660 + branchruledata->nlscoreweight * nlscore;
    661
    662 /* avoid close to integral variables */
    663 if( MIN(frac, 1.0 - frac) < 10.0 * SCIPfeastol(scip) )
    664 score *= 1e-6;
    665
    666 return score;
    667}
    668
    669/** adds given index and direction to bound change arrays */
    670static
    672 SCIP* scip, /**< SCIP data structure */
    673 int** bdchginds, /**< pointer to bound change index array */
    674 SCIP_BOUNDTYPE** bdchgtypes, /**< pointer to bound change types array */
    675 SCIP_Real** bdchgbounds, /**< pointer to bound change new bounds array */
    676 int* nbdchgs, /**< pointer to number of bound changes */
    677 int ind, /**< index to store in bound change index array */
    678 SCIP_BOUNDTYPE type, /**< type of the bound change to store in bound change type array */
    679 SCIP_Real bound /**< new bound to store in bound change new bounds array */
    680 )
    681{
    682 assert(bdchginds != NULL);
    683 assert(bdchgtypes != NULL);
    684 assert(bdchgbounds != NULL);
    685 assert(nbdchgs != NULL);
    686
    687 SCIP_CALL( SCIPreallocBufferArray(scip, bdchginds, (*nbdchgs) + 1) );
    688 SCIP_CALL( SCIPreallocBufferArray(scip, bdchgtypes, (*nbdchgs) + 1) );
    689 SCIP_CALL( SCIPreallocBufferArray(scip, bdchgbounds, (*nbdchgs) + 1) );
    690 assert(*bdchginds != NULL);
    691 assert(*bdchgtypes != NULL);
    692 assert(*bdchgbounds != NULL);
    693
    694 (*bdchginds)[*nbdchgs] = ind;
    695 (*bdchgtypes)[*nbdchgs] = type;
    696 (*bdchgbounds)[*nbdchgs] = bound;
    697 (*nbdchgs)++;
    698
    699 return SCIP_OKAY;
    700}
    701
    702/**! [SnippetCodeStyleStaticAsserts] */
    703/** frees bound change arrays */
    704static
    706 SCIP* scip, /**< SCIP data structure */
    707 int** bdchginds, /**< pointer to bound change index array */
    708 SCIP_BOUNDTYPE** bdchgtypes, /**< pointer to bound change types array */
    709 SCIP_Real** bdchgbounds, /**< pointer to bound change new bounds array */
    710 int* nbdchgs /**< pointer to number of bound changes */
    711 )
    712{
    713 assert(scip != NULL);
    714 assert(bdchginds != NULL);
    715 assert(bdchgtypes != NULL);
    716 assert(bdchgbounds != NULL);
    717 assert(nbdchgs != NULL);
    718/**! [SnippetCodeStyleStaticAsserts] */
    719
    720 SCIPfreeBufferArrayNull(scip, bdchgbounds);
    721 SCIPfreeBufferArrayNull(scip, bdchgtypes);
    722 SCIPfreeBufferArrayNull(scip, bdchginds);
    723 *nbdchgs = 0;
    724}
    725
    726/** applies bound changes stored in bound change arrays */
    727static
    729 SCIP* scip, /**< SCIP data structure */
    730 SCIP_VAR** vars, /**< problem variables */
    731 int* bdchginds, /**< bound change index array */
    732 SCIP_BOUNDTYPE* bdchgtypes, /**< bound change types array */
    733 SCIP_Real* bdchgbounds, /**< bound change new bound array */
    734 int nbdchgs, /**< number of bound changes */
    735 SCIP_RESULT* result /**< result pointer */
    736 )
    737{
    738#ifndef NDEBUG
    739 SCIP_BRANCHRULE* branchrule;
    740 SCIP_BRANCHRULEDATA* branchruledata;
    741#endif
    742 SCIP_Bool infeasible;
    743 SCIP_Bool tightened;
    744 int i;
    745
    746 assert(vars != NULL);
    747
    748#ifndef NDEBUG
    749 /* find branching rule */
    751 assert(branchrule != NULL);
    752
    753 /* get branching rule data */
    754 branchruledata = SCIPbranchruleGetData(branchrule);
    755 assert(branchruledata != NULL);
    756#endif
    757
    758 SCIPdebugMsg(scip, "applying %d bound changes\n", nbdchgs);
    759
    760 for( i = 0; i < nbdchgs; ++i )
    761 {
    762 int v;
    763
    764 v = bdchginds[i];
    765
    766 SCIPdebugMsg(scip, " -> <%s> [%g,%g]\n",
    767 SCIPvarGetName(vars[v]), SCIPvarGetLbLocal(vars[v]), SCIPvarGetUbLocal(vars[v]));
    768
    769 if( bdchgtypes[i] == SCIP_BOUNDTYPE_LOWER )
    770 {
    771 /* change lower bound of variable to given bound */
    772 SCIP_CALL( SCIPtightenVarLb(scip, vars[v], bdchgbounds[i], TRUE, &infeasible, &tightened) );
    773 if( infeasible )
    774 {
    775 *result = SCIP_CUTOFF;
    776 return SCIP_OKAY;
    777 }
    778
    779 /* if we did propagation, the bound change might already have been added */
    780 assert(tightened || (branchruledata->maxproprounds != 0));
    781 }
    782 else
    783 {
    784 assert(bdchgtypes[i] == SCIP_BOUNDTYPE_UPPER);
    785
    786 /* change upper bound of variable to given bound */
    787 SCIP_CALL( SCIPtightenVarUb(scip, vars[v], bdchgbounds[i], TRUE, &infeasible, &tightened) );
    788 if( infeasible )
    789 {
    790 *result = SCIP_CUTOFF;
    791 return SCIP_OKAY;
    792 }
    793
    794 /* if we did propagation, the bound change might already have been added */
    795 assert(tightened || (branchruledata->maxproprounds != 0));
    796 }
    797 SCIPdebugMsg(scip, " -> [%g,%g]\n", SCIPvarGetLbLocal(vars[v]), SCIPvarGetUbLocal(vars[v]));
    798 }
    799
    800 return SCIP_OKAY;
    801}
    802
    803/** Update the min/max gain, and the mean of all gains computed so far.
    804 *
    805 * This mean is used in the definition of the exponential distribution.
    806 */
    807static
    809 SCIP* scip, /**< SCIP data structure */
    810 SCIP_BRANCHRULE* branchrule, /**< branching rule */
    811 SCIP_Real downgain, /**< gain for branching downwards */
    812 SCIP_Real upgain /**< gain for branching upwards */
    813 )
    814{
    815 SCIP_BRANCHRULEDATA* branchruledata = SCIPbranchruleGetData(branchrule);
    816 SCIP_Real logmeangain;
    817 /* initializing to avoid linter, value never used */
    818 SCIP_Real oldlogstdevgain = -1.0;
    819 SCIP_Real oldlogmeangain = -1.0;
    820
    821 assert(branchruledata != NULL);
    822
    823 /* in the case of very large gains, SCIP will already prioritize this variable */
    825 return SCIP_OKAY;
    826
    827 SCIP_Real meangain = sqrt((downgain + GEOMMEANSHIFT) * (upgain + GEOMMEANSHIFT)) - GEOMMEANSHIFT;
    828 assert(SCIPisGE(scip, meangain, 0.0));
    829
    830 if(meangain < MINGAINTHRESHOLD)
    831 {
    832 branchruledata->nzerogains++;
    833 return SCIP_OKAY;
    834 }
    835
    836 branchruledata->currmeandualgain = ((SCIP_Real) branchruledata->currndualgains / (branchruledata->currndualgains + 1) ) * branchruledata->currmeandualgain + meangain / ( branchruledata->currndualgains + 1 ) ;
    837
    838 ++branchruledata->currndualgains;
    839
    840 if(branchruledata->currndualgains > 1)
    841 {
    842 oldlogstdevgain = branchruledata->logstdevgain;
    843 oldlogmeangain = branchruledata->sumlogmeangains / (branchruledata->currndualgains - 1);
    844 }
    845
    846 branchruledata->sumlogmeangains += log(meangain);
    847 /* update the max mean gain */
    848 logmeangain = branchruledata->sumlogmeangains / branchruledata->currndualgains;
    849
    850 int ngains = branchruledata->currndualgains;
    851
    852 if (ngains == 1)
    853 branchruledata->logstdevgain = pow((log(meangain) - logmeangain), 2.0 );
    854 else
    855 branchruledata->logstdevgain = ( (ngains - 2) * oldlogstdevgain + (ngains - 1) * pow( oldlogmeangain - logmeangain, 2.0) + pow((log(meangain) - logmeangain), 2.0 ) ) / (ngains - 1) ;
    856
    857 branchruledata->maxmeangain = MAX(branchruledata->maxmeangain, meangain);
    858 branchruledata->minmeangain = MIN(branchruledata->minmeangain, meangain);
    859 SCIPdebugMsg(scip, " -> downgain: %g upgain: %g minmeangain: %g maxmeangain: %g mean-of-two: %g mean-of-%d-dual-gains: %g\n",downgain, upgain, branchruledata->minmeangain, branchruledata->maxmeangain, meangain, branchruledata->currndualgains, branchruledata->currmeandualgain);
    860
    861 return SCIP_OKAY;
    862}
    863
    864/** compute the depth of the tree with the assumption that left and right dual gains are equal */
    865static
    867 SCIP_Real gap, /**< gap to be closed */
    868 SCIP_Real maxmeangain /**< maximum mean gain of the branching candidates */
    869 )
    870{
    871 assert(maxmeangain >= 0.0);
    872 /* using an epsilon value if maxmeangain is zero */
    873 SCIP_Real depth = ceil(gap / MAX(maxmeangain, MINGAINTHRESHOLD));
    874 assert(depth > 0);
    875 return depth;
    876}
    877
    878/** compute the size of the tree with the assumption that left and right dual gains are equal */
    879static
    881 SCIP_Real estimatedepth /**< estimated depth of the tree */
    882 )
    883{
    884 return pow(2.0, estimatedepth + 1.0) - 1.0;
    885}
    886
    887/** calculate the cumulative distribution function (CDF) value for a mixture of a Dirac at zero and a continuous distribution (depending on distributioncdf) */
    888static
    890 SCIP_Real rate, /**< rate of the distribution */
    891 SCIP_Real zeroprob, /**< probability of zero gain */
    892 SCIP_Real proposedgain, /**< proposed gain */
    893 SCIP_Real mingain, /**< minimum gain */
    894 SCIP_Real logmeangain, /**< logarithm og mean gain */
    895 SCIP_Real logstdevgain, /**< logarithm of standard deviation of gain */
    896 int distributioncdf /**< distribution type (PARETODISTRIBUTION, EXPONENTIALDISTRIBUTION, LOGNORMALDISTRIBUTION) */
    897 )
    898{
    899 if(distributioncdf == PARETODISTRIBUTION)
    900 {
    901 if (proposedgain < mingain)
    902 return 0.0;
    903 else
    904 return zeroprob + (1.0 - zeroprob) * (1.0 - pow(mingain / proposedgain, rate));
    905 }
    906 else if(distributioncdf == EXPONENTIALDISTRIBUTION)
    907 {
    908 assert(rate >= 0.0);
    909 return zeroprob + (1.0 - zeroprob) * (1.0 - exp(-rate * proposedgain));
    910 }
    911 else
    912 {
    913 assert(distributioncdf == LOGNORMALDISTRIBUTION);
    914 return zeroprob + (1.0 - zeroprob) * 0.5 * erfc(-(log(proposedgain) - logmeangain) / (logstdevgain * sqrt(2.0)));
    915 }
    916}
    917
    918/** calculate the expected size of a tree with one more iteration of strong branching */
    919static
    921 SCIP* scip, /**< SCIP data structure */
    922 SCIP_Real gap, /**< gap to be closed */
    923 SCIP_Real zeroprob, /**< probability of zero gain */
    924 SCIP_Real currentdepth, /**< current depth of the tree */
    925 SCIP_Real lambda, /**< rate of the distribution */
    926 SCIP_Real mingain, /**< minimum gain */
    927 SCIP_Real logmeangain, /**< logarithm of mean gain */
    928 SCIP_Real logstdevgain, /**< logarithm of standard deviation of gain */
    929 int distributioncdf /**< distribution type (PARETODISTRIBUTION, EXPONENTIALDISTRIBUTION, LOGNORMALDISTRIBUTION) */
    930 )
    931{
    932 SCIP_Real ptotal = 0.0;
    933 SCIP_Real totalimprovedtree = 0.0;
    934
    935 int depth = (int) currentdepth;
    936 SCIP_Real currenttreesize = strongBranchingTreeSize(currentdepth);
    937 SCIP_Real nexttreesize;
    938 SCIP_Real improvedtree;
    939 if (depth == 1)
    940 {
    941 nexttreesize = currenttreesize;
    942 }
    943 /* compute the expected size with one more strong branching iteration */
    944 else if (depth == 2)
    945 {
    946 /* Probability of finding a better variable that would reduce the depth (smaller tree size). */
    947 SCIP_Real p = 1.0 - cdfProbability(lambda, zeroprob, gap, mingain, logmeangain, logstdevgain, distributioncdf);
    948 SCIPdebugMsg(scip, " -> Probability of finding a better variable that would reduce the depth: %g\n", p);
    949 /* Size of the improved tree. */
    950 improvedtree = strongBranchingTreeSize(currentdepth - 1);
    951 nexttreesize = improvedtree * p + strongBranchingTreeSize(currentdepth) * (1.0 - p) + 2.0;
    952 if( p < MINGAINTHRESHOLD )
    953 return SCIPinfinity(scip);
    954 }
    955 else
    956 {
    957 /* Probability of not finding a better variable that would reduce the depth of the tree (size of the tree). */
    958 SCIP_Real pnotbetter = cdfProbability(lambda, zeroprob, (gap / (depth - 1)), mingain, logmeangain, logstdevgain, distributioncdf);
    959 /* Probability of finding a better variable that would reduce the depth (smaller tree size). */
    960 SCIP_Real pbetter = 1.0 - cdfProbability(lambda, zeroprob, gap / (depth - 1), mingain, logmeangain, logstdevgain, distributioncdf);
    961 SCIPdebugMsg(scip, " -> Probability of finding a better variable that would reduce the depth: %g\n", pbetter);
    962
    963 if( pbetter < MINGAINTHRESHOLD )
    964 return SCIPinfinity(scip);
    965
    966 SCIP_Real p;
    967 p = 0.0;
    968 while (pbetter >= MINGAINTHRESHOLD && ptotal + pnotbetter < 1.0)
    969 {
    970 if (depth > 2)
    971 {
    972 p = cdfProbability(lambda, zeroprob, gap / (depth - 2), mingain, logmeangain, logstdevgain, distributioncdf) - cdfProbability(lambda, zeroprob, gap / (depth - 1), mingain, logmeangain, logstdevgain, distributioncdf);
    973 ptotal += p;
    974 pbetter = 1.0 - cdfProbability(lambda, zeroprob, gap / (depth - 2), mingain, logmeangain, logstdevgain, distributioncdf);
    975 }
    976
    977 else if (depth == 2)
    978 {
    979 p = 1.0 - cdfProbability(lambda, zeroprob, gap, mingain, logmeangain, logstdevgain, distributioncdf);
    980 ptotal += p;
    981 pbetter = 0.0;
    982 }
    983 if (ptotal + pnotbetter <= 1.0)
    984 {
    985 /* Compute expected size of the improved tree based on improved depth, considering the probability of this improvement. */
    986 improvedtree = strongBranchingTreeSize(currentdepth - 1) * p;
    987 }
    988 else
    989 improvedtree = 0.0;
    990 depth--;
    991 totalimprovedtree += improvedtree;
    992 }
    993 /* Compute the expectation of the next tree size with one more iteration of strong branching */
    994 nexttreesize = totalimprovedtree + pnotbetter * strongBranchingTreeSize(currentdepth) + 2.0;
    995 }
    996 return nexttreesize;
    997}
    998
    999/** decide if we continue strong branching based based on lookahead */
    1000static
    1002 SCIP* scip, /**< SCIP data structure */
    1003 int candidx, /**< index of the branching candidate */
    1004 int ninitcands, /**< number of initial candidates */
    1005 SCIP_Real lookahead, /**< lookahead value */
    1006 SCIP_Real maxlookahead, /**< maximum lookahead value */
    1007 int nbdchgs, /**< number of bound changes found */
    1008 int nbdconflicts, /**< number of bound conflicts found */
    1009 int maxbdchgs, /**< maximal number of bound tightenings before the node is reevaluated */
    1010 SCIP_Longint maxnsblpiterations /**< maximal number of strong branching LP iterations */
    1011 )
    1012{
    1013 return candidx < ninitcands && lookahead < maxlookahead && nbdchgs + nbdconflicts < maxbdchgs
    1014 && (candidx < (int) maxlookahead || SCIPgetNStrongbranchLPIterations(scip) < maxnsblpiterations);
    1015}
    1016
    1017/** Decide if we continue strong branching based on the estimation of the tree size given the current gains. */
    1018static
    1020 SCIP* scip, /**< SCIP data structure */
    1021 SCIP_BRANCHRULEDATA* branchruledata, /**< branching rule data */
    1022 SCIP_Real lookahead, /**< lookahead value */
    1023 SCIP_Real maxlookahead /**< maximum lookahead value */
    1024 )
    1025{
    1026 SCIP_Real lambda;
    1027 SCIP_Real maxmeangain;
    1028 SCIP_Real minmeangain;
    1029 SCIP_Real nexttreesize;
    1030 SCIP_Real currentdepth;
    1031 SCIP_Real currenttreesize;
    1032 SCIP_Real absdualgap;
    1033 SCIP_Real gaptoclose = -1.0;
    1034
    1035 /* default values never used */
    1036 SCIP_Real logmeangain = 0.0;
    1037 SCIP_Real logstdevgain = -1.0;
    1038
    1039 if (!branchruledata->dynamiclookahead)
    1040 return TRUE;
    1041
    1042 /* compute the expected tree size after reaching a min lookahaead */
    1043 if( lookahead < branchruledata->dynamiclookaheadquot * maxlookahead)
    1044 return TRUE;
    1045
    1046 /* if we do not have a large enough sample to estimate the tree size we continue with strong branching */
    1047 if ( branchruledata->currndualgains < branchruledata->minsamplesize )
    1048 return TRUE;
    1049
    1050 maxmeangain = branchruledata->maxmeangain;
    1051 minmeangain = branchruledata->minmeangain;
    1052
    1053 /* Compute the absolute gap at the current node. If no upper bound available we continue strong branching as usual */
    1056 else
    1057 absdualgap = SCIPinfinity(scip);
    1058
    1059 if( !SCIPisInfinity(scip, absdualgap) && !SCIPisInfinity(scip, maxmeangain) && SCIPisGT(scip, maxmeangain, 0.0) )
    1060 gaptoclose = absdualgap;
    1061 else
    1062 return TRUE;
    1063
    1064 assert(gaptoclose >= 0.0);
    1065 assert(!SCIPisInfinity(scip, -maxmeangain));
    1066
    1067 SCIP_Real zeroprob = (SCIP_Real) branchruledata->nzerogains / (branchruledata->nzerogains + branchruledata->currndualgains);
    1068 if(branchruledata->dynamiclookdistribution == PARETODISTRIBUTION)
    1069 {
    1070 assert(minmeangain > 0.0);
    1071 assert(branchruledata->currndualgains > 0);
    1072 SCIP_Real sumlambda = branchruledata->sumlogmeangains - branchruledata->currndualgains * log(minmeangain);
    1073 if(SCIPisZero(scip, sumlambda))
    1074 return TRUE;
    1075 lambda = branchruledata->currndualgains / sumlambda;
    1076 }
    1077 else if (branchruledata->dynamiclookdistribution == EXPONENTIALDISTRIBUTION)
    1078 {
    1079 lambda = 1 / (branchruledata->currmeandualgain);
    1080 }
    1081 else
    1082 {
    1083 assert(branchruledata->dynamiclookdistribution == LOGNORMALDISTRIBUTION);
    1084 logmeangain = branchruledata->sumlogmeangains / branchruledata->currndualgains;
    1085 logstdevgain = branchruledata->logstdevgain;
    1086 /* lambda value not used */
    1087 lambda = -1.0;
    1088 }
    1089
    1090 /* Continue strong branching since we do not have good enough gains in this case */
    1091 currentdepth = strongBranchingDepth(gaptoclose, maxmeangain); /*lint !e644*/
    1092
    1093 if (currentdepth >= 50)
    1094 return TRUE;
    1095
    1096 /* Compute the tree size if we branch on the best variable so far, including the strong branching already done. */
    1097 currenttreesize = strongBranchingTreeSize(currentdepth);
    1098
    1099 /* Compute the expected size of the tree with one more strong branching */
    1100 nexttreesize = expectedTreeSize(scip, gaptoclose, zeroprob, currentdepth, lambda, minmeangain, logmeangain, logstdevgain, branchruledata->dynamiclookdistribution);
    1101
    1102 if(SCIPisLE(scip, nexttreesize, currenttreesize - 1.0))
    1103 return TRUE;
    1104
    1105 SCIPdebugMsg(scip," -> Stopped at lookahead %g, current tree size %g, next tree size %g\n", lookahead, currenttreesize, nexttreesize);
    1106 return FALSE;
    1107}
    1108
    1109/** determine if strong branching is needed on the given candidate variable */
    1110static
    1112 SCIP* scip, /**< SCIP data structure */
    1113 SCIP_BRANCHRULE* branchrule, /**< branching rule */
    1114 SCIP_VAR* branchcand, /**< branching candidate */
    1115 SCIP_Real branchcandfrac, /**< fractional part of the branching candidate */
    1116 SCIP_VAR* bestpscand, /**< best candidate as per pscost score, must be present if usehyptestforreliability is used */
    1117 SCIP_Real bestpscandfrac, /**< fractional part of the best candidate as per pscost score, must be present if usehyptestforreliability is used */
    1118 SCIP_Real reliable, /**< size threshold for reliability */
    1119 SCIP_Real relerrorthreshold, /**< relative error threshold for reliability */
    1120 SCIP_CONFIDENCELEVEL clevel, /**< confidence level */
    1121 SCIP_Bool useancpscost /**< check reliability for ancpscost as well */
    1122 )
    1123{ /*lint --e{715}*/
    1124 SCIP_BRANCHRULEDATA* branchruledata;
    1125 SCIP_Real pscostdownsize;
    1126 SCIP_Real pscostupsize;
    1127 SCIP_Real pscostsize;
    1128 SCIP_Real dpscostdownsize;
    1129 SCIP_Real dpscostupsize;
    1130 SCIP_Real dpscostsize;
    1131
    1132 /* get branching rule data */
    1133 branchruledata = SCIPbranchruleGetData(branchrule);
    1134 assert(branchruledata != NULL);
    1135
    1136 /* check, if the pseudo cost score and the discounted pseudocost score of the variable is reliable */
    1139 pscostsize = MIN(pscostdownsize, pscostupsize);
    1142 dpscostsize = MIN(dpscostdownsize, dpscostupsize);
    1143
    1144 /* determine if variable is considered reliable based on the current reliability setting */
    1145 /* check fixed number threshold (aka original) reliability first */
    1146 assert(!branchruledata->usehyptestforreliability || bestpscand != NULL );
    1147 if( pscostsize < reliable || ( useancpscost && dpscostsize < reliable ) )
    1148 return TRUE;
    1149 if( branchruledata->userelerrorforreliability && branchruledata->usehyptestforreliability )
    1150 {
    1151 if( !SCIPisVarPscostRelerrorReliable(scip, branchcand, relerrorthreshold, clevel) &&
    1152 !SCIPsignificantVarPscostDifference(scip, bestpscand, bestpscandfrac,
    1153 branchcand, branchcandfrac, SCIP_BRANCHDIR_DOWNWARDS, clevel, TRUE) &&
    1154 !SCIPsignificantVarPscostDifference(scip, bestpscand, 1 - bestpscandfrac,
    1155 branchcand, 1 - branchcandfrac, SCIP_BRANCHDIR_UPWARDS, clevel, TRUE) )
    1156 return TRUE;
    1157 }
    1158 /* check if relative error is tolerable */
    1159 if( branchruledata->userelerrorforreliability &&
    1160 !SCIPisVarPscostRelerrorReliable(scip, branchcand, relerrorthreshold, clevel))
    1161 return TRUE;
    1162 /* check if best pseudo-candidate is significantly better in both directions, use strong-branching otherwise */
    1163 if( branchruledata->usehyptestforreliability &&
    1164 !SCIPsignificantVarPscostDifference(scip, bestpscand, bestpscandfrac,
    1165 branchcand, branchcandfrac, SCIP_BRANCHDIR_DOWNWARDS, clevel, TRUE) &&
    1166 !SCIPsignificantVarPscostDifference(scip, bestpscand, 1 - bestpscandfrac,
    1167 branchcand, 1 - branchcandfrac, SCIP_BRANCHDIR_UPWARDS, clevel, TRUE) )
    1168 return TRUE;
    1169 return FALSE;
    1170}
    1171
    1172/** execute reliability pseudo cost branching */
    1173static
    1175 SCIP* scip, /**< SCIP data structure */
    1176 SCIP_BRANCHRULE* branchrule, /**< branching rule */
    1177 SCIP_VAR** branchcands, /**< branching candidates */
    1178 SCIP_Real* branchcandssol, /**< solution value for the branching candidates */
    1179 SCIP_Real* branchcandsfrac, /**< fractional part of the branching candidates */
    1180 int* branchorbitidx, /**< indices of orbit (or NULL) */
    1181 int nbranchcands, /**< number of branching candidates */
    1182 SCIP_Bool executebranch, /**< execute a branching step or run probing only */
    1183 SCIP_RESULT* result /**< pointer to the result of the execution */
    1184 )
    1185{ /*lint --e{715}*/
    1186 SCIP_BRANCHRULEDATA* branchruledata;
    1187 SCIP_Real lpobjval;
    1188 SCIP_Real bestsbdown;
    1189 SCIP_Real bestsbup;
    1190 SCIP_Real provedbound;
    1191 SCIP_Bool bestsbdownvalid;
    1192 SCIP_Bool bestsbupvalid;
    1193 SCIP_Bool bestsbdowncutoff;
    1194 SCIP_Bool bestsbupcutoff;
    1195 SCIP_Bool bestisstrongbranch;
    1196 SCIP_Bool allcolsinlp;
    1197 SCIP_Bool exactsolve;
    1198 int ninitcands;
    1199 int bestcand;
    1200
    1201 /* remember which variables strong branching is performed on, and the
    1202 * recorded lp bound changes that are observed */
    1203 SCIP_Real* sbdown = NULL;
    1204 SCIP_Real* sbup = NULL;
    1205 SCIP_Bool* sbdownvalid = NULL;
    1206 SCIP_Bool* sbupvalid = NULL;
    1207
    1208 *result = SCIP_DIDNOTRUN;
    1209
    1211
    1212 /* get branching rule data */
    1213 branchruledata = SCIPbranchruleGetData(branchrule);
    1214 assert(branchruledata != NULL);
    1215
    1216 /* get current LP objective bound of the local sub problem and global cutoff bound */
    1217 lpobjval = SCIPgetLPObjval(scip);
    1218
    1219 /* check, if we want to solve the problem exactly, meaning that strong branching information is not useful
    1220 * for cutting off sub problems and improving lower bounds of children
    1221 */
    1222 exactsolve = SCIPisExact(scip);
    1223
    1224 /* check, if all existing columns are in LP, and thus the strong branching results give lower bounds */
    1225 allcolsinlp = SCIPallColsInLP(scip);
    1226
    1227 bestcand = -1;
    1228 bestisstrongbranch = FALSE;
    1229 bestsbdown = SCIP_INVALID;
    1230 bestsbup = SCIP_INVALID;
    1231 bestsbdownvalid = FALSE;
    1232 bestsbupvalid = FALSE;
    1233 bestsbdowncutoff = FALSE;
    1234 bestsbupcutoff = FALSE;
    1235 provedbound = lpobjval;
    1236
    1237 /* Allocate memory to store the lp bounds of the up and down children
    1238 * for those of the variables that we performed sb on
    1239 */
    1240 SCIP_CALL( SCIPallocBufferArray(scip, &sbdown, nbranchcands) );
    1241 SCIP_CALL( SCIPallocBufferArray(scip, &sbup, nbranchcands) );
    1242 SCIP_CALL( SCIPallocBufferArray(scip, &sbdownvalid, nbranchcands) );
    1243 SCIP_CALL( SCIPallocBufferArray(scip, &sbupvalid, nbranchcands) );
    1244
    1245 if( nbranchcands == 1 )
    1246 {
    1247 /* only one candidate: nothing has to be done */
    1248 bestcand = 0;
    1249 SCIPdebug(ninitcands = 0);
    1250 sbdownvalid[0] = FALSE;
    1251 sbupvalid[0] = FALSE;
    1252 }
    1253 else
    1254 {
    1255 SCIP_VAR** vars;
    1256 int* initcands;
    1257 SCIP_Real* initcandscores;
    1258 SCIP_Real* newlbs = NULL;
    1259 SCIP_Real* newubs = NULL;
    1260 SCIP_Real* mingains = NULL;
    1261 SCIP_Real* maxgains = NULL;
    1262 /* scores computed from pseudocost branching */
    1263 SCIP_Real* scores = NULL;
    1264 SCIP_Real* scoresfrompc = NULL;
    1265 SCIP_Real* scoresfromothers = NULL;
    1266 int* bdchginds;
    1267 SCIP_BOUNDTYPE* bdchgtypes;
    1268 SCIP_Real* bdchgbounds;
    1269 int maxninitcands;
    1270 int nuninitcands;
    1271 int nbdchgs;
    1272 int nbdconflicts;
    1273 SCIP_Real avgconflictscore;
    1274 SCIP_Real avgconflengthscore;
    1275 SCIP_Real avginferencescore;
    1276 SCIP_Real avgcutoffscore;
    1277 SCIP_Real avgpscostscore;
    1278 SCIP_Real avgdpscostscore;
    1279 SCIP_Real bestpsscore;
    1280 SCIP_Real bestpsfracscore;
    1281 SCIP_Real bestpsdomainscore;
    1282 SCIP_Real bestsbscore;
    1283 SCIP_Real bestuninitsbscore;
    1284 SCIP_Real bestsbfracscore;
    1285 SCIP_Real bestsbdomainscore;
    1286 SCIP_Real prio;
    1287 SCIP_Real reliable;
    1288 SCIP_Real maxlookahead;
    1289 SCIP_Real lookahead;
    1290 SCIP_Real relerrorthreshold;
    1291 SCIP_Bool initstrongbranching;
    1292 SCIP_Bool propagate;
    1293 SCIP_Bool probingbounds;
    1294 SCIP_Longint nodenum;
    1295 SCIP_Longint nlpiterationsquot;
    1296 SCIP_Longint nsblpiterations;
    1297 SCIP_Longint maxnsblpiterations;
    1298 int bestsolidx;
    1299 int maxbdchgs;
    1300 int bestpscand;
    1301 int bestsbcand;
    1302 int bestuninitsbcand;
    1303 int inititer;
    1304 int nvars;
    1305 int i;
    1306 int c;
    1307 SCIP_CONFIDENCELEVEL clevel;
    1308 SCIP_Real degeneracyfactor = 1.0;
    1309 SCIP_Bool useancpscost;
    1310
    1311 SCIP_CALL( SCIPgetBoolParam(scip, "branching/collectancpscost", &useancpscost) );
    1312
    1313 /* get LP degeneracy information and compute a factor to change weighting of pseudo cost score vs. other scores */
    1314 if( branchruledata->degeneracyaware > 0 && (SCIPgetDepth(scip) > 0 || branchruledata->degeneracyaware > 1) )
    1315 {
    1316 SCIP_Real degeneracy;
    1317 SCIP_Real varconsratio;
    1318
    1319 /* get LP degeneracy information */
    1320 SCIP_CALL( SCIPgetLPDualDegeneracy(scip, &degeneracy, &varconsratio) );
    1321
    1322 assert(degeneracy >= 0.0);
    1323 assert(degeneracy <= 1.0);
    1324 assert(varconsratio >= 1.0);
    1325
    1326 /* increase factor for a degeneracy >= 80% */
    1327 if( degeneracy >= 0.8 )
    1328 {
    1329 degeneracy = 10.0 * (degeneracy - 0.7);
    1330 degeneracyfactor = degeneracyfactor * pow(10.0,degeneracy);
    1331 }
    1332 /* increase factor for a variable-constraint ratio >= 2.0 */
    1333 if( varconsratio >= 2.0 )
    1334 {
    1335 degeneracyfactor *= 10.0 * varconsratio;
    1336 }
    1337 }
    1338
    1339 vars = SCIPgetVars(scip);
    1340 nvars = SCIPgetNVars(scip);
    1341
    1342 bestsolidx = SCIPgetBestSol(scip) == NULL ? -1 : SCIPsolGetIndex(SCIPgetBestSol(scip));
    1343
    1344 /* get average conflict, inference, and pseudocost scores */
    1345 avgconflictscore = SCIPgetAvgConflictScore(scip);
    1346 avgconflictscore = MAX(avgconflictscore, 0.1);
    1347 avgconflengthscore = SCIPgetAvgConflictlengthScore(scip);
    1348 avgconflengthscore = MAX(avgconflengthscore, 0.1);
    1349 avginferencescore = SCIPgetAvgInferenceScore(scip);
    1350 avginferencescore = MAX(avginferencescore, 0.1);
    1351 avgcutoffscore = SCIPgetAvgCutoffScore(scip);
    1352 avgcutoffscore = MAX(avgcutoffscore, 0.1);
    1353 avgpscostscore = SCIPgetAvgPseudocostScore(scip);
    1354 avgpscostscore = MAX(avgpscostscore, 0.1);
    1355 avgdpscostscore = SCIPgetAvgDPseudocostScore(scip, branchruledata->discountfactor);
    1356 avgdpscostscore = MAX(avgdpscostscore, 0.1);
    1357
    1358 /* get nonlinear counts according to parameters */
    1359 SCIP_CALL( branchruledataEnsureNlcount(scip, branchruledata) );
    1360
    1361 initstrongbranching = FALSE;
    1362
    1363 /* check whether propagation should be performed */
    1364 propagate = (branchruledata->maxproprounds != 0) && !SCIPisExact(scip);
    1365
    1366 /* check whether valid bounds should be identified in probing-like fashion */
    1367 probingbounds = propagate && branchruledata->probingbounds;
    1368
    1369 /* get maximal number of candidates to initialize with strong branching; if the current solutions is not basic,
    1370 * we cannot warmstart the simplex algorithm and therefore don't initialize any candidates
    1371 */
    1372 maxninitcands = MIN(nbranchcands, branchruledata->initcand);
    1373 if( !SCIPisLPSolBasic(scip) )
    1374 maxninitcands = 0;
    1375
    1376 /* calculate maximal number of strong branching LP iterations; if we used too many, don't apply strong branching
    1377 * any more; also, if degeneracy is too high, don't run strong branching at this node
    1378 */
    1379 nlpiterationsquot = (SCIP_Longint)(branchruledata->sbiterquot * SCIPgetNNodeLPIterations(scip));
    1380 maxnsblpiterations = nlpiterationsquot + branchruledata->sbiterofs + SCIPgetNRootStrongbranchLPIterations(scip);
    1381 nsblpiterations = SCIPgetNStrongbranchLPIterations(scip);
    1382 if( nsblpiterations > maxnsblpiterations || degeneracyfactor >= 10.0 )
    1383 maxninitcands = 0;
    1384
    1385 /* get buffer for storing the unreliable candidates */
    1386 SCIP_CALL( SCIPallocBufferArray(scip, &initcands, maxninitcands+1) ); /* allocate one additional slot for convenience */
    1387 SCIP_CALL( SCIPallocBufferArray(scip, &initcandscores, maxninitcands+1) );
    1388 ninitcands = 0;
    1389
    1390 /* Allocate memory for the down and up gains, and the computed pseudocost scores */
    1391 SCIP_CALL( SCIPallocBufferArray(scip, &mingains, nbranchcands) );
    1392 SCIP_CALL( SCIPallocBufferArray(scip, &maxgains, nbranchcands) );
    1393 SCIP_CALL( SCIPallocBufferArray(scip, &scores, nbranchcands) );
    1394 SCIP_CALL( SCIPallocBufferArray(scip, &scoresfrompc, nbranchcands) );
    1395 SCIP_CALL( SCIPallocBufferArray(scip, &scoresfromothers, nbranchcands) );
    1396
    1397 /* get current node number */
    1398 nodenum = SCIPgetNNodes(scip);
    1399
    1400 /* initialize bound change arrays */
    1401 bdchginds = NULL;
    1402 bdchgtypes = NULL;
    1403 bdchgbounds = NULL;
    1404 nbdchgs = 0;
    1405 nbdconflicts = 0;
    1406 maxbdchgs = branchruledata->maxbdchgs;
    1407 if( maxbdchgs == -1 )
    1408 maxbdchgs = INT_MAX;
    1409
    1410 /* calculate value used as reliability */
    1411 prio = (maxnsblpiterations - nsblpiterations)/(nsblpiterations + 1.0);
    1412 prio = MIN(prio, 1.0);
    1413 prio = MAX(prio, (nlpiterationsquot - nsblpiterations)/(nsblpiterations + 1.0));
    1414 reliable = (1.0-prio) * branchruledata->minreliable + prio * branchruledata->maxreliable;
    1415
    1416 /* calculate the threshold for the relative error in the same way; low tolerance is more strict than higher tolerance */
    1417 relerrorthreshold = (1.0 - prio) * branchruledata->higherrortol + prio * branchruledata->lowerrortol;
    1418
    1419 clevel = (SCIP_CONFIDENCELEVEL)branchruledata->confidencelevel;
    1420 /* determine the confidence level for hypothesis testing based on value of prio */
    1421 if( branchruledata->usedynamicconfidence )
    1422 {
    1423 /* with decreasing priority, use a less strict confidence level */
    1424 if( prio >= 0.9 )
    1425 clevel = SCIP_CONFIDENCELEVEL_MAX;
    1426 else if( prio >= 0.7 )
    1428 else if( prio >= 0.5 )
    1430 else if( prio >= 0.3 )
    1431 clevel = SCIP_CONFIDENCELEVEL_LOW;
    1432 else
    1433 clevel = SCIP_CONFIDENCELEVEL_MIN;
    1434 }
    1435
    1436 /* search for the best pseudo cost candidate, while remembering unreliable candidates in a sorted buffer */
    1437 nuninitcands = 0;
    1438 bestpscand = -1;
    1439 bestpsscore = -SCIPinfinity(scip);
    1440 bestpsfracscore = -SCIPinfinity(scip);
    1441 bestpsdomainscore = -SCIPinfinity(scip);
    1442
    1443 /* search for the best candidate first */
    1444 if( branchruledata->usehyptestforreliability )
    1445 {
    1446 for( c = 0; c < nbranchcands; ++c )
    1447 {
    1448 SCIP_Real conflictscore;
    1449 SCIP_Real conflengthscore;
    1450 SCIP_Real inferencescore;
    1451 SCIP_Real cutoffscore;
    1452 SCIP_Real gmieffscore;
    1453 SCIP_Real lastgmieffscore;
    1454 SCIP_Real pscostscore;
    1455 SCIP_Real nlscore;
    1456 SCIP_Real score;
    1457
    1458 conflictscore = SCIPgetVarConflictScore(scip, branchcands[c]);
    1459 conflengthscore = SCIPgetVarConflictlengthScore(scip, branchcands[c]);
    1460 inferencescore = SCIPgetVarAvgInferenceScore(scip, branchcands[c]);
    1461 cutoffscore = SCIPgetVarAvgCutoffScore(scip, branchcands[c]);
    1462 gmieffscore = SCIPgetVarAvgGMIScore(scip, branchcands[c]);
    1463 lastgmieffscore = SCIPgetVarLastGMIScore(scip, branchcands[c]);
    1464 nlscore = calcNlscore(scip, branchruledata->nlcount, branchruledata->nlcountmax, SCIPvarGetProbindex(branchcands[c]));
    1465 pscostscore = SCIPgetVarPseudocostScore(scip, branchcands[c], branchcandssol[c]);
    1466
    1467 /* replace the pseudo cost score with the already calculated one;
    1468 * @todo: use old data for strong branching with propagation?
    1469 */
    1470 if( SCIPgetVarStrongbranchNode(scip, branchcands[c]) == nodenum )
    1471 {
    1472 SCIP_Real down;
    1473 SCIP_Real up;
    1474 SCIP_Real lastlpobjval;
    1475 SCIP_Real downgain;
    1476 SCIP_Real upgain;
    1477
    1478 /* use the score of the strong branching call at the current node */
    1479 SCIP_CALL( SCIPgetVarStrongbranchLast(scip, branchcands[c], &down, &up, NULL, NULL, NULL, &lastlpobjval) );
    1480 downgain = MAX(down - lastlpobjval, 0.0);
    1481 upgain = MAX(up - lastlpobjval, 0.0);
    1482 if( useancpscost )
    1483 {
    1484 /* add discounted gains as stored in dpscost */
    1485 SCIP_Real downsol;
    1486 SCIP_Real upsol;
    1487 downsol = SCIPfeasCeil(scip, branchcandssol[c]-1.0);
    1488 upsol = SCIPfeasFloor(scip, branchcandssol[c]+1.0);
    1489 downgain += branchruledata->discountfactor * SCIPgetVarAncPseudocostVal(scip, branchcands[c], downsol-branchcandssol[c]);
    1490 upgain += branchruledata->discountfactor * SCIPgetVarAncPseudocostVal(scip, branchcands[c], upsol-branchcandssol[c]);
    1491 downgain /= (1 + branchruledata->discountfactor);
    1492 upgain /= (1 + branchruledata->discountfactor);
    1493 }
    1494 pscostscore = SCIPgetBranchScore(scip, branchcands[c], downgain, upgain);
    1495
    1496 SCIPdebugMsg(scip, " -> strong branching on variable <%s> already performed (down=%g (%+g), up=%g (%+g), pscostscore=%g)\n",
    1497 SCIPvarGetName(branchcands[c]), down, downgain, up, upgain, pscostscore);
    1498 }
    1499
    1500 score = calcScore(scip, branchruledata, conflictscore, avgconflictscore, conflengthscore, avgconflengthscore,
    1501 inferencescore, avginferencescore, cutoffscore, avgcutoffscore, gmieffscore, lastgmieffscore,
    1502 pscostscore, avgpscostscore, nlscore, branchcandsfrac[c], degeneracyfactor);
    1503
    1504 /* check for better score of candidate */
    1505 if( SCIPisSumGE(scip, score, bestpsscore) )
    1506 {
    1507 SCIP_Real fracscore;
    1508 SCIP_Real domainscore;
    1509
    1510 fracscore = MIN(branchcandsfrac[c], 1.0 - branchcandsfrac[c]);
    1511 domainscore = -(SCIPvarGetUbLocal(branchcands[c]) - SCIPvarGetLbLocal(branchcands[c]));
    1512 if( SCIPisSumGT(scip, score, bestpsscore)
    1513 || SCIPisSumGT(scip, fracscore, bestpsfracscore)
    1514 || (SCIPisSumGE(scip, fracscore, bestpsfracscore) && domainscore > bestpsdomainscore) )
    1515 {
    1516 bestpscand = c;
    1517 bestpsscore = score;
    1518 bestpsfracscore = fracscore;
    1519 bestpsdomainscore = domainscore;
    1520 }
    1521 }
    1522 }
    1523 }
    1524
    1525 /* use discounted pseudocosts only if all candidates are reliable. */
    1526 if( useancpscost && maxninitcands > 0 )
    1527 {
    1528 /* look for at least one unreliable candidate */
    1529 for( c = 0; c < nbranchcands; ++c )
    1530 {
    1531 if( needsStrongBranching(scip, branchrule, branchcands[c], branchcandsfrac[c],
    1532 bestpscand >= 0 ? branchcands[bestpscand] : NULL,
    1533 bestpscand >= 0 ? branchcandsfrac[bestpscand] : 0.0,
    1534 reliable, relerrorthreshold, clevel, useancpscost) )
    1535 {
    1536 useancpscost = FALSE;
    1537 break;
    1538 }
    1539 }
    1540 }
    1541
    1542 if( useancpscost )
    1543 avgpscostscore = avgdpscostscore;
    1544
    1545 for( c = 0; c < nbranchcands; ++c )
    1546 {
    1547 SCIP_Real conflictscore;
    1548 SCIP_Real conflengthscore;
    1549 SCIP_Real inferencescore;
    1550 SCIP_Real cutoffscore;
    1551 SCIP_Real gmieffscore;
    1552 SCIP_Real lastgmieffscore;
    1553 SCIP_Real pscostscore;
    1554 SCIP_Real nlscore;
    1555 SCIP_Real score;
    1556 SCIP_Bool usesb;
    1557 SCIP_Real downgain;
    1558 SCIP_Real upgain;
    1559 SCIP_Real fracpart;
    1560
    1561 assert(branchcands[c] != NULL);
    1562 assert(!SCIPisFeasIntegral(scip, branchcandssol[c]) || SCIPisExact(scip));
    1563 assert(!SCIPisFeasIntegral(scip, SCIPvarGetLPSol(branchcands[c])) || SCIPisExact(scip));
    1564
    1565 /* Record the variables current pseudocosts. These may be overwritten if
    1566 * strong branching is performed.
    1567 */
    1568 sbdownvalid[c] = FALSE;
    1569 sbupvalid[c] = FALSE;
    1570 fracpart = SCIPfeasFrac(scip, SCIPvarGetLPSol(branchcands[c]));
    1571 downgain = SCIPgetVarPseudocostVal(scip, branchcands[c], 0.0 - fracpart);
    1572 upgain = SCIPgetVarPseudocostVal(scip, branchcands[c], 1.0 - fracpart);
    1573 mingains[c] = MIN(downgain, upgain);
    1574 maxgains[c] = MAX(downgain, upgain);
    1575
    1576 /* get conflict, inference, cutoff, nonlinear, and pseudo cost scores for candidate */
    1577 conflictscore = SCIPgetVarConflictScore(scip, branchcands[c]);
    1578 conflengthscore = SCIPgetVarConflictlengthScore(scip, branchcands[c]);
    1579 inferencescore = SCIPgetVarAvgInferenceScore(scip, branchcands[c]);
    1580 cutoffscore = SCIPgetVarAvgCutoffScore(scip, branchcands[c]);
    1581 gmieffscore = SCIPgetVarAvgGMIScore(scip, branchcands[c]);
    1582 lastgmieffscore = SCIPgetVarLastGMIScore(scip, branchcands[c]);
    1583 nlscore = calcNlscore(scip, branchruledata->nlcount, branchruledata->nlcountmax, SCIPvarGetProbindex(branchcands[c]));
    1584 pscostscore = SCIPgetVarPseudocostScore(scip, branchcands[c], branchcandssol[c]);
    1585 usesb = FALSE;
    1586 if( useancpscost )
    1587 pscostscore = SCIPgetVarDPseudocostScore(scip, branchcands[c], branchcandssol[c],branchruledata->discountfactor);
    1588
    1589 /* don't use strong branching on variables that have already been initialized at the current node;
    1590 * instead replace the pseudo cost score with the already calculated one;
    1591 * @todo: use old data for strong branching with propagation?
    1592 */
    1593 if( SCIPgetVarStrongbranchNode(scip, branchcands[c]) == nodenum )
    1594 {
    1595 SCIP_Real down;
    1596 SCIP_Real up;
    1597 SCIP_Real lastlpobjval;
    1598
    1599 /* use the score of the strong branching call at the current node */
    1600 SCIP_CALL( SCIPgetVarStrongbranchLast(scip, branchcands[c], &down, &up, NULL, NULL, NULL, &lastlpobjval) );
    1601 downgain = MAX(down - lastlpobjval, 0.0);
    1602 upgain = MAX(up - lastlpobjval, 0.0);
    1603 /* add discounted gains as stored in anspscost */
    1604 if( useancpscost ) {
    1605 /* the anspscost must be reliable here */
    1606 SCIP_Real downsol;
    1607 SCIP_Real upsol;
    1608 downsol = SCIPfeasCeil(scip, branchcandssol[c]-1.0);
    1609 upsol = SCIPfeasFloor(scip, branchcandssol[c]+1.0);
    1610 downgain += branchruledata->discountfactor * SCIPgetVarAncPseudocostVal(scip, branchcands[c], downsol-branchcandssol[c]);
    1611 upgain += branchruledata->discountfactor * SCIPgetVarAncPseudocostVal(scip, branchcands[c], upsol-branchcandssol[c]);
    1612 downgain /= (1 + branchruledata->discountfactor);
    1613 upgain /= (1 + branchruledata->discountfactor);
    1614 }
    1615 pscostscore = SCIPgetBranchScore(scip, branchcands[c], downgain, upgain);
    1616
    1617 mingains[c] = MIN(downgain, upgain);
    1618 maxgains[c] = MAX(downgain, upgain);
    1619
    1620 if( branchruledata->dynamiclookahead )
    1621 SCIP_CALL( updateMinMaxMeanGain(scip, branchrule, downgain, upgain) );
    1622
    1623 SCIPdebugMsg(scip, " -> strong branching on variable <%s> already performed (down=%g (%+g), up=%g (%+g), pscostscore=%g)\n",
    1624 SCIPvarGetName(branchcands[c]), down, downgain, up, upgain, pscostscore);
    1625 }
    1626 else if( maxninitcands > 0 )
    1627 {
    1628 SCIP_Real downsize;
    1629 SCIP_Real upsize;
    1630 SCIP_Real size;
    1631
    1632 /* check, if the pseudo cost score of the variable is reliable */
    1635 size = MIN(downsize, upsize);
    1636
    1637 usesb = needsStrongBranching(scip, branchrule, branchcands[c], branchcandsfrac[c],
    1638 bestpscand >= 0 ? branchcands[bestpscand] : NULL,
    1639 bestpscand >= 0 ? branchcandsfrac[bestpscand] : 0.0,
    1640 reliable, relerrorthreshold, clevel, FALSE);
    1641
    1642 /* count the number of variables that are completely uninitialized */
    1643 if( size < 0.1 )
    1644 nuninitcands++;
    1645 }
    1646
    1647 /* combine the five score values */
    1648 scoresfrompc[c] = calcScore(scip, branchruledata, 0.0, avgconflictscore, 0.0, avgconflengthscore,
    1649 0.0, avginferencescore, 0.0, avgcutoffscore, 0.0, 0.0,
    1650 pscostscore, avgpscostscore, 0.0, branchcandsfrac[c], degeneracyfactor);
    1651 scoresfromothers[c] = calcScore(scip, branchruledata, conflictscore, avgconflictscore, conflengthscore, avgconflengthscore,
    1652 inferencescore, avginferencescore, cutoffscore, avgcutoffscore, gmieffscore, lastgmieffscore,
    1653 0.0, avgpscostscore, nlscore, branchcandsfrac[c], degeneracyfactor);
    1654 score = scoresfrompc[c] + scoresfromothers[c];
    1655 scores[c] = score;
    1656 /*score = calcScore(scip, branchruledata, conflictscore, avgconflictscore, conflengthscore, avgconflengthscore,
    1657 inferencescore, avginferencescore, cutoffscore, avgcutoffscore, gmieffscore, lastgmieffscore,
    1658 pscostscore, avgpscostscore, nlscore, branchcandsfrac[c], degeneracyfactor);*/
    1659 if( usesb )
    1660 {
    1661 int j;
    1662
    1663 mingains[c] = 0;
    1664 maxgains[c] = 0;
    1665 scoresfrompc[c] = 0;
    1666 scoresfromothers[c] = 0;
    1667
    1668 /* assign a random score to this uninitialized candidate */
    1669 if( branchruledata->randinitorder )
    1670 score += SCIPrandomGetReal(branchruledata->randnumgen, 0.0, 1e-4);
    1671
    1672 /* pseudo cost of variable is not reliable: insert candidate in initcands buffer */
    1673 for( j = ninitcands; j > 0 && score > initcandscores[j-1]; --j )
    1674 {
    1675 initcands[j] = initcands[j-1];
    1676 initcandscores[j] = initcandscores[j-1];
    1677 }
    1678 initcands[j] = c;
    1679 initcandscores[j] = score;
    1680 ninitcands++;
    1681 ninitcands = MIN(ninitcands, maxninitcands);
    1682 }
    1683 /* in the case of hypothesis reliability, the best pseudo candidate has been determined already */
    1684 else if( !branchruledata->usehyptestforreliability )
    1685 {
    1686 /* variable will keep its pseudo cost value: check for better score of candidate */
    1687 if( SCIPisSumGE(scip, score, bestpsscore) )
    1688 {
    1689 SCIP_Real fracscore;
    1690 SCIP_Real domainscore;
    1691
    1692 fracscore = MIN(branchcandsfrac[c], 1.0 - branchcandsfrac[c]);
    1693 domainscore = -(SCIPvarGetUbLocal(branchcands[c]) - SCIPvarGetLbLocal(branchcands[c]));
    1694 if( SCIPisSumGT(scip, score, bestpsscore)
    1695 || SCIPisSumGT(scip, fracscore, bestpsfracscore)
    1696 || (SCIPisSumGE(scip, fracscore, bestpsfracscore) && domainscore > bestpsdomainscore) )
    1697 {
    1698 bestpscand = c;
    1699 bestpsscore = score;
    1700 bestpsfracscore = fracscore;
    1701 bestpsdomainscore = domainscore;
    1702 }
    1703 }
    1704 }
    1705 }
    1706
    1707 /* in the special case that only the best pseudo candidate was selected for strong branching, skip the strong branching */
    1708 if( branchruledata->usehyptestforreliability && ninitcands == 1 )
    1709 {
    1710 ninitcands = 0;
    1711 SCIPdebugMsg(scip, "Only one single candidate for initialization-->Skipping strong branching\n");
    1712 }
    1713
    1714 /* initialize unreliable candidates with strong branching until maxlookahead is reached,
    1715 * search best strong branching candidate
    1716 */
    1717 maxlookahead = (SCIP_Real)branchruledata->maxlookahead * (1.0 + (SCIP_Real)nuninitcands/(SCIP_Real)nbranchcands);
    1718 inititer = branchruledata->inititer;
    1719 if( inititer == 0 )
    1720 {
    1721 SCIP_Longint nlpiterations;
    1722 SCIP_Longint nlps;
    1723
    1724 /* iteration limit is set to twice the average number of iterations spent to resolve a dual feasible SCIP_LP;
    1725 * at the first few nodes, this average is not very exact, so we better increase the iteration limit on
    1726 * these very important nodes
    1727 */
    1728 nlpiterations = SCIPgetNDualResolveLPIterations(scip);
    1730 if( nlps == 0 )
    1731 {
    1732 nlpiterations = SCIPgetNNodeInitLPIterations(scip);
    1733 nlps = SCIPgetNNodeInitLPs(scip);
    1734 if( nlps == 0 )
    1735 {
    1736 nlpiterations = 1000;
    1737 nlps = 1;
    1738 }
    1739 }
    1740 assert(nlps >= 1);
    1741 inititer = (int)(2*nlpiterations / nlps);
    1742 inititer = (int)((SCIP_Real)inititer * (1.0 + 20.0/nodenum));
    1743 inititer = MAX(inititer, 10);
    1744 inititer = MIN(inititer, 500);
    1745 }
    1746
    1747 SCIPdebugMsg(scip, "strong branching (reliable=%g, %d/%d cands, %d uninit, maxcands=%d, maxlookahead=%g, maxbdchgs=%d, inititer=%d, iterations:%" SCIP_LONGINT_FORMAT "/%" SCIP_LONGINT_FORMAT ", basic:%u)\n",
    1748 reliable, ninitcands, nbranchcands, nuninitcands, maxninitcands, maxlookahead, maxbdchgs, inititer,
    1750
    1751 bestsbcand = -1;
    1752 bestsbscore = -SCIPinfinity(scip);
    1753 bestsbfracscore = -SCIPinfinity(scip);
    1754 bestsbdomainscore = -SCIPinfinity(scip);
    1755 bestuninitsbscore = -SCIPinfinity(scip);
    1756 bestuninitsbcand = -1;
    1757 lookahead = 0.0;
    1758
    1759 for( i = 0; continueStrongBranchingLookahead(scip, i, ninitcands, lookahead, maxlookahead, nbdchgs, nbdconflicts, maxbdchgs, maxnsblpiterations) && continueStrongBranchingTreeSizeEstimation(scip, branchruledata, lookahead, maxlookahead); ++i )
    1760 {
    1761 SCIP_Real down;
    1762 SCIP_Real up;
    1763 SCIP_Real downgain;
    1764 SCIP_Real upgain;
    1765 SCIP_Bool downvalid;
    1766 SCIP_Bool upvalid;
    1767 SCIP_Longint ndomredsdown;
    1768 SCIP_Longint ndomredsup;
    1769 SCIP_Bool lperror;
    1770 SCIP_Bool downinf;
    1771 SCIP_Bool upinf;
    1772 SCIP_Bool downconflict;
    1773 SCIP_Bool upconflict;
    1774
    1775 /* get candidate number to initialize */
    1776 c = initcands[i];
    1777 assert(!SCIPisFeasIntegral(scip, branchcandssol[c]) || SCIPisExact(scip));
    1778
    1779 if( branchruledata->skipbadinitcands )
    1780 {
    1781 SCIP_Bool skipsb = FALSE;
    1782 /* if the current best candidate is a candidate found by strong branching, determine if candidate pseudo-costs are
    1783 * significantly smaller in at least one direction, in which case we safe the execution of strong-branching for now
    1784 */
    1785 if( bestsbscore > bestpsscore && bestsbscore > bestuninitsbscore && bestsbupvalid && bestsbdownvalid )
    1786 {
    1787 assert(bestsbcand != -1);
    1788 assert(bestsbup != SCIP_INVALID && bestsbdown != SCIP_INVALID); /*lint !e777 lint doesn't like comparing floats */
    1789
    1790 /* test if the variable is unlikely to produce a better gain than the currently best one. Skip strong-branching
    1791 * in such a case
    1792 */
    1793 if( SCIPpscostThresholdProbabilityTest(scip, branchcands[c], branchcandsfrac[c], bestsbdown,
    1795 || SCIPpscostThresholdProbabilityTest(scip, branchcands[c], 1.0 - branchcandsfrac[c], bestsbup,
    1796 SCIP_BRANCHDIR_UPWARDS, clevel) )
    1797 skipsb = TRUE;
    1798 }
    1799 /* the currently best candidate is also a pseudo-candidate; apply significance test and skip candidate if it
    1800 * is significantly worse in at least one direction
    1801 */
    1802 else if( bestpscand != -1 && bestpsscore > bestuninitsbscore )
    1803 {
    1804 if( SCIPsignificantVarPscostDifference(scip, branchcands[bestpscand], branchcandsfrac[bestpscand],
    1805 branchcands[c], branchcandsfrac[c], SCIP_BRANCHDIR_DOWNWARDS, clevel, TRUE)
    1806 || SCIPsignificantVarPscostDifference(scip, branchcands[bestpscand], 1.0 - branchcandsfrac[bestpscand],
    1807 branchcands[c], 1.0 - branchcandsfrac[c], SCIP_BRANCHDIR_UPWARDS, clevel, TRUE) )
    1808 skipsb = TRUE;
    1809 }
    1810 /* compare against the best init cand that has been skipped already */
    1811 else if( bestuninitsbcand != -1 )
    1812 {
    1813 if( SCIPsignificantVarPscostDifference(scip, branchcands[bestuninitsbcand], branchcandsfrac[bestuninitsbcand],
    1814 branchcands[c], branchcandsfrac[c], SCIP_BRANCHDIR_DOWNWARDS, clevel, TRUE)
    1815 || SCIPsignificantVarPscostDifference(scip, branchcands[bestuninitsbcand], 1.0 - branchcandsfrac[bestuninitsbcand],
    1816 branchcands[c], 1.0 - branchcandsfrac[c], SCIP_BRANCHDIR_UPWARDS, clevel, TRUE) )
    1817 skipsb = TRUE;
    1818 }
    1819
    1820 /* skip candidate, update the best score of an unitialized candidate */
    1821 if( skipsb )
    1822 {
    1823 if( bestuninitsbcand == -1 )
    1824 {
    1825 bestuninitsbcand = c;
    1826 bestuninitsbscore = initcandscores[i];
    1827 }
    1828 continue;
    1829 }
    1830 }
    1831 SCIPdebugMsg(scip, "init pseudo cost (%g/%g) of <%s> at %g (score:%g) with strong branching (%d iterations) -- %" SCIP_LONGINT_FORMAT "/%" SCIP_LONGINT_FORMAT " iterations\n",
    1834 SCIPvarGetName(branchcands[c]), branchcandssol[c], initcandscores[i],
    1835 inititer, SCIPgetNStrongbranchLPIterations(scip), maxnsblpiterations);
    1836
    1837 /* use strong branching on candidate */
    1838 if( !initstrongbranching )
    1839 {
    1840 initstrongbranching = TRUE;
    1841
    1842 SCIP_CALL( SCIPstartStrongbranch(scip, propagate) );
    1843
    1844 /* create arrays for probing-like bound tightening */
    1845 if( probingbounds )
    1846 {
    1847 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &newlbs, nvars) );
    1848 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &newubs, nvars) );
    1849 }
    1850 }
    1851
    1852 if( propagate )
    1853 {
    1854 /* apply strong branching */
    1855 SCIP_CALL( SCIPgetVarStrongbranchWithPropagation(scip, branchcands[c], branchcandssol[c], lpobjval, inititer,
    1856 branchruledata->maxproprounds, &down, &up, &downvalid, &upvalid, &ndomredsdown, &ndomredsup, &downinf, &upinf,
    1857 &downconflict, &upconflict, &lperror, newlbs, newubs) );
    1858 }
    1859 else
    1860 {
    1861 /* apply strong branching */
    1862 SCIP_CALL( SCIPgetVarStrongbranchFrac(scip, branchcands[c], inititer, FALSE,
    1863 &down, &up, &downvalid, &upvalid, &downinf, &upinf, &downconflict, &upconflict, &lperror) );
    1864
    1865 ndomredsdown = ndomredsup = 0;
    1866 }
    1867
    1868 /* check for an error in strong branching */
    1869 if( lperror )
    1870 {
    1871 if( !SCIPisStopped(scip) )
    1872 {
    1874 "(node %" SCIP_LONGINT_FORMAT ") error in strong branching call for variable <%s> with solution %g\n",
    1875 SCIPgetNNodes(scip), SCIPvarGetName(branchcands[c]), branchcandssol[c]);
    1876 }
    1877 break;
    1878 }
    1879
    1880 /* Strong branching might have found a new primal solution which updated the cutoff bound. In this case, the
    1881 * provedbound computed before can be higher than the cutoffbound and the current node can be cut off.
    1882 * Additionally, also if the value for the current best candidate is valid and exceeds the new cutoff bound,
    1883 * we want to change the domain of this variable rather than branching on it.
    1884 */
    1885 if( SCIPgetBestSol(scip) != NULL && SCIPsolGetIndex(SCIPgetBestSol(scip)) != bestsolidx )
    1886 {
    1887 bestsolidx = SCIPsolGetIndex(SCIPgetBestSol(scip));
    1888
    1889 SCIPdebugMsg(scip, " -> strong branching on variable <%s> lead to a new incumbent\n",
    1890 SCIPvarGetName(branchcands[c]));
    1891
    1892 /* proved bound for current node is larger than new cutoff bound -> cut off current node */
    1893 if( SCIPisGE(scip, provedbound, SCIPgetCutoffbound(scip)) )
    1894 {
    1895 SCIPdebugMsg(scip, " -> node can be cut off (provedbound=%g, cutoff=%g)\n", provedbound, SCIPgetCutoffbound(scip));
    1896
    1897 *result = SCIP_CUTOFF;
    1898 break; /* terminate initialization loop, because node is infeasible */
    1899 }
    1900 /* proved bound for down child of best candidate is larger than cutoff bound
    1901 * -> increase lower bound of best candidate
    1902 * we must only do this if the LP is complete, i.e., we are not doing column generation
    1903 */
    1904
    1905 else if( bestsbcand != -1 && allcolsinlp )
    1906 {
    1907 if( !bestsbdowncutoff && bestsbdownvalid && SCIPisGE(scip, bestsbdown, SCIPgetCutoffbound(scip)) )
    1908 {
    1909 bestsbdowncutoff = TRUE;
    1910
    1911 SCIPdebugMsg(scip, " -> valid dual bound for down child of best candidate <%s> is higher than new cutoff bound (valid=%u, bestsbdown=%g, cutoff=%g)\n",
    1912 SCIPvarGetName(branchcands[bestsbcand]), bestsbdownvalid, bestsbdown, SCIPgetCutoffbound(scip));
    1913
    1914 SCIPdebugMsg(scip, " -> increase lower bound of best candidate <%s> to %g\n",
    1915 SCIPvarGetName(branchcands[bestsbcand]), SCIPfeasCeil(scip, branchcandssol[bestsbcand]));
    1916
    1917 SCIP_CALL( addBdchg(scip, &bdchginds, &bdchgtypes, &bdchgbounds, &nbdchgs, SCIPvarGetProbindex(branchcands[bestsbcand]),
    1918 SCIP_BOUNDTYPE_LOWER, SCIPfeasCeil(scip, branchcandssol[bestsbcand])) );
    1919 }
    1920 /* proved bound for up child of best candidate is larger than cutoff bound -> decrease upper bound of best candidate */
    1921 else if( !bestsbupcutoff && bestsbupvalid && SCIPisGE(scip, bestsbup, SCIPgetCutoffbound(scip)) )
    1922 {
    1923 bestsbupcutoff = TRUE;
    1924
    1925 SCIPdebugMsg(scip, " -> valid dual bound for up child of best candidate <%s> is higher than new cutoff bound (valid=%u, bestsbup=%g, cutoff=%g)\n",
    1926 SCIPvarGetName(branchcands[bestsbcand]), bestsbupvalid, bestsbup, SCIPgetCutoffbound(scip));
    1927
    1928 SCIPdebugMsg(scip, " -> decrease upper bound of best candidate <%s> to %g\n",
    1929 SCIPvarGetName(branchcands[bestsbcand]), SCIPfeasFloor(scip, branchcandssol[bestsbcand]));
    1930
    1931 SCIP_CALL( addBdchg(scip, &bdchginds, &bdchgtypes, &bdchgbounds, &nbdchgs, SCIPvarGetProbindex(branchcands[bestsbcand]),
    1932 SCIP_BOUNDTYPE_UPPER, SCIPfeasFloor(scip, branchcandssol[bestsbcand])) );
    1933 }
    1934 }
    1935 }
    1936
    1937 /* evaluate strong branching */
    1938 down = MAX(down, lpobjval);
    1939 up = MAX(up, lpobjval);
    1940 downgain = down - lpobjval;
    1941 upgain = up - lpobjval;
    1942 assert(!useancpscost);
    1943 assert(!allcolsinlp || exactsolve || !downvalid || downinf == SCIPisGE(scip, down, SCIPgetCutoffbound(scip)));
    1944 assert(!allcolsinlp || exactsolve || !upvalid || upinf == SCIPisGE(scip, up, SCIPgetCutoffbound(scip)));
    1945 assert(downinf || !downconflict);
    1946 assert(upinf || !upconflict);
    1947
    1948 if( branchruledata->dynamiclookahead )
    1949 SCIP_CALL( updateMinMaxMeanGain(scip, branchrule, downgain, upgain) );
    1950
    1951 /* @todo: store pseudo cost only for valid bounds?
    1952 * depending on the user parameter choice of storesemiinitcosts, pseudo costs are also updated in single directions,
    1953 * if the node in the other direction was infeasible or cut off
    1954 */
    1955 if( !downinf
    1956#ifdef WITH_LPSOLSTAT
    1958#endif
    1959 && (!upinf || branchruledata->storesemiinitcosts) )
    1960 {
    1961 SCIP_Real weight;
    1962
    1963 /* smaller weights are given if the strong branching hit the time limit in the corresponding direction */
    1964 if( branchruledata->usesmallweightsitlim )
    1966 else
    1967 weight = 1.0;
    1968
    1969 /* update pseudo cost values */
    1970 SCIP_CALL( SCIPupdateVarPseudocostSymmetric(scip, branchruledata, branchcands[c], branchorbitidx, c, 0.0 - branchcandsfrac[c], downgain, weight) );
    1971 }
    1972 if( !upinf
    1973#ifdef WITH_LPSOLSTAT
    1975#endif
    1976 && (!downinf || branchruledata->storesemiinitcosts) )
    1977 {
    1978 SCIP_Real weight;
    1979
    1980 /* smaller weights are given if the strong branching hit the time limit in the corresponding direction */
    1981 if( branchruledata->usesmallweightsitlim )
    1983 else
    1984 weight = 1.0;
    1985
    1986 /* update pseudo cost values */
    1987 SCIP_CALL( SCIPupdateVarPseudocostSymmetric(scip, branchruledata, branchcands[c], branchorbitidx, c, 1.0 - branchcandsfrac[c], upgain, weight) );
    1988 }
    1989
    1990 /* the minimal lower bound of both children is a proved lower bound of the current subtree */
    1991 if( allcolsinlp && !exactsolve && downvalid && upvalid )
    1992 {
    1993 SCIP_Real minbound;
    1994
    1995 minbound = MIN(down, up);
    1996 provedbound = MAX(provedbound, minbound);
    1997 assert((downinf && upinf) || SCIPisLT(scip, provedbound, SCIPgetCutoffbound(scip)));
    1998
    1999 /* save probing-like bounds detected during strong branching */
    2000 if( probingbounds && ( !downinf || !upinf ) )
    2001 {
    2002 int v;
    2003
    2004 assert(newlbs != NULL);
    2005 assert(newubs != NULL);
    2006
    2007 for( v = 0; v < nvars; ++v )
    2008 {
    2009 if( SCIPisGT(scip, newlbs[v], SCIPvarGetLbLocal(vars[v])) )
    2010 {
    2011 SCIPdebugMsg(scip, "better lower bound for variable <%s>: %.9g -> %.9g (by strongbranching on <%s>)\n",
    2012 SCIPvarGetName(vars[v]), SCIPvarGetLbLocal(vars[v]), newlbs[v], SCIPvarGetName(branchcands[c]));
    2013
    2014 SCIP_CALL( addBdchg(scip, &bdchginds, &bdchgtypes, &bdchgbounds, &nbdchgs, v,
    2015 SCIP_BOUNDTYPE_LOWER, newlbs[v]) );
    2016 }
    2017 if( SCIPisLT(scip, newubs[v], SCIPvarGetUbLocal(vars[v])) )
    2018 {
    2019 SCIPdebugMsg(scip, "better upper bound for variable <%s>: %.9g -> %.9g (by strongbranching on <%s>)\n",
    2020 SCIPvarGetName(vars[v]), SCIPvarGetUbLocal(vars[v]), newubs[v], SCIPvarGetName(branchcands[c]));
    2021
    2022 SCIP_CALL( addBdchg(scip, &bdchginds, &bdchgtypes, &bdchgbounds, &nbdchgs, v,
    2023 SCIP_BOUNDTYPE_UPPER, newubs[v]) );
    2024 }
    2025 }
    2026 }
    2027 }
    2028
    2029 /* check if there are infeasible roundings */
    2030 if( (downinf || upinf) && !exactsolve )
    2031 {
    2032 assert(allcolsinlp || propagate);
    2033
    2034 if( downinf && upinf )
    2035 {
    2036 /* both roundings are infeasible -> node is infeasible */
    2037 SCIPdebugMsg(scip, " -> variable <%s> is infeasible in both directions (conflict: %u/%u)\n",
    2038 SCIPvarGetName(branchcands[c]), downconflict, upconflict);
    2039 *result = SCIP_CUTOFF;
    2040 break; /* terminate initialization loop, because node is infeasible */
    2041 }
    2042 else
    2043 {
    2044 /* rounding is infeasible in one direction -> round variable in other direction */
    2045 SCIPdebugMsg(scip, " -> variable <%s> is infeasible in %s branch (conflict: %u/%u)\n",
    2046 SCIPvarGetName(branchcands[c]), downinf ? "downward" : "upward", downconflict, upconflict);
    2047 SCIP_CALL( addBdchg(scip, &bdchginds, &bdchgtypes, &bdchgbounds, &nbdchgs, SCIPvarGetProbindex(branchcands[c]),
    2049 (downinf ? SCIPfeasCeil(scip, branchcandssol[c]) : SCIPfeasFloor(scip, branchcandssol[c]))) );
    2050 if( nbdchgs + nbdconflicts >= maxbdchgs )
    2051 break; /* terminate initialization loop, because enough roundings are performed */
    2052 }
    2053 }
    2054 else
    2055 {
    2056 SCIP_Real conflictscore;
    2057 SCIP_Real conflengthscore;
    2058 SCIP_Real inferencescore;
    2059 SCIP_Real cutoffscore;
    2060 SCIP_Real gmieffscore;
    2061 SCIP_Real lastgmieffscore;
    2062 SCIP_Real pscostscore;
    2063 SCIP_Real nlscore;
    2064 SCIP_Real score;
    2065
    2066 mingains[c] = MIN(downgain, upgain);
    2067 maxgains[c] = MAX(downgain, upgain);
    2068
    2069 sbdown[c] = down;
    2070 sbup[c] = up;
    2071 sbdownvalid[c] = downvalid;
    2072 sbupvalid[c] = upvalid;
    2073
    2074 /* check for a better score */
    2075 conflictscore = SCIPgetVarConflictScore(scip, branchcands[c]);
    2076 conflengthscore = SCIPgetVarConflictlengthScore(scip, branchcands[c]);
    2077 nlscore = calcNlscore(scip, branchruledata->nlcount, branchruledata->nlcountmax, SCIPvarGetProbindex(branchcands[c]));
    2078
    2079 /* optionally, use only local information obtained via strong branching for this candidate, i.e., local
    2080 * domain reductions and no cutoff score
    2081 */
    2082 inferencescore = branchruledata->usesblocalinfo ? SCIPgetBranchScore(scip, branchcands[c], (SCIP_Real)ndomredsdown, (SCIP_Real)ndomredsup)
    2083 : SCIPgetVarAvgInferenceScore(scip, branchcands[c]);
    2084 cutoffscore = branchruledata->usesblocalinfo ? 0.0 : SCIPgetVarAvgCutoffScore(scip, branchcands[c]);
    2085 gmieffscore = branchruledata->usesblocalinfo ? 0.0 : SCIPgetVarAvgGMIScore(scip, branchcands[c]);
    2086 lastgmieffscore = branchruledata->usesblocalinfo ? 0.0 : SCIPgetVarLastGMIScore(scip, branchcands[c]);
    2087 pscostscore = SCIPgetBranchScore(scip, branchcands[c], downgain, upgain);
    2088
    2089 scoresfrompc[c] = calcScore(scip, branchruledata, 0.0, avgconflictscore, 0.0, avgconflengthscore,
    2090 0.0, avginferencescore, 0.0, avgcutoffscore, 0.0, 0.0, pscostscore,
    2091 avgpscostscore, 0.0, branchcandsfrac[c], degeneracyfactor);
    2092 scoresfromothers[c] = calcScore(scip, branchruledata, conflictscore, avgconflictscore, conflengthscore, avgconflengthscore,
    2093 inferencescore, avginferencescore, cutoffscore, avgcutoffscore, gmieffscore,
    2094 lastgmieffscore, 0.0, avgpscostscore, nlscore, branchcandsfrac[c],
    2095 degeneracyfactor);
    2096 score = scoresfrompc[c] + scoresfromothers[c];
    2097 scores[c] = score;
    2098 /*score = calcScore(scip, branchruledata, conflictscore, avgconflictscore, conflengthscore, avgconflengthscore,
    2099 inferencescore, avginferencescore, cutoffscore, avgcutoffscore, gmieffscore, lastgmieffscore,
    2100 pscostscore, avgpscostscore, nlscore, branchcandsfrac[c], degeneracyfactor);*/
    2101
    2102 if( SCIPisSumGE(scip, score, bestsbscore) )
    2103 {
    2104 SCIP_Real fracscore;
    2105 SCIP_Real domainscore;
    2106
    2107 fracscore = MIN(branchcandsfrac[c], 1.0 - branchcandsfrac[c]);
    2108 domainscore = -(SCIPvarGetUbLocal(branchcands[c]) - SCIPvarGetLbLocal(branchcands[c]));
    2109 if( SCIPisSumGT(scip, score, bestsbscore)
    2110 || SCIPisSumGT(scip, fracscore, bestsbfracscore)
    2111 || (SCIPisSumGE(scip, fracscore, bestsbfracscore) && domainscore > bestsbdomainscore) )
    2112 {
    2113 bestsbcand = c;
    2114 bestsbscore = score;
    2115 bestsbdown = down;
    2116 bestsbup = up;
    2117 bestsbdownvalid = downvalid;
    2118 bestsbupvalid = upvalid;
    2119 bestsbdowncutoff = FALSE;
    2120 bestsbupcutoff = FALSE;
    2121 bestsbfracscore = fracscore;
    2122 bestsbdomainscore = domainscore;
    2123 lookahead = 0.0;
    2124 }
    2125 else
    2126 lookahead += 0.5;
    2127 }
    2128 else
    2129 lookahead += 1.0;
    2130
    2131 SCIPdebugMsg(scip, " -> variable <%s> (solval=%g, down=%g (%+g,valid=%u), up=%g (%+g,valid=%u), score=%g/ %g/%g %g/%g %g -> %g)\n",
    2132 SCIPvarGetName(branchcands[c]), branchcandssol[c], down, downgain, downvalid, up, upgain, upvalid,
    2133 pscostscore, conflictscore, conflengthscore, inferencescore, cutoffscore, gmieffscore, score);
    2134 }
    2135 }
    2136#ifdef SCIP_DEBUG
    2137 if( bestsbcand >= 0 )
    2138 {
    2139 SCIPdebugMsg(scip, " -> best: <%s> (%g / %g / %g), lookahead=%g/%g\n",
    2140 SCIPvarGetName(branchcands[bestsbcand]), bestsbscore, bestsbfracscore, bestsbdomainscore,
    2141 lookahead, maxlookahead);
    2142 }
    2143#endif
    2144
    2145 if( initstrongbranching )
    2146 {
    2147 if( probingbounds )
    2148 {
    2149 assert(newlbs != NULL);
    2150 assert(newubs != NULL);
    2151
    2152 SCIPfreeBlockMemoryArray(scip, &newubs, nvars);
    2153 SCIPfreeBlockMemoryArray(scip, &newlbs, nvars);
    2154 }
    2155
    2157
    2159 {
    2160 assert(SCIPhasCurrentNodeLP(scip));
    2161 *result = SCIP_CUTOFF;
    2162 }
    2163 }
    2164
    2165 if( *result != SCIP_CUTOFF )
    2166 {
    2167 /* get the score of the best uninitialized strong branching candidate */
    2168 if( i < ninitcands && bestuninitsbcand == -1 )
    2169 bestuninitsbscore = initcandscores[i];
    2170
    2171 /* if the best pseudo cost candidate is better than the best uninitialized strong branching candidate,
    2172 * compare it to the best initialized strong branching candidate
    2173 */
    2174 if( bestpsscore > bestuninitsbscore && SCIPisSumGT(scip, bestpsscore, bestsbscore) )
    2175 {
    2176 bestcand = bestpscand;
    2177 bestisstrongbranch = FALSE;
    2178 }
    2179 else if( bestsbcand >= 0 )
    2180 {
    2181 bestcand = bestsbcand;
    2182 bestisstrongbranch = TRUE;
    2183 }
    2184 else
    2185 {
    2186 /* no candidate was initialized, and the best score is the one of the first candidate in the initialization
    2187 * queue
    2188 */
    2189 assert(ninitcands >= 1);
    2190 bestcand = initcands[0];
    2191 bestisstrongbranch = FALSE;
    2192 }
    2193
    2194 /* update lower bound of current node */
    2195 if( allcolsinlp && !exactsolve )
    2196 {
    2197 assert(SCIPisLT(scip, provedbound, SCIPgetCutoffbound(scip)));
    2198 SCIP_CALL( SCIPupdateLocalLowerbound(scip, provedbound) );
    2199 assert(SCIPisGE(scip, SCIPgetLocalLowerbound(scip), provedbound));
    2200 }
    2201 }
    2202
    2203 /* apply domain reductions */
    2204 if( nbdchgs > 0 )
    2205 {
    2206 if( *result != SCIP_CUTOFF )
    2207 {
    2208 SCIP_CALL( applyBdchgs(scip, vars, bdchginds, bdchgtypes, bdchgbounds, nbdchgs, result) );
    2209 if( *result != SCIP_CUTOFF )
    2210 *result = SCIP_REDUCEDDOM;
    2211 }
    2212 freeBdchgs(scip, &bdchginds, &bdchgtypes, &bdchgbounds, &nbdchgs);
    2213 }
    2214
    2215 /* Apply the Treemodel branching rule to potentially select a better branching candidate than the current one. */
    2216 if( *result != SCIP_CUTOFF && *result != SCIP_REDUCEDDOM && *result != SCIP_CONSADDED && SCIPtreemodelIsEnabled(scip, branchruledata->treemodel) )
    2217 {
    2218 SCIP_Real smallpscost;
    2219 SCIP_Bool usetreemodel;
    2220
    2221 usetreemodel = TRUE;
    2222
    2223 /* If the pseudocosts are zero, use SCIPs best variable since the Treemodel is not applicable */
    2224 if( SCIPisZero(scip, maxgains[bestcand]))
    2225 {
    2226 usetreemodel = FALSE;
    2227 }
    2228
    2229 /* If SCIPs best candidate was selected due to hybrid branching scores
    2230 * rather than because of pseudocosts, then we keep it.
    2231 */
    2232 SCIP_CALL( SCIPgetRealParam(scip, "branching/treemodel/smallpscost", &smallpscost) );
    2233 if( usetreemodel == TRUE && avgpscostscore <= smallpscost )
    2234 {
    2235 int cand;
    2236 for( cand = 0; cand < nbranchcands; ++cand )
    2237 {
    2238 if( scoresfrompc[cand] > scoresfrompc[bestcand] )
    2239 {
    2240 usetreemodel = FALSE;
    2241 break;
    2242 }
    2243 }
    2244 }
    2245
    2246 if( usetreemodel == TRUE )
    2247 {
    2249 scip, /* SCIP data structure */
    2250 branchruledata->treemodel, /* branching rule */
    2251 branchcands, /* branching candidate storage */
    2252 mingains, /* minimum gain of rounding downwards or upwards */
    2253 maxgains, /* maximum gain of rounding downwards or upwards */
    2254 scoresfromothers, /* scores from other branching methods */
    2255 nbranchcands, /* the number of branching candidates */
    2256 &bestcand /* the best branching candidate found by SCIP */
    2257 ) );
    2258 }
    2259 }
    2260
    2261 /* free buffer for the lp gains and pseudocost scores */
    2262 SCIPfreeBufferArray(scip, &scoresfromothers);
    2263 SCIPfreeBufferArray(scip, &scoresfrompc);
    2264 SCIPfreeBufferArray(scip, &scores);
    2265 SCIPfreeBufferArray(scip, &maxgains);
    2266 SCIPfreeBufferArray(scip, &mingains);
    2267
    2268 /* free buffer for the unreliable candidates */
    2269 SCIPfreeBufferArray(scip, &initcandscores);
    2270 SCIPfreeBufferArray(scip, &initcands);
    2271 }
    2272
    2273 /* if no domain could be reduced, create the branching */
    2274 if( *result != SCIP_CUTOFF && *result != SCIP_REDUCEDDOM && *result != SCIP_CONSADDED && executebranch )
    2275 {
    2276 SCIP_NODE* downchild;
    2277 SCIP_NODE* upchild;
    2278 SCIP_VAR* var;
    2279 SCIP_Real val;
    2280
    2281 assert(*result == SCIP_DIDNOTRUN);
    2282 assert(0 <= bestcand && bestcand < nbranchcands);
    2283 assert(!SCIPisFeasIntegral(scip, branchcandssol[bestcand]));
    2284 assert(!allcolsinlp || SCIPisLT(scip, provedbound, SCIPgetCutoffbound(scip)) || exactsolve);
    2285 assert(!bestsbdowncutoff && !bestsbupcutoff);
    2286
    2287 var = branchcands[bestcand];
    2288 val = branchcandssol[bestcand];
    2289
    2290 /* perform the branching */
    2291 SCIPdebugMsg(scip, " -> %d (%d) cands, sel cand %d: var <%s> (sol=%g, down=%g (%+g), up=%g (%+g), sb=%u, psc=%g/%g [%g])\n",
    2292 nbranchcands, ninitcands, bestcand, SCIPvarGetName(var), branchcandssol[bestcand],
    2293 bestsbdown, bestsbdown - lpobjval, bestsbup, bestsbup - lpobjval, bestisstrongbranch,
    2296 SCIPgetVarPseudocostScoreCurrentRun(scip, var, branchcandssol[bestcand]));
    2297 SCIP_UNUSED(bestisstrongbranch);
    2298 SCIP_CALL( SCIPbranchVarVal(scip, var, val, &downchild, NULL, &upchild) );
    2299 assert(downchild != NULL);
    2300 assert(upchild != NULL);
    2301
    2302 /* update the lower bounds in the children */
    2303 if( allcolsinlp && !exactsolve )
    2304 {
    2305 if( sbdownvalid[bestcand] )
    2306 {
    2307 assert(SCIPisLT(scip, sbdown[bestcand], SCIPgetCutoffbound(scip)));
    2308 SCIP_CALL( SCIPupdateNodeLowerbound(scip, downchild, sbdown[bestcand]) );
    2309 assert(SCIPisGE(scip, SCIPgetNodeLowerbound(scip, downchild), provedbound));
    2310 }
    2311 if( sbupvalid[bestcand] )
    2312 {
    2313 assert(SCIPisLT(scip, sbup[bestcand], SCIPgetCutoffbound(scip)));
    2314 SCIP_CALL( SCIPupdateNodeLowerbound(scip, upchild, sbup[bestcand]) );
    2315 assert(SCIPisGE(scip, SCIPgetNodeLowerbound(scip, upchild), provedbound));
    2316 }
    2317 }
    2318
    2319 SCIPdebugMsg(scip, " -> down child's lowerbound: %g\n", SCIPnodeGetLowerbound(downchild));
    2320 SCIPdebugMsg(scip, " -> up child's lowerbound : %g\n", SCIPnodeGetLowerbound(upchild));
    2321
    2323
    2324 *result = SCIP_BRANCHED;
    2325 }
    2326
    2327 /* free buffer for the strong branching lp gains */
    2328 SCIPfreeBufferArray(scip, &sbupvalid);
    2329 SCIPfreeBufferArray(scip, &sbdownvalid);
    2330 SCIPfreeBufferArray(scip, &sbup);
    2331 SCIPfreeBufferArray(scip, &sbdown);
    2332
    2333 return SCIP_OKAY;
    2334}
    2335
    2336
    2337/*
    2338 * Callback methods
    2339 */
    2340
    2341/** copy method for branchrule plugins (called when SCIP copies plugins) */
    2342static
    2343SCIP_DECL_BRANCHCOPY(branchCopyRelpscost)
    2344{ /*lint --e{715}*/
    2345 assert(scip != NULL);
    2346 assert(branchrule != NULL);
    2347 assert(strcmp(SCIPbranchruleGetName(branchrule), BRANCHRULE_NAME) == 0);
    2348
    2349 /* call inclusion method of branchrule */
    2351
    2352 return SCIP_OKAY;
    2353}
    2354
    2355/** destructor of branching rule to free user data (called when SCIP is exiting) */
    2356static
    2357SCIP_DECL_BRANCHFREE(branchFreeRelpscost)
    2358{ /*lint --e{715}*/
    2359 SCIP_BRANCHRULEDATA* branchruledata;
    2360 branchruledata = SCIPbranchruleGetData(branchrule);
    2361
    2362 /* free Treemodel parameter data structure */
    2363 SCIP_CALL( SCIPtreemodelFree(scip, &branchruledata->treemodel) );
    2364
    2365 /* free branching rule data */
    2366 SCIPfreeBlockMemory(scip, &branchruledata);
    2367 SCIPbranchruleSetData(branchrule, NULL);
    2368
    2369 return SCIP_OKAY;
    2370}
    2371
    2372
    2373/** solving process initialization method of branching rule (called when branch and bound process is about to begin) */
    2374static
    2375SCIP_DECL_BRANCHINITSOL(branchInitsolRelpscost)
    2376{ /*lint --e{715}*/
    2377 SCIP_BRANCHRULEDATA* branchruledata;
    2378
    2379 /* initialize branching rule data */
    2380 branchruledata = SCIPbranchruleGetData(branchrule);
    2381 branchruledata->nlcount = NULL;
    2382 branchruledata->nlcountsize = 0;
    2383 branchruledata->nlcountmax = 1;
    2384 assert(branchruledata->startrandseed >= 0);
    2385
    2386 /* create a random number generator */
    2387 SCIP_CALL( SCIPcreateRandom(scip, &branchruledata->randnumgen,
    2388 (unsigned int)branchruledata->startrandseed, TRUE) );
    2389
    2390 return SCIP_OKAY;
    2391}
    2392
    2393
    2394/** solving process deinitialization method of branching rule (called before branch and bound process data is freed) */
    2395static
    2396SCIP_DECL_BRANCHEXITSOL(branchExitsolRelpscost)
    2397{ /*lint --e{715}*/
    2398 SCIP_BRANCHRULEDATA* branchruledata;
    2399
    2400 /* free memory in branching rule data */
    2401 branchruledata = SCIPbranchruleGetData(branchrule);
    2402 SCIPfreeBlockMemoryArrayNull(scip, &branchruledata->nlcount, branchruledata->nlcountsize);
    2403
    2404 /* free random number generator */
    2405 SCIPfreeRandom(scip, &branchruledata->randnumgen);
    2406
    2407 SCIPfreeBlockMemoryArrayNull(scip, &branchruledata->orbitrep, branchruledata->npermvars);
    2408 SCIPfreeBlockMemoryArrayNull(scip, &branchruledata->varorbitmap, branchruledata->npermvars);
    2409 SCIPfreeBlockMemoryArrayNull(scip, &branchruledata->orbitbegins, branchruledata->npermvars);
    2410 SCIPfreeBlockMemoryArrayNull(scip, &branchruledata->orbits, branchruledata->npermvars);
    2411 branchruledata->nosymmetry = FALSE;
    2412 branchruledata->norbits = 0;
    2413 branchruledata->permvars = NULL;
    2414 branchruledata->permvarmap = NULL;
    2415 branchruledata->npermvars = 0;
    2416
    2417 return SCIP_OKAY;
    2418}
    2419
    2420
    2421/** branching execution method for fractional LP solutions */
    2422static
    2423SCIP_DECL_BRANCHEXECLP(branchExeclpRelpscost)
    2424{ /*lint --e{715}*/
    2425 SCIP_BRANCHRULEDATA* branchruledata;
    2426 SCIP_VAR** lpcands;
    2427 SCIP_Real* lpcandssol;
    2428 SCIP_Real* lpcandsfrac;
    2429 SCIP_VAR** filteredlpcands;
    2430 SCIP_Real* filteredlpcandssol;
    2431 SCIP_Real* filteredlpcandsfrac;
    2432 SCIP_Bool runfiltering;
    2433 int* filteredlpcandsorbitidx = NULL;
    2434 int nfilteredlpcands;
    2435 int nlpcands;
    2436
    2437 assert(branchrule != NULL);
    2438 assert(strcmp(SCIPbranchruleGetName(branchrule), BRANCHRULE_NAME) == 0);
    2439 assert(scip != NULL);
    2440 assert(result != NULL);
    2441
    2442 SCIPdebugMsg(scip, "Execlp method of relpscost branching in node %" SCIP_LONGINT_FORMAT "\n", SCIPnodeGetNumber(SCIPgetCurrentNode(scip)));
    2443
    2445 {
    2446 *result = SCIP_DIDNOTRUN;
    2447 SCIPdebugMsg(scip, "Could not apply relpscost branching, as the current LP was not solved to optimality.\n");
    2448
    2449 return SCIP_OKAY;
    2450 }
    2451
    2452 /* get branching candidates */
    2453 SCIP_CALL( SCIPgetLPBranchCands(scip, &lpcands, &lpcandssol, &lpcandsfrac, NULL, &nlpcands, NULL) );
    2454 assert(nlpcands > 0);
    2455
    2456 branchruledata = SCIPbranchruleGetData(branchrule);
    2457 assert(branchruledata != NULL);
    2458
    2459 branchruledata->maxmeangain = -SCIPinfinity(scip);
    2460 branchruledata->minmeangain = SCIPinfinity(scip);
    2461 branchruledata->sumlogmeangains = 0.0;
    2462 branchruledata->logstdevgain = 0.0;
    2463 branchruledata->nzerogains = 0;
    2464
    2465 /* determine whether we should run filtering */
    2466 runfiltering = ! branchruledata->nosymmetry && branchruledata->filtercandssym && SCIPgetSubscipDepth(scip) == 0 && ! SCIPinDive(scip) && ! SCIPinProbing(scip);
    2467
    2468 /* init orbits if necessary */
    2469 if( runfiltering )
    2470 {
    2471 SCIP_CALL( initOrbits(scip, branchruledata) );
    2472 }
    2473
    2474 /* determine fractional variables (possibly filter by using symmetries) */
    2475 if( runfiltering && branchruledata->norbits != 0 )
    2476 {
    2477 SCIP_CALL( SCIPallocBufferArray(scip, &filteredlpcands, nlpcands) );
    2478 SCIP_CALL( SCIPallocBufferArray(scip, &filteredlpcandssol, nlpcands) );
    2479 SCIP_CALL( SCIPallocBufferArray(scip, &filteredlpcandsfrac, nlpcands) );
    2480 SCIP_CALL( SCIPallocBufferArray(scip, &filteredlpcandsorbitidx, nlpcands) );
    2481
    2482 /* determine filtered fractional variables */
    2483 SCIP_CALL( filterSymmetricVariables(scip, branchruledata, lpcands, lpcandssol, lpcandsfrac, nlpcands,
    2484 filteredlpcands, filteredlpcandssol, filteredlpcandsfrac, filteredlpcandsorbitidx, &nfilteredlpcands) );
    2485 }
    2486 else
    2487 {
    2488 /* No orbits available. Copy all (unfiltered) branching candidates, because they will be updated w.r.t. the strong branching LP solution */
    2489 SCIP_CALL( SCIPduplicateBufferArray(scip, &filteredlpcands, lpcands, nlpcands) );
    2490 SCIP_CALL( SCIPduplicateBufferArray(scip, &filteredlpcandssol, lpcandssol, nlpcands) );
    2491 SCIP_CALL( SCIPduplicateBufferArray(scip, &filteredlpcandsfrac, lpcandsfrac, nlpcands) );
    2492 nfilteredlpcands = nlpcands;
    2493 }
    2494
    2495 /* execute branching rule */
    2496 SCIP_CALL( execRelpscost(scip, branchrule, filteredlpcands, filteredlpcandssol, filteredlpcandsfrac, filteredlpcandsorbitidx, nfilteredlpcands, TRUE, result) );
    2497
    2498 SCIPfreeBufferArrayNull(scip, &filteredlpcandsorbitidx);
    2499 SCIPfreeBufferArray(scip, &filteredlpcandsfrac);
    2500 SCIPfreeBufferArray(scip, &filteredlpcandssol);
    2501 SCIPfreeBufferArray(scip, &filteredlpcands);
    2502
    2503 return SCIP_OKAY;
    2504}
    2505
    2506
    2507/*
    2508 * branching specific interface methods
    2509 */
    2510
    2511/** creates the reliable pseudo cost branching rule and includes it in SCIP */
    2513 SCIP* scip /**< SCIP data structure */
    2514 )
    2515{
    2516 SCIP_BRANCHRULEDATA* branchruledata;
    2517 SCIP_BRANCHRULE* branchrule;
    2518
    2519 /* create relpscost branching rule data */
    2520 SCIP_CALL( SCIPallocBlockMemory(scip, &branchruledata) );
    2521
    2522 branchruledata->nosymmetry = FALSE;
    2523 branchruledata->orbits = NULL;
    2524 branchruledata->orbitbegins = NULL;
    2525 branchruledata->orbitrep = NULL;
    2526 branchruledata->varorbitmap = NULL;
    2527 branchruledata->norbits = 0;
    2528 branchruledata->permvars = NULL;
    2529 branchruledata->npermvars = 0;
    2530 branchruledata->permvarmap = NULL;
    2531 branchruledata->meandualgain = 0.0;
    2532 branchruledata->currmeandualgain = 0.0;
    2533 branchruledata->currndualgains = 0;
    2534 branchruledata->maxmeangain = -SCIPinfinity(scip);
    2535 branchruledata->minmeangain = SCIPinfinity(scip);
    2536 branchruledata->sumlogmeangains = 0.0;
    2537 branchruledata->logstdevgain = 0.0;
    2538 branchruledata->nzerogains = 0;
    2539
    2540 /* include branching rule */
    2542 BRANCHRULE_MAXDEPTH, BRANCHRULE_MAXBOUNDDIST, branchruledata) );
    2543
    2544 assert(branchrule != NULL);
    2545
    2546 /* set non-fundamental callbacks via specific setter functions*/
    2547 SCIP_CALL( SCIPsetBranchruleCopy(scip, branchrule, branchCopyRelpscost) );
    2548 SCIP_CALL( SCIPsetBranchruleFree(scip, branchrule, branchFreeRelpscost) );
    2549 SCIP_CALL( SCIPsetBranchruleInitsol(scip, branchrule, branchInitsolRelpscost) );
    2550 SCIP_CALL( SCIPsetBranchruleExitsol(scip, branchrule, branchExitsolRelpscost) );
    2551 SCIP_CALL( SCIPsetBranchruleExecLp(scip, branchrule, branchExeclpRelpscost) );
    2552
    2553 /* relpscost branching rule parameters */
    2555 "branching/relpscost/conflictweight",
    2556 "weight in score calculations for conflict score",
    2557 &branchruledata->conflictweight, TRUE, DEFAULT_CONFLICTWEIGHT, SCIP_REAL_MIN, SCIP_REAL_MAX, NULL, NULL) );
    2559 "branching/relpscost/conflictlengthweight",
    2560 "weight in score calculations for conflict length score",
    2561 &branchruledata->conflengthweight, TRUE, DEFAULT_CONFLENGTHWEIGHT, SCIP_REAL_MIN, SCIP_REAL_MAX, NULL, NULL) );
    2563 "branching/relpscost/inferenceweight",
    2564 "weight in score calculations for inference score",
    2565 &branchruledata->inferenceweight, TRUE, DEFAULT_INFERENCEWEIGHT, SCIP_REAL_MIN, SCIP_REAL_MAX, NULL, NULL) );
    2567 "branching/relpscost/cutoffweight",
    2568 "weight in score calculations for cutoff score",
    2569 &branchruledata->cutoffweight, TRUE, DEFAULT_CUTOFFWEIGHT, SCIP_REAL_MIN, SCIP_REAL_MAX, NULL, NULL) );
    2571 "branching/relpscost/gmiavgeffweight",
    2572 "weight in score calculations for average GMI cuts normalized efficacy",
    2573 &branchruledata->gmiavgeffweight, TRUE, DEFAULT_GMIAVGEFFWEIGHT, SCIP_REAL_MIN, SCIP_REAL_MAX, NULL, NULL) );
    2575 "branching/relpscost/gmilasteffweight",
    2576 "weight in score calculations for last GMI cuts normalized efficacy",
    2577 &branchruledata->gmilasteffweight, TRUE, DEFAULT_GMILASTEFFWEIGHT, SCIP_REAL_MIN, SCIP_REAL_MAX, NULL, NULL) );
    2579 "branching/relpscost/pscostweight",
    2580 "weight in score calculations for pseudo cost score",
    2581 &branchruledata->pscostweight, TRUE, DEFAULT_PSCOSTWEIGHT, SCIP_REAL_MIN, SCIP_REAL_MAX, NULL, NULL) );
    2583 "branching/relpscost/nlscoreweight",
    2584 "weight in score calculations for nlcount score",
    2585 &branchruledata->nlscoreweight, TRUE, DEFAULT_NLSCOREWEIGHT, SCIP_REAL_MIN, SCIP_REAL_MAX, NULL, NULL) );
    2587 "branching/relpscost/minreliable",
    2588 "minimal value for minimum pseudo cost size to regard pseudo cost value as reliable",
    2589 &branchruledata->minreliable, TRUE, DEFAULT_MINRELIABLE, 0.0, SCIP_REAL_MAX, NULL, NULL) );
    2591 "branching/relpscost/maxreliable",
    2592 "maximal value for minimum pseudo cost size to regard pseudo cost value as reliable",
    2593 &branchruledata->maxreliable, TRUE, DEFAULT_MAXRELIABLE, 0.0, SCIP_REAL_MAX, NULL, NULL) );
    2595 "branching/relpscost/sbiterquot",
    2596 "maximal fraction of strong branching LP iterations compared to node relaxation LP iterations",
    2597 &branchruledata->sbiterquot, FALSE, DEFAULT_SBITERQUOT, 0.0, SCIP_REAL_MAX, NULL, NULL) );
    2599 "branching/relpscost/dynamiclookaheadquot",
    2600 "apply dynamic lookahead after this fraction maxlookahead is reached",
    2601 &branchruledata->dynamiclookaheadquot, TRUE, DEFAULT_DYNAMICLOOKAHEADQUOT , 0.0, 1.0, NULL, NULL) );
    2603 "branching/relpscost/sbiterofs",
    2604 "additional number of allowed strong branching LP iterations",
    2605 &branchruledata->sbiterofs, FALSE, DEFAULT_SBITEROFS, 0, INT_MAX, NULL, NULL) );
    2607 "branching/relpscost/maxlookahead",
    2608 "maximal number of further variables evaluated without better score",
    2609 &branchruledata->maxlookahead, TRUE, DEFAULT_MAXLOOKAHEAD, 1, INT_MAX, NULL, NULL) );
    2610 SCIP_CALL( SCIPaddBoolParam(scip, "branching/relpscost/dynamiclookahead",
    2611 "should we use a dynamic lookahead based on a tree size estimation of further strong branchings?",
    2612 &branchruledata->dynamiclookahead, TRUE, DEFAULT_DYNAMICLOOKAHEAD, NULL, NULL) );
    2614 "branching/relpscost/initcand",
    2615 "maximal number of candidates initialized with strong branching per node",
    2616 &branchruledata->initcand, FALSE, DEFAULT_INITCAND, 0, INT_MAX, NULL, NULL) );
    2617 SCIP_CALL( SCIPaddIntParam(scip, "branching/relpscost/dynamiclookdistribution",
    2618 "which distribution should be used for dynamic lookahead? 0=exponential, 1=Pareto, 2=log-normal?",
    2619 &branchruledata->dynamiclookdistribution, TRUE, DEFAULT_DYNAMICLOOKDISTRIBUTION, EXPONENTIALDISTRIBUTION, LOGNORMALDISTRIBUTION, NULL, NULL) );
    2621 "branching/relpscost/inititer",
    2622 "iteration limit for strong branching initializations of pseudo cost entries (0: auto)",
    2623 &branchruledata->inititer, FALSE, DEFAULT_INITITER, 0, INT_MAX, NULL, NULL) );
    2625 "branching/relpscost/maxbdchgs",
    2626 "maximal number of bound tightenings before the node is reevaluated (-1: unlimited)",
    2627 &branchruledata->maxbdchgs, TRUE, DEFAULT_MAXBDCHGS, -1, INT_MAX, NULL, NULL) );
    2629 "branching/relpscost/maxproprounds",
    2630 "maximum number of propagation rounds to be performed during strong branching before solving the LP (-1: no limit, -2: parameter settings)",
    2631 &branchruledata->maxproprounds, TRUE, SCIPisExact(scip) ? 0 : DEFAULT_MAXPROPROUNDS, -2, INT_MAX, NULL, NULL) );
    2633 "branching/relpscost/probingbounds",
    2634 "should valid bounds be identified in a probing-like fashion during strong branching (only with propagation)?",
    2635 &branchruledata->probingbounds, TRUE, DEFAULT_PROBINGBOUNDS, NULL, NULL) );
    2636
    2637 SCIP_CALL( SCIPaddBoolParam(scip, "branching/relpscost/userelerrorreliability",
    2638 "should reliability be based on relative errors?", &branchruledata->userelerrorforreliability, TRUE, DEFAULT_USERELERRORFORRELIABILITY,
    2639 NULL, NULL) );
    2640
    2641 SCIP_CALL( SCIPaddRealParam(scip, "branching/relpscost/lowerrortol", "low relative error tolerance for reliability",
    2642 &branchruledata->lowerrortol, TRUE, DEFAULT_LOWERRORTOL, 0.0, SCIP_REAL_MAX, NULL, NULL) );
    2643
    2644 SCIP_CALL( SCIPaddRealParam(scip, "branching/relpscost/higherrortol", "high relative error tolerance for reliability",
    2645 &branchruledata->higherrortol, TRUE, DEFAULT_HIGHERRORTOL, 0.0, SCIP_REAL_MAX, NULL, NULL) );
    2646
    2647/**! [SnippetCodeStyleParenIndent] */
    2648
    2649 SCIP_CALL( SCIPaddBoolParam(scip, "branching/relpscost/storesemiinitcosts",
    2650 "should strong branching result be considered for pseudo costs if the other direction was infeasible?",
    2651 &branchruledata->storesemiinitcosts, TRUE, DEFAULT_STORESEMIINITCOSTS,
    2652 NULL, NULL) );
    2653
    2654/**! [SnippetCodeStyleParenIndent] */
    2655
    2656 SCIP_CALL( SCIPaddBoolParam(scip, "branching/relpscost/usesblocalinfo",
    2657 "should the scoring function use only local cutoff and inference information obtained for strong branching candidates?",
    2658 &branchruledata->usesblocalinfo, TRUE, DEFAULT_USESBLOCALINFO,
    2659 NULL, NULL) );
    2660
    2661 SCIP_CALL( SCIPaddBoolParam(scip, "branching/relpscost/usehyptestforreliability",
    2662 "should the strong branching decision be based on a hypothesis test?",
    2663 &branchruledata->usehyptestforreliability, TRUE, DEFAULT_USEHYPTESTFORRELIABILITY,
    2664 NULL, NULL) );
    2665
    2666 SCIP_CALL( SCIPaddBoolParam(scip, "branching/relpscost/usedynamicconfidence",
    2667 "should the confidence level be adjusted dynamically?",
    2668 &branchruledata->usedynamicconfidence, TRUE, DEFAULT_USEDYNAMICCONFIDENCE,
    2669 NULL, NULL) );
    2670 SCIP_CALL( SCIPaddBoolParam(scip, "branching/relpscost/skipbadinitcands",
    2671 "should branching rule skip candidates that have a low probability to "
    2672 "be better than the best strong-branching or pseudo-candidate?",
    2673 &branchruledata->skipbadinitcands, TRUE, DEFAULT_SKIPBADINITCANDS,
    2674 NULL, NULL) );
    2676 "branching/relpscost/confidencelevel",
    2677 "the confidence level for statistical methods, between 0 (Min) and 4 (Max).",
    2678 &branchruledata->confidencelevel, TRUE, DEFAULT_CONFIDENCELEVEL, 0, 4, NULL, NULL) );
    2679
    2680 SCIP_CALL( SCIPaddBoolParam(scip, "branching/relpscost/randinitorder",
    2681 "should candidates be initialized in randomized order?",
    2682 &branchruledata->randinitorder, TRUE, DEFAULT_RANDINITORDER,
    2683 NULL, NULL) );
    2684
    2685 SCIP_CALL( SCIPaddBoolParam(scip, "branching/relpscost/usesmallweightsitlim",
    2686 "should smaller weights be used for pseudo cost updates after hitting the LP iteration limit?",
    2687 &branchruledata->usesmallweightsitlim, TRUE, DEFAULT_USESMALLWEIGHTSITLIM,
    2688 NULL, NULL) );
    2689
    2690 SCIP_CALL( SCIPaddBoolParam(scip, "branching/relpscost/dynamicweights",
    2691 "should the weights of the branching rule be adjusted dynamically during solving based on objective and infeasible leaf counters?",
    2692 &branchruledata->dynamicweights, TRUE, DEFAULT_DYNAMICWEIGHTS,
    2693 NULL, NULL) );
    2694 SCIP_CALL( SCIPaddIntParam(scip, "branching/relpscost/degeneracyaware",
    2695 "should degeneracy be taken into account to update weights and skip strong branching? (0: off, 1: after root, 2: always)",
    2696 &branchruledata->degeneracyaware, TRUE, DEFAULT_DEGENERACYAWARE, 0, 2,
    2697 NULL, NULL) );
    2698 SCIP_CALL( SCIPaddIntParam(scip, "branching/relpscost/startrandseed", "start seed for random number generation",
    2699 &branchruledata->startrandseed, TRUE, DEFAULT_STARTRANDSEED, 0, INT_MAX, NULL, NULL) );
    2700 SCIP_CALL( SCIPaddIntParam(scip, "branching/relpscost/minsamplesize",
    2701 "minimum sample size to estimate the tree size for dynamic lookahead",
    2702 &branchruledata->minsamplesize, TRUE, DEFAULT_MINSAMPLESIZE, 0, INT_MAX, NULL, NULL) );
    2703 SCIP_CALL( SCIPaddBoolParam(scip, "branching/relpscost/filtercandssym",
    2704 "Use symmetry to filter branching candidates?",
    2705 &branchruledata->filtercandssym, TRUE, DEFAULT_FILTERCANDSSYM, NULL, NULL) );
    2706
    2707 SCIP_CALL( SCIPaddBoolParam(scip, "branching/relpscost/transsympscost",
    2708 "Transfer pscost information to symmetric variables?",
    2709 &branchruledata->transsympscost, TRUE, DEFAULT_TRANSSYMPSCOST, NULL, NULL) );
    2710
    2711 SCIP_CALL( SCIPaddRealParam(scip, "branching/" BRANCHRULE_NAME "/discountfactor",
    2712 "discount factor for ancestral pseudo costs (0.0: disable discounted pseudo costs)",
    2713 &branchruledata->discountfactor, FALSE, BRANCHRULE_DISCOUNTFACTOR, 0.0, 1.0, NULL, NULL) );
    2714
    2715 /* relpcost is safe to use in exact solving mode */
    2716 SCIPbranchruleMarkExact(branchrule);
    2717
    2718 /* initialise the Treemodel parameters */
    2719 SCIP_CALL( SCIPtreemodelInit(scip, &branchruledata->treemodel) );
    2720
    2721 return SCIP_OKAY;
    2722}
    2723
    2724/** execution reliability pseudo cost branching with the given branching candidates */
    2726 SCIP* scip, /**< SCIP data structure */
    2727 SCIP_VAR** branchcands, /**< branching candidates */
    2728 SCIP_Real* branchcandssol, /**< solution value for the branching candidates */
    2729 SCIP_Real* branchcandsfrac, /**< fractional part of the branching candidates */
    2730 int nbranchcands, /**< number of branching candidates */
    2731 SCIP_Bool executebranching, /**< perform a branching step after probing */
    2732 SCIP_RESULT* result /**< pointer to the result of the execution */
    2733 )
    2734{
    2735 SCIP_BRANCHRULE* branchrule;
    2736
    2737 assert(scip != NULL);
    2738 assert(result != NULL);
    2739
    2740 /* find branching rule */
    2742 assert(branchrule != NULL);
    2743
    2744 /* execute branching rule */
    2745 SCIP_CALL( execRelpscost(scip, branchrule, branchcands, branchcandssol, branchcandsfrac, NULL, nbranchcands, executebranching, result) );
    2746
    2747 return SCIP_OKAY;
    2748}
    static long bound
    #define BRANCHRULE_DESC
    #define DEFAULT_DEGENERACYAWARE
    #define DEFAULT_USESBLOCALINFO
    #define DEFAULT_SKIPBADINITCANDS
    #define DEFAULT_SBITERQUOT
    #define LOGNORMALDISTRIBUTION
    static SCIP_Real strongBranchingTreeSize(SCIP_Real estimatedepth)
    static SCIP_Real calcNlscore(SCIP *scip, int *nlcount, int nlcountmax, int probindex)
    #define DEFAULT_HIGHERRORTOL
    #define BRANCHRULE_PRIORITY
    #define DEFAULT_PROBINGBOUNDS
    #define BRANCHRULE_DISCOUNTFACTOR
    #define DEFAULT_INITITER
    static SCIP_Real expectedTreeSize(SCIP *scip, SCIP_Real gap, SCIP_Real zeroprob, SCIP_Real currentdepth, SCIP_Real lambda, SCIP_Real mingain, SCIP_Real logmeangain, SCIP_Real logstdevgain, int distributioncdf)
    #define DEFAULT_USESMALLWEIGHTSITLIM
    #define DEFAULT_DYNAMICLOOKAHEADQUOT
    static SCIP_RETCODE applyBdchgs(SCIP *scip, SCIP_VAR **vars, int *bdchginds, SCIP_BOUNDTYPE *bdchgtypes, SCIP_Real *bdchgbounds, int nbdchgs, SCIP_RESULT *result)
    static SCIP_Real cdfProbability(SCIP_Real rate, SCIP_Real zeroprob, SCIP_Real proposedgain, SCIP_Real mingain, SCIP_Real logmeangain, SCIP_Real logstdevgain, int distributioncdf)
    #define DEFAULT_STARTRANDSEED
    #define MINGAINTHRESHOLD
    #define DEFAULT_FILTERCANDSSYM
    #define MAXGAINTHRESHOLD
    #define DEFAULT_USEDYNAMICCONFIDENCE
    #define DEFAULT_DYNAMICWEIGHTS
    #define DEFAULT_MAXBDCHGS
    #define DEFAULT_USEHYPTESTFORRELIABILITY
    #define DEFAULT_GMIAVGEFFWEIGHT
    #define GEOMMEANSHIFT
    static SCIP_RETCODE SCIPupdateVarPseudocostSymmetric(SCIP *scip, SCIP_BRANCHRULEDATA *branchruledata, SCIP_VAR *branchvar, int *branchorbitidx, int branchvaridx, SCIP_Real solvaldelta, SCIP_Real objdelta, SCIP_Real weight)
    #define DEFAULT_INFERENCEWEIGHT
    #define BRANCHRULE_NAME
    #define DEFAULT_RANDINITORDER
    static SCIP_RETCODE initOrbits(SCIP *scip, SCIP_BRANCHRULEDATA *branchruledata)
    #define DEFAULT_MAXLOOKAHEAD
    #define DEFAULT_SBITEROFS
    static SCIP_DECL_BRANCHFREE(branchFreeRelpscost)
    #define DEFAULT_NLSCOREWEIGHT
    #define DEFAULT_CONFLICTWEIGHT
    static SCIP_RETCODE filterSymmetricVariables(SCIP *scip, SCIP_BRANCHRULEDATA *branchruledata, SCIP_VAR **origbranchcands, SCIP_Real *origbranchcandssol, SCIP_Real *origbranchcandsfrac, int norigbranchcands, SCIP_VAR **branchcands, SCIP_Real *branchcandssol, SCIP_Real *branchcandsfrac, int *branchorbitidx, int *nbranchcands)
    #define DEFAULT_GMILASTEFFWEIGHT
    #define DEFAULT_USERELERRORFORRELIABILITY
    #define PARETODISTRIBUTION
    #define DEFAULT_CUTOFFWEIGHT
    static SCIP_DECL_BRANCHCOPY(branchCopyRelpscost)
    static SCIP_RETCODE countNonlinearities(SCIP *scip, int *nlcount, int nlcountsize, int *nlcountmax)
    #define EXPONENTIALDISTRIBUTION
    static SCIP_Bool needsStrongBranching(SCIP *scip, SCIP_BRANCHRULE *branchrule, SCIP_VAR *branchcand, SCIP_Real branchcandfrac, SCIP_VAR *bestpscand, SCIP_Real bestpscandfrac, SCIP_Real reliable, SCIP_Real relerrorthreshold, SCIP_CONFIDENCELEVEL clevel, SCIP_Bool useancpscost)
    static SCIP_DECL_BRANCHINITSOL(branchInitsolRelpscost)
    #define DEFAULT_TRANSSYMPSCOST
    static SCIP_RETCODE addBdchg(SCIP *scip, int **bdchginds, SCIP_BOUNDTYPE **bdchgtypes, SCIP_Real **bdchgbounds, int *nbdchgs, int ind, SCIP_BOUNDTYPE type, SCIP_Real bound)
    #define DEFAULT_LOWERRORTOL
    static SCIP_RETCODE execRelpscost(SCIP *scip, SCIP_BRANCHRULE *branchrule, SCIP_VAR **branchcands, SCIP_Real *branchcandssol, SCIP_Real *branchcandsfrac, int *branchorbitidx, int nbranchcands, SCIP_Bool executebranch, SCIP_RESULT *result)
    static SCIP_RETCODE branchruledataEnsureNlcount(SCIP *scip, SCIP_BRANCHRULEDATA *branchruledata)
    static SCIP_Bool continueStrongBranchingTreeSizeEstimation(SCIP *scip, SCIP_BRANCHRULEDATA *branchruledata, SCIP_Real lookahead, SCIP_Real maxlookahead)
    static SCIP_Real strongBranchingDepth(SCIP_Real gap, SCIP_Real maxmeangain)
    #define DEFAULT_MINSAMPLESIZE
    #define DEFAULT_CONFLENGTHWEIGHT
    #define DEFAULT_CONFIDENCELEVEL
    static SCIP_RETCODE updateMinMaxMeanGain(SCIP *scip, SCIP_BRANCHRULE *branchrule, SCIP_Real downgain, SCIP_Real upgain)
    #define DEFAULT_MINRELIABLE
    #define DEFAULT_DYNAMICLOOKAHEAD
    static SCIP_Real calcScore(SCIP *scip, SCIP_BRANCHRULEDATA *branchruledata, SCIP_Real conflictscore, SCIP_Real avgconflictscore, SCIP_Real conflengthscore, SCIP_Real avgconflengthscore, SCIP_Real inferencescore, SCIP_Real avginferencescore, SCIP_Real cutoffscore, SCIP_Real avgcutoffscore, SCIP_Real gmieffscore, SCIP_Real lastgmieffscore, SCIP_Real pscostscore, SCIP_Real avgpscostscore, SCIP_Real nlscore, SCIP_Real frac, SCIP_Real degeneracyfactor)
    #define DEFAULT_STORESEMIINITCOSTS
    #define DEFAULT_MAXPROPROUNDS
    static SCIP_DECL_BRANCHEXITSOL(branchExitsolRelpscost)
    #define DEFAULT_INITCAND
    static SCIP_Bool continueStrongBranchingLookahead(SCIP *scip, int candidx, int ninitcands, SCIP_Real lookahead, SCIP_Real maxlookahead, int nbdchgs, int nbdconflicts, int maxbdchgs, SCIP_Longint maxnsblpiterations)
    #define BRANCHRULE_MAXDEPTH
    #define DEFAULT_MAXRELIABLE
    #define DEFAULT_DYNAMICLOOKDISTRIBUTION
    #define DEFAULT_PSCOSTWEIGHT
    #define BRANCHRULE_MAXBOUNDDIST
    static void freeBdchgs(SCIP *scip, int **bdchginds, SCIP_BOUNDTYPE **bdchgtypes, SCIP_Real **bdchgbounds, int *nbdchgs)
    static SCIP_DECL_BRANCHEXECLP(branchExeclpRelpscost)
    reliable pseudo costs branching rule
    Constraint handler for AND constraints, .
    #define NULL
    Definition: def.h:248
    #define SCIP_Longint
    Definition: def.h:141
    #define SCIP_UNUSED(x)
    Definition: def.h:409
    #define SCIP_REAL_MAX
    Definition: def.h:158
    #define SCIP_INVALID
    Definition: def.h:178
    #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_REAL_MIN
    Definition: def.h:159
    #define SCIP_CALL(x)
    Definition: def.h:355
    SCIP_RETCODE SCIPexecRelpscostBranching(SCIP *scip, SCIP_VAR **branchcands, SCIP_Real *branchcandssol, SCIP_Real *branchcandsfrac, int nbranchcands, SCIP_Bool executebranching, SCIP_RESULT *result)
    SCIP_RETCODE SCIPincludeBranchruleRelpscost(SCIP *scip)
    SCIP_VAR * SCIPgetResultantAnd(SCIP *scip, SCIP_CONS *cons)
    Definition: cons_and.c:5248
    int SCIPgetNVarsAnd(SCIP *scip, SCIP_CONS *cons)
    Definition: cons_and.c:5199
    SCIP_VAR ** SCIPgetVarsAnd(SCIP *scip, SCIP_CONS *cons)
    Definition: cons_and.c:5223
    int SCIPgetSubscipDepth(SCIP *scip)
    Definition: scip_copy.c:2588
    SCIP_Bool SCIPisStopped(SCIP *scip)
    Definition: scip_general.c:759
    SCIP_RETCODE SCIPgetVarsData(SCIP *scip, SCIP_VAR ***vars, int *nvars, int *nbinvars, int *nintvars, int *nimplvars, int *ncontvars)
    Definition: scip_prob.c:2115
    int SCIPgetNVars(SCIP *scip)
    Definition: scip_prob.c:2246
    SCIP_VAR ** SCIPgetVars(SCIP *scip)
    Definition: scip_prob.c:2201
    int SCIPhashmapGetImageInt(SCIP_HASHMAP *hashmap, void *origin)
    Definition: misc.c:3304
    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
    SCIP_Real SCIPgetLocalLowerbound(SCIP *scip)
    Definition: scip_prob.c:4178
    SCIP_Real SCIPgetNodeLowerbound(SCIP *scip, SCIP_NODE *node)
    Definition: scip_prob.c:4215
    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 SCIPgetBoolParam(SCIP *scip, const char *name, SCIP_Bool *value)
    Definition: scip_param.c:250
    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 SCIPgetRealParam(SCIP *scip, const char *name, SCIP_Real *value)
    Definition: scip_param.c:307
    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 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
    void SCIPbranchruleMarkExact(SCIP_BRANCHRULE *branchrule)
    Definition: branch.c:1907
    SCIP_RETCODE SCIPsetBranchruleExitsol(SCIP *scip, SCIP_BRANCHRULE *branchrule, SCIP_DECL_BRANCHEXITSOL((*branchexitsol)))
    Definition: scip_branch.c:240
    void SCIPbranchruleSetData(SCIP_BRANCHRULE *branchrule, SCIP_BRANCHRULEDATA *branchruledata)
    Definition: branch.c:1896
    SCIP_RETCODE SCIPsetBranchruleInitsol(SCIP *scip, SCIP_BRANCHRULE *branchrule, SCIP_DECL_BRANCHINITSOL((*branchinitsol)))
    Definition: scip_branch.c:224
    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_Real SCIPgetBranchScore(SCIP *scip, SCIP_VAR *var, SCIP_Real downgain, SCIP_Real upgain)
    Definition: scip_branch.c:857
    SCIP_CONSHDLR * SCIPfindConshdlr(SCIP *scip, const char *name)
    Definition: scip_cons.c:940
    int SCIPconshdlrGetNActiveConss(SCIP_CONSHDLR *conshdlr)
    Definition: cons.c:4812
    SCIP_CONS ** SCIPconshdlrGetConss(SCIP_CONSHDLR *conshdlr)
    Definition: cons.c:4735
    SCIP_Bool SCIPisExact(SCIP *scip)
    Definition: scip_exact.c:193
    SCIP_RETCODE SCIPgetLPDualDegeneracy(SCIP *scip, SCIP_Real *degeneracy, SCIP_Real *varconsratio)
    Definition: scip_lp.c:2757
    SCIP_Bool SCIPinDive(SCIP *scip)
    Definition: scip_lp.c:2740
    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
    SCIP_Bool SCIPisLPSolBasic(SCIP *scip)
    Definition: scip_lp.c:673
    #define SCIPfreeBlockMemoryArray(scip, ptr, num)
    Definition: scip_mem.h:110
    #define SCIPallocBufferArray(scip, ptr, num)
    Definition: scip_mem.h:124
    #define SCIPreallocBufferArray(scip, ptr, num)
    Definition: scip_mem.h:128
    #define SCIPfreeBufferArray(scip, ptr)
    Definition: scip_mem.h:136
    #define SCIPduplicateBufferArray(scip, ptr, source, num)
    Definition: scip_mem.h:132
    #define SCIPallocBlockMemoryArray(scip, ptr, num)
    Definition: scip_mem.h:93
    #define SCIPreallocBlockMemoryArray(scip, ptr, oldnum, newnum)
    Definition: scip_mem.h:99
    #define SCIPfreeBlockMemory(scip, ptr)
    Definition: scip_mem.h:108
    #define SCIPfreeBlockMemoryArrayNull(scip, ptr, num)
    Definition: scip_mem.h:111
    #define SCIPfreeBufferArrayNull(scip, ptr)
    Definition: scip_mem.h:137
    #define SCIPallocBlockMemory(scip, ptr)
    Definition: scip_mem.h:89
    SCIP_Bool SCIPisNLPConstructed(SCIP *scip)
    Definition: scip_nlp.c:110
    int SCIPgetNNLPVars(SCIP *scip)
    Definition: scip_nlp.c:201
    SCIP_RETCODE SCIPgetNLPVarsNonlinearity(SCIP *scip, int *nlcount)
    Definition: scip_nlp.c:223
    SCIP_Real SCIPnodeGetLowerbound(SCIP_NODE *node)
    Definition: tree.c:8503
    SCIP_DOMCHG * SCIPnodeGetDomchg(SCIP_NODE *node)
    Definition: tree.c:8588
    SCIP_Longint SCIPnodeGetNumber(SCIP_NODE *node)
    Definition: tree.c:8483
    int SCIPnodeGetDepth(SCIP_NODE *node)
    Definition: tree.c:8493
    SCIP_Bool SCIPinProbing(SCIP *scip)
    Definition: scip_probing.c:98
    SCIP_SOL * SCIPgetBestSol(SCIP *scip)
    Definition: scip_sol.c:2981
    int SCIPsolGetIndex(SCIP_SOL *sol)
    Definition: sol.c:4290
    SCIP_Real SCIPgetAvgInferenceScore(SCIP *scip)
    SCIP_Real SCIPgetUpperbound(SCIP *scip)
    SCIP_Real SCIPgetAvgConflictlengthScore(SCIP *scip)
    SCIP_Longint SCIPgetNInfeasibleLeaves(SCIP *scip)
    SCIP_Longint SCIPgetNNodes(SCIP *scip)
    SCIP_Longint SCIPgetNNodeInitLPs(SCIP *scip)
    SCIP_Longint SCIPgetNStrongbranchLPIterations(SCIP *scip)
    SCIP_Longint SCIPgetNNodeLPIterations(SCIP *scip)
    SCIP_Real SCIPgetAvgConflictScore(SCIP *scip)
    SCIP_Longint SCIPgetNDualResolveLPIterations(SCIP *scip)
    SCIP_Real SCIPgetAvgPseudocostScore(SCIP *scip)
    SCIP_Real SCIPgetCutoffbound(SCIP *scip)
    SCIP_Longint SCIPgetNObjlimLeaves(SCIP *scip)
    SCIP_Longint SCIPgetNNodeInitLPIterations(SCIP *scip)
    SCIP_Real SCIPgetAvgDPseudocostScore(SCIP *scip, SCIP_Real discountfac)
    SCIP_Longint SCIPgetNDualResolveLPs(SCIP *scip)
    SCIP_Longint SCIPgetNRootStrongbranchLPIterations(SCIP *scip)
    SCIP_Real SCIPgetAvgCutoffScore(SCIP *scip)
    SCIP_RETCODE SCIPcomputeOrbitsComponentsSym(SCIP *scip, int npermvars, int **permstrans, int nperms, int *components, int *componentbegins, int *vartocomponent, int ncomponents, int *orbits, int *orbitbegins, int *norbits, int *varorbitmap)
    Definition: symmetry.c:435
    SCIP_Real SCIPinfinity(SCIP *scip)
    SCIP_Bool SCIPisGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Real SCIPfeasFrac(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisRelGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Real SCIPfeasCeil(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Real SCIPfeasFloor(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisFeasIntegral(SCIP *scip, SCIP_Real val)
    SCIP_Real SCIPfeastol(SCIP *scip)
    SCIP_Bool SCIPisSumGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisZero(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisSumGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_NODE * SCIPgetFocusNode(SCIP *scip)
    Definition: scip_tree.c:72
    int SCIPgetDepth(SCIP *scip)
    Definition: scip_tree.c:672
    SCIP_NODE * SCIPgetCurrentNode(SCIP *scip)
    Definition: scip_tree.c:91
    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_Real SCIPgetVarAncPseudocostCountCurrentRun(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
    Definition: scip_var.c:11378
    SCIP_RETCODE SCIPtightenVarLb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
    Definition: scip_var.c:6401
    SCIP_Bool SCIPpscostThresholdProbabilityTest(SCIP *scip, SCIP_VAR *var, SCIP_Real frac, SCIP_Real threshold, SCIP_BRANCHDIR dir, SCIP_CONFIDENCELEVEL clevel)
    Definition: scip_var.c:11487
    SCIP_Bool SCIPvarIsActive(SCIP_VAR *var)
    Definition: var.c:23642
    SCIP_VAR * SCIPboundchgGetVar(SCIP_BOUNDCHG *boundchg)
    Definition: var.c:23174
    SCIP_Real SCIPgetVarPseudocostCountCurrentRun(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
    Definition: scip_var.c:11350
    SCIP_Real SCIPgetVarAvgInferenceScore(SCIP *scip, SCIP_VAR *var)
    Definition: scip_var.c:11945
    SCIP_RETCODE SCIPendStrongbranch(SCIP *scip)
    Definition: scip_var.c:3488
    SCIP_BOUNDCHG * SCIPdomchgGetBoundchg(SCIP_DOMCHG *domchg, int pos)
    Definition: var.c:23222
    SCIP_BOUNDCHGTYPE SCIPboundchgGetBoundchgtype(SCIP_BOUNDCHG *boundchg)
    Definition: var.c:23184
    SCIP_Real SCIPgetVarPseudocostCurrentRun(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
    Definition: scip_var.c:11296
    SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
    Definition: var.c:24268
    SCIP_Bool SCIPisVarPscostRelerrorReliable(SCIP *scip, SCIP_VAR *var, SCIP_Real threshold, SCIP_CONFIDENCELEVEL clevel)
    Definition: scip_var.c:11506
    SCIP_Real SCIPboundchgGetNewbound(SCIP_BOUNDCHG *boundchg)
    Definition: var.c:23154
    SCIP_VAR * SCIPvarGetProbvar(SCIP_VAR *var)
    Definition: var.c:17550
    SCIP_RETCODE SCIPtightenVarUb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
    Definition: scip_var.c:6651
    int SCIPdomchgGetNBoundchgs(SCIP_DOMCHG *domchg)
    Definition: var.c:23214
    int SCIPvarGetProbindex(SCIP_VAR *var)
    Definition: var.c:23662
    const char * SCIPvarGetName(SCIP_VAR *var)
    Definition: var.c:23267
    SCIP_Longint SCIPgetVarStrongbranchNode(SCIP *scip, SCIP_VAR *var)
    Definition: scip_var.c:5019
    SCIP_Real SCIPgetVarDPseudocostScore(SCIP *scip, SCIP_VAR *var, SCIP_Real solval, SCIP_Real discountfac)
    Definition: scip_var.c:11570
    SCIP_LPSOLSTAT SCIPgetLastStrongbranchLPSolStat(SCIP *scip, SCIP_BRANCHDIR branchdir)
    Definition: scip_var.c:4847
    SCIP_Real SCIPgetVarPseudocostVal(SCIP *scip, SCIP_VAR *var, SCIP_Real solvaldelta)
    Definition: scip_var.c:11188
    SCIP_Real SCIPgetVarConflictlengthScore(SCIP *scip, SCIP_VAR *var)
    Definition: scip_var.c:11775
    SCIP_Bool SCIPsignificantVarPscostDifference(SCIP *scip, SCIP_VAR *varx, SCIP_Real fracx, SCIP_VAR *vary, SCIP_Real fracy, SCIP_BRANCHDIR dir, SCIP_CONFIDENCELEVEL clevel, SCIP_Bool onesided)
    Definition: scip_var.c:11457
    SCIP_RETCODE SCIPgetVarStrongbranchWithPropagation(SCIP *scip, SCIP_VAR *var, SCIP_Real solval, SCIP_Real lpobjval, int itlim, int maxproprounds, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, SCIP_Longint *ndomredsdown, SCIP_Longint *ndomredsup, SCIP_Bool *downinf, SCIP_Bool *upinf, SCIP_Bool *downconflict, SCIP_Bool *upconflict, SCIP_Bool *lperror, SCIP_Real *newlbs, SCIP_Real *newubs)
    Definition: scip_var.c:4138
    SCIP_Bool SCIPvarIsIntegral(SCIP_VAR *var)
    Definition: var.c:23490
    SCIP_Real SCIPgetVarAncPseudocostVal(SCIP *scip, SCIP_VAR *var, SCIP_Real solvaldelta)
    Definition: scip_var.c:11214
    SCIP_Real SCIPvarGetLPSol(SCIP_VAR *var)
    Definition: var.c:24664
    SCIP_Real SCIPgetVarPseudocostScoreCurrentRun(SCIP *scip, SCIP_VAR *var, SCIP_Real solval)
    Definition: scip_var.c:11613
    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_Real SCIPgetVarAvgGMIScore(SCIP *scip, SCIP_VAR *var)
    Definition: scip_var.c:12349
    SCIP_Real SCIPgetVarLastGMIScore(SCIP *scip, SCIP_VAR *var)
    Definition: scip_var.c:12403
    SCIP_Real SCIPgetVarConflictScore(SCIP *scip, SCIP_VAR *var)
    Definition: scip_var.c:11713
    SCIP_Real SCIPgetVarAvgCutoffScore(SCIP *scip, SCIP_VAR *var)
    Definition: scip_var.c:12199
    SCIP_RETCODE SCIPupdateVarAncPseudocost(SCIP *scip, SCIP_VAR *var, SCIP_Real solvaldelta, SCIP_Real objdelta, SCIP_Real weight)
    Definition: scip_var.c:11154
    SCIP_RETCODE SCIPgetVarStrongbranchLast(SCIP *scip, SCIP_VAR *var, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, SCIP_Real *solval, SCIP_Real *lpobjval)
    Definition: scip_var.c:4869
    SCIP_Real SCIPboundchgGetLPSolVal(SCIP_BOUNDCHG *boundchg)
    Definition: var.c:23164
    SCIP_Real SCIPgetVarPseudocostScore(SCIP *scip, SCIP_VAR *var, SCIP_Real solval)
    Definition: scip_var.c:11531
    SCIP_RETCODE SCIPstartStrongbranch(SCIP *scip, SCIP_Bool enablepropagation)
    Definition: scip_var.c:3430
    void SCIPfreeRandom(SCIP *scip, SCIP_RANDNUMGEN **randnumgen)
    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)
    memory allocation routines
    #define BMSclearMemoryArray(ptr, num)
    Definition: memory.h:130
    SCIP_RETCODE SCIPgetSymmetry(SCIP *scip, int *npermvars, SCIP_VAR ***permvars, SCIP_HASHMAP **permvarmap, int *nperms, int ***perms, int ***permstrans, SCIP_Real *log10groupsize, SCIP_Bool *binvaraffected, int **components, int **componentbegins, int **vartocomponent, int *ncomponents)
    propagator for symmetry handling
    public methods for branching rules
    public methods for managing constraints
    public methods for message output
    #define SCIPdebug(x)
    Definition: pub_message.h:93
    public data structures and miscellaneous methods
    public methods for primal CIP solutions
    public methods for branch and bound tree
    public methods for problem variables
    public methods for branching rule plugins and branching
    public methods for constraint handler plugins and constraints
    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 nonlinear relaxation
    public methods for numerical tolerances
    public methods for SCIP parameter handling
    public methods for global and local (sub)problems
    public methods for random numbers
    public methods for solutions
    public methods for querying solving statistics
    public methods for the branch-and-bound tree
    public methods for SCIP variables
    methods for handling symmetries
    SCIP_RETCODE SCIPtreemodelSelectCandidate(SCIP *scip, SCIP_TREEMODEL *treemodel, SCIP_VAR **branchcands, SCIP_Real *mingains, SCIP_Real *maxgains, SCIP_Real *tiebreakerscore, int nbranchcands, int *bestcand)
    Definition: treemodel.c:912
    SCIP_RETCODE SCIPtreemodelInit(SCIP *scip, SCIP_TREEMODEL **treemodel)
    Definition: treemodel.c:826
    SCIP_RETCODE SCIPtreemodelFree(SCIP *scip, SCIP_TREEMODEL **treemodel)
    Definition: treemodel.c:884
    SCIP_Bool SCIPtreemodelIsEnabled(SCIP *scip, SCIP_TREEMODEL *treemodel)
    Definition: treemodel.c:900
    Branching rules based on the Single-Variable-Branching (SVB) model.
    struct SCIP_BranchruleData SCIP_BRANCHRULEDATA
    Definition: type_branch.h:57
    @ SCIP_BRANCHDIR_DOWNWARDS
    Definition: type_history.h:43
    @ SCIP_BRANCHDIR_UPWARDS
    Definition: type_history.h:44
    @ SCIP_BOUNDTYPE_UPPER
    Definition: type_lp.h:58
    @ SCIP_BOUNDTYPE_LOWER
    Definition: type_lp.h:57
    enum SCIP_BoundType SCIP_BOUNDTYPE
    Definition: type_lp.h:60
    @ SCIP_LPSOLSTAT_OPTIMAL
    Definition: type_lp.h:44
    @ SCIP_LPSOLSTAT_INFEASIBLE
    Definition: type_lp.h:45
    @ SCIP_LPSOLSTAT_OBJLIMIT
    Definition: type_lp.h:47
    @ SCIP_LPSOLSTAT_ITERLIMIT
    Definition: type_lp.h:48
    @ SCIP_VERBLEVEL_HIGH
    Definition: type_message.h:61
    @ SCIP_CONFIDENCELEVEL_MAX
    Definition: type_misc.h:51
    @ SCIP_CONFIDENCELEVEL_MEDIUM
    Definition: type_misc.h:49
    @ SCIP_CONFIDENCELEVEL_HIGH
    Definition: type_misc.h:50
    @ SCIP_CONFIDENCELEVEL_MIN
    Definition: type_misc.h:47
    @ SCIP_CONFIDENCELEVEL_LOW
    Definition: type_misc.h:48
    enum SCIP_Confidencelevel SCIP_CONFIDENCELEVEL
    Definition: type_misc.h:53
    @ SCIP_DIDNOTRUN
    Definition: type_result.h:42
    @ SCIP_CUTOFF
    Definition: type_result.h:48
    @ SCIP_REDUCEDDOM
    Definition: type_result.h:51
    @ SCIP_CONSADDED
    Definition: type_result.h:52
    @ SCIP_BRANCHED
    Definition: type_result.h:54
    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
    @ SCIP_BOUNDCHGTYPE_BRANCHING
    Definition: type_var.h:131