Scippy

    SCIP

    Solving Constraint Integer Programs

    branch.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.c
    26 * @ingroup OTHER_CFILES
    27 * @brief methods for branching rules and branching candidate storage
    28 * @author Tobias Achterberg
    29 * @author Timo Berthold
    30 * @author Gerald Gamrath
    31 * @author Stefan Heinz
    32 * @author Michael Winkler
    33 * @author Stefan Vigerske
    34 */
    35
    36/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
    37
    38#include <assert.h>
    39#include <string.h>
    40
    41#include "scip/def.h"
    43#include "scip/set.h"
    44#include "scip/stat.h"
    45#include "scip/clock.h"
    46#include "scip/paramset.h"
    47#include "scip/event.h"
    48#include "scip/lp.h"
    49#include "scip/var.h"
    50#include "scip/prob.h"
    51#include "scip/tree.h"
    52#include "scip/sepastore.h"
    53#include "scip/scip.h"
    54#include "scip/branch.h"
    55#include "scip/solve.h"
    56
    57#include "scip/struct_branch.h"
    58
    59/*
    60 * memory growing methods for dynamically allocated arrays
    61 */
    62
    63/** ensures, that lpcands array can store at least num entries */
    64static
    66 SCIP_BRANCHCAND* branchcand, /**< branching candidate storage */
    67 SCIP_SET* set, /**< global SCIP settings */
    68 int num /**< minimum number of entries to store */
    69 )
    70{
    71 assert(branchcand->nlpcands <= branchcand->lpcandssize);
    72
    73 if( num > branchcand->lpcandssize )
    74 {
    75 int newsize;
    76
    77 newsize = SCIPsetCalcMemGrowSize(set, num);
    78 SCIP_ALLOC( BMSreallocMemoryArray(&branchcand->lpcands, newsize) );
    79 SCIP_ALLOC( BMSreallocMemoryArray(&branchcand->lpcandssol, newsize) );
    80 SCIP_ALLOC( BMSreallocMemoryArray(&branchcand->lpcandsfrac, newsize) );
    81 branchcand->lpcandssize = newsize;
    82 }
    83 assert(num <= branchcand->lpcandssize);
    84
    85 return SCIP_OKAY;
    86}
    87
    88/** ensures, that pseudocands array can store at least num entries */
    89static
    91 SCIP_BRANCHCAND* branchcand, /**< branching candidate storage */
    92 SCIP_SET* set, /**< global SCIP settings */
    93 int num /**< minimum number of entries to store */
    94 )
    95{
    96 assert(branchcand->npseudocands <= branchcand->pseudocandssize);
    97
    98 if( num > branchcand->pseudocandssize )
    99 {
    100 int newsize;
    101
    102 newsize = SCIPsetCalcMemGrowSize(set, num);
    103 SCIP_ALLOC( BMSreallocMemoryArray(&branchcand->pseudocands, newsize) );
    104 branchcand->pseudocandssize = newsize;
    105 }
    106 assert(num <= branchcand->pseudocandssize);
    107
    108 return SCIP_OKAY;
    109}
    110
    111/** ensures, that externcands array can store at least num entries */
    112static
    114 SCIP_BRANCHCAND* branchcand, /**< branching candidate storage */
    115 SCIP_SET* set, /**< global SCIP settings */
    116 int num /**< minimum number of entries to store */
    117 )
    118{
    119 assert(branchcand->nexterncands <= branchcand->externcandssize);
    120
    121 if( num > branchcand->externcandssize )
    122 {
    123 int newsize;
    124
    125 newsize = SCIPsetCalcMemGrowSize(set, num);
    126 SCIP_ALLOC( BMSreallocMemoryArray(&branchcand->externcands, newsize) );
    127 SCIP_ALLOC( BMSreallocMemoryArray(&branchcand->externcandsscore, newsize) );
    128 SCIP_ALLOC( BMSreallocMemoryArray(&branchcand->externcandssol, newsize) );
    129 branchcand->externcandssize = newsize;
    130 }
    131 assert(num <= branchcand->externcandssize);
    132
    133 return SCIP_OKAY;
    134}
    135
    136
    137
    138/*
    139 * branching candidate storage methods
    140 */
    141
    142/** creates a branching candidate storage */
    144 SCIP_BRANCHCAND** branchcand /**< pointer to store branching candidate storage */
    145 )
    146{
    147 assert(branchcand != NULL);
    148
    149 SCIP_ALLOC( BMSallocMemory(branchcand) );
    150 (*branchcand)->lpcands = NULL;
    151 (*branchcand)->lpcandssol = NULL;
    152 (*branchcand)->lpcandsfrac = NULL;
    153 (*branchcand)->externcands = NULL;
    154 (*branchcand)->externcandssol = NULL;
    155 (*branchcand)->externcandsscore = NULL;
    156 (*branchcand)->pseudocands = NULL;
    157 (*branchcand)->lpcandssize = 0;
    158 (*branchcand)->nlpcands = 0;
    159 (*branchcand)->nimpllpfracs = 0;
    160 (*branchcand)->npriolpcands = 0;
    161 (*branchcand)->npriolpbins = 0;
    162 (*branchcand)->nenfoimpllpfracs = 0;
    163 (*branchcand)->lpmaxpriority = INT_MIN;
    164 (*branchcand)->externcandssize = 0;
    165 (*branchcand)->nexterncands = 0;
    166 (*branchcand)->nprioexterncands = 0;
    167 (*branchcand)->nprioexternbins = 0;
    168 (*branchcand)->nprioexternints = 0;
    169 (*branchcand)->nprioexternimpls = 0;
    170 (*branchcand)->externmaxpriority = INT_MIN;
    171 (*branchcand)->pseudocandssize = 0;
    172 (*branchcand)->npseudocands = 0;
    173 (*branchcand)->npriopseudocands = 0;
    174 (*branchcand)->npriopseudobins = 0;
    175 (*branchcand)->npriopseudoints = 0;
    176 (*branchcand)->pseudomaxpriority = INT_MIN;
    177
    178 SCIPbranchcandInvalidate(*branchcand);
    179
    180 return SCIP_OKAY;
    181}
    182
    183/** frees branching candidate storage */
    185 SCIP_BRANCHCAND** branchcand /**< pointer to store branching candidate storage */
    186 )
    187{
    188 assert(branchcand != NULL);
    189
    190 BMSfreeMemoryArrayNull(&(*branchcand)->lpcands);
    191 BMSfreeMemoryArrayNull(&(*branchcand)->lpcandssol);
    192 BMSfreeMemoryArrayNull(&(*branchcand)->lpcandsfrac);
    193 BMSfreeMemoryArrayNull(&(*branchcand)->pseudocands);
    194 BMSfreeMemoryArrayNull(&(*branchcand)->externcands);
    195 BMSfreeMemoryArrayNull(&(*branchcand)->externcandsscore);
    196 BMSfreeMemoryArrayNull(&(*branchcand)->externcandssol);
    197 BMSfreeMemory(branchcand);
    198
    199 return SCIP_OKAY;
    200}
    201
    202/** resets branching candidates storage */
    204 SCIP_BRANCHCAND* branchcand /**< pointer to store branching candidate storage */
    205 )
    206{
    207 assert(branchcand != NULL);
    208
    209 branchcand->validlpcandslp = -1;
    210}
    211
    212/** calculates branching candidates for LP solution branching (fractional variables) */
    213static
    215 SCIP_BRANCHCAND* branchcand, /**< branching candidate storage */
    216 SCIP_SET* set, /**< global SCIP settings */
    217 SCIP_STAT* stat, /**< problem statistics */
    218 SCIP_LP* lp /**< current LP data */
    219 )
    220{
    221 assert(branchcand != NULL);
    222 assert(stat != NULL);
    223 assert(branchcand->validlpcandslp <= stat->lpcount);
    224 assert(lp != NULL);
    225 assert(lp->solved);
    227
    228 SCIPsetDebugMsg(set, "calculating LP branching candidates: validlp=%" SCIP_LONGINT_FORMAT ", lpcount=%" SCIP_LONGINT_FORMAT "\n",
    229 branchcand->validlpcandslp, stat->lpcount);
    230
    231 /* check, if the current LP branching candidate array is invalid */
    232 if( branchcand->validlpcandslp < stat->lpcount )
    233 {
    234 SCIP_COL** cols;
    235 SCIP_VAR* var;
    236 SCIP_COL* col;
    237 SCIP_Real primsol;
    238 SCIP_Real frac;
    239 SCIP_VARTYPE vartype;
    240 SCIP_IMPLINTTYPE impltype;
    241 int branchpriority;
    242 int ncols;
    243 int c;
    244 int insertpos;
    245
    246 SCIPsetDebugMsg(set, " -> recalculating LP branching candidates\n");
    247
    248 cols = SCIPlpGetCols(lp);
    249 ncols = SCIPlpGetNCols(lp);
    250
    251 /* construct the LP branching candidate set, moving the candidates with maximal priority to the front */
    252 SCIP_CALL( ensureLpcandsSize(branchcand, set, ncols) );
    253
    254 branchcand->lpmaxpriority = INT_MIN / 2;
    255 branchcand->nlpcands = 0;
    256 branchcand->nimpllpfracs = 0;
    257 branchcand->npriolpcands = 0;
    258 branchcand->npriolpbins = 0;
    259 branchcand->nenfoimpllpfracs = 0;
    260 for( c = 0; c < ncols; ++c )
    261 {
    262 col = cols[c];
    263 assert(col != NULL);
    264 assert(col->lppos == c);
    265 assert(col->lpipos >= 0);
    266
    267 primsol = SCIPcolGetPrimsol(col);
    268 assert(primsol != SCIP_INVALID); /*lint !e777*/
    269 assert(SCIPsetIsInfinity(set, -col->lb) || SCIPsetIsFeasGE(set, primsol, col->lb));
    270 assert(SCIPsetIsInfinity(set, col->ub) || SCIPsetIsFeasLE(set, primsol, col->ub));
    271
    272 /* count values at infinity as integral */
    273 if( SCIPsetIsInfinity(set, REALABS(primsol)) )
    274 continue;
    275
    276 var = col->var;
    277 assert(var != NULL);
    279 assert(SCIPvarGetCol(var) == col);
    280
    281 /* LP branching candidates are fractional binary and integer variables; implicit variables are kept at the end
    282 * of the candidates array for some rounding heuristics
    283 */
    284 vartype = SCIPvarGetType(var);
    285 impltype = SCIPvarGetImplType(var);
    286 if( vartype == SCIP_VARTYPE_CONTINUOUS && impltype == SCIP_IMPLINTTYPE_NONE )
    287 continue;
    288
    289 /* ignore fixed variables (due to numerics, it is possible, that the LP solution of a fixed integer variable
    290 * (with large fixed value) is fractional in terms of absolute feasibility measure)
    291 */
    292 if( SCIPvarGetLbLocal(var) >= SCIPvarGetUbLocal(var) - 0.5 )
    293 continue;
    294
    295 /* check, if the LP solution value is fractional */
    296 frac = SCIPsetFeasFrac(set, primsol);
    297
    298 /* The fractionality should not be smaller than -feastol, however, if the primsol is large enough
    299 * and close to an integer, fixed precision floating point arithmetic might give us values slightly
    300 * smaller than -feastol. Originally, the "frac >= -feastol"-check was within SCIPsetIsFeasFracIntegral(),
    301 * however, we relaxed it to "frac >= -2*feastol" and have the stricter check here for small-enough primsols.
    302 */
    303 assert(SCIPsetIsGE(set, frac, -SCIPsetFeastol(set)) || (primsol > 1e14 * SCIPsetFeastol(set)));
    304
    305 if( SCIPsetIsFeasFracIntegral(set, frac) )
    306 continue;
    307
    308 /* insert candidate in candidate list */
    309 branchpriority = SCIPvarGetBranchPriority(var);
    310 insertpos = branchcand->nlpcands + branchcand->nimpllpfracs;
    311 assert(insertpos < branchcand->lpcandssize);
    312
    313 if( impltype != SCIP_IMPLINTTYPE_NONE )
    314 branchpriority = INT_MIN;
    315
    316 assert(impltype != SCIP_IMPLINTTYPE_NONE || branchpriority >= INT_MIN/2);
    317
    318 /* ensure that unenforced implied integral variables are stored at the end of the array */
    319 if( branchcand->nimpllpfracs > branchcand->nenfoimpllpfracs && vartype != SCIP_VARTYPE_CONTINUOUS )
    320 {
    321 branchcand->lpcands[insertpos] = branchcand->lpcands[branchcand->nlpcands + branchcand->nenfoimpllpfracs];
    322 branchcand->lpcandssol[insertpos] = branchcand->lpcandssol[branchcand->nlpcands + branchcand->nenfoimpllpfracs];
    323 branchcand->lpcandsfrac[insertpos] = branchcand->lpcandsfrac[branchcand->nlpcands + branchcand->nenfoimpllpfracs];
    324 assert(SCIPvarIsImpliedIntegral(branchcand->lpcands[insertpos]));
    325 insertpos = branchcand->nlpcands + branchcand->nenfoimpllpfracs;
    326 }
    327
    328 /* ensure that enforced implied integral variables are stored before the end of the array */
    329 if( branchcand->nenfoimpllpfracs > 0 && impltype == SCIP_IMPLINTTYPE_NONE )
    330 {
    331 branchcand->lpcands[insertpos] = branchcand->lpcands[branchcand->nlpcands];
    332 branchcand->lpcandssol[insertpos] = branchcand->lpcandssol[branchcand->nlpcands];
    333 branchcand->lpcandsfrac[insertpos] = branchcand->lpcandsfrac[branchcand->nlpcands];
    334 assert(SCIPvarIsImpliedIntegral(branchcand->lpcands[insertpos]));
    335 insertpos = branchcand->nlpcands;
    336 }
    337
    338 if( branchpriority > branchcand->lpmaxpriority )
    339 {
    340 /* candidate has higher priority than the current maximum:
    341 * move it to the front and declare it to be the single best candidate
    342 */
    343 if( insertpos != 0 )
    344 {
    345 branchcand->lpcands[insertpos] = branchcand->lpcands[0];
    346 branchcand->lpcandssol[insertpos] = branchcand->lpcandssol[0];
    347 branchcand->lpcandsfrac[insertpos] = branchcand->lpcandsfrac[0];
    348 insertpos = 0;
    349 }
    350 branchcand->npriolpcands = 1;
    351 assert(!SCIPvarIsImpliedIntegral(var));
    352 branchcand->npriolpbins = (vartype == SCIP_VARTYPE_BINARY ? 1 : 0);
    353 branchcand->lpmaxpriority = branchpriority;
    354 }
    355 else if( branchpriority == branchcand->lpmaxpriority )
    356 {
    357 /* candidate has equal priority as the current maximum:
    358 * move away the first non-maximal priority candidate, move the current candidate to the correct
    359 * slot (binaries first) and increase the number of maximal priority candidates
    360 */
    361 if( insertpos != branchcand->npriolpcands )
    362 {
    363 branchcand->lpcands[insertpos] = branchcand->lpcands[branchcand->npriolpcands];
    364 branchcand->lpcandssol[insertpos] = branchcand->lpcandssol[branchcand->npriolpcands];
    365 branchcand->lpcandsfrac[insertpos] = branchcand->lpcandsfrac[branchcand->npriolpcands];
    366 insertpos = branchcand->npriolpcands;
    367 }
    368 ++branchcand->npriolpcands;
    369
    370 assert(!SCIPvarIsImpliedIntegral(var));
    371 if( vartype == SCIP_VARTYPE_BINARY )
    372 {
    373 if( insertpos != branchcand->npriolpbins )
    374 {
    375 branchcand->lpcands[insertpos] = branchcand->lpcands[branchcand->npriolpbins];
    376 branchcand->lpcandssol[insertpos] = branchcand->lpcandssol[branchcand->npriolpbins];
    377 branchcand->lpcandsfrac[insertpos] = branchcand->lpcandsfrac[branchcand->npriolpbins];
    378 insertpos = branchcand->npriolpbins;
    379 }
    380 ++branchcand->npriolpbins;
    381 }
    382 }
    383 /* insert variable at the correct position of the candidates storage */
    384 branchcand->lpcands[insertpos] = var;
    385 branchcand->lpcandssol[insertpos] = primsol;
    386 branchcand->lpcandsfrac[insertpos] = frac;
    387
    388 /* increase the counter depending on the variable type */
    389 if( impltype == SCIP_IMPLINTTYPE_NONE )
    390 ++branchcand->nlpcands;
    391 else
    392 {
    393 ++branchcand->nimpllpfracs;
    394
    395 if( vartype != SCIP_VARTYPE_CONTINUOUS )
    396 ++branchcand->nenfoimpllpfracs;
    397 }
    398
    399 SCIPsetDebugMsg(set, " -> candidate %d: var=<%s>, sol=%g, frac=%g, prio=%d (max: %d) -> pos %d\n",
    400 branchcand->nlpcands, SCIPvarGetName(var), primsol, frac, branchpriority, branchcand->lpmaxpriority,
    401 insertpos);
    402 }
    403
    404#ifndef NDEBUG
    405 /* in debug mode we assert that the variables are positioned correctly (binaries and integers first,
    406 * implicit integers last)
    407 */
    408 for( c = 0; c < branchcand->nlpcands + branchcand->nimpllpfracs; ++c )
    409 {
    410 assert(SCIPvarIsImpliedIntegral(branchcand->lpcands[c]) == (c >= branchcand->nlpcands));
    411 assert((SCIPvarGetType(branchcand->lpcands[c]) == SCIP_VARTYPE_CONTINUOUS) == (c >= branchcand->nlpcands + branchcand->nenfoimpllpfracs));
    412 }
    413#endif
    414
    415 branchcand->validlpcandslp = stat->lpcount;
    416 }
    417 assert(0 <= branchcand->npriolpcands && branchcand->npriolpcands <= branchcand->nlpcands);
    418
    419 SCIPsetDebugMsg(set, " -> %d fractional variables (%d of maximal priority)\n", branchcand->nlpcands, branchcand->npriolpcands);
    420
    421 return SCIP_OKAY;
    422}
    423
    424/** gets branching candidates for LP solution branching (fractional variables) */
    426 SCIP_BRANCHCAND* branchcand, /**< branching candidate storage */
    427 SCIP_SET* set, /**< global SCIP settings */
    428 SCIP_STAT* stat, /**< problem statistics */
    429 SCIP_LP* lp, /**< current LP data */
    430 SCIP_VAR*** lpcands, /**< pointer to store the array of LP branching candidates, or NULL */
    431 SCIP_Real** lpcandssol, /**< pointer to store the array of LP candidate solution values, or NULL */
    432 SCIP_Real** lpcandsfrac, /**< pointer to store the array of LP candidate fractionalities, or NULL */
    433 int* nlpcands, /**< pointer to store the number of LP branching candidates, or NULL */
    434 int* npriolpcands, /**< pointer to store the number of candidates with maximal priority, or NULL */
    435 int* nfracimplvars /**< pointer to store the number of fractional continuous implied integral variables, or NULL */
    436 )
    437{
    438 /* calculate branching candidates */
    439 SCIP_CALL( branchcandCalcLPCands(branchcand, set, stat, lp) );
    440
    441 /* assign return values */
    442 if( lpcands != NULL )
    443 *lpcands = branchcand->lpcands;
    444 if( lpcandssol != NULL )
    445 *lpcandssol = branchcand->lpcandssol;
    446 if( lpcandsfrac != NULL )
    447 *lpcandsfrac = branchcand->lpcandsfrac;
    448 if( nlpcands != NULL )
    449 *nlpcands = branchcand->nlpcands + branchcand->nenfoimpllpfracs;
    450 if( npriolpcands != NULL )
    451 *npriolpcands = (set->branch_preferbinary && branchcand->npriolpbins > 0 ? branchcand->npriolpbins
    452 : branchcand->npriolpcands);
    453 if( nfracimplvars != NULL )
    454 *nfracimplvars = branchcand->nimpllpfracs - branchcand->nenfoimpllpfracs;
    455
    456 return SCIP_OKAY;
    457}
    458
    459/** gets external branching candidates */
    461 SCIP_BRANCHCAND* branchcand, /**< branching candidate storage */
    462 SCIP_VAR*** externcands, /**< pointer to store the array of external branching candidates, or NULL */
    463 SCIP_Real** externcandssol, /**< pointer to store the array of external candidate solution values, or NULL */
    464 SCIP_Real** externcandsscore, /**< pointer to store the array of external candidate scores, or NULL */
    465 int* nexterncands, /**< pointer to store the number of external branching candidates, or NULL */
    466 int* nprioexterncands, /**< pointer to store the number of candidates with maximal priority, or NULL */
    467 int* nprioexternbins, /**< pointer to store the number of binary candidates with maximal priority, or NULL */
    468 int* nprioexternints, /**< pointer to store the number of integer candidates with maximal priority, or NULL */
    469 int* nprioexternimpls /**< pointer to store the number of implicit integer candidates with maximal priority,
    470 * or NULL */
    471 )
    472{
    473 assert(branchcand != NULL);
    474
    475 /* assign return values */
    476 if( externcands != NULL )
    477 *externcands = branchcand->externcands;
    478 if( externcandssol != NULL )
    479 *externcandssol = branchcand->externcandssol;
    480 if( externcandsscore != NULL )
    481 *externcandsscore = branchcand->externcandsscore;
    482 if( nexterncands != NULL )
    483 *nexterncands = branchcand->nexterncands;
    484 if( nprioexterncands != NULL )
    485 *nprioexterncands = branchcand->nprioexterncands;
    486 if( nprioexternbins != NULL )
    487 *nprioexternbins = branchcand->nprioexternbins;
    488 if( nprioexternints != NULL )
    489 *nprioexternints = branchcand->nprioexternints;
    490 if( nprioexternimpls != NULL )
    491 *nprioexternimpls = branchcand->nprioexternimpls;
    492
    493 return SCIP_OKAY;
    494}
    495
    496/** gets maximal branching priority of LP branching candidates */
    498 SCIP_BRANCHCAND* branchcand /**< branching candidate storage */
    499 )
    500{
    501 assert(branchcand != NULL);
    502
    503 return branchcand->lpmaxpriority;
    504}
    505
    506/** gets number of LP branching candidates with maximal branch priority */
    508 SCIP_BRANCHCAND* branchcand /**< branching candidate storage */
    509 )
    510{
    511 assert(branchcand != NULL);
    512
    513 return branchcand->npriolpcands;
    514}
    515
    516/** gets maximal branching priority of external branching candidates */
    518 SCIP_BRANCHCAND* branchcand /**< branching candidate storage */
    519 )
    520{
    521 assert(branchcand != NULL);
    522
    523 return branchcand->externmaxpriority;
    524}
    525
    526/** gets number of external branching candidates */
    528 SCIP_BRANCHCAND* branchcand /**< branching candidate storage */
    529 )
    530{
    531 assert(branchcand != NULL);
    532
    533 return branchcand->nexterncands;
    534}
    535
    536/** gets number of external branching candidates with maximal branch priority */
    538 SCIP_BRANCHCAND* branchcand /**< branching candidate storage */
    539 )
    540{
    541 assert(branchcand != NULL);
    542
    543 return branchcand->nprioexterncands;
    544}
    545
    546/** gets number of binary external branching candidates with maximal branch priority */
    548 SCIP_BRANCHCAND* branchcand /**< branching candidate storage */
    549 )
    550{
    551 assert(branchcand != NULL);
    552
    553 return branchcand->nprioexternbins;
    554}
    555
    556/** gets number of integer external branching candidates with maximal branch priority */
    558 SCIP_BRANCHCAND* branchcand /**< branching candidate storage */
    559 )
    560{
    561 assert(branchcand != NULL);
    562
    563 return branchcand->nprioexternints;
    564}
    565
    566/** gets number of implicit integer external branching candidates with maximal branch priority */
    568 SCIP_BRANCHCAND* branchcand /**< branching candidate storage */
    569 )
    570{
    571 assert(branchcand != NULL);
    572
    573 return branchcand->nprioexternimpls;
    574}
    575
    576/** gets number of continuous external branching candidates with maximal branch priority */
    578 SCIP_BRANCHCAND* branchcand /**< branching candidate storage */
    579 )
    580{
    581 assert(branchcand != NULL);
    582
    583 return branchcand->nprioexterncands - branchcand->nprioexternbins - branchcand->nprioexternints - branchcand->nprioexternimpls;
    584}
    585
    586/** insert variable, its score and its solution value into the external branching candidate storage
    587 * the absolute difference of the current lower and upper bounds of the variable must be at least epsilon
    588 */
    590 SCIP_BRANCHCAND* branchcand, /**< branching candidate storage */
    591 SCIP_SET* set, /**< global SCIP settings */
    592 SCIP_VAR* var, /**< variable to insert */
    593 SCIP_Real score, /**< score of external candidate, e.g. infeasibility */
    594 SCIP_Real solval /**< value of the variable in the current solution */
    595 )
    596{
    597 SCIP_VARTYPE vartype = SCIPvarGetType(var);
    598 SCIP_IMPLINTTYPE impltype = SCIPvarGetImplType(var);
    599 int branchpriority = SCIPvarGetBranchPriority(var);
    600 int insertpos;
    601
    602 assert(branchcand != NULL);
    603 assert(!SCIPsetIsEQ(set, SCIPvarGetLbLocal(var), SCIPvarGetUbLocal(var))); /* the variable should not be fixed yet */
    604 assert((vartype == SCIP_VARTYPE_CONTINUOUS && impltype == SCIP_IMPLINTTYPE_NONE) || !SCIPsetIsEQ(set, SCIPsetCeil(set, SCIPvarGetLbLocal(var)), SCIPsetFloor(set, SCIPvarGetUbLocal(var)))); /* a discrete variable should also not be fixed, even after rounding bounds to integral values */
    605 assert(SCIPvarGetStatus(var) != SCIP_VARSTATUS_MULTAGGR || !SCIPsetIsEQ(set, SCIPvarGetMultaggrLbLocal(var, set), SCIPvarGetMultaggrUbLocal(var, set))); /* also the current bounds of a multi-aggregated variable should not be fixed yet */
    606 assert(branchcand->nprioexterncands <= branchcand->nexterncands);
    607 assert(branchcand->nexterncands <= branchcand->externcandssize);
    608
    609 insertpos = branchcand->nexterncands;
    610
    611 SCIP_CALL( ensureExterncandsSize(branchcand, set, branchcand->nexterncands+1) );
    612
    613 SCIPsetDebugMsg(set, "inserting external candidate <%s> of type %d and priority %d into candidate set (maxprio: %d), score = %g, solval = %g\n",
    614 SCIPvarGetName(var), vartype, branchpriority, branchcand->externmaxpriority, score, solval);
    615
    616 /* insert the variable into externcands, making sure, that the highest priority candidates are at the front
    617 * and ordered binaries, integers, implicit integers, continuous
    618 */
    619 if( branchpriority > branchcand->externmaxpriority )
    620 {
    621 /* candidate has higher priority than the current maximum:
    622 * move it to the front and declare it to be the single best candidate
    623 */
    624 branchcand->externcands[insertpos] = branchcand->externcands[0];
    625 branchcand->externcandsscore[insertpos] = branchcand->externcandsscore[0];
    626 branchcand->externcandssol[insertpos] = branchcand->externcandssol[0];
    627
    628 insertpos = 0;
    629
    630 branchcand->nprioexterncands = 1;
    631 branchcand->nprioexternbins = 0;
    632 branchcand->nprioexternints = 0;
    633 branchcand->nprioexternimpls = 0;
    634 if( impltype != SCIP_IMPLINTTYPE_NONE )
    635 branchcand->nprioexternimpls = 1;
    636 else if( vartype == SCIP_VARTYPE_BINARY )
    637 branchcand->nprioexternbins = 1;
    638 else if( vartype == SCIP_VARTYPE_INTEGER )
    639 branchcand->nprioexternints = 1;
    640 branchcand->externmaxpriority = branchpriority;
    641 }
    642 else if( branchpriority == branchcand->externmaxpriority )
    643 {
    644 /* candidate has equal priority as the current maximum:
    645 * move away the first non-maximal priority candidate, move the current candidate to the correct
    646 * slot (binaries first, integers next, implicit integers next, continuous last) and increase the number
    647 * of maximal priority candidates
    648 */
    649 if( insertpos != branchcand->nprioexterncands )
    650 {
    651 branchcand->externcands[insertpos] = branchcand->externcands[branchcand->nprioexterncands];
    652 branchcand->externcandsscore[insertpos] = branchcand->externcandsscore[branchcand->nprioexterncands];
    653 branchcand->externcandssol[insertpos] = branchcand->externcandssol[branchcand->nprioexterncands];
    654
    655 insertpos = branchcand->nprioexterncands;
    656 }
    657 branchcand->nprioexterncands++;
    658 if( vartype != SCIP_VARTYPE_CONTINUOUS || impltype != SCIP_IMPLINTTYPE_NONE )
    659 {
    660 if( insertpos != branchcand->nprioexternbins + branchcand->nprioexternints + branchcand->nprioexternimpls )
    661 {
    662 branchcand->externcands[insertpos] =
    663 branchcand->externcands[branchcand->nprioexternbins + branchcand->nprioexternints + branchcand->nprioexternimpls];
    664 branchcand->externcandsscore[insertpos] =
    665 branchcand->externcandsscore[branchcand->nprioexternbins + branchcand->nprioexternints + branchcand->nprioexternimpls];
    666 branchcand->externcandssol[insertpos] =
    667 branchcand->externcandssol[branchcand->nprioexternbins + branchcand->nprioexternints + branchcand->nprioexternimpls];
    668
    669 insertpos = branchcand->nprioexternbins + branchcand->nprioexternints + branchcand->nprioexternimpls;
    670 }
    671 branchcand->nprioexternimpls++;
    672
    673 if( impltype == SCIP_IMPLINTTYPE_NONE )
    674 {
    675 assert(vartype != SCIP_VARTYPE_CONTINUOUS);
    676 if( insertpos != branchcand->nprioexternbins + branchcand->nprioexternints )
    677 {
    678 branchcand->externcands[insertpos] =
    679 branchcand->externcands[branchcand->nprioexternbins + branchcand->nprioexternints];
    680 branchcand->externcandsscore[insertpos] =
    681 branchcand->externcandsscore[branchcand->nprioexternbins + branchcand->nprioexternints];
    682 branchcand->externcandssol[insertpos] =
    683 branchcand->externcandssol[branchcand->nprioexternbins + branchcand->nprioexternints];
    684
    685 insertpos = branchcand->nprioexternbins + branchcand->nprioexternints;
    686 }
    687 branchcand->nprioexternints++;
    688 branchcand->nprioexternimpls--;
    689
    690 if( vartype == SCIP_VARTYPE_BINARY )
    691 {
    692 if( insertpos != branchcand->nprioexternbins )
    693 {
    694 branchcand->externcands[insertpos] = branchcand->externcands[branchcand->nprioexternbins];
    695 branchcand->externcandsscore[insertpos] = branchcand->externcandsscore[branchcand->nprioexternbins];
    696 branchcand->externcandssol[insertpos] = branchcand->externcandssol[branchcand->nprioexternbins];
    697
    698 insertpos = branchcand->nprioexternbins;
    699 }
    700 branchcand->nprioexternbins++;
    701 branchcand->nprioexternints--;
    702 }
    703 }
    704 }
    705 }
    706 branchcand->externcands[insertpos] = var;
    707 branchcand->externcandsscore[insertpos] = score;
    708 branchcand->externcandssol[insertpos] = solval;
    709 branchcand->nexterncands++;
    710
    711 SCIPsetDebugMsg(set, " -> inserted at position %d (nprioexterncands=%d)\n", insertpos, branchcand->nprioexterncands);
    712
    713 assert(0 <= branchcand->nprioexterncands && branchcand->nprioexterncands <= branchcand->nexterncands);
    714 assert(0 <= branchcand->nprioexternbins && branchcand->nprioexternbins <= branchcand->nprioexterncands);
    715 assert(0 <= branchcand->nprioexternints && branchcand->nprioexternints <= branchcand->nprioexterncands);
    716 assert(0 <= branchcand->nprioexternimpls && branchcand->nprioexternimpls <= branchcand->nprioexterncands);
    717
    718 return SCIP_OKAY;
    719}
    720
    721/** removes all external candidates from the storage for external branching */
    723 SCIP_BRANCHCAND* branchcand /**< branching candidate storage */
    724 )
    725{
    726 assert(branchcand != NULL);
    727
    728 branchcand->nexterncands = 0;
    729 branchcand->nprioexterncands = 0;
    730 branchcand->nprioexternbins = 0;
    731 branchcand->nprioexternints = 0;
    732 branchcand->nprioexternimpls = 0;
    733 branchcand->externmaxpriority = INT_MIN;
    734}
    735
    736/** checks whether the given variable is contained in the candidate storage for external branching */
    738 SCIP_BRANCHCAND* branchcand, /**< branching candidate storage */
    739 SCIP_VAR* var /**< variable to look for */
    740 )
    741{
    742 int branchpriority;
    743 int i;
    744
    745 assert(branchcand != NULL);
    746 assert(var != NULL);
    747 assert(branchcand->nprioexterncands <= branchcand->nexterncands);
    748 assert(branchcand->nexterncands <= branchcand->externcandssize);
    749
    750 branchpriority = SCIPvarGetBranchPriority(var);
    751
    752 /* look for the variable in the externcands, using the fact, that the highest priority candidates are at the front
    753 * and ordered binaries, integers, implicit integers, continuous
    754 */
    755 if( branchpriority > branchcand->externmaxpriority )
    756 {
    757 /* the branching priority of the variable is higher than the maximal priority contained in the array;
    758 * the variable can thus not be contained */
    759 return FALSE;
    760 }
    761 if( branchpriority == branchcand->externmaxpriority )
    762 {
    763 SCIP_VARTYPE vartype;
    764
    765 vartype = SCIPvarGetType(var);
    766
    767 /* variable has equal priority as the current maximum:
    768 * look for it in the correct slot (binaries first, integers next, implicit integers next, continuous last)
    769 */
    770 if( SCIPvarIsImpliedIntegral(var) )
    771 {
    772 /* the variable is implicit integer, look at the slots containing implicit integers */
    773 for( i = 0; i < branchcand->nprioexternimpls; i++ )
    774 if( branchcand->externcands[branchcand->nprioexternbins + branchcand->nprioexternints + i] == var )
    775 return TRUE;
    776 return FALSE;
    777 }
    778 if( vartype == SCIP_VARTYPE_BINARY )
    779 {
    780 /* the variable is binary, look at the first branchcand->nprioexternbins slots */
    781 for( i = 0; i < branchcand->nprioexternbins; i++ )
    782 if( branchcand->externcands[i] == var )
    783 return TRUE;
    784 return FALSE;
    785 }
    786 if( vartype == SCIP_VARTYPE_INTEGER )
    787 {
    788 /* the variable is integer, look at the slots containing integers */
    789 for( i = 0; i < branchcand->nprioexternints; i++ )
    790 if( branchcand->externcands[branchcand->nprioexternbins + i] == var )
    791 return TRUE;
    792 return FALSE;
    793 }
    794 /* the variable is continuous, look at the slots containing continuous variables */
    795 assert(vartype == SCIP_VARTYPE_CONTINUOUS);
    796 for( i = branchcand->nprioexternbins + branchcand->nprioexternints + branchcand->nprioexternimpls;
    797 i < branchcand->nprioexterncands; i++ )
    798 if( branchcand->externcands[i] == var )
    799 return TRUE;
    800 return FALSE;
    801 }
    802 /* the branching priority of the variable is lower than the maximal priority contained in the array;
    803 * look for the variable in the candidates which do not have maximal priority */
    804 assert(branchpriority < branchcand->externmaxpriority);
    805
    806 for( i = branchcand->nprioexterncands; i < branchcand->nexterncands; i++ )
    807 if( branchcand->externcands[i] == var )
    808 return TRUE;
    809 return FALSE;
    810}
    811
    812/** gets branching candidates for pseudo solution branching (non-fixed variables) */
    814 SCIP_BRANCHCAND* branchcand, /**< branching candidate storage */
    815 SCIP_SET* set, /**< global SCIP settings */
    816 SCIP_PROB* prob, /**< problem data */
    817 SCIP_VAR*** pseudocands, /**< pointer to store the array of pseudo branching candidates, or NULL */
    818 int* npseudocands, /**< pointer to store the number of pseudo branching candidates, or NULL */
    819 int* npriopseudocands /**< pointer to store the number of candidates with maximal priority, or NULL */
    820 )
    821{
    822 assert(branchcand != NULL);
    823
    824#ifndef NDEBUG
    825 /* check, if the current pseudo branching candidate array is correct */
    826 {
    827 SCIP_VAR* var;
    828 int npcs;
    829 int v;
    830
    831 assert(prob != NULL);
    832
    833 /* pseudo branching candidates are non-fixed binary, integer, and implicit integer variables */
    834 npcs = 0;
    835 for( v = 0; v < SCIPprobGetNBinVars(prob) + SCIPprobGetNIntVars(prob) + SCIPprobGetNImplVars(prob); ++v )
    836 {
    837 var = SCIPprobGetVars(prob)[v];
    838 assert(var != NULL);
    840 assert(SCIPvarIsIntegral(var));
    844
    846 {
    847 assert(0 <= var->pseudocandindex && var->pseudocandindex < branchcand->npseudocands);
    848 assert(branchcand->pseudocands[var->pseudocandindex] == var);
    849 npcs++;
    850 }
    851 else
    852 {
    853 assert(var->pseudocandindex == -1);
    854 }
    855 }
    856 assert(branchcand->npseudocands == npcs);
    857 for (v = 0; v < branchcand->npriopseudocands; ++v)
    858 assert( branchcand->pseudocands[v]->branchpriority == branchcand->pseudomaxpriority );
    859 }
    860#endif
    861
    862 /* assign return values */
    863 if( pseudocands != NULL )
    864 *pseudocands = branchcand->pseudocands;
    865 if( npseudocands != NULL )
    866 *npseudocands = branchcand->npseudocands;
    867 if( npriopseudocands != NULL )
    868 *npriopseudocands = (set->branch_preferbinary && branchcand->npriopseudobins > 0 ? branchcand->npriopseudobins
    869 : branchcand->npriopseudocands);
    870
    871 return SCIP_OKAY;
    872}
    873
    874/** gets number of branching candidates for pseudo solution branching (non-fixed variables) */
    876 SCIP_BRANCHCAND* branchcand /**< branching candidate storage */
    877 )
    878{
    879 assert(branchcand != NULL);
    880
    881 return branchcand->npseudocands;
    882}
    883
    884/** gets number of branching candidates with maximal branch priority for pseudo solution branching */
    886 SCIP_BRANCHCAND* branchcand /**< branching candidate storage */
    887 )
    888{
    889 assert(branchcand != NULL);
    890
    891 return branchcand->npriopseudocands;
    892}
    893
    894/** gets number of binary branching candidates with maximal branch priority for pseudo solution branching */
    896 SCIP_BRANCHCAND* branchcand /**< branching candidate storage */
    897 )
    898{
    899 assert(branchcand != NULL);
    900
    901 return branchcand->npriopseudobins;
    902}
    903
    904/** gets number of integer branching candidates with maximal branch priority for pseudo solution branching */
    906 SCIP_BRANCHCAND* branchcand /**< branching candidate storage */
    907 )
    908{
    909 assert(branchcand != NULL);
    910
    911 return branchcand->npriopseudoints;
    912}
    913
    914/** gets number of implicit integer branching candidates with maximal branch priority for pseudo solution branching */
    916 SCIP_BRANCHCAND* branchcand /**< branching candidate storage */
    917 )
    918{
    919 assert(branchcand != NULL);
    920
    921 return branchcand->npriopseudocands - branchcand->npriopseudobins - branchcand->npriopseudoints;
    922}
    923
    924/** insert pseudocand at given position, or to the first positions of the maximal priority candidates, using the
    925 * given position as free slot for the other candidates
    926 */
    927static
    929 SCIP_BRANCHCAND* branchcand, /**< branching candidate storage */
    930 SCIP_VAR* var, /**< variable to insert */
    931 int insertpos /**< free position to insert the variable */
    932 )
    933{
    934 SCIP_VARTYPE vartype;
    935 SCIP_IMPLINTTYPE impltype;
    936 int branchpriority;
    937
    938 assert(branchcand != NULL);
    939 assert(var != NULL);
    940 assert(branchcand->npriopseudocands <= insertpos && insertpos < branchcand->npseudocands);
    941 assert(branchcand->npseudocands <= branchcand->pseudocandssize);
    942
    943 vartype = SCIPvarGetType(var);
    944 impltype = SCIPvarGetImplType(var);
    945 branchpriority = SCIPvarGetBranchPriority(var);
    946
    947 SCIPdebugMessage("inserting pseudo candidate <%s> of type %d and priority %d into candidate set at position %d (maxprio: %d)\n",
    948 SCIPvarGetName(var), vartype, branchpriority, insertpos, branchcand->pseudomaxpriority);
    949
    950 /* insert the variable into pseudocands, making sure, that the highest priority candidates are at the front
    951 * and ordered binaries, integers, implicit integers
    952 */
    953 if( branchpriority > branchcand->pseudomaxpriority )
    954 {
    955 /* candidate has higher priority than the current maximum:
    956 * move it to the front and declare it to be the single best candidate
    957 */
    958 if( insertpos != 0 )
    959 {
    960 branchcand->pseudocands[insertpos] = branchcand->pseudocands[0];
    961 branchcand->pseudocands[insertpos]->pseudocandindex = insertpos;
    962 insertpos = 0;
    963 }
    964 branchcand->npriopseudocands = 1;
    965 if( impltype != SCIP_IMPLINTTYPE_NONE )
    966 {
    967 branchcand->npriopseudobins = 0;
    968 branchcand->npriopseudoints = 0;
    969 }
    970 else
    971 {
    972 branchcand->npriopseudobins = (vartype == SCIP_VARTYPE_BINARY ? 1 : 0);
    973 branchcand->npriopseudoints = (vartype == SCIP_VARTYPE_INTEGER ? 1 : 0);
    974 }
    975 branchcand->pseudomaxpriority = branchpriority;
    976 }
    977 else if( branchpriority == branchcand->pseudomaxpriority )
    978 {
    979 /* candidate has equal priority as the current maximum:
    980 * move away the first non-maximal priority candidate, move the current candidate to the correct
    981 * slot (binaries first, integers next, implicit integers last) and increase the number of maximal priority candidates
    982 */
    983 if( insertpos != branchcand->npriopseudocands )
    984 {
    985 branchcand->pseudocands[insertpos] = branchcand->pseudocands[branchcand->npriopseudocands];
    986 branchcand->pseudocands[insertpos]->pseudocandindex = insertpos;
    987 insertpos = branchcand->npriopseudocands;
    988 }
    989 branchcand->npriopseudocands++;
    990 if( vartype != SCIP_VARTYPE_CONTINUOUS && impltype == SCIP_IMPLINTTYPE_NONE )
    991 {
    992 if( insertpos != branchcand->npriopseudobins + branchcand->npriopseudoints )
    993 {
    994 branchcand->pseudocands[insertpos] =
    995 branchcand->pseudocands[branchcand->npriopseudobins + branchcand->npriopseudoints];
    996 branchcand->pseudocands[insertpos]->pseudocandindex = insertpos;
    997 insertpos = branchcand->npriopseudobins + branchcand->npriopseudoints;
    998 }
    999 branchcand->npriopseudoints++;
    1000
    1001 if( vartype == SCIP_VARTYPE_BINARY )
    1002 {
    1003 if( insertpos != branchcand->npriopseudobins )
    1004 {
    1005 branchcand->pseudocands[insertpos] = branchcand->pseudocands[branchcand->npriopseudobins];
    1006 branchcand->pseudocands[insertpos]->pseudocandindex = insertpos;
    1007 insertpos = branchcand->npriopseudobins;
    1008 }
    1009 branchcand->npriopseudobins++;
    1010 branchcand->npriopseudoints--;
    1011 }
    1012 }
    1013 }
    1014 branchcand->pseudocands[insertpos] = var;
    1015 var->pseudocandindex = insertpos;
    1016
    1017 SCIPdebugMessage(" -> inserted at position %d (npriopseudocands=%d)\n", insertpos, branchcand->npriopseudocands);
    1018
    1019 assert(0 <= branchcand->npriopseudocands && branchcand->npriopseudocands <= branchcand->npseudocands);
    1020 assert(0 <= branchcand->npriopseudobins && branchcand->npriopseudobins <= branchcand->npriopseudocands);
    1021 assert(0 <= branchcand->npriopseudoints && branchcand->npriopseudoints <= branchcand->npriopseudocands);
    1022}
    1023
    1024/** sorts the pseudo branching candidates, such that the candidates of maximal priority are at the front,
    1025 * ordered by binaries, integers, implicit integers
    1026 */
    1027static
    1029 SCIP_BRANCHCAND* branchcand /**< branching candidate storage */
    1030 )
    1031{
    1032 SCIP_VAR* var;
    1033 int i;
    1034
    1035 assert(branchcand != NULL);
    1036 assert(branchcand->npriopseudocands == 0); /* is only be called after removal of last maximal candidate */
    1037 assert(branchcand->npriopseudobins == 0);
    1038 assert(branchcand->npriopseudoints == 0);
    1039
    1040 SCIPdebugMessage("resorting pseudo candidates\n");
    1041
    1042 branchcand->pseudomaxpriority = INT_MIN;
    1043
    1044 for( i = 0; i < branchcand->npseudocands; ++i )
    1045 {
    1046 var = branchcand->pseudocands[i];
    1047 assert(var->pseudocandindex == i);
    1048
    1049 if( SCIPvarGetBranchPriority(var) >= branchcand->pseudomaxpriority )
    1050 branchcandInsertPseudoCand(branchcand, var, i);
    1051 }
    1052
    1053 assert(0 <= branchcand->npriopseudocands && branchcand->npriopseudocands <= branchcand->npseudocands);
    1054 assert(0 <= branchcand->npriopseudobins && branchcand->npriopseudobins <= branchcand->npriopseudocands);
    1055 assert(0 <= branchcand->npriopseudoints && branchcand->npriopseudoints <= branchcand->npriopseudocands);
    1056#ifndef NDEBUG
    1057 {
    1058 for (i = 0; i < branchcand->npriopseudocands; ++i)
    1059 assert( branchcand->pseudocands[i]->branchpriority == branchcand->pseudomaxpriority );
    1060 }
    1061#endif
    1062}
    1063
    1064/** removes pseudo candidate from pseudocands array
    1065 */
    1066static
    1068 SCIP_BRANCHCAND* branchcand, /**< branching candidate storage */
    1069 SCIP_VAR* var /**< variable to remove */
    1070 )
    1071{
    1072 int freepos;
    1073
    1074 assert(branchcand != NULL);
    1075 assert(var != NULL);
    1076 assert(var->pseudocandindex < branchcand->npseudocands);
    1077 assert(branchcand->pseudocands[var->pseudocandindex] == var);
    1078 assert(branchcand->pseudocands[branchcand->npseudocands-1] != NULL);
    1079
    1080 /* Note that the branching priority of the variable to be removed is not necessarily equal to pseudomaxpriority, since
    1081 * the status of the variable might have changed, leading to a change in the branching priority. Moreover, if the
    1082 * variable was part of an aggregation, even other variables might at this point have different priorities. */
    1083 SCIPdebugMessage("removing pseudo candidate <%s> of type %d and priority %d at %d from candidate set (maxprio: %d)\n",
    1085 branchcand->pseudomaxpriority);
    1086
    1087 /* delete the variable from pseudocands, making sure, that the highest priority candidates are at the front
    1088 * and ordered binaries, integers, implicit integers
    1089 */
    1090 freepos = var->pseudocandindex;
    1091 var->pseudocandindex = -1;
    1092 assert(0 <= freepos && freepos < branchcand->npseudocands);
    1093
    1094 if( freepos < branchcand->npriopseudobins )
    1095 {
    1096 /* a binary candidate of maximal priority was removed */
    1098 if( freepos != branchcand->npriopseudobins - 1 )
    1099 {
    1100 branchcand->pseudocands[freepos] = branchcand->pseudocands[branchcand->npriopseudobins - 1];
    1101 branchcand->pseudocands[freepos]->pseudocandindex = freepos;
    1102 freepos = branchcand->npriopseudobins - 1;
    1103 }
    1104 branchcand->npriopseudobins--;
    1105 branchcand->npriopseudoints++;
    1106 }
    1107
    1108 if( freepos < branchcand->npriopseudobins + branchcand->npriopseudoints )
    1109 {
    1110 /* a binary or integer candidate of maximal priority was removed */
    1111 assert(SCIPvarIsNonimpliedIntegral(var));
    1112 if( freepos != branchcand->npriopseudobins + branchcand->npriopseudoints - 1 )
    1113 {
    1114 branchcand->pseudocands[freepos] =
    1115 branchcand->pseudocands[branchcand->npriopseudobins + branchcand->npriopseudoints - 1];
    1116 branchcand->pseudocands[freepos]->pseudocandindex = freepos;
    1117 freepos = branchcand->npriopseudobins + branchcand->npriopseudoints - 1;
    1118 }
    1119 branchcand->npriopseudoints--;
    1120 }
    1121
    1122 if( freepos < branchcand->npriopseudocands )
    1123 {
    1124 /* a candidate of maximal priority was removed */
    1125 if( freepos != branchcand->npriopseudocands - 1 )
    1126 {
    1127 branchcand->pseudocands[freepos] = branchcand->pseudocands[branchcand->npriopseudocands - 1];
    1128 branchcand->pseudocands[freepos]->pseudocandindex = freepos;
    1129 freepos = branchcand->npriopseudocands - 1;
    1130 }
    1131 branchcand->npriopseudocands--;
    1132 }
    1133 if( freepos != branchcand->npseudocands - 1 )
    1134 {
    1135 branchcand->pseudocands[freepos] = branchcand->pseudocands[branchcand->npseudocands - 1];
    1136 branchcand->pseudocands[freepos]->pseudocandindex = freepos;
    1137 }
    1138 branchcand->npseudocands--;
    1139
    1140 assert(0 <= branchcand->npriopseudocands && branchcand->npriopseudocands <= branchcand->npseudocands);
    1141 assert(0 <= branchcand->npriopseudobins && branchcand->npriopseudobins <= branchcand->npriopseudocands);
    1142 assert(0 <= branchcand->npriopseudoints && branchcand->npriopseudoints <= branchcand->npriopseudocands);
    1143
    1144 /* if all maximal priority candidates were removed, resort the array s.t. the new maximal priority candidates
    1145 * are at the front
    1146 */
    1147 if( branchcand->npriopseudocands == 0 )
    1148 branchcandSortPseudoCands(branchcand);
    1149}
    1150
    1151/** removes variable from branching candidate list */
    1153 SCIP_BRANCHCAND* branchcand, /**< branching candidate storage */
    1154 SCIP_VAR* var /**< variable that changed its bounds */
    1155 )
    1156{
    1157 assert(var != NULL);
    1158
    1159 /* make sure, variable is not member of the pseudo branching candidate list */
    1160 if( var->pseudocandindex >= 0 )
    1161 {
    1162 branchcandRemovePseudoCand(branchcand, var);
    1163 }
    1164
    1165 return SCIP_OKAY;
    1166}
    1167
    1168/** updates branching candidate list for a given variable */
    1170 SCIP_BRANCHCAND* branchcand, /**< branching candidate storage */
    1171 SCIP_SET* set, /**< global SCIP settings */
    1172 SCIP_VAR* var /**< variable that changed its bounds */
    1173 )
    1174{
    1175 assert(branchcand != NULL);
    1176 assert(var != NULL);
    1177
    1179 && SCIPvarIsIntegral(var)
    1181 {
    1182 /* variable is neither continuous nor fixed and has non-empty domain: make sure it is member of the pseudo branching candidate list */
    1183 if( var->pseudocandindex == -1 )
    1184 {
    1185 SCIP_CALL( ensurePseudocandsSize(branchcand, set, branchcand->npseudocands+1) );
    1186
    1187 branchcand->npseudocands++;
    1188 branchcandInsertPseudoCand(branchcand, var, branchcand->npseudocands-1);
    1189 }
    1190 }
    1191 else
    1192 {
    1198 || !SCIPvarIsIntegral(var)
    1200
    1201 /* variable is continuous or fixed or has empty domain: make sure it is not member of the pseudo branching candidate list */
    1202 SCIP_CALL( SCIPbranchcandRemoveVar(branchcand, var) );
    1203 }
    1204
    1205 return SCIP_OKAY;
    1206}
    1207
    1208/** updates branching priority of the given variable and update the pseudo candidate array if needed */
    1210 SCIP_BRANCHCAND* branchcand, /**< branching candidate storage */
    1211 SCIP_SET* set, /**< global SCIP settings */
    1212 SCIP_VAR* var, /**< variable that changed its bounds */
    1213 int branchpriority /**< branch priority of the variable */
    1214 )
    1215{
    1216 int oldbranchpriority;
    1217 int pseudomaxpriority;
    1218
    1219 assert(branchcand != NULL);
    1220
    1221 oldbranchpriority = SCIPvarGetBranchPriority(var);
    1222
    1223 if( oldbranchpriority == branchpriority )
    1224 return SCIP_OKAY;
    1225
    1226 pseudomaxpriority = branchcand->pseudomaxpriority;
    1227
    1228 /* if the variable currently belongs to the priority set or the new branching priority is larger than the current one,
    1229 * remove it from the pseudo branch candidate array */
    1230 if( oldbranchpriority == pseudomaxpriority || branchpriority > pseudomaxpriority )
    1231 {
    1232 SCIP_CALL( SCIPbranchcandRemoveVar(branchcand, var) );
    1233 assert(var->pseudocandindex == -1);
    1234 }
    1235
    1236 /* change the branching priority of the variable */
    1237 SCIP_CALL( SCIPvarChgBranchPriority(var, branchpriority) );
    1238
    1239 /* if the variable is not part of the pseudo branching candidate array, check if it is a pseudo branching candidate
    1240 * and add it if so */
    1241 SCIP_CALL( SCIPbranchcandUpdateVar(branchcand, set, var) );
    1242
    1243 return SCIP_OKAY;
    1244}
    1245
    1246
    1247
    1248/*
    1249 * branching rule methods
    1250 */
    1251
    1252/** compares two branching rules w. r. to their priority */
    1253SCIP_DECL_SORTPTRCOMP(SCIPbranchruleComp)
    1254{ /*lint --e{715}*/
    1255 return ((SCIP_BRANCHRULE*)elem2)->priority - ((SCIP_BRANCHRULE*)elem1)->priority;
    1256}
    1257
    1258/** comparison method for sorting branching rules w.r.t. to their name */
    1259SCIP_DECL_SORTPTRCOMP(SCIPbranchruleCompName)
    1260{
    1262}
    1263
    1264/** method to call, when the priority of a branching rule was changed */
    1265static
    1266SCIP_DECL_PARAMCHGD(paramChgdBranchrulePriority)
    1267{ /*lint --e{715}*/
    1268 SCIP_PARAMDATA* paramdata;
    1269
    1270 paramdata = SCIPparamGetData(param);
    1271 assert(paramdata != NULL);
    1272
    1273 /* use SCIPsetBranchrulePriority() to mark the branchrules unsorted */
    1274 SCIP_CALL( SCIPsetBranchrulePriority(scip, (SCIP_BRANCHRULE*)paramdata, SCIPparamGetInt(param)) ); /*lint !e740*/
    1275
    1276 return SCIP_OKAY;
    1277}
    1278
    1279/** copies the given branchrule to a new scip */
    1281 SCIP_BRANCHRULE* branchrule, /**< branchrule */
    1282 SCIP_SET* set /**< SCIP_SET of SCIP to copy to */
    1283 )
    1284{
    1285 assert(branchrule != NULL);
    1286 assert(set != NULL);
    1287 assert(set->scip != NULL);
    1288
    1289 if( branchrule->branchcopy != NULL )
    1290 {
    1291 SCIPsetDebugMsg(set, "including branching rule %s in subscip %p\n", SCIPbranchruleGetName(branchrule), (void*)set->scip);
    1292 SCIP_CALL( branchrule->branchcopy(set->scip, branchrule) );
    1293 }
    1294
    1295 return SCIP_OKAY;
    1296}
    1297
    1298/** internal method for creating a branching rule */
    1299static
    1301 SCIP_BRANCHRULE** branchrule, /**< pointer to store branching rule */
    1302 SCIP_SET* set, /**< global SCIP settings */
    1303 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
    1304 BMS_BLKMEM* blkmem, /**< block memory for parameter settings */
    1305 const char* name, /**< name of branching rule */
    1306 const char* desc, /**< description of branching rule */
    1307 int priority, /**< priority of the branching rule */
    1308 int maxdepth, /**< maximal depth level, up to which this branching rule should be used (or -1) */
    1309 SCIP_Real maxbounddist, /**< maximal relative distance from current node's dual bound to primal bound
    1310 * compared to best node's dual bound for applying branching rule
    1311 * (0.0: only on current best node, 1.0: on all nodes) */
    1312 SCIP_DECL_BRANCHCOPY ((*branchcopy)), /**< copy method of branching rule */
    1313 SCIP_DECL_BRANCHFREE ((*branchfree)), /**< destructor of branching rule */
    1314 SCIP_DECL_BRANCHINIT ((*branchinit)), /**< initialize branching rule */
    1315 SCIP_DECL_BRANCHEXIT ((*branchexit)), /**< deinitialize branching rule */
    1316 SCIP_DECL_BRANCHINITSOL((*branchinitsol)),/**< solving process initialization method of branching rule */
    1317 SCIP_DECL_BRANCHEXITSOL((*branchexitsol)),/**< solving process deinitialization method of branching rule */
    1318 SCIP_DECL_BRANCHEXECLP((*branchexeclp)), /**< branching execution method for fractional LP solutions */
    1319 SCIP_DECL_BRANCHEXECEXT((*branchexecext)),/**< branching execution method for external solutions */
    1320 SCIP_DECL_BRANCHEXECPS((*branchexecps)), /**< branching execution method for not completely fixed pseudo solutions */
    1321 SCIP_BRANCHRULEDATA* branchruledata /**< branching rule data */
    1322 )
    1323{
    1325 char paramdesc[SCIP_MAXSTRLEN];
    1326
    1327 assert(branchrule != NULL);
    1328 assert(name != NULL);
    1329 assert(desc != NULL);
    1330
    1331 SCIP_ALLOC( BMSallocMemory(branchrule) );
    1332 BMSclearMemory(*branchrule);
    1333
    1334 SCIP_ALLOC( BMSduplicateMemoryArray(&(*branchrule)->name, name, strlen(name)+1) );
    1335 SCIP_ALLOC( BMSduplicateMemoryArray(&(*branchrule)->desc, desc, strlen(desc)+1) );
    1336 (*branchrule)->priority = priority;
    1337 (*branchrule)->maxdepth = maxdepth;
    1338 (*branchrule)->maxbounddist = maxbounddist;
    1339 (*branchrule)->branchcopy = branchcopy;
    1340 (*branchrule)->branchfree = branchfree;
    1341 (*branchrule)->branchinit = branchinit;
    1342 (*branchrule)->branchexit = branchexit;
    1343 (*branchrule)->branchinitsol = branchinitsol;
    1344 (*branchrule)->branchexitsol = branchexitsol;
    1345 (*branchrule)->branchexeclp = branchexeclp;
    1346 (*branchrule)->branchexecext = branchexecext;
    1347 (*branchrule)->branchexecps = branchexecps;
    1348 (*branchrule)->branchruledata = branchruledata;
    1349 SCIP_CALL( SCIPclockCreate(&(*branchrule)->setuptime, SCIP_CLOCKTYPE_DEFAULT) );
    1350 SCIP_CALL( SCIPclockCreate(&(*branchrule)->branchclock, SCIP_CLOCKTYPE_DEFAULT) );
    1351 (*branchrule)->nlpcalls = 0;
    1352 (*branchrule)->nexterncalls = 0;
    1353 (*branchrule)->npseudocalls = 0;
    1354 (*branchrule)->ncutoffs = 0;
    1355 (*branchrule)->ncutsfound = 0;
    1356 (*branchrule)->nconssfound = 0;
    1357 (*branchrule)->ndomredsfound = 0;
    1358 (*branchrule)->nchildren = 0;
    1359 (*branchrule)->initialized = FALSE;
    1360 (*branchrule)->exact = FALSE;
    1361
    1362 /* add parameters */
    1363 (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "branching/%s/priority", name);
    1364 (void) SCIPsnprintf(paramdesc, SCIP_MAXSTRLEN, "priority of branching rule <%s>", name);
    1365 SCIP_CALL( SCIPsetAddIntParam(set, messagehdlr, blkmem, paramname, paramdesc,
    1366 &(*branchrule)->priority, FALSE, priority, INT_MIN/4, INT_MAX/4,
    1367 paramChgdBranchrulePriority, (SCIP_PARAMDATA*)(*branchrule)) ); /*lint !e740*/
    1368 (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "branching/%s/maxdepth", name);
    1369 (void) SCIPsnprintf(paramdesc, SCIP_MAXSTRLEN, "maximal depth level, up to which branching rule <%s> should be used (-1 for no limit)", name);
    1370 SCIP_CALL( SCIPsetAddIntParam(set, messagehdlr, blkmem, paramname, paramdesc,
    1371 &(*branchrule)->maxdepth, FALSE, maxdepth, -1, SCIP_MAXTREEDEPTH,
    1372 NULL, NULL) ); /*lint !e740*/
    1373 (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "branching/%s/maxbounddist", name);
    1374 (void) SCIPsnprintf(paramdesc, SCIP_MAXSTRLEN, "maximal relative distance from current node's dual bound to primal bound compared to best node's dual bound for applying branching rule (0.0: only on current best node, 1.0: on all nodes)");
    1375 SCIP_CALL( SCIPsetAddRealParam(set, messagehdlr, blkmem, paramname, paramdesc,
    1376 &(*branchrule)->maxbounddist, FALSE, maxbounddist, 0.0, 1.0,
    1377 NULL, NULL) ); /*lint !e740*/
    1378
    1379 return SCIP_OKAY;
    1380}
    1381
    1382/** creates a branching rule */
    1384 SCIP_BRANCHRULE** branchrule, /**< pointer to store branching rule */
    1385 SCIP_SET* set, /**< global SCIP settings */
    1386 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
    1387 BMS_BLKMEM* blkmem, /**< block memory for parameter settings */
    1388 const char* name, /**< name of branching rule */
    1389 const char* desc, /**< description of branching rule */
    1390 int priority, /**< priority of the branching rule */
    1391 int maxdepth, /**< maximal depth level, up to which this branching rule should be used (or -1) */
    1392 SCIP_Real maxbounddist, /**< maximal relative distance from current node's dual bound to primal bound
    1393 * compared to best node's dual bound for applying branching rule
    1394 * (0.0: only on current best node, 1.0: on all nodes) */
    1395 SCIP_DECL_BRANCHCOPY ((*branchcopy)), /**< copy method of branching rule */
    1396 SCIP_DECL_BRANCHFREE ((*branchfree)), /**< destructor of branching rule */
    1397 SCIP_DECL_BRANCHINIT ((*branchinit)), /**< initialize branching rule */
    1398 SCIP_DECL_BRANCHEXIT ((*branchexit)), /**< deinitialize branching rule */
    1399 SCIP_DECL_BRANCHINITSOL((*branchinitsol)),/**< solving process initialization method of branching rule */
    1400 SCIP_DECL_BRANCHEXITSOL((*branchexitsol)),/**< solving process deinitialization method of branching rule */
    1401 SCIP_DECL_BRANCHEXECLP((*branchexeclp)), /**< branching execution method for fractional LP solutions */
    1402 SCIP_DECL_BRANCHEXECEXT((*branchexecext)),/**< branching execution method for external solutions */
    1403 SCIP_DECL_BRANCHEXECPS((*branchexecps)), /**< branching execution method for not completely fixed pseudo solutions */
    1404 SCIP_BRANCHRULEDATA* branchruledata /**< branching rule data */
    1405 )
    1406{
    1407 assert(branchrule != NULL);
    1408 assert(name != NULL);
    1409 assert(desc != NULL);
    1410
    1411 SCIP_CALL_FINALLY( doBranchruleCreate(branchrule, set, messagehdlr, blkmem, name, desc, priority, maxdepth,
    1412 maxbounddist, branchcopy, branchfree, branchinit, branchexit, branchinitsol, branchexitsol, branchexeclp,
    1413 branchexecext, branchexecps, branchruledata), (void) SCIPbranchruleFree(branchrule, set) );
    1414
    1415 return SCIP_OKAY;
    1416}
    1417
    1418/** frees memory of branching rule */
    1420 SCIP_BRANCHRULE** branchrule, /**< pointer to branching rule data structure */
    1421 SCIP_SET* set /**< global SCIP settings */
    1422 )
    1423{
    1424 assert(branchrule != NULL);
    1425 if( *branchrule == NULL )
    1426 return SCIP_OKAY;
    1427 assert(!(*branchrule)->initialized);
    1428 assert(set != NULL);
    1429
    1430 /* call destructor of branching rule */
    1431 if( (*branchrule)->branchfree != NULL )
    1432 {
    1433 SCIP_CALL( (*branchrule)->branchfree(set->scip, *branchrule) );
    1434 }
    1435
    1436 SCIPclockFree(&(*branchrule)->branchclock);
    1437 SCIPclockFree(&(*branchrule)->setuptime);
    1438 BMSfreeMemoryArrayNull(&(*branchrule)->name);
    1439 BMSfreeMemoryArrayNull(&(*branchrule)->desc);
    1440 BMSfreeMemory(branchrule);
    1441
    1442 return SCIP_OKAY;
    1443}
    1444
    1445/** initializes branching rule */
    1447 SCIP_BRANCHRULE* branchrule, /**< branching rule */
    1448 SCIP_SET* set /**< global SCIP settings */
    1449 )
    1450{
    1451 assert(branchrule != NULL);
    1452 assert(set != NULL);
    1453
    1454 if( branchrule->initialized )
    1455 {
    1456 SCIPerrorMessage("branching rule <%s> already initialized\n", branchrule->name);
    1457 return SCIP_INVALIDCALL;
    1458 }
    1459
    1460 if( set->misc_resetstat )
    1461 {
    1462 SCIPclockReset(branchrule->setuptime);
    1463 SCIPclockReset(branchrule->branchclock);
    1464 branchrule->nlpcalls = 0;
    1465 branchrule->nexterncalls = 0;
    1466 branchrule->npseudocalls = 0;
    1467 branchrule->ncutoffs = 0;
    1468 branchrule->ncutsfound = 0;
    1469 branchrule->nconssfound = 0;
    1470 branchrule->ndomredsfound = 0;
    1471 branchrule->nchildren = 0;
    1472 }
    1473
    1474 if( branchrule->branchinit != NULL )
    1475 {
    1476 /* start timing */
    1477 SCIPclockStart(branchrule->setuptime, set);
    1478
    1479 SCIP_CALL( branchrule->branchinit(set->scip, branchrule) );
    1480
    1481 /* stop timing */
    1482 SCIPclockStop(branchrule->setuptime, set);
    1483 }
    1484 branchrule->initialized = TRUE;
    1485
    1486 return SCIP_OKAY;
    1487}
    1488
    1489/** deinitializes branching rule */
    1491 SCIP_BRANCHRULE* branchrule, /**< branching rule */
    1492 SCIP_SET* set /**< global SCIP settings */
    1493 )
    1494{
    1495 assert(branchrule != NULL);
    1496 assert(set != NULL);
    1497
    1498 if( !branchrule->initialized )
    1499 {
    1500 SCIPerrorMessage("branching rule <%s> not initialized\n", branchrule->name);
    1501 return SCIP_INVALIDCALL;
    1502 }
    1503
    1504 if( branchrule->branchexit != NULL )
    1505 {
    1506 /* start timing */
    1507 SCIPclockStart(branchrule->setuptime, set);
    1508
    1509 SCIP_CALL( branchrule->branchexit(set->scip, branchrule) );
    1510
    1511 /* stop timing */
    1512 SCIPclockStop(branchrule->setuptime, set);
    1513 }
    1514 branchrule->initialized = FALSE;
    1515
    1516 return SCIP_OKAY;
    1517}
    1518
    1519/** informs branching rule that the branch and bound process is being started */
    1521 SCIP_BRANCHRULE* branchrule, /**< branching rule */
    1522 SCIP_SET* set /**< global SCIP settings */
    1523 )
    1524{
    1525 assert(branchrule != NULL);
    1526 assert(set != NULL);
    1527
    1528 /* call solving process initialization method of branching rule */
    1529 if( branchrule->branchinitsol != NULL )
    1530 {
    1531 /* start timing */
    1532 SCIPclockStart(branchrule->setuptime, set);
    1533
    1534 SCIP_CALL( branchrule->branchinitsol(set->scip, branchrule) );
    1535
    1536 /* stop timing */
    1537 SCIPclockStop(branchrule->setuptime, set);
    1538 }
    1539
    1540 return SCIP_OKAY;
    1541}
    1542
    1543/** informs branching rule that the branch and bound process data is being freed */
    1545 SCIP_BRANCHRULE* branchrule, /**< branching rule */
    1546 SCIP_SET* set /**< global SCIP settings */
    1547 )
    1548{
    1549 assert(branchrule != NULL);
    1550 assert(set != NULL);
    1551
    1552 /* call solving process deinitialization method of branching rule */
    1553 if( branchrule->branchexitsol != NULL )
    1554 {
    1555 /* start timing */
    1556 SCIPclockStart(branchrule->setuptime, set);
    1557
    1558 SCIP_CALL( branchrule->branchexitsol(set->scip, branchrule) );
    1559
    1560 /* stop timing */
    1561 SCIPclockStop(branchrule->setuptime, set);
    1562 }
    1563
    1564 return SCIP_OKAY;
    1565}
    1566
    1567/** executes branching rule for fractional LP solution */
    1569 SCIP_BRANCHRULE* branchrule, /**< branching rule */
    1570 SCIP_SET* set, /**< global SCIP settings */
    1571 SCIP_STAT* stat, /**< problem statistics */
    1572 SCIP_TREE* tree, /**< branch and bound tree */
    1573 SCIP_SEPASTORE* sepastore, /**< separation storage */
    1574 SCIP_Real cutoffbound, /**< global upper cutoff bound */
    1575 SCIP_Bool allowaddcons, /**< should adding constraints be allowed to avoid a branching? */
    1576 SCIP_RESULT* result /**< pointer to store the result of the callback method */
    1577 )
    1578{
    1579 assert(branchrule != NULL);
    1580 assert(set != NULL);
    1581 assert(tree != NULL);
    1582 assert(tree->focusnode != NULL);
    1583 assert(tree->nchildren == 0);
    1584 assert(result != NULL);
    1585
    1586 *result = SCIP_DIDNOTRUN;
    1587 if( branchrule->branchexeclp != NULL
    1588 && (branchrule->maxdepth == -1 || branchrule->maxdepth >= SCIPtreeGetCurrentDepth(tree))
    1589 && (!set->exact_enable || branchrule->exact) )
    1590 {
    1591 SCIP_Real loclowerbound;
    1592 SCIP_Real glblowerbound;
    1593 SCIP_Bool runbranchrule;
    1594
    1595 loclowerbound = SCIPnodeGetLowerbound(tree->focusnode);
    1596 glblowerbound = SCIPtreeGetLowerbound(tree, set);
    1597
    1598 /* we distinguish between finite and infinite global lower bounds to avoid comparisons between different values > SCIPinfinity() */
    1599 if( SCIPsetIsInfinity(set, -glblowerbound) )
    1600 runbranchrule = SCIPsetIsInfinity(set, -loclowerbound) || SCIPsetIsGE(set, branchrule->maxbounddist, 1.0);
    1601 else
    1602 {
    1603 assert(!SCIPsetIsInfinity(set, -loclowerbound));
    1604 runbranchrule = SCIPsetIsLE(set, loclowerbound - glblowerbound, branchrule->maxbounddist * (cutoffbound - glblowerbound));
    1605 }
    1606
    1607 if( runbranchrule )
    1608 {
    1609 SCIP_Longint oldndomchgs;
    1610 SCIP_Longint oldnprobdomchgs;
    1611 SCIP_Longint oldnactiveconss;
    1612 int oldncuts;
    1613
    1614 SCIPsetDebugMsg(set, "executing LP branching rule <%s>\n", branchrule->name);
    1615
    1616 oldndomchgs = stat->nboundchgs + stat->nholechgs;
    1617 oldnprobdomchgs = stat->nprobboundchgs + stat->nprobholechgs;
    1618 oldncuts = SCIPsepastoreGetNCuts(sepastore);
    1619 oldnactiveconss = stat->nactiveconssadded;
    1620
    1621 /* start timing */
    1622 SCIPclockStart(branchrule->branchclock, set);
    1623
    1624 /* call external method */
    1625 SCIP_CALL( branchrule->branchexeclp(set->scip, branchrule, allowaddcons, result) );
    1626
    1627 /* stop timing */
    1628 SCIPclockStop(branchrule->branchclock, set);
    1629
    1630 /* evaluate result */
    1631 if( *result != SCIP_CUTOFF
    1632 && *result != SCIP_CONSADDED
    1633 && *result != SCIP_REDUCEDDOM
    1634 && *result != SCIP_SEPARATED
    1635 && *result != SCIP_BRANCHED
    1636 && *result != SCIP_DIDNOTFIND
    1637 && *result != SCIP_DIDNOTRUN )
    1638 {
    1639 SCIPerrorMessage("branching rule <%s> returned invalid result code <%d> from LP solution branching\n",
    1640 branchrule->name, *result);
    1641 return SCIP_INVALIDRESULT;
    1642 }
    1643 if( *result == SCIP_CONSADDED && !allowaddcons )
    1644 {
    1645 SCIPerrorMessage("branching rule <%s> added a constraint in LP solution branching without permission\n",
    1646 branchrule->name);
    1647 return SCIP_INVALIDRESULT;
    1648 }
    1649
    1650 /* update statistics */
    1651 if( *result != SCIP_DIDNOTRUN )
    1652 branchrule->nlpcalls++;
    1653 if( *result == SCIP_CUTOFF )
    1654 branchrule->ncutoffs++;
    1655 if( *result != SCIP_BRANCHED )
    1656 {
    1657 assert(tree->nchildren == 0);
    1658
    1659 /* update domain reductions; therefore remove the domain
    1660 * reduction counts which were generated in probing mode */
    1661 branchrule->ndomredsfound += stat->nboundchgs + stat->nholechgs - oldndomchgs;
    1662 branchrule->ndomredsfound -= (stat->nprobboundchgs + stat->nprobholechgs - oldnprobdomchgs);
    1663
    1664 branchrule->ncutsfound += SCIPsepastoreGetNCuts(sepastore) - oldncuts; /*lint !e776*/
    1665 branchrule->nconssfound += stat->nactiveconssadded - oldnactiveconss; /*lint !e776*/
    1666 }
    1667 else
    1668 branchrule->nchildren += tree->nchildren;
    1669 }
    1670 }
    1671
    1672 return SCIP_OKAY;
    1673}
    1674
    1675/** executes branching rule for external branching candidates */
    1677 SCIP_BRANCHRULE* branchrule, /**< branching rule */
    1678 SCIP_SET* set, /**< global SCIP settings */
    1679 SCIP_STAT* stat, /**< problem statistics */
    1680 SCIP_TREE* tree, /**< branch and bound tree */
    1681 SCIP_SEPASTORE* sepastore, /**< separation storage */
    1682 SCIP_Real cutoffbound, /**< global upper cutoff bound */
    1683 SCIP_Bool allowaddcons, /**< should adding constraints be allowed to avoid a branching? */
    1684 SCIP_RESULT* result /**< pointer to store the result of the callback method */
    1685 )
    1686{
    1687 assert(branchrule != NULL);
    1688 assert(set != NULL);
    1689 assert(tree != NULL);
    1690 assert(tree->focusnode != NULL);
    1691 assert(tree->nchildren == 0);
    1692 assert(result != NULL);
    1693
    1694 *result = SCIP_DIDNOTRUN;
    1695 if( branchrule->branchexecext != NULL
    1696 && (branchrule->maxdepth == -1 || branchrule->maxdepth >= SCIPtreeGetCurrentDepth(tree))
    1697 && (!set->exact_enable || branchrule->exact) )
    1698 {
    1699 SCIP_Real loclowerbound;
    1700 SCIP_Real glblowerbound;
    1701 SCIP_Bool runbranchrule;
    1702
    1703 loclowerbound = SCIPnodeGetLowerbound(tree->focusnode);
    1704 glblowerbound = SCIPtreeGetLowerbound(tree, set);
    1705 assert(!SCIPsetIsInfinity(set, loclowerbound));
    1706
    1707 /* we distinguish between finite and infinite global lower bounds to avoid comparisons between different values > SCIPinfinity() */
    1708 if( SCIPsetIsInfinity(set, -glblowerbound) )
    1709 runbranchrule = SCIPsetIsInfinity(set, -loclowerbound) || SCIPsetIsGE(set, branchrule->maxbounddist, 1.0);
    1710 else
    1711 {
    1712 assert(!SCIPsetIsInfinity(set, -loclowerbound));
    1713 runbranchrule = SCIPsetIsLE(set, loclowerbound - glblowerbound, branchrule->maxbounddist * (cutoffbound - glblowerbound));
    1714 }
    1715
    1716 if( runbranchrule )
    1717 {
    1718 SCIP_Longint oldndomchgs;
    1719 SCIP_Longint oldnprobdomchgs;
    1720 int oldncuts;
    1721 int oldnactiveconss;
    1722
    1723 SCIPsetDebugMsg(set, "executing external solution branching rule <%s>\n", branchrule->name);
    1724
    1725 oldndomchgs = stat->nboundchgs + stat->nholechgs;
    1726 oldnprobdomchgs = stat->nprobboundchgs + stat->nprobholechgs;
    1727 oldncuts = SCIPsepastoreGetNCuts(sepastore);
    1728 oldnactiveconss = stat->nactiveconss;
    1729
    1730 /* start timing */
    1731 SCIPclockStart(branchrule->branchclock, set);
    1732
    1733 /* call external method */
    1734 SCIP_CALL( branchrule->branchexecext(set->scip, branchrule, allowaddcons, result) );
    1735
    1736 /* stop timing */
    1737 SCIPclockStop(branchrule->branchclock, set);
    1738
    1739 /* evaluate result */
    1740 if( *result != SCIP_CUTOFF
    1741 && *result != SCIP_CONSADDED
    1742 && *result != SCIP_REDUCEDDOM
    1743 && *result != SCIP_SEPARATED
    1744 && *result != SCIP_BRANCHED
    1745 && *result != SCIP_DIDNOTFIND
    1746 && *result != SCIP_DIDNOTRUN )
    1747 {
    1748 SCIPerrorMessage("branching rule <%s> returned invalid result code <%d> from external solution branching\n",
    1749 branchrule->name, *result);
    1750 return SCIP_INVALIDRESULT;
    1751 }
    1752 if( *result == SCIP_CONSADDED && !allowaddcons )
    1753 {
    1754 SCIPerrorMessage("branching rule <%s> added a constraint in external solution branching without permission\n",
    1755 branchrule->name);
    1756 return SCIP_INVALIDRESULT;
    1757 }
    1758
    1759 /* update statistics */
    1760 if( *result != SCIP_DIDNOTRUN )
    1761 branchrule->nexterncalls++;
    1762 if( *result == SCIP_CUTOFF )
    1763 branchrule->ncutoffs++;
    1764 if( *result != SCIP_BRANCHED )
    1765 {
    1766 assert(tree->nchildren == 0);
    1767
    1768 /* update domain reductions; therefore remove the domain
    1769 * reduction counts which were generated in probing mode */
    1770 branchrule->ndomredsfound += stat->nboundchgs + stat->nholechgs - oldndomchgs;
    1771 branchrule->ndomredsfound -= (stat->nprobboundchgs + stat->nprobholechgs - oldnprobdomchgs);
    1772
    1773 branchrule->ncutsfound += SCIPsepastoreGetNCuts(sepastore) - oldncuts; /*lint !e776*/
    1774 branchrule->nconssfound += stat->nactiveconss - oldnactiveconss; /*lint !e776*/
    1775 }
    1776 else
    1777 branchrule->nchildren += tree->nchildren;
    1778 }
    1779 }
    1780 return SCIP_OKAY;
    1781}
    1782
    1783/** executes branching rule for not completely fixed pseudo solution */
    1785 SCIP_BRANCHRULE* branchrule, /**< branching rule */
    1786 SCIP_SET* set, /**< global SCIP settings */
    1787 SCIP_STAT* stat, /**< problem statistics */
    1788 SCIP_TREE* tree, /**< branch and bound tree */
    1789 SCIP_Real cutoffbound, /**< global upper cutoff bound */
    1790 SCIP_Bool allowaddcons, /**< should adding constraints be allowed to avoid a branching? */
    1791 SCIP_RESULT* result /**< pointer to store the result of the callback method */
    1792 )
    1793{
    1794 assert(branchrule != NULL);
    1795 assert(set != NULL);
    1796 assert(tree != NULL);
    1797 assert(tree->nchildren == 0);
    1798 assert(result != NULL);
    1799
    1800 *result = SCIP_DIDNOTRUN;
    1801 if( branchrule->branchexecps != NULL
    1802 && (branchrule->maxdepth == -1 || branchrule->maxdepth >= SCIPtreeGetCurrentDepth(tree))
    1803 && (!set->exact_enable || branchrule->exact) )
    1804 {
    1805 SCIP_Real loclowerbound;
    1806 SCIP_Real glblowerbound;
    1807 SCIP_Bool runbranchrule;
    1808
    1809 loclowerbound = SCIPnodeGetLowerbound(tree->focusnode);
    1810 glblowerbound = SCIPtreeGetLowerbound(tree, set);
    1811
    1812 /* we distinguish between finite and infinite global lower bounds to avoid comparisons between different values > SCIPinfinity() */
    1813 if( SCIPsetIsInfinity(set, -glblowerbound) )
    1814 runbranchrule = SCIPsetIsInfinity(set, -loclowerbound) || SCIPsetIsGE(set, branchrule->maxbounddist, 1.0);
    1815 else
    1816 {
    1817 assert(!SCIPsetIsInfinity(set, -loclowerbound));
    1818 runbranchrule = SCIPsetIsLE(set, loclowerbound - glblowerbound, branchrule->maxbounddist * (cutoffbound - glblowerbound));
    1819 }
    1820
    1821 if( runbranchrule )
    1822 {
    1823 SCIP_Longint oldndomchgs;
    1824 SCIP_Longint oldnprobdomchgs;
    1825 SCIP_Longint oldnactiveconss;
    1826
    1827 SCIPsetDebugMsg(set, "executing pseudo branching rule <%s>\n", branchrule->name);
    1828
    1829 oldndomchgs = stat->nboundchgs + stat->nholechgs;
    1830 oldnprobdomchgs = stat->nprobboundchgs + stat->nprobholechgs;
    1831 oldnactiveconss = stat->nactiveconss;
    1832
    1833 /* start timing */
    1834 SCIPclockStart(branchrule->branchclock, set);
    1835
    1836 /* call external method */
    1837 SCIP_CALL( branchrule->branchexecps(set->scip, branchrule, allowaddcons, result) );
    1838
    1839 /* stop timing */
    1840 SCIPclockStop(branchrule->branchclock, set);
    1841
    1842 /* evaluate result */
    1843 if( *result != SCIP_CUTOFF
    1844 && *result != SCIP_CONSADDED
    1845 && *result != SCIP_REDUCEDDOM
    1846 && *result != SCIP_BRANCHED
    1847 && *result != SCIP_DIDNOTFIND
    1848 && *result != SCIP_DIDNOTRUN )
    1849 {
    1850 SCIPerrorMessage("branching rule <%s> returned invalid result code <%d> from pseudo solution branching\n",
    1851 branchrule->name, *result);
    1852 return SCIP_INVALIDRESULT;
    1853 }
    1854 if( *result == SCIP_CONSADDED && !allowaddcons )
    1855 {
    1856 SCIPerrorMessage("branching rule <%s> added a constraint in pseudo solution branching without permission\n",
    1857 branchrule->name);
    1858 return SCIP_INVALIDRESULT;
    1859 }
    1860
    1861 /* update statistics */
    1862 if( *result != SCIP_DIDNOTRUN )
    1863 branchrule->npseudocalls++;
    1864 if( *result == SCIP_CUTOFF )
    1865 branchrule->ncutoffs++;
    1866 if( *result != SCIP_BRANCHED )
    1867 {
    1868 assert(tree->nchildren == 0);
    1869
    1870 /* update domain reductions; therefore remove the domain
    1871 * reduction counts which were generated in probing mode */
    1872 branchrule->ndomredsfound += stat->nboundchgs + stat->nholechgs - oldndomchgs;
    1873 branchrule->ndomredsfound -= (stat->nprobboundchgs + stat->nprobholechgs - oldnprobdomchgs);
    1874
    1875 branchrule->nconssfound += stat->nactiveconss - oldnactiveconss;
    1876 }
    1877 else
    1878 branchrule->nchildren += tree->nchildren;
    1879 }
    1880 }
    1881
    1882 return SCIP_OKAY;
    1883}
    1884
    1885/** gets user data of branching rule */
    1887 SCIP_BRANCHRULE* branchrule /**< branching rule */
    1888 )
    1889{
    1890 assert(branchrule != NULL);
    1891
    1892 return branchrule->branchruledata;
    1893}
    1894
    1895/** sets user data of branching rule; user has to free old data in advance! */
    1897 SCIP_BRANCHRULE* branchrule, /**< branching rule */
    1898 SCIP_BRANCHRULEDATA* branchruledata /**< new branching rule user data */
    1899 )
    1900{
    1901 assert(branchrule != NULL);
    1902
    1903 branchrule->branchruledata = branchruledata;
    1904}
    1905
    1906/** marks this branching rule as safe to use in exact solving mode */
    1908 SCIP_BRANCHRULE* branchrule /**< branching rule */
    1909 )
    1910{
    1911 assert(branchrule != NULL);
    1912
    1913 branchrule->exact = TRUE;
    1914}
    1915
    1916/** sets copy method of branching rule */
    1918 SCIP_BRANCHRULE* branchrule, /**< branching rule */
    1919 SCIP_DECL_BRANCHCOPY ((*branchcopy)) /**< copy method of branching rule or NULL if you don't want to copy your plugin into sub-SCIPs */
    1920 )
    1921{
    1922 assert(branchrule != NULL);
    1923
    1924 branchrule->branchcopy = branchcopy;
    1925}
    1926
    1927/** sets destructor method of branching rule */
    1929 SCIP_BRANCHRULE* branchrule, /**< branching rule */
    1930 SCIP_DECL_BRANCHFREE ((*branchfree)) /**< destructor of branching rule */
    1931 )
    1932{
    1933 assert(branchrule != NULL);
    1934
    1935 branchrule->branchfree = branchfree;
    1936}
    1937
    1938/** sets initialization method of branching rule */
    1940 SCIP_BRANCHRULE* branchrule, /**< branching rule */
    1941 SCIP_DECL_BRANCHINIT ((*branchinit)) /**< initialize branching rule */
    1942 )
    1943{
    1944 assert(branchrule != NULL);
    1945
    1946 branchrule->branchinit = branchinit;
    1947}
    1948
    1949/** sets deinitialization method of branching rule */
    1951 SCIP_BRANCHRULE* branchrule, /**< branching rule */
    1952 SCIP_DECL_BRANCHEXIT ((*branchexit)) /**< deinitialize branching rule */
    1953 )
    1954{
    1955 assert(branchrule != NULL);
    1956
    1957 branchrule->branchexit = branchexit;
    1958}
    1959
    1960/** sets solving process initialization method of branching rule */
    1962 SCIP_BRANCHRULE* branchrule, /**< branching rule */
    1963 SCIP_DECL_BRANCHINITSOL((*branchinitsol)) /**< solving process initialization method of branching rule */
    1964 )
    1965{
    1966 assert(branchrule != NULL);
    1967
    1968 branchrule->branchinitsol = branchinitsol;
    1969}
    1970
    1971/** sets solving process deinitialization method of branching rule */
    1973 SCIP_BRANCHRULE* branchrule, /**< branching rule */
    1974 SCIP_DECL_BRANCHEXITSOL((*branchexitsol)) /**< solving process deinitialization method of branching rule */
    1975 )
    1976{
    1977 assert(branchrule != NULL);
    1978
    1979 branchrule->branchexitsol = branchexitsol;
    1980}
    1981
    1982
    1983
    1984/** sets branching execution method for fractional LP solutions */
    1986 SCIP_BRANCHRULE* branchrule, /**< branching rule */
    1987 SCIP_DECL_BRANCHEXECLP((*branchexeclp)) /**< branching execution method for fractional LP solutions */
    1988 )
    1989{
    1990 assert(branchrule != NULL);
    1991
    1992 branchrule->branchexeclp = branchexeclp;
    1993}
    1994
    1995/** sets branching execution method for external candidates */
    1997 SCIP_BRANCHRULE* branchrule, /**< branching rule */
    1998 SCIP_DECL_BRANCHEXECEXT((*branchexecext)) /**< branching execution method for external candidates */
    1999 )
    2000{
    2001 assert(branchrule != NULL);
    2002
    2003 branchrule->branchexecext = branchexecext;
    2004}
    2005
    2006/** sets branching execution method for not completely fixed pseudo solutions */
    2008 SCIP_BRANCHRULE* branchrule, /**< branching rule */
    2009 SCIP_DECL_BRANCHEXECPS((*branchexecps)) /**< branching execution method for not completely fixed pseudo solutions */
    2010 )
    2011{
    2012 assert(branchrule != NULL);
    2013
    2014 branchrule->branchexecps = branchexecps;
    2015}
    2016
    2017/** gets name of branching rule */
    2019 SCIP_BRANCHRULE* branchrule /**< branching rule */
    2020 )
    2021{
    2022 assert(branchrule != NULL);
    2023
    2024 return branchrule->name;
    2025}
    2026
    2027/** gets description of branching rule */
    2029 SCIP_BRANCHRULE* branchrule /**< branching rule */
    2030 )
    2031{
    2032 assert(branchrule != NULL);
    2033
    2034 return branchrule->desc;
    2035}
    2036
    2037/** gets priority of branching rule */
    2039 SCIP_BRANCHRULE* branchrule /**< branching rule */
    2040 )
    2041{
    2042 assert(branchrule != NULL);
    2043
    2044 return branchrule->priority;
    2045}
    2046
    2047/** sets priority of branching rule */
    2049 SCIP_BRANCHRULE* branchrule, /**< branching rule */
    2050 SCIP_SET* set, /**< global SCIP settings */
    2051 int priority /**< new priority of the branching rule */
    2052 )
    2053{
    2054 assert(branchrule != NULL);
    2055 assert(set != NULL);
    2056
    2057 branchrule->priority = priority;
    2058 set->branchrulessorted = FALSE;
    2059}
    2060
    2061/** gets maximal depth level, up to which this branching rule should be used (-1 for no limit) */
    2063 SCIP_BRANCHRULE* branchrule /**< branching rule */
    2064 )
    2065{
    2066 assert(branchrule != NULL);
    2067
    2068 return branchrule->maxdepth;
    2069}
    2070
    2071/** sets maximal depth level, up to which this branching rule should be used (-1 for no limit) */
    2073 SCIP_BRANCHRULE* branchrule, /**< branching rule */
    2074 int maxdepth /**< new maxdepth of the branching rule */
    2075 )
    2076{
    2077 assert(branchrule != NULL);
    2078 assert(maxdepth >= -1);
    2079
    2080 branchrule->maxdepth = maxdepth;
    2081}
    2082
    2083/** gets maximal relative distance from current node's dual bound to primal bound for applying branching rule */
    2085 SCIP_BRANCHRULE* branchrule /**< branching rule */
    2086 )
    2087{
    2088 assert(branchrule != NULL);
    2089
    2090 return branchrule->maxbounddist;
    2091}
    2092
    2093/** sets maximal relative distance from current node's dual bound to primal bound for applying branching rule */
    2095 SCIP_BRANCHRULE* branchrule, /**< branching rule */
    2096 SCIP_Real maxbounddist /**< new maxbounddist of the branching rule */
    2097 )
    2098{
    2099 assert(branchrule != NULL);
    2100 assert(maxbounddist >= -1);
    2101
    2102 branchrule->maxbounddist = maxbounddist;
    2103}
    2104
    2105/** enables or disables all clocks of \p branchrule, depending on the value of the flag */
    2107 SCIP_BRANCHRULE* branchrule, /**< the branching rule for which all clocks should be enabled or disabled */
    2108 SCIP_Bool enable /**< should the clocks of the branching rule be enabled? */
    2109 )
    2110{
    2111 assert(branchrule != NULL);
    2112
    2113 SCIPclockEnableOrDisable(branchrule->setuptime, enable);
    2114 SCIPclockEnableOrDisable(branchrule->branchclock, enable);
    2115}
    2116
    2117/** gets time in seconds used in this branching rule for setting up for next stages */
    2119 SCIP_BRANCHRULE* branchrule /**< branching rule */
    2120 )
    2121{
    2122 assert(branchrule != NULL);
    2123
    2124 return SCIPclockGetTime(branchrule->setuptime);
    2125}
    2126
    2127/** gets time in seconds used in this branching rule */
    2129 SCIP_BRANCHRULE* branchrule /**< branching rule */
    2130 )
    2131{
    2132 assert(branchrule != NULL);
    2133
    2134 return SCIPclockGetTime(branchrule->branchclock);
    2135}
    2136
    2137/** gets the total number of times, the branching rule was called on an LP solution */
    2139 SCIP_BRANCHRULE* branchrule /**< branching rule */
    2140 )
    2141{
    2142 assert(branchrule != NULL);
    2143
    2144 return branchrule->nlpcalls;
    2145}
    2146
    2147/** gets the total number of times, the branching rule was called on an external solution */
    2149 SCIP_BRANCHRULE* branchrule /**< branching rule */
    2150 )
    2151{
    2152 assert(branchrule != NULL);
    2153
    2154 return branchrule->nexterncalls;
    2155}
    2156
    2157/** gets the total number of times, the branching rule was called on a pseudo solution */
    2159 SCIP_BRANCHRULE* branchrule /**< branching rule */
    2160 )
    2161{
    2162 assert(branchrule != NULL);
    2163
    2164 return branchrule->npseudocalls;
    2165}
    2166
    2167/** gets the total number of times, the branching rule detected a cutoff */
    2169 SCIP_BRANCHRULE* branchrule /**< branching rule */
    2170 )
    2171{
    2172 assert(branchrule != NULL);
    2173
    2174 return branchrule->ncutoffs;
    2175}
    2176
    2177/** gets the total number of cuts, the branching rule separated */
    2179 SCIP_BRANCHRULE* branchrule /**< branching rule */
    2180 )
    2181{
    2182 assert(branchrule != NULL);
    2183
    2184 return branchrule->ncutsfound;
    2185}
    2186
    2187/** gets the total number of constraints, the branching rule added to the respective local nodes (not counting constraints
    2188 * that were added to the child nodes as branching decisions)
    2189 */
    2191 SCIP_BRANCHRULE* branchrule /**< branching rule */
    2192 )
    2193{
    2194 assert(branchrule != NULL);
    2195
    2196 return branchrule->nconssfound;
    2197}
    2198
    2199/** gets the total number of domain reductions, the branching rule found */
    2201 SCIP_BRANCHRULE* branchrule /**< branching rule */
    2202 )
    2203{
    2204 assert(branchrule != NULL);
    2205
    2206 return branchrule->ndomredsfound;
    2207}
    2208
    2209/** gets the total number of children, the branching rule created */
    2211 SCIP_BRANCHRULE* branchrule /**< branching rule */
    2212 )
    2213{
    2214 assert(branchrule != NULL);
    2215
    2216 return branchrule->nchildren;
    2217}
    2218
    2219/** is branching rule initialized? */
    2221 SCIP_BRANCHRULE* branchrule /**< branching rule */
    2222 )
    2223{
    2224 assert(branchrule != NULL);
    2225
    2226 return branchrule->initialized;
    2227}
    2228
    2229
    2230
    2231/*
    2232 * branching methods
    2233 */
    2234
    2235/** calculates the branching score out of the gain predictions for a binary branching */
    2237 SCIP_SET* set, /**< global SCIP settings */
    2238 SCIP_VAR* var, /**< variable, of which the branching factor should be applied, or NULL */
    2239 SCIP_Real downgain, /**< prediction of objective gain for rounding downwards */
    2240 SCIP_Real upgain /**< prediction of objective gain for rounding upwards */
    2241 )
    2242{
    2243 SCIP_Real score;
    2244 SCIP_Real eps;
    2245
    2246 assert(set != NULL);
    2247
    2248 /* adjust scores near zero to always yield product score greater than 0 */
    2250 if( set->branch_sumadjustscore )
    2251 {
    2252 /* adjust scores by adding eps to keep near zero score differences between variables */
    2253 downgain = downgain + eps;
    2254 upgain = upgain + eps;
    2255 }
    2256 else
    2257 {
    2258 /* disregard near zero score differences between variables and consider the branching factor for them */
    2259 downgain = MAX(downgain, eps);
    2260 upgain = MAX(upgain, eps);
    2261 }
    2262
    2263 switch( set->branch_scorefunc )
    2264 {
    2265 case 's': /* linear sum score function */
    2266 /* weigh the two child nodes with branchscorefac and 1-branchscorefac */
    2267 if( downgain > upgain )
    2268 score = set->branch_scorefac * downgain + (1.0-set->branch_scorefac) * upgain;
    2269 else
    2270 score = set->branch_scorefac * upgain + (1.0-set->branch_scorefac) * downgain;
    2271 break;
    2272
    2273 case 'p': /* product score function */
    2274 score = downgain * upgain;
    2275 break;
    2276 case 'q': /* quotient score function */
    2277 if( downgain > upgain )
    2278 score = upgain * upgain / downgain;
    2279 else
    2280 score = downgain * downgain / upgain;
    2281 break;
    2282 default:
    2283 SCIPerrorMessage("invalid branching score function <%c>\n", set->branch_scorefunc);
    2284 SCIPABORT();
    2285 score = 0.0;
    2286 }
    2287
    2288 /* apply the branch factor of the variable */
    2289 if( var != NULL )
    2290 score *= SCIPvarGetBranchFactor(var);
    2291
    2292 return score;
    2293}
    2294
    2295/** calculates the branching score out of the gain predictions for a branching with arbitrary many children */
    2297 SCIP_SET* set, /**< global SCIP settings */
    2298 SCIP_VAR* var, /**< variable, of which the branching factor should be applied, or NULL */
    2299 int nchildren, /**< number of children that the branching will create */
    2300 SCIP_Real* gains /**< prediction of objective gain for each child */
    2301 )
    2302{
    2303 SCIP_Real min1;
    2304 SCIP_Real min2;
    2305 int c;
    2306
    2307 assert(nchildren == 0 || gains != NULL);
    2308
    2309 /* search for the two minimal gains in the child list and use these to calculate the branching score */
    2310 min1 = SCIPsetInfinity(set);
    2311 min2 = SCIPsetInfinity(set);
    2312 for( c = 0; c < nchildren; ++c )
    2313 {
    2314 if( gains[c] < min1 )
    2315 {
    2316 min2 = min1;
    2317 min1 = gains[c];
    2318 }
    2319 else if( gains[c] < min2 )
    2320 min2 = gains[c];
    2321 }
    2322
    2323 return SCIPbranchGetScore(set, var, min1, min2);
    2324}
    2325
    2326/** computes a branching point for a (not necessarily discrete) variable
    2327 * a suggested branching point is first projected onto the box
    2328 * if no point is suggested, then the value in the current LP or pseudo solution is used
    2329 * if this value is at infinity, then 0.0 projected onto the bounds and then moved inside the interval is used
    2330 * for a discrete variable, it is ensured that the returned value is fractional
    2331 * for a continuous variable, the parameter branching/clamp defines how far a branching point need to be from the bounds of a variable
    2332 * the latter is only applied if no point has been suggested, or the suggested point is not inside the variable's interval
    2333 */
    2335 SCIP_SET* set, /**< global SCIP settings */
    2336 SCIP_TREE* tree, /**< branch and bound tree */
    2337 SCIP_VAR* var, /**< variable, of which the branching point should be computed */
    2338 SCIP_Real suggestion /**< suggestion for branching point, or SCIP_INVALID if no suggestion */
    2339 )
    2340{
    2341 SCIP_Real branchpoint;
    2342 SCIP_Real lb;
    2343 SCIP_Real ub;
    2344
    2345 assert(set != NULL);
    2346 assert(var != NULL);
    2347
    2348 lb = SCIPvarGetLbLocal(var);
    2349 ub = SCIPvarGetUbLocal(var);
    2350
    2351 /* for a fixed variable, we cannot branch further */
    2352 assert(!SCIPsetIsEQ(set, lb, ub));
    2353
    2354 if( !SCIPsetIsInfinity(set, REALABS(suggestion)) )
    2355 {
    2356 /* use user suggested branching point */
    2357
    2358 /* first, project it onto the current domain */
    2359 branchpoint = MAX(lb, MIN(suggestion, ub));
    2360
    2361 if( SCIPvarIsIntegral(var) )
    2362 {
    2363 /* if it is a discrete variable, then try to round it down and up and accept this choice */
    2364 if( SCIPsetIsEQ(set, branchpoint, ub) )
    2365 {
    2366 /* if branchpoint is at ub, then create branches [lb,ub-1] and [ub,ub], that is branch on ub-0.5
    2367 * however, if ub is too large, then ub-0.5 = ub (in double precision)
    2368 * in that case, fall back to the code below, which branches closer to the middle of [lb,ub]
    2369 */
    2370 branchpoint = SCIPsetFloor(set, branchpoint) - 0.5;
    2371 if( branchpoint < ub )
    2372 return branchpoint;
    2373 }
    2374 else
    2375 {
    2376 /* create branches [lb,branchpoint] and [branchpoint+1,ub]
    2377 * however, if |branchpoint| is too large, then branchpoint+0.5 = branchpoint (in double precision)
    2378 * in that case, fall back to the code below, which branches closer to the middle of [lb,ub]
    2379 */
    2380 branchpoint = SCIPsetFloor(set, branchpoint) + 0.5;
    2381 if( branchpoint > lb )
    2382 return branchpoint;
    2383 }
    2384 }
    2385 else if( (SCIPsetIsInfinity(set, -lb) || SCIPsetIsRelGT(set, branchpoint, lb)) &&
    2386 (SCIPsetIsInfinity(set, ub) || SCIPsetIsRelLT(set, branchpoint, ub)) )
    2387 {
    2388 /* if it is continuous and inside the box, then accept it */
    2389 return branchpoint;
    2390 }
    2391 /* if it is continuous and suggestion is one of the bounds, continue below */
    2392 }
    2393 else
    2394 {
    2395 /* if no point is suggested, try the LP or pseudo solution */
    2396 branchpoint = SCIPvarGetSol(var, SCIPtreeHasCurrentNodeLP(tree));
    2397
    2398 if( REALABS(branchpoint) > 1e+12 )
    2399 {
    2400 /* if the value in the LP or pseudosolution is large (here 1e+12), use 0.0 (will be projected onto bounds below) */
    2401 branchpoint = 0.0;
    2402 }
    2403 else if( SCIPtreeHasCurrentNodeLP(tree) && set->branch_midpull > 0.0 && !SCIPsetIsInfinity(set, -lb) && !SCIPsetIsInfinity(set, ub) )
    2404 {
    2405 /* if the value is from the LP and midpull is activated, then push towards middle of domain */
    2406 SCIP_Real midpull = set->branch_midpull;
    2407 SCIP_Real glb;
    2408 SCIP_Real gub;
    2409 SCIP_Real reldomainwidth;
    2410
    2411 /* shrink midpull if width of local domain, relative to global domain, is small
    2412 * that is, if there has been already one or several branchings on this variable, then give more emphasis on LP solution
    2413 *
    2414 * do this only if the relative domain width is below the minreldomainwidth value
    2415 */
    2416 glb = SCIPvarGetLbGlobal(var);
    2417 gub = SCIPvarGetUbGlobal(var);
    2418 assert(glb < gub);
    2419
    2420 if( !SCIPsetIsInfinity(set, -glb) && !SCIPsetIsInfinity(set, gub) )
    2421 reldomainwidth = (ub - lb) / (gub - glb);
    2422 else
    2423 reldomainwidth = SCIPsetEpsilon(set);
    2424
    2425 if( reldomainwidth < set->branch_midpullreldomtrig )
    2426 midpull *= reldomainwidth;
    2427
    2428 branchpoint = midpull * (lb+ub) / 2.0 + (1.0 - midpull) * branchpoint;
    2429 }
    2430
    2431 /* make sure branchpoint is on interval, below we make sure that it is within bounds for continuous vars */
    2432 branchpoint = MAX(lb, MIN(branchpoint, ub));
    2433 }
    2434
    2435 /* if value is at +/- infty, then choose some value a bit off from bounds or 0.0 */
    2436 if( SCIPsetIsInfinity(set, branchpoint) )
    2437 {
    2438 /* if value is at +infty, then the upper bound should be at infinity */
    2439 assert(SCIPsetIsInfinity(set, ub));
    2440
    2441 /* choose 0.0 or something above lower bound if lower bound > 0 */
    2442 if( SCIPsetIsPositive(set, lb) )
    2443 branchpoint = lb + 1000.0;
    2444 else
    2445 branchpoint = 0.0;
    2446 }
    2447 else if( SCIPsetIsInfinity(set, -branchpoint) )
    2448 {
    2449 /* if value is at -infty, then the lower bound should be at -infinity */
    2450 assert(SCIPsetIsInfinity(set, -lb));
    2451
    2452 /* choose 0.0 or something below upper bound if upper bound < 0 */
    2453 if( SCIPsetIsNegative(set, ub) )
    2454 branchpoint = ub - 1000.0;
    2455 else
    2456 branchpoint = 0.0;
    2457 }
    2458
    2459 assert(SCIPsetIsInfinity(set, ub) || SCIPsetIsLE(set, branchpoint, ub));
    2460 assert(SCIPsetIsInfinity(set, -lb) || SCIPsetIsGE(set, branchpoint, lb));
    2461
    2462 if( !SCIPvarIsNonimpliedIntegral(var) )
    2463 {
    2464 if( !SCIPsetIsInfinity(set, -lb) || !SCIPsetIsInfinity(set, ub) )
    2465 {
    2466 /* if one bound is missing, we are temporarily guessing the other one, so we can apply the clamp below */
    2467 if( SCIPsetIsInfinity(set, ub) )
    2468 {
    2469 ub = lb + MIN(MAX(0.5 * REALABS(lb), 1000), 0.9 * (SCIPsetInfinity(set) - lb)); /*lint !e666*/
    2470 }
    2471 else if( SCIPsetIsInfinity(set, -lb) )
    2472 {
    2473 lb = ub - MIN(MAX(0.5 * REALABS(ub), 1000), 0.9 * (SCIPsetInfinity(set) + ub)); /*lint !e666*/
    2474 }
    2475
    2476 /* if branching point is too close to the bounds, move more into the middle of the interval */
    2477 if( SCIPrelDiff(ub, lb) <= 2.02 * SCIPsetEpsilon(set) )
    2478 {
    2479 /* for very tiny intervals we set it exactly into the middle */
    2480 branchpoint = (lb+ub)/2.0;
    2481 }
    2482 else
    2483 {
    2484 /* otherwise we project it away from the bounds */
    2485 SCIP_Real minbrpoint;
    2486 SCIP_Real maxbrpoint;
    2487 SCIP_Real scale;
    2488 SCIP_Real lbabs;
    2489 SCIP_Real ubabs;
    2490
    2491 lbabs = REALABS(lb);
    2492 ubabs = REALABS(ub);
    2493
    2494 scale = MAX3(lbabs, ubabs, 1.0);
    2495
    2496 /* the minimal branching point should be
    2497 * - set->clamp away from the lower bound - relative to the local domain size
    2498 * - SCIPsetEpsilon(set)*scale above the lower bound - in absolute value
    2499 */
    2500 minbrpoint = (1.0 - set->branch_clamp) * lb + set->branch_clamp * ub;
    2501 minbrpoint = MAX(lb + 1.01*SCIPsetEpsilon(set)*scale, minbrpoint); /*lint !e666*/
    2502
    2503 /* the maximal branching point should be
    2504 * - set->clamp away from the upper bound - relative to the local domain size
    2505 * - SCIPsetEpsilon(set)*scale below the upper bound - in absolute value
    2506 */
    2507 maxbrpoint = set->branch_clamp * lb + (1.0 - set->branch_clamp) * ub;
    2508 maxbrpoint = MIN(ub - 1.01*SCIPsetEpsilon(set)*scale, maxbrpoint); /*lint !e666*/
    2509
    2510 /* project branchpoint into [minbrpoint, maxbrpoint] */
    2511 branchpoint = MAX(minbrpoint, MIN(branchpoint, maxbrpoint));
    2512
    2513 /* if selected branching point is close to 0.0 and bounds are away from 0.0, it often makes sense to branch exactly on 0.0 */
    2514 if( SCIPsetIsFeasZero(set, branchpoint) && SCIPsetIsFeasNegative(set, lb) && SCIPsetIsFeasPositive(set, ub) )
    2515 branchpoint = 0.0;
    2516
    2517 assert(SCIPsetIsRelLT(set, SCIPvarGetLbLocal(var), branchpoint));
    2518 assert(SCIPsetIsRelLT(set, branchpoint, SCIPvarGetUbLocal(var)));
    2519 }
    2520 }
    2521
    2522 /* ensure fractional branching point for implicit integer variables */
    2523 if( SCIPvarIsImpliedIntegral(var) && SCIPsetIsIntegral(set, branchpoint) )
    2524 {
    2525 /* if branchpoint is integral but not on bounds, then it should be one of the value {lb+1, ..., ub-1} */
    2526 assert(SCIPsetIsGE(set, SCIPsetRound(set, branchpoint), lb + 1.0));
    2527 assert(SCIPsetIsLE(set, SCIPsetRound(set, branchpoint), ub - 1.0));
    2528 /* if branchpoint is integral, create one branch with x <= x'-1 and one with x >= x'
    2529 * @todo could in the same way be x <= x' and x >= x'+1; is there some easy way to know which is better?
    2530 */
    2531 return branchpoint - 0.5;
    2532 }
    2533
    2534 return branchpoint;
    2535 }
    2536 else
    2537 {
    2538 /* discrete variables */
    2539 if( branchpoint <= lb + 0.5 )
    2540 {
    2541 /* if branchpoint is on lower bound, create one branch with x = lb and one with x >= lb+1
    2542 * however, if |lb| is huge, then lb + 0.5 == lb
    2543 * in that case, branch at middle of [lb,ub]
    2544 */
    2545 branchpoint = lb + 0.5;
    2546 if( branchpoint == lb ) /*lint !e777*/
    2547 branchpoint = 0.5 * (lb+ub);
    2548 return branchpoint;
    2549 }
    2550 else if( branchpoint >= ub - 0.5 )
    2551 {
    2552 /* if branchpoint is on upper bound, create one branch with x = ub and one with x <= ub-1
    2553 * however, if |ub| is huge, then ub - 0.5 == ub
    2554 * in that case, branch at middle of [lb,ub]
    2555 */
    2556 branchpoint = ub - 0.5;
    2557 if( branchpoint == ub ) /*lint !e777*/
    2558 branchpoint = 0.5 * (lb+ub);
    2559 return branchpoint;
    2560 }
    2561 else if( SCIPsetIsIntegral(set, branchpoint) )
    2562 {
    2563 /* if branchpoint is integral but not on bounds, then it should be one of the value {lb+1, ..., ub-1} */
    2564 assert(SCIPsetIsGE(set, SCIPsetRound(set, branchpoint), lb + 1.0));
    2565 assert(SCIPsetIsLE(set, SCIPsetRound(set, branchpoint), ub - 1.0));
    2566 /* if branchpoint is integral, create one branch with x <= x'-1 and one with x >= x'
    2567 * @todo could in the same way be x <= x' and x >= x'+1; is there some easy way to know which is better? */
    2568 return branchpoint - 0.5;
    2569 }
    2570 else
    2571 {
    2572 /* branchpoint is somewhere between bounds and fractional, so just round down and up */
    2573 return branchpoint;
    2574 }
    2575 }
    2576}
    2577
    2578/** calls branching rules to branch on an LP solution; if no fractional variables exist, the result is SCIP_DIDNOTRUN;
    2579 * if the branch priority of an unfixed variable is larger than the maximal branch priority of the fractional
    2580 * variables, pseudo solution branching is applied on the unfixed variables with maximal branch priority
    2581 */
    2583 BMS_BLKMEM* blkmem, /**< block memory for parameter settings */
    2584 SCIP_SET* set, /**< global SCIP settings */
    2585 SCIP_STAT* stat, /**< problem statistics */
    2586 SCIP_PROB* transprob, /**< transformed problem after presolve */
    2587 SCIP_PROB* origprob, /**< original problem */
    2588 SCIP_TREE* tree, /**< branch and bound tree */
    2589 SCIP_REOPT* reopt, /**< reoptimization data structure */
    2590 SCIP_LP* lp, /**< current LP data */
    2591 SCIP_SEPASTORE* sepastore, /**< separation storage */
    2592 SCIP_BRANCHCAND* branchcand, /**< branching candidate storage */
    2593 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
    2594 SCIP_EVENTFILTER* eventfilter, /**< global event filter */
    2595 SCIP_Real cutoffbound, /**< global upper cutoff bound */
    2596 SCIP_Bool allowaddcons, /**< should adding constraints be allowed to avoid a branching? */
    2597 SCIP_RESULT* result /**< pointer to store the result of the branching (s. branch.h) */
    2598 )
    2599{
    2600 int i;
    2601 int nalllpcands; /* sum of binary and integer branching candidates */
    2602
    2603 assert(branchcand != NULL);
    2604 assert(result != NULL);
    2605
    2606 *result = SCIP_DIDNOTRUN;
    2607
    2608 /* calculate branching candidates */
    2609 SCIP_CALL( branchcandCalcLPCands(branchcand, set, stat, lp) );
    2610 assert(0 <= branchcand->npriolpcands && branchcand->npriolpcands <= branchcand->nlpcands);
    2611 assert((branchcand->npriolpcands == 0) == (branchcand->nlpcands == 0));
    2612
    2613 SCIPsetDebugMsg(set, "branching on LP solution with %d (+%d) fractional (+implicit fractional) variables (%d of maximal priority)\n",
    2614 branchcand->nlpcands, branchcand->nenfoimpllpfracs, branchcand->npriolpcands);
    2615
    2616 nalllpcands = branchcand->nlpcands + branchcand->nenfoimpllpfracs;
    2617 /* do nothing, if no fractional variables exist */
    2618 if( nalllpcands == 0 )
    2619 return SCIP_OKAY;
    2620
    2621 /* if there is a non-fixed variable with higher priority than the maximal priority of the fractional candidates,
    2622 * use pseudo solution branching instead
    2623 */
    2624 if( branchcand->pseudomaxpriority > branchcand->lpmaxpriority )
    2625 {
    2626 SCIP_CALL( SCIPbranchExecPseudo(blkmem, set, stat, transprob, origprob, tree, reopt, lp, branchcand, eventqueue, eventfilter,
    2627 cutoffbound, allowaddcons, result) );
    2628 assert(*result != SCIP_DIDNOTRUN && *result != SCIP_DIDNOTFIND);
    2629 return SCIP_OKAY;
    2630 }
    2631
    2632 /* sort the branching rules by priority */
    2634
    2635 /* try all branching rules until one succeeded to branch */
    2636 for( i = 0; i < set->nbranchrules && (*result == SCIP_DIDNOTRUN || *result == SCIP_DIDNOTFIND); ++i )
    2637 {
    2638 SCIP_CALL( SCIPbranchruleExecLPSol(set->branchrules[i], set, stat, tree, sepastore, cutoffbound, allowaddcons, result) );
    2639 }
    2640
    2641 if( *result == SCIP_DIDNOTRUN || *result == SCIP_DIDNOTFIND )
    2642 {
    2643 SCIP_VAR* var;
    2644 SCIP_Real factor;
    2645 SCIP_Real bestfactor;
    2646 int priority;
    2647 int bestpriority;
    2648 int bestcand;
    2649
    2650 /* no branching method succeeded in choosing a branching: just branch on the first fractional variable with maximal
    2651 * priority, and out of these on the one with maximal branch factor
    2652 */
    2653 bestcand = -1;
    2654 bestpriority = INT_MIN;
    2655 bestfactor = SCIP_REAL_MIN;
    2656 for( i = 0; i < nalllpcands; ++i )
    2657 {
    2658 priority = SCIPvarGetBranchPriority(branchcand->lpcands[i]);
    2659 factor = SCIPvarGetBranchFactor(branchcand->lpcands[i]);
    2660 if( priority > bestpriority || (priority == bestpriority && factor > bestfactor) )
    2661 {
    2662 bestcand = i;
    2663 bestpriority = priority;
    2664 bestfactor = factor;
    2665 }
    2666 }
    2667 assert(0 <= bestcand && bestcand < nalllpcands);
    2668
    2669 var = branchcand->lpcands[bestcand];
    2670 assert(SCIPvarIsIntegral(var));
    2671 assert(branchcand->nlpcands == 0 || !SCIPvarIsImpliedIntegral(var));
    2672
    2673 assert(!SCIPsetIsEQ(set, SCIPvarGetLbLocal(var), SCIPvarGetUbLocal(var)));
    2674
    2675 SCIP_CALL( SCIPtreeBranchVar(tree, reopt, blkmem, set, stat, transprob, origprob, lp, branchcand, eventqueue, eventfilter, var, SCIP_INVALID,
    2676 NULL, NULL, NULL) );
    2677
    2678 *result = SCIP_BRANCHED;
    2679 }
    2680
    2681 return SCIP_OKAY;
    2682}
    2683
    2684/** calculates branching candidates for LP solution branching (fractional variables) */
    2685static
    2687 SCIP_BRANCHCAND* branchcand, /**< branching candidate storage */
    2688 SCIP_SET* set, /**< global SCIP settings */
    2689 SCIP_STAT* stat, /**< problem statistics */
    2690 SCIP_LP* lp /**< current LP data */
    2691 )
    2692{
    2693 SCIP_COL** cols;
    2694 SCIP_VAR* var;
    2695 SCIP_COL* col;
    2696 SCIP_RATIONAL* tmp;
    2697 SCIP_Real primsol;
    2698 SCIP_Real frac;
    2699 SCIP_VARTYPE vartype;
    2700 SCIP_IMPLINTTYPE impltype;
    2701 int branchpriority;
    2702 int ncols;
    2703 int c;
    2704 int insertpos;
    2705
    2706 assert(branchcand != NULL);
    2707 assert(stat != NULL);
    2708 assert(branchcand->validlpcandslp <= stat->lpcount);
    2709 assert(lp != NULL);
    2710 assert(lp->solved);
    2712 /* this should only be called when fp-methods did not find any candidates */
    2713 assert(branchcand->nlpcands == 0);
    2714 assert(branchcand->validlpcandslp == stat->lpcount);
    2715
    2716 SCIPsetDebugMsg(set, "calculating LP branching candidates exactly: validlp=%" SCIP_LONGINT_FORMAT ", lpcount=%" SCIP_LONGINT_FORMAT "\n",
    2717 branchcand->validlpcandslp, stat->lpcount);
    2718
    2720 {
    2721 branchcand->lpmaxpriority = INT_MIN / 2;
    2722 branchcand->nlpcands = 0;
    2723 branchcand->npriolpcands = 0;
    2724 branchcand->npriolpbins = 0;
    2725 branchcand->nimpllpfracs = 0;
    2726 branchcand->nenfoimpllpfracs = 0;
    2727 branchcand->validlpcandslp = stat->lpcount;
    2728
    2729 SCIPsetDebugMsg(set, " LP is unbounded -> no branching candidates\n");
    2730 return SCIP_OKAY;
    2731 }
    2732
    2733 /* always recalculate */
    2734 SCIPsetDebugMsg(set, " -> recalculating LP branching candidates exactly\n");
    2735
    2736 cols = SCIPlpGetCols(lp);
    2737 ncols = SCIPlpGetNCols(lp);
    2738
    2739 /* construct the LP branching candidate set, moving the candidates with maximal priority to the front */
    2740 SCIP_CALL( ensureLpcandsSize(branchcand, set, ncols) );
    2741
    2742 branchcand->lpmaxpriority = INT_MIN / 2;
    2743 branchcand->nlpcands = 0;
    2744 branchcand->nimpllpfracs = 0;
    2745 branchcand->npriolpcands = 0;
    2746 branchcand->npriolpbins = 0;
    2747 branchcand->nenfoimpllpfracs = 0;
    2748
    2749 SCIP_CALL( SCIPrationalCreateBuffer(set->buffer, &tmp) );
    2750
    2751 for( c = 0; c < ncols; ++c )
    2752 {
    2753 col = cols[c];
    2754 assert(col != NULL);
    2755 assert(col->lppos == c);
    2756 assert(col->lpipos >= 0);
    2757
    2758 primsol = SCIPcolGetPrimsol(col);
    2759 assert(primsol < SCIP_INVALID);
    2760 assert(SCIPsetIsInfinity(set, -col->lb) || SCIPsetIsFeasGE(set, primsol, col->lb));
    2761 assert(SCIPsetIsInfinity(set, col->ub) || SCIPsetIsFeasLE(set, primsol, col->ub));
    2762
    2763 var = col->var;
    2764 assert(var != NULL);
    2766 assert(SCIPvarGetCol(var) == col);
    2767
    2768 /* LP branching candidates are fractional binary and integer variables; implicit variables are kept at the end
    2769 * of the candidates array for some rounding heuristics
    2770 */
    2771 vartype = SCIPvarGetType(var);
    2772 impltype = SCIPvarGetImplType(var);
    2773 if( vartype == SCIP_VARTYPE_CONTINUOUS && impltype == SCIP_IMPLINTTYPE_NONE )
    2774 continue;
    2775
    2776 /* ignore fixed variables (due to numerics, it is possible, that the LP solution of a fixed integer variable
    2777 * (with large fixed value) is fractional in terms of absolute feasibility measure)
    2778 */
    2779 if( SCIPvarGetLbLocal(var) >= SCIPvarGetUbLocal(var) - 0.5 )
    2780 continue;
    2781
    2782 SCIPrationalSetReal(tmp, primsol);
    2783
    2784 /* check, if the LP solution value is fractional */
    2785 if( SCIPrationalIsIntegral(tmp) )
    2786 continue;
    2787
    2788 SCIPrationalGetFrac(tmp, tmp);
    2789 frac = SCIPrationalGetReal(tmp);
    2790
    2791 /* insert candidate in candidate list */
    2792 branchpriority = SCIPvarGetBranchPriority(var);
    2793 insertpos = branchcand->nlpcands + branchcand->nimpllpfracs;
    2794 assert(insertpos < branchcand->lpcandssize);
    2795
    2796 if( impltype != SCIP_IMPLINTTYPE_NONE )
    2797 branchpriority = INT_MIN;
    2798
    2799 assert(impltype != SCIP_IMPLINTTYPE_NONE || branchpriority >= INT_MIN/2);
    2800
    2801 /* ensure that unenforced implied integral variables are stored at the end of the array */
    2802 if( branchcand->nimpllpfracs > branchcand->nenfoimpllpfracs && vartype != SCIP_VARTYPE_CONTINUOUS )
    2803 {
    2804 branchcand->lpcands[insertpos] = branchcand->lpcands[branchcand->nlpcands + branchcand->nenfoimpllpfracs];
    2805 branchcand->lpcandssol[insertpos] = branchcand->lpcandssol[branchcand->nlpcands + branchcand->nenfoimpllpfracs];
    2806 branchcand->lpcandsfrac[insertpos] = branchcand->lpcandsfrac[branchcand->nlpcands + branchcand->nenfoimpllpfracs];
    2807 assert(SCIPvarIsImpliedIntegral(branchcand->lpcands[insertpos]));
    2808 insertpos = branchcand->nlpcands + branchcand->nenfoimpllpfracs;
    2809 }
    2810
    2811 /* ensure that enforced implied integral variables are stored before the end of the array */
    2812 if( branchcand->nenfoimpllpfracs > 0 && impltype == SCIP_IMPLINTTYPE_NONE )
    2813 {
    2814 branchcand->lpcands[insertpos] = branchcand->lpcands[branchcand->nlpcands];
    2815 branchcand->lpcandssol[insertpos] = branchcand->lpcandssol[branchcand->nlpcands];
    2816 branchcand->lpcandsfrac[insertpos] = branchcand->lpcandsfrac[branchcand->nlpcands];
    2817 assert(SCIPvarIsImpliedIntegral(branchcand->lpcands[insertpos]));
    2818 insertpos = branchcand->nlpcands;
    2819 }
    2820
    2821 if( branchpriority > branchcand->lpmaxpriority )
    2822 {
    2823 /* candidate has higher priority than the current maximum:
    2824 * move it to the front and declare it to be the single best candidate
    2825 */
    2826 if( insertpos != 0 )
    2827 {
    2828 branchcand->lpcands[insertpos] = branchcand->lpcands[0];
    2829 branchcand->lpcandssol[insertpos] = branchcand->lpcandssol[0];
    2830 branchcand->lpcandsfrac[insertpos] = branchcand->lpcandsfrac[0];
    2831 insertpos = 0;
    2832 }
    2833 branchcand->npriolpcands = 1;
    2834 assert(!SCIPvarIsImpliedIntegral(var));
    2835 branchcand->npriolpbins = (vartype == SCIP_VARTYPE_BINARY ? 1 : 0);
    2836 branchcand->lpmaxpriority = branchpriority;
    2837 }
    2838 else if( branchpriority == branchcand->lpmaxpriority )
    2839 {
    2840 /* candidate has equal priority as the current maximum:
    2841 * move away the first non-maximal priority candidate, move the current candidate to the correct
    2842 * slot (binaries first) and increase the number of maximal priority candidates
    2843 */
    2844 if( insertpos != branchcand->npriolpcands )
    2845 {
    2846 branchcand->lpcands[insertpos] = branchcand->lpcands[branchcand->npriolpcands];
    2847 branchcand->lpcandssol[insertpos] = branchcand->lpcandssol[branchcand->npriolpcands];
    2848 branchcand->lpcandsfrac[insertpos] = branchcand->lpcandsfrac[branchcand->npriolpcands];
    2849 insertpos = branchcand->npriolpcands;
    2850 }
    2851 ++branchcand->npriolpcands;
    2852
    2853 assert(!SCIPvarIsImpliedIntegral(var));
    2854 if( vartype == SCIP_VARTYPE_BINARY )
    2855 {
    2856 if( insertpos != branchcand->npriolpbins )
    2857 {
    2858 branchcand->lpcands[insertpos] = branchcand->lpcands[branchcand->npriolpbins];
    2859 branchcand->lpcandssol[insertpos] = branchcand->lpcandssol[branchcand->npriolpbins];
    2860 branchcand->lpcandsfrac[insertpos] = branchcand->lpcandsfrac[branchcand->npriolpbins];
    2861 insertpos = branchcand->npriolpbins;
    2862 }
    2863 ++branchcand->npriolpbins;
    2864 }
    2865 }
    2866 /* insert variable at the correct position of the candidates storage */
    2867 branchcand->lpcands[insertpos] = var;
    2868 branchcand->lpcandssol[insertpos] = primsol;
    2869 branchcand->lpcandsfrac[insertpos] = frac;
    2870
    2871 /* increase the counter depending on the variable type */
    2872 if( impltype == SCIP_IMPLINTTYPE_NONE )
    2873 ++branchcand->nlpcands;
    2874 else
    2875 {
    2876 ++branchcand->nimpllpfracs;
    2877
    2878 if( vartype != SCIP_VARTYPE_CONTINUOUS )
    2879 ++branchcand->nenfoimpllpfracs;
    2880 }
    2881
    2882 SCIPsetDebugMsg(set, " -> candidate %d: var=<%s>, sol=%g, frac=%g, prio=%d (max: %d) -> pos %d\n",
    2883 branchcand->nlpcands, SCIPvarGetName(var), primsol, frac, branchpriority, branchcand->lpmaxpriority,
    2884 insertpos);
    2885 }
    2886
    2887#ifndef NDEBUG
    2888 /* in debug mode we assert that the variables are positioned correctly (binaries and integers first,
    2889 * implicit integers last)
    2890 */
    2891 for( c = 0; c < branchcand->nlpcands + branchcand->nimpllpfracs; ++c )
    2892 {
    2893 assert(SCIPvarIsImpliedIntegral(branchcand->lpcands[c]) == (c >= branchcand->nlpcands));
    2894 assert((SCIPvarGetType(branchcand->lpcands[c]) == SCIP_VARTYPE_CONTINUOUS) == (c >= branchcand->nlpcands + branchcand->nenfoimpllpfracs));
    2895 }
    2896#endif
    2897
    2898 branchcand->validlpcandslp = stat->lpcount;
    2899
    2900 assert(0 <= branchcand->npriolpcands && branchcand->npriolpcands <= branchcand->nlpcands);
    2901
    2902 SCIPsetDebugMsg(set, " -> %d fractional variables (%d of maximal priority)\n", branchcand->nlpcands, branchcand->npriolpcands);
    2903
    2904 SCIPrationalFreeBuffer(set->buffer, &tmp);
    2905
    2906 return SCIP_OKAY;
    2907}
    2908
    2909/** calls branching rules to branch on an LP solution; if no fractional variables exist, the result is SCIP_DIDNOTRUN;
    2910 * if the branch priority of an unfixed variable is larger than the maximal branch priority of the fractional
    2911 * variables, pseudo solution branching is applied on the unfixed variables with maximal branch priority
    2912 */
    2914 BMS_BLKMEM* blkmem, /**< block memory for parameter settings */
    2915 SCIP_SET* set, /**< global SCIP settings */
    2916 SCIP_STAT* stat, /**< problem statistics */
    2917 SCIP_PROB* transprob, /**< transformed problem after presolve */
    2918 SCIP_PROB* origprob, /**< original problem */
    2919 SCIP_TREE* tree, /**< branch and bound tree */
    2920 SCIP_REOPT* reopt, /**< reoptimization data structure */
    2921 SCIP_LP* lp, /**< current LP data */
    2922 SCIP_BRANCHCAND* branchcand, /**< branching candidate storage */
    2923 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
    2924 SCIP_EVENTFILTER* eventfilter, /**< global event filter */
    2925 SCIP_Real cutoffbound, /**< global upper cutoff bound */
    2926 SCIP_Bool allowaddcons, /**< should adding constraints be allowed to avoid a branching? */
    2927 SCIP_RESULT* result /**< pointer to store the result of the branching (s. branch.h) */
    2928 )
    2929{
    2930 int i;
    2931 int nalllpcands; /* sum of binary and integer branching candidates */
    2932
    2933 assert(branchcand != NULL);
    2934 assert(result != NULL);
    2935
    2936 *result = SCIP_DIDNOTRUN;
    2937
    2938 /* calculate branching candidates */
    2939 SCIP_CALL( branchcandCalcLPCandsExact(branchcand, set, stat, lp) );
    2940 assert(0 <= branchcand->npriolpcands && branchcand->npriolpcands <= branchcand->nlpcands);
    2941 assert((branchcand->npriolpcands == 0) == (branchcand->nlpcands == 0));
    2942
    2943 SCIPsetDebugMsg(set, "branching on LP solution with %d (+%d) fractional (+implicit fractional) variables (%d of maximal priority)\n",
    2944 branchcand->nlpcands, branchcand->nenfoimpllpfracs, branchcand->npriolpcands);
    2945
    2946 nalllpcands = branchcand->nlpcands + branchcand->nenfoimpllpfracs;
    2947 /* do nothing, if no fractional variables exist */
    2948 if( nalllpcands == 0 )
    2949 return SCIP_OKAY;
    2950
    2951 /* if there is a non-fixed variable with higher priority than the maximal priority of the fractional candidates,
    2952 * use pseudo solution branching instead
    2953 */
    2954 if( branchcand->pseudomaxpriority > branchcand->lpmaxpriority )
    2955 {
    2956 SCIP_CALL( SCIPbranchExecPseudo(blkmem, set, stat, transprob, origprob, tree, reopt, lp, branchcand, eventqueue,
    2957 eventfilter, cutoffbound, allowaddcons, result) );
    2958 assert(*result != SCIP_DIDNOTRUN && *result != SCIP_DIDNOTFIND);
    2959 return SCIP_OKAY;
    2960 }
    2961
    2962 /* it does not make sense to call the normal branching rules, due to assumed very small fractionalities,
    2963 * SCIP is not designed to branch on such values. So we simply branch on the first possible variable
    2964 */
    2965 for( i = 0; i < branchcand->nlpcands && *result != SCIP_BRANCHED; i++ )
    2966 {
    2967 SCIP_VAR* branchvar;
    2968
    2969 branchvar = branchcand->lpcands[i];
    2970
    2971#ifndef NDEBUG
    2972 {
    2973 SCIP_RATIONAL* tmp;
    2974 SCIP_Real branchval;
    2975
    2976 SCIP_CALL( SCIPrationalCreateBuffer(set->buffer, &tmp) );
    2977 branchval = branchcand->lpcandssol[i];
    2978 SCIPrationalSetReal(tmp, branchval);
    2979 assert(!SCIPrationalIsIntegral(tmp));
    2980 SCIPrationalFreeBuffer(set->buffer, &tmp);
    2981 }
    2982#endif
    2983
    2984 SCIP_CALL( SCIPtreeBranchVarExact(tree, reopt, blkmem, set, stat, transprob, origprob, lp,
    2985 branchcand, eventqueue, eventfilter, branchvar, NULL, NULL) );
    2986 *result = SCIP_BRANCHED;
    2987 }
    2988 /* reset the validlpcandslp to recalculate the branchcands for normal branching */
    2989 branchcand->validlpcandslp = -1;
    2990
    2991 return SCIP_OKAY;
    2992}
    2993
    2994/** calls branching rules to branch on an external solution; if no external branching candidates exist, the result is SCIP_DIDNOTRUN */
    2996 BMS_BLKMEM* blkmem, /**< block memory for parameter settings */
    2997 SCIP_SET* set, /**< global SCIP settings */
    2998 SCIP_STAT* stat, /**< problem statistics */
    2999 SCIP_PROB* transprob, /**< transformed problem after presolve */
    3000 SCIP_PROB* origprob, /**< original problem */
    3001 SCIP_TREE* tree, /**< branch and bound tree */
    3002 SCIP_REOPT* reopt, /**< reoptimization data structure */
    3003 SCIP_LP* lp, /**< current LP data */
    3004 SCIP_SEPASTORE* sepastore, /**< separation storage */
    3005 SCIP_BRANCHCAND* branchcand, /**< branching candidate storage */
    3006 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
    3007 SCIP_EVENTFILTER* eventfilter, /**< global event filter */
    3008 SCIP_Real cutoffbound, /**< global upper cutoff bound */
    3009 SCIP_Bool allowaddcons, /**< should adding constraints be allowed to avoid a branching? */
    3010 SCIP_RESULT* result /**< pointer to store the result of the branching (s. branch.h) */
    3011 )
    3012{
    3013 int i;
    3014
    3015 assert(branchcand != NULL);
    3016 assert(result != NULL);
    3017 assert(0 <= branchcand->nprioexterncands && branchcand->nprioexterncands <= branchcand->nexterncands);
    3018 assert((branchcand->nprioexterncands == 0) == (branchcand->nexterncands == 0));
    3019
    3020 *result = SCIP_DIDNOTRUN;
    3021
    3022 SCIPsetDebugMsg(set, "branching on external solution with %d branching candidates (%d of maximal priority)\n",
    3023 branchcand->nexterncands, branchcand->nprioexterncands);
    3024
    3025 /* do nothing, if no external candidates exist */
    3026 if( branchcand->nexterncands == 0 )
    3027 return SCIP_OKAY;
    3028
    3029 /* if there is a non-fixed variable with higher priority than the maximal priority of the external candidates,
    3030 * use pseudo solution branching instead
    3031 */
    3032 if( branchcand->pseudomaxpriority > branchcand->externmaxpriority )
    3033 {
    3034 /* @todo: adjust this, that also LP branching might be called, if lpmaxpriority != externmaxpriority.
    3035 * Therefor, it has to be clear which of both has the higher priority
    3036 */
    3037 SCIP_CALL( SCIPbranchExecPseudo(blkmem, set, stat, transprob, origprob, tree, reopt, lp, branchcand, eventqueue, eventfilter,
    3038 cutoffbound, allowaddcons, result) );
    3039 assert(*result != SCIP_DIDNOTRUN && *result != SCIP_DIDNOTFIND);
    3040 return SCIP_OKAY;
    3041 }
    3042
    3043 /* sort the branching rules by priority */
    3045
    3046 /* try all branching rules until one succeeded to branch */
    3047 for( i = 0; i < set->nbranchrules && (*result == SCIP_DIDNOTRUN || *result == SCIP_DIDNOTFIND); ++i )
    3048 {
    3049 SCIP_CALL( SCIPbranchruleExecExternSol(set->branchrules[i], set, stat, tree, sepastore, cutoffbound, allowaddcons, result) );
    3050 }
    3051
    3052 if( *result == SCIP_DIDNOTRUN || *result == SCIP_DIDNOTFIND )
    3053 {
    3054 SCIP_VAR* var;
    3055 SCIP_Real val;
    3056 SCIP_Real bestfactor;
    3057 SCIP_Real bestdomain;
    3058 int bestpriority;
    3059 int bestcand;
    3060
    3061 /* if all branching rules did nothing, then they should also not have cleared all branching candidates */
    3062 assert(branchcand->nexterncands > 0);
    3063
    3064 /* no branching method succeeded in choosing a branching: just branch on the first branching candidates with maximal
    3065 * priority, and out of these on the one with maximal branch factor, and out of these on the one with largest domain
    3066 */
    3067 bestcand = -1;
    3068 bestpriority = INT_MIN;
    3069 bestfactor = SCIP_REAL_MIN;
    3070 bestdomain = 0.0;
    3071 for( i = 0; i < branchcand->nexterncands; ++i )
    3072 {
    3073 SCIP_VAR* cand;
    3074 SCIP_Real domain;
    3075 SCIP_Real factor;
    3076 int priority;
    3077
    3078 cand = branchcand->externcands[i];
    3079 priority = SCIPvarGetBranchPriority(cand);
    3080 factor = SCIPvarGetBranchFactor(cand);
    3081
    3082 /* the domain size is infinite, iff one of the bounds is infinite */
    3084 domain = SCIPsetInfinity(set);
    3085 else
    3086 domain = SCIPvarGetUbLocal(cand) - SCIPvarGetLbLocal(cand);
    3087
    3088 /* choose variable with higher priority, higher factor, larger domain (in that order) */
    3089 if( priority > bestpriority || (priority == bestpriority && factor > bestfactor) || (priority == bestpriority && factor == bestfactor && domain > bestdomain) ) /*lint !e777*/
    3090 {
    3091 bestcand = i;
    3092 bestpriority = priority;
    3093 bestfactor = factor;
    3094 bestdomain = domain;
    3095 }
    3096 }
    3097 assert(0 <= bestcand && bestcand < branchcand->nexterncands);
    3098
    3099 var = branchcand->externcands[bestcand];
    3100 val = SCIPbranchGetBranchingPoint(set, tree, var, branchcand->externcandssol[bestcand]);
    3101 assert(!SCIPsetIsEQ(set, SCIPvarGetLbLocal(var), SCIPvarGetUbLocal(var)));
    3103 || SCIPsetIsLT(set, SCIPvarGetLbLocal(var), val));
    3105 || SCIPsetIsLT(set, val, SCIPvarGetUbLocal(var)));
    3106
    3107 SCIPsetDebugMsg(set, "no branching method succeeded; fallback selected to branch on variable <%s> with bounds [%g, %g] on value %g\n",
    3108 SCIPvarGetName(var), SCIPvarGetLbLocal(var), SCIPvarGetUbLocal(var), val);
    3109
    3110 SCIP_CALL( SCIPtreeBranchVar(tree, reopt, blkmem, set, stat, transprob, origprob, lp, branchcand, eventqueue, eventfilter, var, val,
    3111 NULL, NULL, NULL) );
    3112
    3113 if( tree->nchildren >= 1 )
    3114 *result = SCIP_BRANCHED;
    3115 /* if the bounds are too close, it may happen that we cannot branch but rather fix the variable */
    3116 else
    3117 {
    3119 *result = SCIP_REDUCEDDOM;
    3120 }
    3121 }
    3122
    3123 return SCIP_OKAY;
    3124}
    3125
    3126/** calls branching rules to branch on a pseudo solution; if no unfixed variables exist, the result is SCIP_DIDNOTRUN */
    3128 BMS_BLKMEM* blkmem, /**< block memory for parameter settings */
    3129 SCIP_SET* set, /**< global SCIP settings */
    3130 SCIP_STAT* stat, /**< problem statistics */
    3131 SCIP_PROB* transprob, /**< transformed problem after presolve */
    3132 SCIP_PROB* origprob, /**< original problem */
    3133 SCIP_TREE* tree, /**< branch and bound tree */
    3134 SCIP_REOPT* reopt, /**< reoptimization data structure */
    3135 SCIP_LP* lp, /**< current LP data */
    3136 SCIP_BRANCHCAND* branchcand, /**< branching candidate storage */
    3137 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
    3138 SCIP_EVENTFILTER* eventfilter, /**< global event filter */
    3139 SCIP_Real cutoffbound, /**< global upper cutoff bound */
    3140 SCIP_Bool allowaddcons, /**< should adding constraints be allowed to avoid a branching? */
    3141 SCIP_RESULT* result /**< pointer to store the result of the branching (s. branch.h) */
    3142 )
    3143{
    3144 int i;
    3145
    3146 assert(branchcand != NULL);
    3147 assert(result != NULL);
    3148
    3149 SCIPsetDebugMsg(set, "branching on pseudo solution with %d unfixed variables\n", branchcand->npseudocands);
    3150
    3151 *result = SCIP_DIDNOTRUN;
    3152
    3153 /* do nothing, if no unfixed variables exist */
    3154 if( branchcand->npseudocands == 0 )
    3155 return SCIP_OKAY;
    3156
    3157 /* sort the branching rules by priority */
    3159
    3160 /* try all branching rules until one succeeded to branch */
    3161 for( i = 0; i < set->nbranchrules && (*result == SCIP_DIDNOTRUN || *result == SCIP_DIDNOTFIND); ++i )
    3162 {
    3163 SCIP_CALL( SCIPbranchruleExecPseudoSol(set->branchrules[i], set, stat, tree, cutoffbound, allowaddcons, result) );
    3164 }
    3165
    3166 if( *result == SCIP_DIDNOTRUN || *result == SCIP_DIDNOTFIND )
    3167 {
    3168 SCIP_VAR* var;
    3169 SCIP_Real factor;
    3170 SCIP_Real bestfactor;
    3171 int priority;
    3172 int bestpriority;
    3173 int bestcand;
    3174
    3175 /* no branching method succeeded in choosing a branching: just branch on the first unfixed variable with maximal
    3176 * priority, and out of these on the one with maximal branch factor
    3177 */
    3178 bestcand = -1;
    3179 bestpriority = INT_MIN;
    3180 bestfactor = SCIP_REAL_MIN;
    3181 for( i = 0; i < branchcand->npseudocands; ++i )
    3182 {
    3183 priority = SCIPvarGetBranchPriority(branchcand->pseudocands[i]);
    3184 factor = SCIPvarGetBranchFactor(branchcand->pseudocands[i]);
    3185 if( priority > bestpriority || (priority == bestpriority && factor > bestfactor) )
    3186 {
    3187 bestcand = i;
    3188 bestpriority = priority;
    3189 bestfactor = factor;
    3190 }
    3191 }
    3192 assert(0 <= bestcand && bestcand < branchcand->npseudocands);
    3193
    3194 var = branchcand->pseudocands[bestcand];
    3195 assert(SCIPvarIsIntegral(var));
    3196 assert(!SCIPsetIsEQ(set, SCIPvarGetLbLocal(var), SCIPvarGetUbLocal(var)));
    3197
    3198 SCIP_CALL( SCIPtreeBranchVar(tree, reopt, blkmem, set, stat, transprob, origprob, lp, branchcand, eventqueue, eventfilter, var, SCIP_INVALID,
    3199 NULL, NULL, NULL) );
    3200
    3201 *result = SCIP_BRANCHED;
    3202 }
    3203
    3204 return SCIP_OKAY;
    3205}
    3206
    SCIP_RETCODE SCIPbranchcandGetLPCands(SCIP_BRANCHCAND *branchcand, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp, SCIP_VAR ***lpcands, SCIP_Real **lpcandssol, SCIP_Real **lpcandsfrac, int *nlpcands, int *npriolpcands, int *nfracimplvars)
    Definition: branch.c:425
    SCIP_RETCODE SCIPbranchExecLP(BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_SEPASTORE *sepastore, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_Real cutoffbound, SCIP_Bool allowaddcons, SCIP_RESULT *result)
    Definition: branch.c:2582
    int SCIPbranchcandGetNPrioPseudoCands(SCIP_BRANCHCAND *branchcand)
    Definition: branch.c:885
    int SCIPbranchcandGetNExternCands(SCIP_BRANCHCAND *branchcand)
    Definition: branch.c:527
    static SCIP_DECL_PARAMCHGD(paramChgdBranchrulePriority)
    Definition: branch.c:1266
    SCIP_Real SCIPbranchGetBranchingPoint(SCIP_SET *set, SCIP_TREE *tree, SCIP_VAR *var, SCIP_Real suggestion)
    Definition: branch.c:2334
    SCIP_RETCODE SCIPbranchcandCreate(SCIP_BRANCHCAND **branchcand)
    Definition: branch.c:143
    void SCIPbranchruleSetExit(SCIP_BRANCHRULE *branchrule, SCIP_DECL_BRANCHEXIT((*branchexit)))
    Definition: branch.c:1950
    void SCIPbranchruleSetInitsol(SCIP_BRANCHRULE *branchrule, SCIP_DECL_BRANCHINITSOL((*branchinitsol)))
    Definition: branch.c:1961
    void SCIPbranchruleSetMaxdepth(SCIP_BRANCHRULE *branchrule, int maxdepth)
    Definition: branch.c:2072
    void SCIPbranchruleSetFree(SCIP_BRANCHRULE *branchrule, SCIP_DECL_BRANCHFREE((*branchfree)))
    Definition: branch.c:1928
    void SCIPbranchruleSetInit(SCIP_BRANCHRULE *branchrule, SCIP_DECL_BRANCHINIT((*branchinit)))
    Definition: branch.c:1939
    SCIP_RETCODE SCIPbranchruleExecLPSol(SCIP_BRANCHRULE *branchrule, SCIP_SET *set, SCIP_STAT *stat, SCIP_TREE *tree, SCIP_SEPASTORE *sepastore, SCIP_Real cutoffbound, SCIP_Bool allowaddcons, SCIP_RESULT *result)
    Definition: branch.c:1568
    SCIP_Real SCIPbranchGetScoreMultiple(SCIP_SET *set, SCIP_VAR *var, int nchildren, SCIP_Real *gains)
    Definition: branch.c:2296
    int SCIPbranchcandGetNPrioExternCands(SCIP_BRANCHCAND *branchcand)
    Definition: branch.c:537
    SCIP_RETCODE SCIPbranchruleExit(SCIP_BRANCHRULE *branchrule, SCIP_SET *set)
    Definition: branch.c:1490
    void SCIPbranchcandClearExternCands(SCIP_BRANCHCAND *branchcand)
    Definition: branch.c:722
    int SCIPbranchcandGetExternMaxPrio(SCIP_BRANCHCAND *branchcand)
    Definition: branch.c:517
    static SCIP_RETCODE doBranchruleCreate(SCIP_BRANCHRULE **branchrule, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, BMS_BLKMEM *blkmem, const char *name, const char *desc, int priority, int maxdepth, SCIP_Real maxbounddist, SCIP_DECL_BRANCHCOPY((*branchcopy)), SCIP_DECL_BRANCHFREE((*branchfree)), SCIP_DECL_BRANCHINIT((*branchinit)), SCIP_DECL_BRANCHEXIT((*branchexit)), SCIP_DECL_BRANCHINITSOL((*branchinitsol)), SCIP_DECL_BRANCHEXITSOL((*branchexitsol)), SCIP_DECL_BRANCHEXECLP((*branchexeclp)), SCIP_DECL_BRANCHEXECEXT((*branchexecext)), SCIP_DECL_BRANCHEXECPS((*branchexecps)), SCIP_BRANCHRULEDATA *branchruledata)
    Definition: branch.c:1300
    SCIP_RETCODE SCIPbranchruleFree(SCIP_BRANCHRULE **branchrule, SCIP_SET *set)
    Definition: branch.c:1419
    SCIP_RETCODE SCIPbranchruleInitsol(SCIP_BRANCHRULE *branchrule, SCIP_SET *set)
    Definition: branch.c:1520
    static SCIP_RETCODE branchcandCalcLPCandsExact(SCIP_BRANCHCAND *branchcand, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp)
    Definition: branch.c:2686
    SCIP_RETCODE SCIPbranchcandUpdateVarBranchPriority(SCIP_BRANCHCAND *branchcand, SCIP_SET *set, SCIP_VAR *var, int branchpriority)
    Definition: branch.c:1209
    int SCIPbranchcandGetNPrioExternBins(SCIP_BRANCHCAND *branchcand)
    Definition: branch.c:547
    SCIP_RETCODE SCIPbranchruleExecPseudoSol(SCIP_BRANCHRULE *branchrule, SCIP_SET *set, SCIP_STAT *stat, SCIP_TREE *tree, SCIP_Real cutoffbound, SCIP_Bool allowaddcons, SCIP_RESULT *result)
    Definition: branch.c:1784
    void SCIPbranchruleSetExecPs(SCIP_BRANCHRULE *branchrule, SCIP_DECL_BRANCHEXECPS((*branchexecps)))
    Definition: branch.c:2007
    int SCIPbranchcandGetNPseudoCands(SCIP_BRANCHCAND *branchcand)
    Definition: branch.c:875
    SCIP_RETCODE SCIPbranchExecExtern(BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_SEPASTORE *sepastore, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_Real cutoffbound, SCIP_Bool allowaddcons, SCIP_RESULT *result)
    Definition: branch.c:2995
    int SCIPbranchcandGetNPrioPseudoBins(SCIP_BRANCHCAND *branchcand)
    Definition: branch.c:895
    SCIP_RETCODE SCIPbranchcandGetExternCands(SCIP_BRANCHCAND *branchcand, SCIP_VAR ***externcands, SCIP_Real **externcandssol, SCIP_Real **externcandsscore, int *nexterncands, int *nprioexterncands, int *nprioexternbins, int *nprioexternints, int *nprioexternimpls)
    Definition: branch.c:460
    void SCIPbranchruleSetCopy(SCIP_BRANCHRULE *branchrule, SCIP_DECL_BRANCHCOPY((*branchcopy)))
    Definition: branch.c:1917
    SCIP_RETCODE SCIPbranchruleExitsol(SCIP_BRANCHRULE *branchrule, SCIP_SET *set)
    Definition: branch.c:1544
    int SCIPbranchcandGetNPrioExternImpls(SCIP_BRANCHCAND *branchcand)
    Definition: branch.c:567
    SCIP_RETCODE SCIPbranchruleExecExternSol(SCIP_BRANCHRULE *branchrule, SCIP_SET *set, SCIP_STAT *stat, SCIP_TREE *tree, SCIP_SEPASTORE *sepastore, SCIP_Real cutoffbound, SCIP_Bool allowaddcons, SCIP_RESULT *result)
    Definition: branch.c:1676
    int SCIPbranchcandGetNPrioLPCands(SCIP_BRANCHCAND *branchcand)
    Definition: branch.c:507
    SCIP_RETCODE SCIPbranchExecLPExact(BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_Real cutoffbound, SCIP_Bool allowaddcons, SCIP_RESULT *result)
    Definition: branch.c:2913
    SCIP_RETCODE SCIPbranchcandGetPseudoCands(SCIP_BRANCHCAND *branchcand, SCIP_SET *set, SCIP_PROB *prob, SCIP_VAR ***pseudocands, int *npseudocands, int *npriopseudocands)
    Definition: branch.c:813
    void SCIPbranchcandInvalidate(SCIP_BRANCHCAND *branchcand)
    Definition: branch.c:203
    void SCIPbranchruleSetExecExt(SCIP_BRANCHRULE *branchrule, SCIP_DECL_BRANCHEXECEXT((*branchexecext)))
    Definition: branch.c:1996
    int SCIPbranchcandGetNPrioExternInts(SCIP_BRANCHCAND *branchcand)
    Definition: branch.c:557
    int SCIPbranchcandGetNPrioPseudoImpls(SCIP_BRANCHCAND *branchcand)
    Definition: branch.c:915
    static SCIP_RETCODE ensureExterncandsSize(SCIP_BRANCHCAND *branchcand, SCIP_SET *set, int num)
    Definition: branch.c:113
    SCIP_RETCODE SCIPbranchcandRemoveVar(SCIP_BRANCHCAND *branchcand, SCIP_VAR *var)
    Definition: branch.c:1152
    static SCIP_RETCODE branchcandCalcLPCands(SCIP_BRANCHCAND *branchcand, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp)
    Definition: branch.c:214
    SCIP_RETCODE SCIPbranchcandAddExternCand(SCIP_BRANCHCAND *branchcand, SCIP_SET *set, SCIP_VAR *var, SCIP_Real score, SCIP_Real solval)
    Definition: branch.c:589
    void SCIPbranchruleEnableOrDisableClocks(SCIP_BRANCHRULE *branchrule, SCIP_Bool enable)
    Definition: branch.c:2106
    static SCIP_RETCODE ensurePseudocandsSize(SCIP_BRANCHCAND *branchcand, SCIP_SET *set, int num)
    Definition: branch.c:90
    static void branchcandRemovePseudoCand(SCIP_BRANCHCAND *branchcand, SCIP_VAR *var)
    Definition: branch.c:1067
    static SCIP_RETCODE ensureLpcandsSize(SCIP_BRANCHCAND *branchcand, SCIP_SET *set, int num)
    Definition: branch.c:65
    SCIP_RETCODE SCIPbranchcandFree(SCIP_BRANCHCAND **branchcand)
    Definition: branch.c:184
    int SCIPbranchcandGetNPrioPseudoInts(SCIP_BRANCHCAND *branchcand)
    Definition: branch.c:905
    SCIP_RETCODE SCIPbranchcandUpdateVar(SCIP_BRANCHCAND *branchcand, SCIP_SET *set, SCIP_VAR *var)
    Definition: branch.c:1169
    static void branchcandSortPseudoCands(SCIP_BRANCHCAND *branchcand)
    Definition: branch.c:1028
    void SCIPbranchruleSetMaxbounddist(SCIP_BRANCHRULE *branchrule, SCIP_Real maxbounddist)
    Definition: branch.c:2094
    SCIP_RETCODE SCIPbranchExecPseudo(BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_Real cutoffbound, SCIP_Bool allowaddcons, SCIP_RESULT *result)
    Definition: branch.c:3127
    int SCIPbranchcandGetLPMaxPrio(SCIP_BRANCHCAND *branchcand)
    Definition: branch.c:497
    void SCIPbranchruleSetPriority(SCIP_BRANCHRULE *branchrule, SCIP_SET *set, int priority)
    Definition: branch.c:2048
    void SCIPbranchruleSetExitsol(SCIP_BRANCHRULE *branchrule, SCIP_DECL_BRANCHEXITSOL((*branchexitsol)))
    Definition: branch.c:1972
    SCIP_RETCODE SCIPbranchruleCreate(SCIP_BRANCHRULE **branchrule, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, BMS_BLKMEM *blkmem, const char *name, const char *desc, int priority, int maxdepth, SCIP_Real maxbounddist, SCIP_DECL_BRANCHCOPY((*branchcopy)), SCIP_DECL_BRANCHFREE((*branchfree)), SCIP_DECL_BRANCHINIT((*branchinit)), SCIP_DECL_BRANCHEXIT((*branchexit)), SCIP_DECL_BRANCHINITSOL((*branchinitsol)), SCIP_DECL_BRANCHEXITSOL((*branchexitsol)), SCIP_DECL_BRANCHEXECLP((*branchexeclp)), SCIP_DECL_BRANCHEXECEXT((*branchexecext)), SCIP_DECL_BRANCHEXECPS((*branchexecps)), SCIP_BRANCHRULEDATA *branchruledata)
    Definition: branch.c:1383
    void SCIPbranchruleSetExecLp(SCIP_BRANCHRULE *branchrule, SCIP_DECL_BRANCHEXECLP((*branchexeclp)))
    Definition: branch.c:1985
    int SCIPbranchcandGetNPrioExternConts(SCIP_BRANCHCAND *branchcand)
    Definition: branch.c:577
    SCIP_Real SCIPbranchGetScore(SCIP_SET *set, SCIP_VAR *var, SCIP_Real downgain, SCIP_Real upgain)
    Definition: branch.c:2236
    SCIP_RETCODE SCIPbranchruleCopyInclude(SCIP_BRANCHRULE *branchrule, SCIP_SET *set)
    Definition: branch.c:1280
    SCIP_Bool SCIPbranchcandContainsExternCand(SCIP_BRANCHCAND *branchcand, SCIP_VAR *var)
    Definition: branch.c:737
    SCIP_RETCODE SCIPbranchruleInit(SCIP_BRANCHRULE *branchrule, SCIP_SET *set)
    Definition: branch.c:1446
    static void branchcandInsertPseudoCand(SCIP_BRANCHCAND *branchcand, SCIP_VAR *var, int insertpos)
    Definition: branch.c:928
    internal methods for branching rules and branching candidate storage
    void SCIPclockStop(SCIP_CLOCK *clck, SCIP_SET *set)
    Definition: clock.c:360
    void SCIPclockEnableOrDisable(SCIP_CLOCK *clck, SCIP_Bool enable)
    Definition: clock.c:260
    void SCIPclockStart(SCIP_CLOCK *clck, SCIP_SET *set)
    Definition: clock.c:290
    SCIP_Real SCIPclockGetTime(SCIP_CLOCK *clck)
    Definition: clock.c:438
    void SCIPclockReset(SCIP_CLOCK *clck)
    Definition: clock.c:209
    void SCIPclockFree(SCIP_CLOCK **clck)
    Definition: clock.c:185
    SCIP_RETCODE SCIPclockCreate(SCIP_CLOCK **clck, SCIP_CLOCKTYPE clocktype)
    Definition: clock.c:170
    internal methods for clocks and timing issues
    common defines and data types used in all packages of SCIP
    #define NULL
    Definition: def.h:248
    #define SCIP_MAXSTRLEN
    Definition: def.h:269
    #define SCIP_Longint
    Definition: def.h:141
    #define SCIP_MAXTREEDEPTH
    Definition: def.h:297
    #define SCIP_INVALID
    Definition: def.h:178
    #define SCIP_Bool
    Definition: def.h:91
    #define MIN(x, y)
    Definition: def.h:224
    #define SCIP_ALLOC(x)
    Definition: def.h:366
    #define MAX3(x, y, z)
    Definition: def.h:228
    #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 SCIPABORT()
    Definition: def.h:327
    #define SCIP_REAL_MIN
    Definition: def.h:159
    #define REALABS(x)
    Definition: def.h:182
    #define SCIP_CALL(x)
    Definition: def.h:355
    #define SCIP_CALL_FINALLY(x, y)
    Definition: def.h:397
    internal methods for managing events
    SCIP_Real SCIPrelDiff(SCIP_Real val1, SCIP_Real val2)
    Definition: misc.c:11162
    SCIP_Bool SCIPbranchruleIsInitialized(SCIP_BRANCHRULE *branchrule)
    Definition: branch.c:2220
    SCIP_Longint SCIPbranchruleGetNDomredsFound(SCIP_BRANCHRULE *branchrule)
    Definition: branch.c:2200
    SCIP_Longint SCIPbranchruleGetNPseudoCalls(SCIP_BRANCHRULE *branchrule)
    Definition: branch.c:2158
    int SCIPbranchruleGetMaxdepth(SCIP_BRANCHRULE *branchrule)
    Definition: branch.c:2062
    SCIP_Longint SCIPbranchruleGetNConssFound(SCIP_BRANCHRULE *branchrule)
    Definition: branch.c:2190
    SCIP_DECL_SORTPTRCOMP(SCIPbranchruleComp)
    Definition: branch.c:1253
    SCIP_Longint SCIPbranchruleGetNLPCalls(SCIP_BRANCHRULE *branchrule)
    Definition: branch.c:2138
    const char * SCIPbranchruleGetName(SCIP_BRANCHRULE *branchrule)
    Definition: branch.c:2018
    SCIP_BRANCHRULEDATA * SCIPbranchruleGetData(SCIP_BRANCHRULE *branchrule)
    Definition: branch.c:1886
    SCIP_Longint SCIPbranchruleGetNChildren(SCIP_BRANCHRULE *branchrule)
    Definition: branch.c:2210
    SCIP_Real SCIPbranchruleGetTime(SCIP_BRANCHRULE *branchrule)
    Definition: branch.c:2128
    void SCIPbranchruleMarkExact(SCIP_BRANCHRULE *branchrule)
    Definition: branch.c:1907
    int SCIPbranchruleGetPriority(SCIP_BRANCHRULE *branchrule)
    Definition: branch.c:2038
    SCIP_Real SCIPbranchruleGetSetupTime(SCIP_BRANCHRULE *branchrule)
    Definition: branch.c:2118
    SCIP_Real SCIPbranchruleGetMaxbounddist(SCIP_BRANCHRULE *branchrule)
    Definition: branch.c:2084
    const char * SCIPbranchruleGetDesc(SCIP_BRANCHRULE *branchrule)
    Definition: branch.c:2028
    SCIP_Longint SCIPbranchruleGetNCutoffs(SCIP_BRANCHRULE *branchrule)
    Definition: branch.c:2168
    SCIP_RETCODE SCIPsetBranchrulePriority(SCIP *scip, SCIP_BRANCHRULE *branchrule, int priority)
    Definition: scip_branch.c:341
    SCIP_Longint SCIPbranchruleGetNExternCalls(SCIP_BRANCHRULE *branchrule)
    Definition: branch.c:2148
    void SCIPbranchruleSetData(SCIP_BRANCHRULE *branchrule, SCIP_BRANCHRULEDATA *branchruledata)
    Definition: branch.c:1896
    SCIP_Longint SCIPbranchruleGetNCutsFound(SCIP_BRANCHRULE *branchrule)
    Definition: branch.c:2178
    SCIP_Real SCIPcolGetPrimsol(SCIP_COL *col)
    Definition: lp.c:17379
    SCIP_Real SCIPnodeGetLowerbound(SCIP_NODE *node)
    Definition: tree.c:8503
    SCIP_Real SCIPrationalGetReal(SCIP_RATIONAL *rational)
    Definition: rational.cpp:2085
    void SCIPrationalGetFrac(SCIP_RATIONAL *res, SCIP_RATIONAL *src)
    Definition: rational.cpp:2057
    void SCIPrationalSetReal(SCIP_RATIONAL *res, SCIP_Real real)
    Definition: rational.cpp:603
    void SCIPrationalFreeBuffer(BMS_BUFMEM *bufmem, SCIP_RATIONAL **rational)
    Definition: rational.cpp:473
    SCIP_RETCODE SCIPrationalCreateBuffer(BMS_BUFMEM *bufmem, SCIP_RATIONAL **rational)
    Definition: rational.cpp:123
    SCIP_Bool SCIPrationalIsIntegral(SCIP_RATIONAL *rational)
    Definition: rational.cpp:1691
    SCIP_COL * SCIPvarGetCol(SCIP_VAR *var)
    Definition: var.c:23683
    SCIP_Real SCIPvarGetSol(SCIP_VAR *var, SCIP_Bool getlpval)
    Definition: var.c:19007
    SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
    Definition: var.c:23386
    SCIP_Bool SCIPvarIsImpliedIntegral(SCIP_VAR *var)
    Definition: var.c:23498
    SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
    Definition: var.c:24268
    SCIP_Bool SCIPvarIsNonimpliedIntegral(SCIP_VAR *var)
    Definition: var.c:23506
    SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
    Definition: var.c:23453
    SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
    Definition: var.c:24142
    const char * SCIPvarGetName(SCIP_VAR *var)
    Definition: var.c:23267
    SCIP_Real SCIPvarGetBranchFactor(SCIP_VAR *var)
    Definition: var.c:24450
    SCIP_Bool SCIPvarIsIntegral(SCIP_VAR *var)
    Definition: var.c:23490
    SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
    Definition: var.c:24234
    int SCIPvarGetBranchPriority(SCIP_VAR *var)
    Definition: var.c:24462
    SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
    Definition: var.c:24120
    SCIP_IMPLINTTYPE SCIPvarGetImplType(SCIP_VAR *var)
    Definition: var.c:23463
    int SCIPsnprintf(char *t, int len, const char *s,...)
    Definition: misc.c:10827
    SCIP_LPSOLSTAT SCIPlpGetSolstat(SCIP_LP *lp)
    Definition: lp.c:13420
    SCIP_COL ** SCIPlpGetCols(SCIP_LP *lp)
    Definition: lp.c:17969
    int SCIPlpGetNCols(SCIP_LP *lp)
    Definition: lp.c:17979
    internal methods for LP management
    static const char * paramname[]
    Definition: lpi_msk.c:5172
    memory allocation routines
    #define BMSfreeMemory(ptr)
    Definition: memory.h:145
    #define BMSreallocMemoryArray(ptr, num)
    Definition: memory.h:127
    #define BMSduplicateMemoryArray(ptr, source, num)
    Definition: memory.h:143
    #define BMSclearMemory(ptr)
    Definition: memory.h:129
    struct BMS_BlkMem BMS_BLKMEM
    Definition: memory.h:437
    #define BMSfreeMemoryArrayNull(ptr)
    Definition: memory.h:148
    #define BMSallocMemory(ptr)
    Definition: memory.h:118
    real eps
    SCIP_PARAMDATA * SCIPparamGetData(SCIP_PARAM *param)
    Definition: paramset.c:678
    int SCIPparamGetInt(SCIP_PARAM *param)
    Definition: paramset.c:733
    internal methods for handling parameter settings
    int SCIPprobGetNImplVars(SCIP_PROB *prob)
    Definition: prob.c:2895
    int SCIPprobGetNIntVars(SCIP_PROB *prob)
    Definition: prob.c:2886
    int SCIPprobGetNBinVars(SCIP_PROB *prob)
    Definition: prob.c:2877
    SCIP_VAR ** SCIPprobGetVars(SCIP_PROB *prob)
    Definition: prob.c:2913
    internal methods for storing and manipulating the main problem
    #define SCIPerrorMessage
    Definition: pub_message.h:64
    #define SCIPdebugMessage
    Definition: pub_message.h:96
    SCIP callable library.
    int SCIPsepastoreGetNCuts(SCIP_SEPASTORE *sepastore)
    Definition: sepastore.c:1183
    internal methods for storing separated cuts
    SCIP_Real SCIPsetFloor(SCIP_SET *set, SCIP_Real val)
    Definition: set.c:6716
    void SCIPsetSortBranchrules(SCIP_SET *set)
    Definition: set.c:5164
    SCIP_RETCODE SCIPsetAddIntParam(SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, BMS_BLKMEM *blkmem, 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: set.c:3229
    SCIP_Bool SCIPsetIsRelLT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
    Definition: set.c:7487
    SCIP_Bool SCIPsetIsFeasPositive(SCIP_SET *set, SCIP_Real val)
    Definition: set.c:7076
    SCIP_Bool SCIPsetIsGE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
    Definition: set.c:6617
    SCIP_Bool SCIPsetIsFeasFracIntegral(SCIP_SET *set, SCIP_Real val)
    Definition: set.c:7110
    SCIP_Bool SCIPsetIsFeasNegative(SCIP_SET *set, SCIP_Real val)
    Definition: set.c:7087
    SCIP_Real SCIPsetFeastol(SCIP_SET *set)
    Definition: set.c:6422
    SCIP_Real SCIPsetCeil(SCIP_SET *set, SCIP_Real val)
    Definition: set.c:6728
    SCIP_Bool SCIPsetIsFeasLE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
    Definition: set.c:6993
    SCIP_Bool SCIPsetIsPositive(SCIP_SET *set, SCIP_Real val)
    Definition: set.c:6648
    SCIP_Bool SCIPsetIsLE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
    Definition: set.c:6577
    SCIP_RETCODE SCIPsetAddRealParam(SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, BMS_BLKMEM *blkmem, 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: set.c:3277
    SCIP_Real SCIPsetEpsilon(SCIP_SET *set)
    Definition: set.c:6402
    SCIP_Bool SCIPsetIsEQ(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
    Definition: set.c:6537
    SCIP_Bool SCIPsetIsFeasZero(SCIP_SET *set, SCIP_Real val)
    Definition: set.c:7065
    SCIP_Real SCIPsetInfinity(SCIP_SET *set)
    Definition: set.c:6380
    SCIP_Real SCIPsetSumepsilon(SCIP_SET *set)
    Definition: set.c:6412
    SCIP_Bool SCIPsetIsLT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
    Definition: set.c:6557
    SCIP_Bool SCIPsetIsInfinity(SCIP_SET *set, SCIP_Real val)
    Definition: set.c:6515
    SCIP_Bool SCIPsetIsRelGT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
    Definition: set.c:7535
    SCIP_Bool SCIPsetIsIntegral(SCIP_SET *set, SCIP_Real val)
    Definition: set.c:6670
    SCIP_Real SCIPsetFeasFrac(SCIP_SET *set, SCIP_Real val)
    Definition: set.c:7160
    SCIP_Bool SCIPsetIsFeasGE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
    Definition: set.c:7041
    SCIP_Real SCIPsetRound(SCIP_SET *set, SCIP_Real val)
    Definition: set.c:6740
    int SCIPsetCalcMemGrowSize(SCIP_SET *set, int num)
    Definition: set.c:6080
    SCIP_Bool SCIPsetIsFeasIntegral(SCIP_SET *set, SCIP_Real val)
    Definition: set.c:7098
    SCIP_Bool SCIPsetIsNegative(SCIP_SET *set, SCIP_Real val)
    Definition: set.c:6659
    internal methods for global SCIP settings
    #define SCIPsetDebugMsg
    Definition: set.h:1811
    internal methods for main solving loop and node processing
    internal methods for problem statistics
    SCIP_Longint validlpcandslp
    Definition: struct_branch.h:55
    SCIP_Real * lpcandssol
    Definition: struct_branch.h:49
    SCIP_VAR ** externcands
    Definition: struct_branch.h:51
    SCIP_VAR ** pseudocands
    Definition: struct_branch.h:54
    SCIP_Real * externcandsscore
    Definition: struct_branch.h:52
    SCIP_Real * externcandssol
    Definition: struct_branch.h:53
    SCIP_Real * lpcandsfrac
    Definition: struct_branch.h:50
    SCIP_VAR ** lpcands
    Definition: struct_branch.h:48
    SCIP_Longint nexterncalls
    Definition: struct_branch.h:85
    SCIP_Longint nchildren
    Definition: struct_branch.h:92
    SCIP_BRANCHRULEDATA * branchruledata
    SCIP_Longint ncutsfound
    Definition: struct_branch.h:88
    SCIP_Real maxbounddist
    Definition: struct_branch.h:81
    SCIP_Longint nlpcalls
    Definition: struct_branch.h:84
    SCIP_CLOCK * branchclock
    SCIP_CLOCK * setuptime
    SCIP_Longint nconssfound
    Definition: struct_branch.h:89
    SCIP_Bool initialized
    SCIP_Longint ncutoffs
    Definition: struct_branch.h:87
    SCIP_Longint npseudocalls
    Definition: struct_branch.h:86
    SCIP_Longint ndomredsfound
    Definition: struct_branch.h:91
    SCIP_Real lb
    Definition: struct_lp.h:140
    SCIP_Real ub
    Definition: struct_lp.h:141
    int lppos
    Definition: struct_lp.h:174
    int lpipos
    Definition: struct_lp.h:175
    SCIP_VAR * var
    Definition: struct_lp.h:162
    SCIP_Bool solved
    Definition: struct_lp.h:373
    SCIP_Longint nactiveconssadded
    Definition: struct_stat.h:126
    SCIP_Longint lpcount
    Definition: struct_stat.h:205
    SCIP_Longint nprobholechgs
    Definition: struct_stat.h:120
    SCIP_Longint nboundchgs
    Definition: struct_stat.h:117
    SCIP_Longint nholechgs
    Definition: struct_stat.h:118
    int nactiveconss
    Definition: struct_stat.h:275
    SCIP_Longint nprobboundchgs
    Definition: struct_stat.h:119
    SCIP_NODE * focusnode
    Definition: struct_tree.h:193
    int nchildren
    Definition: struct_tree.h:226
    int pseudocandindex
    Definition: struct_var.h:312
    int branchpriority
    Definition: struct_var.h:321
    datastructures for branching rules and branching candidate storage
    Definition: heur_padm.c:135
    SCIP_RETCODE SCIPtreeBranchVar(SCIP_TREE *tree, SCIP_REOPT *reopt, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_VAR *var, SCIP_Real val, SCIP_NODE **downchild, SCIP_NODE **eqchild, SCIP_NODE **upchild)
    Definition: tree.c:6135
    SCIP_RETCODE SCIPtreeBranchVarExact(SCIP_TREE *tree, SCIP_REOPT *reopt, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_VAR *var, SCIP_NODE **downchild, SCIP_NODE **upchild)
    Definition: tree.c:6549
    SCIP_Bool SCIPtreeHasCurrentNodeLP(SCIP_TREE *tree)
    Definition: tree.c:9496
    SCIP_Real SCIPtreeGetLowerbound(SCIP_TREE *tree, SCIP_SET *set)
    Definition: tree.c:8224
    int SCIPtreeGetCurrentDepth(SCIP_TREE *tree)
    Definition: tree.c:9479
    internal methods for branch and bound tree
    #define SCIP_DECL_BRANCHEXECPS(x)
    Definition: type_branch.h:176
    #define SCIP_DECL_BRANCHEXECLP(x)
    Definition: type_branch.h:134
    #define SCIP_DECL_BRANCHEXECEXT(x)
    Definition: type_branch.h:155
    #define SCIP_DECL_BRANCHINITSOL(x)
    Definition: type_branch.h:102
    #define SCIP_DECL_BRANCHINIT(x)
    Definition: type_branch.h:83
    #define SCIP_DECL_BRANCHCOPY(x)
    Definition: type_branch.h:67
    #define SCIP_DECL_BRANCHEXIT(x)
    Definition: type_branch.h:91
    #define SCIP_DECL_BRANCHFREE(x)
    Definition: type_branch.h:75
    struct SCIP_BranchruleData SCIP_BRANCHRULEDATA
    Definition: type_branch.h:57
    #define SCIP_DECL_BRANCHEXITSOL(x)
    Definition: type_branch.h:113
    @ SCIP_CLOCKTYPE_DEFAULT
    Definition: type_clock.h:43
    @ SCIP_LPSOLSTAT_OPTIMAL
    Definition: type_lp.h:44
    @ SCIP_LPSOLSTAT_UNBOUNDEDRAY
    Definition: type_lp.h:46
    struct SCIP_ParamData SCIP_PARAMDATA
    Definition: type_paramset.h:87
    @ SCIP_DIDNOTRUN
    Definition: type_result.h:42
    @ SCIP_CUTOFF
    Definition: type_result.h:48
    @ SCIP_REDUCEDDOM
    Definition: type_result.h:51
    @ SCIP_DIDNOTFIND
    Definition: type_result.h:44
    @ SCIP_CONSADDED
    Definition: type_result.h:52
    @ SCIP_BRANCHED
    Definition: type_result.h:54
    @ SCIP_SEPARATED
    Definition: type_result.h:49
    enum SCIP_Result SCIP_RESULT
    Definition: type_result.h:61
    @ SCIP_INVALIDRESULT
    Definition: type_retcode.h:53
    @ SCIP_OKAY
    Definition: type_retcode.h:42
    @ SCIP_INVALIDCALL
    Definition: type_retcode.h:51
    enum SCIP_Retcode SCIP_RETCODE
    Definition: type_retcode.h:63
    enum SCIP_ImplintType SCIP_IMPLINTTYPE
    Definition: type_var.h:117
    @ SCIP_IMPLINTTYPE_NONE
    Definition: type_var.h:90
    @ SCIP_VARTYPE_INTEGER
    Definition: type_var.h:65
    @ SCIP_VARTYPE_CONTINUOUS
    Definition: type_var.h:71
    @ SCIP_VARTYPE_BINARY
    Definition: type_var.h:64
    @ SCIP_VARSTATUS_ORIGINAL
    Definition: type_var.h:51
    @ SCIP_VARSTATUS_FIXED
    Definition: type_var.h:54
    @ SCIP_VARSTATUS_COLUMN
    Definition: type_var.h:53
    @ SCIP_VARSTATUS_MULTAGGR
    Definition: type_var.h:56
    @ SCIP_VARSTATUS_NEGATED
    Definition: type_var.h:57
    @ SCIP_VARSTATUS_AGGREGATED
    Definition: type_var.h:55
    @ SCIP_VARSTATUS_LOOSE
    Definition: type_var.h:52
    enum SCIP_Vartype SCIP_VARTYPE
    Definition: type_var.h:73
    SCIP_Real SCIPvarGetMultaggrLbLocal(SCIP_VAR *var, SCIP_SET *set)
    Definition: var.c:13574
    SCIP_RETCODE SCIPvarChgBranchPriority(SCIP_VAR *var, int branchpriority)
    Definition: var.c:17019
    SCIP_Real SCIPvarGetMultaggrUbLocal(SCIP_VAR *var, SCIP_SET *set)
    Definition: var.c:13722
    internal methods for problem variables