SCIP

    Solving Constraint Integer Programs

    branch_inference.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-2026 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_inference.c
    26 * @ingroup DEFPLUGINS_BRANCH
    27 * @brief inference history branching rule
    28 * @author Tobias Achterberg
    29 * @author Timo Berthold
    30 * @author Stefan Heinz
    31 */
    32
    33/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
    34
    36#include "scip/pub_branch.h"
    37#include "scip/pub_history.h"
    38#include "scip/pub_message.h"
    39#include "scip/pub_var.h"
    40#include "scip/scip_branch.h"
    41#include "scip/scip_message.h"
    42#include "scip/scip_mem.h"
    43#include "scip/scip_numerics.h"
    44#include "scip/scip_param.h"
    45#include "scip/scip_var.h"
    46
    47
    48/**@name Branching rule properties
    49 *
    50 * @{
    51 */
    52
    53#define BRANCHRULE_NAME "inference"
    54#define BRANCHRULE_DESC "inference history branching"
    55#define BRANCHRULE_PRIORITY 1000
    56#define BRANCHRULE_MAXDEPTH -1
    57#define BRANCHRULE_MAXBOUNDDIST 1.0
    58
    59/**@} */
    60
    61/**@name Default parameter values
    62 *
    63 * @{
    64 */
    65
    66#define DEFAULT_CONFLICTWEIGHT 1000.0 /**< weight in score calculations for conflict score */
    67#define DEFAULT_CUTOFFWEIGHT 1.0 /**< weight in score calculations for cutoff score */
    68#define DEFAULT_INFERENCEWEIGHT 1.0 /**< weight in score calculations for inference score */
    69#define DEFAULT_RELIABLESCORE 0.001 /**< score which is seen to be reliable for a branching decision */
    70#define DEFAULT_FRACTIONALS TRUE /**< should branching on LP solution be restricted to the fractional variables? */
    71#define DEFAULT_USEWEIGHTEDSUM TRUE /**< should a weighted sum of inference, conflict and cutoff weights be used? */
    72
    73#define DEFAULT_CONFLICTPRIO 1 /**< priority value for using conflict weights in lex. order */
    74#define DEFAULT_CUTOFFPRIO 1 /**< priority value for using cutoff weights in lex. order */
    75
    76/**@} */
    77
    78/** branching rule data */
    79struct SCIP_BranchruleData
    80{
    81 SCIP_Real conflictweight; /**< weight in score calculations for conflict score */
    82 SCIP_Real cutoffweight; /**< weight in score calculations for cutoff score */
    83 SCIP_Real inferenceweight; /**< weight in score calculations for inference score */
    84 SCIP_Real reliablescore; /**< score which is seen to be reliable for a branching decision */
    85 SCIP_Bool fractionals; /**< should branching on LP solution be restricted to the fractional variables? */
    86 SCIP_Bool useweightedsum; /**< should a weighted sum of inference, conflict and cutoff weights be used? */
    87 int conflictprio; /**< priority value for using conflict weights in lexicographic order */
    88 int cutoffprio; /**< priority value for using cutoff weights in lexicographic order */
    89};
    90
    91/** evaluate the given candidate with the given score against the currently best know candidate, tiebreaking included */
    92static
    94 SCIP_VAR* cand, /**< candidate to be checked */
    95 SCIP_Real score, /**< score of the candidate */
    96 SCIP_Real branchpoint, /**< potential branching point */
    97 SCIP_BRANCHDIR branchdir, /**< potential branching direction */
    98 SCIP_VAR** bestcand, /**< pointer to the currently best candidate */
    99 SCIP_Real* bestscore, /**< pointer to the score of the currently best candidate */
    100 SCIP_Real* bestbranchpoint, /**< pointer to store the (best) branching point */
    101 SCIP_BRANCHDIR* bestbranchdir /**< pointer to store the branching direction relative to the branching point */
    102 )
    103{
    104 /* evaluate the candidate against the currently best candidate */
    105 if( *bestscore < score )
    106 {
    107 /* the score of the candidate is better than the currently best know candidate */
    108 *bestscore = score;
    109 *bestcand = cand;
    110 *bestbranchpoint = branchpoint;
    111 *bestbranchdir = branchdir;
    112 }
    113 else if( (*bestscore) == score ) /*lint !e777*/
    114 {
    115 SCIP_Real bestobj;
    116 SCIP_Real candobj;
    117
    118 bestobj = REALABS(SCIPvarGetObj(*bestcand));
    119 candobj = REALABS(SCIPvarGetObj(cand));
    120
    121 /* the candidate has the same score as the best known candidate; therefore we use a second and third
    122 * criteria to detect a unique best candidate;
    123 *
    124 * - the second criteria prefers the candidate with a larger absolute value of its objective coefficient
    125 * since branching on that variable might trigger further propagation w.r.t. objective function
    126 * - if the absolute values of the objective coefficient are equal the variable index is used to define a
    127 * unique best candidate
    128 *
    129 * @note It is very important to select a unique best candidate. Otherwise the solver might vary w.r.t. the
    130 * performance to much since the candidate array which is used here (SCIPgetPseudoBranchCands() or
    131 * SCIPgetLPBranchCands()) gets dynamically changed during the solution process. In particular,
    132 * starting a probing mode might already change the order of these arrays. To be independent of that
    133 * the selection should be unique. Otherwise, to selection process can get influenced by starting a
    134 * probing or not.
    135 */
    136 if( bestobj < candobj || (bestobj == candobj && SCIPvarGetIndex(*bestcand) < SCIPvarGetIndex(cand)) ) /*lint !e777*/
    137 {
    138 *bestcand = cand;
    139 *bestbranchpoint = branchpoint;
    140 *bestbranchdir = branchdir;
    141 }
    142 }
    143}
    144
    145/** evaluate the given candidate with the given score against the currently best know candidate */
    146static
    148 SCIP* scip, /**< SCIP data structure */
    149 SCIP_VAR* cand, /**< candidate to be checked */
    150 SCIP_Real score, /**< score of the candidate */
    151 SCIP_Real val, /**< solution value of the candidate */
    152 SCIP_VAR** bestcand, /**< pointer to the currently best candidate */
    153 SCIP_Real* bestscore, /**< pointer to the score of the currently best candidate */
    154 SCIP_Real* bestval, /**< pointer to the solution value of the currently best candidate */
    155 SCIP_VAR** bestcands, /**< buffer array to return selected candidates */
    156 int* nbestcands /**< pointer to return number of selected candidates */
    157 )
    158{
    159 /* evaluate the candidate against the currently best candidate */
    160 /* TODO: consider a weaker comparison of some kind */
    161 if( *bestscore < score )
    162 {
    163 /* the score of the candidate is better than the currently best know candidate, so it should be the first candidate in bestcands and nbestcands should be set to 1*/
    164 *bestscore = score;
    165 *bestcand = cand;
    166 *bestval = val;
    167 *nbestcands = 1;
    168 bestcands[0] = cand;
    169 }
    170 /* TODO: consider a weaker comparison of some kind */
    171 else if( SCIPisEQ(scip, *bestscore, score) )
    172 {
    173 /* the score of the candidate is comparable to the currently known best, so we add it to bestcands and increase nbestcands by 1*/
    174 bestcands[*nbestcands] = cand;
    175 (*nbestcands)++;
    176 }
    177}
    178
    179/** choose a singular best candidate from bestcands and move it to the beginning of the candidate array */
    180static
    182 SCIP_VAR** bestcands, /**< buffer array to return selected candidates */
    183 int nbestcands /**< number of selected candidates */
    184 )
    185{
    186 int c;
    187
    188 for( c = 0; c < nbestcands; ++c )
    189 {
    190 SCIP_Real bestobj;
    191 SCIP_Real candobj;
    192
    193 bestobj = REALABS(SCIPvarGetObj(bestcands[0]));
    194 candobj = REALABS(SCIPvarGetObj(bestcands[c]));
    195
    196 /* the candidate has the same score as the best known candidate; therefore we use a second and third
    197 * criteria to detect a unique best candidate;
    198 *
    199 * - the second criteria prefers the candidate with a larger absolute value of its objective coefficient
    200 * since branching on that variable might trigger further propagation w.r.t. objective function
    201 * - if the absolute values of the objective coefficient are equal the variable index is used to define a
    202 * unique best candidate
    203 *
    204 * @note It is very important to select a unique best candidate. Otherwise the solver might vary w.r.t. the
    205 * performance too much since the candidate array which is used here (SCIPgetPseudoBranchCands() or
    206 * SCIPgetLPBranchCands()) gets dynamically changed during the solution process. In particular,
    207 * starting a probing mode might already change the order of these arrays. To be independent of that
    208 * the selection should be unique. Otherwise, to selection process can get influenced by starting a
    209 * probing or not.
    210 */
    211 if( bestobj < candobj || (bestobj == candobj && SCIPvarGetIndex(bestcands[0]) < SCIPvarGetIndex(bestcands[c])) ) /*lint !e777*/
    212 {
    213 bestcands[0] = bestcands[c];
    214 }
    215 }
    216}
    217
    218/** check if the score for the given domain value and variable domain value is better than the current best know one */
    219static
    221 SCIP_Real value, /**< domain value */
    222 SCIP_HISTORY* history, /**< variable history for given donain value */
    223 SCIP_BRANCHDIR dir, /**< branching direction */
    224 SCIP_Real conflictweight, /**< weight in score calculations for conflict score */
    225 SCIP_Real cutoffweight, /**< weight in score calculations for cutoff score */
    226 SCIP_Real reliablescore, /**< score which is seen to be reliable for a branching decision */
    227 SCIP_Real* bestscore, /**< pointer to store the best score */
    228 SCIP_Real* branchpoint, /**< pointer to store the (best) branching point */
    229 SCIP_BRANCHDIR* branchdir /**< pointer to store the branching direction relative to the branching point */
    230 )
    231{
    232 SCIP_Real conflictscore;
    233 SCIP_Real cutoffscore;
    234 SCIP_Real score;
    235
    236 conflictscore = SCIPhistoryGetVSIDS(history, dir);
    237 cutoffscore = SCIPhistoryGetCutoffSum(history, dir);
    238
    239 /* in case the conflict score is below the reliable score we set it to zero since it is seen to be
    240 * unreliable
    241 */
    242 if( conflictscore < reliablescore )
    243 conflictscore = 0.0;
    244
    245 /* in case the cutoff score is below the reliable score we set it to zero since it is seen to be unreliable */
    246 if( cutoffscore < reliablescore )
    247 cutoffscore = 0.0;
    248
    249 /* compute weight score */
    250 score = conflictweight * conflictscore + cutoffweight * cutoffscore;
    251
    252 if( score > *bestscore )
    253 {
    254 (*bestscore) = score;
    255 (*branchpoint) = value;
    256 (*branchdir) = dir;
    257 }
    258}
    259
    260/** return an aggregated score for the given variable using the conflict score and cutoff score */
    261static
    263 SCIP* scip, /**< SCIP data structure */
    264 SCIP_VAR* var, /**< problem variable */
    265 SCIP_Real conflictweight, /**< weight in score calculations for conflict score */
    266 SCIP_Real inferenceweight, /**< weight in score calculations for inference score */
    267 SCIP_Real cutoffweight, /**< weight in score calculations for cutoff score */
    268 SCIP_Real reliablescore /**< score which is seen to be reliable for a branching decision */
    269 )
    270{
    271 SCIP_Real conflictscore;
    272 SCIP_Real cutoffscore;
    273
    274 conflictscore = SCIPgetVarConflictScore(scip, var);
    275 cutoffscore = SCIPgetVarAvgInferenceCutoffScore(scip, var, cutoffweight);
    276
    277 /* in case the conflict score is below the reliable score we set it to zero since it is seen to be
    278 * unreliable
    279 */
    280 if( conflictscore < reliablescore )
    281 conflictscore = 0.0;
    282
    283 /* in case the cutoff score is below the reliable score we set it to zero since it is seen to be unreliable */
    284 if( cutoffscore < reliablescore )
    285 cutoffscore = 0.0;
    286
    287 /* compute weighted score for the candidate */
    288 return (conflictweight * conflictscore + inferenceweight * cutoffscore);
    289}
    290
    291/** return an aggregated score for the given variable using the conflict score and cutoff score */
    292static
    294 SCIP_VAR* var, /**< problem variable */
    295 SCIP_Real conflictweight, /**< weight in score calculations for conflict score */
    296 SCIP_Real cutoffweight, /**< weight in score calculations for cutoff score */
    297 SCIP_Real reliablescore, /**< score which is seen to be reliable for a branching decision */
    298 SCIP_Real* branchpoint, /**< pointer to store the branching point */
    299 SCIP_BRANCHDIR* branchdir /**< pointer to store the branching direction relative to the branching point */
    300 )
    301{
    302 SCIP_VALUEHISTORY* valuehistory;
    303 SCIP_Real bestscore;
    304
    305 (*branchpoint) = SCIP_UNKNOWN;
    306 (*branchdir) = SCIP_BRANCHDIR_UPWARDS;
    307
    308 valuehistory = SCIPvarGetValuehistory(var);
    309 bestscore = 0.0;
    310
    311 if( valuehistory != NULL )
    312 {
    313 SCIP_HISTORY** histories;
    314 SCIP_Real* values;
    315 int nvalues;
    316 int v;
    317
    318 histories = SCIPvaluehistoryGetHistories(valuehistory);
    319 values = SCIPvaluehistoryGetValues(valuehistory);
    320 nvalues = SCIPvaluehistoryGetNValues(valuehistory);
    321
    322 for( v = 0; v < nvalues; ++v )
    323 {
    324 SCIP_Real value;
    325
    326 value = values[v];
    327
    328 /* skip all domain values which are smaller or equal to the lower bound */
    329 if( value <= SCIPvarGetLbLocal(var) )
    330 continue;
    331
    332 /* skip all domain values which are larger or equal to the upper bound */
    333 if( value >= SCIPvarGetUbLocal(var) )
    334 break;
    335
    336 /* check var <= value */
    337 checkValueScore(value, histories[v], SCIP_BRANCHDIR_DOWNWARDS, conflictweight, cutoffweight, reliablescore, &bestscore, branchpoint, branchdir);
    338
    339 /* check var >= value */
    340 checkValueScore(value, histories[v], SCIP_BRANCHDIR_UPWARDS, conflictweight, cutoffweight, reliablescore, &bestscore, branchpoint, branchdir);
    341 }
    342 }
    343
    344 return bestscore;
    345}
    346
    347static
    349 SCIP* scip, /**< SCIP data structure */
    350 SCIP_VAR** cands, /**< candidate array */
    351 SCIP_Real* candsols, /**< array of candidate solution values, or NULL */
    352 int ncands, /**< number of candidates */
    353 SCIP_Real conflictweight, /**< weight in score calculations for conflict score */
    354 SCIP_Real inferenceweight, /**< weight in score calculations for inference score */
    355 SCIP_Real cutoffweight, /**< weight in score calculations for cutoff score */
    356 SCIP_Real reliablescore, /**< score which is seen to be reliable for a branching decision */
    357 SCIP_VAR** bestcands, /**< buffer array to return selected candidates */
    358 int* nbestcands /**< pointer to return number of selected candidates */
    359 )
    360{
    361 SCIP_VAR* bestaggrcand;
    362 SCIP_Real bestval;
    363 SCIP_Real bestaggrscore;
    364 int c;
    365
    366 bestaggrcand = cands[0];
    367 assert(cands[0] != NULL);
    368
    369 bestval = candsols[0];
    370 bestcands[0] = cands[0];
    371 *nbestcands = 1;
    372
    373 /* get aggregated score for the first candidate */
    374 bestaggrscore = getAggrScore(scip, cands[0], conflictweight, inferenceweight, cutoffweight, reliablescore);
    375
    376 for( c = 1; c < ncands; ++c )
    377 {
    378 SCIP_VAR* cand;
    379 SCIP_Real val;
    380 SCIP_Real aggrscore;
    381
    382 cand = cands[c];
    383 assert(cand != NULL);
    384
    385 val = candsols[c];
    386
    387 /* get score for the candidate */
    388 aggrscore = getAggrScore(scip, cand, conflictweight, inferenceweight, cutoffweight, reliablescore);
    389
    390 /*lint -e777*/
    391 SCIPdebugMsg(scip, " -> cand <%s>: prio=%d, solval=%g, score=%g\n", SCIPvarGetName(cand), SCIPvarGetBranchPriority(cand),
    392 val == SCIP_UNKNOWN ? SCIPgetVarSol(scip, cand) : val, aggrscore);
    393
    394 /* evaluate the candidate against the currently best candidate w.r.t. aggregated score */
    395 evaluateAggrCand(scip, cand, aggrscore, val, &bestaggrcand, &bestaggrscore, &bestval, bestcands, nbestcands);
    396 }
    397} /*lint --e{438}*/
    398
    399
    400/** selects a variable out of the given candidate array and performs the branching */
    401static
    403 SCIP* scip, /**< SCIP data structure */
    404 SCIP_VAR** cands, /**< candidate array */
    405 SCIP_Real* candsols, /**< array of candidate solution values, or NULL */
    406 int ncands, /**< number of candidates */
    407 SCIP_Real conflictweight, /**< weight in score calculations for conflict score */
    408 SCIP_Real inferenceweight, /**< weight in score calculations for inference score */
    409 SCIP_Real cutoffweight, /**< weight in score calculations for cutoff score */
    410 SCIP_Real reliablescore, /**< score which is seen to be reliable for a branching decision */
    411 SCIP_Bool useweightedsum, /**< should a weighted sum of inference, conflict and cutoff weights be used? */
    412 SCIP_RESULT* result, /**< buffer to store result (branched, reduced domain, ...) */
    413 int conflictprio, /**< priority value for using conflict weights in lex. order */
    414 int cutoffprio /**< priority value for using conflict weights in lex. order */
    415 )
    416{
    417 SCIP_VAR* bestaggrcand;
    418 SCIP_Real bestval;
    419 SCIP_NODE* downchild;
    420 SCIP_NODE* eqchild;
    421 SCIP_NODE* upchild;
    422 SCIP_VAR** bestcands;
    423 int nbestcands;
    424 int c;
    425
    426 assert(ncands > 0);
    427 assert(result != NULL);
    428
    429 *result = SCIP_DIDNOTFIND;
    430
    431 /* check if conflict score, inferences, and cutoff score should be used in combination; otherwise just use
    432 * inference */
    433 if( useweightedsum == FALSE )
    434 {
    435 conflictprio = 0;
    436 cutoffprio = 0;
    437 conflictweight = 0.0;
    438 inferenceweight = 1.0;
    439 cutoffweight = 0.0;
    440 }
    441
    442 /* allocate temporary memory */
    443 SCIP_CALL( SCIPallocClearBufferArray(scip, &bestcands, ncands) );
    444 nbestcands = 0;
    445
    446 if( conflictprio > cutoffprio )
    447 {
    448 /* select the best candidates w.r.t. the first criterion */
    449 selectBestCands(scip, cands, candsols, ncands, conflictweight, 0.0, 0.0, reliablescore,
    450 bestcands, &nbestcands);
    451
    452 /* select the best candidates w.r.t. the second criterion; we use bestcands and nbestcands as input and
    453 * output, so the method must make sure to overwrite the last argument only at the very end */
    454 if( nbestcands > 1 )
    455 {
    456 selectBestCands(scip, bestcands, candsols, nbestcands, 0.0, inferenceweight, cutoffweight, reliablescore,
    457 bestcands, &nbestcands);
    458 }
    459 }
    460 else if( conflictprio == cutoffprio )
    461 {
    462 /* select the best candidates w.r.t. weighted sum of both criteria */
    463 selectBestCands(scip, cands, candsols, ncands, conflictweight, inferenceweight, cutoffweight, reliablescore,
    464 bestcands, &nbestcands);
    465 }
    466 else
    467 {
    468 assert(conflictprio < cutoffprio);
    469
    470 /* select the best candidates w.r.t. the first criterion */
    471 selectBestCands(scip, cands, candsols, ncands, 0.0, inferenceweight, cutoffweight, reliablescore,
    472 bestcands, &nbestcands);
    473
    474 /* select the best candidates w.r.t. the second criterion; we use bestcands and nbestcands as input and
    475 * output, so the method must make sure to overwrite the last argument only at the very end */
    476 if( nbestcands > 1 )
    477 {
    478 /* select the best candidates w.r.t. the first criterion */
    479 selectBestCands(scip, bestcands, candsols, nbestcands, conflictweight, 0.0, 0.0, reliablescore,
    480 bestcands, &nbestcands);
    481 }
    482 }
    483
    484 assert(nbestcands == 0 || bestcands[0] != NULL);
    485
    486 /* final tie breaking */
    487 if( nbestcands > 1 )
    488 {
    489 tiebreakAggrCand(bestcands, nbestcands);
    490 nbestcands = 1;
    491 }
    492
    493 assert(nbestcands == 1);
    494
    495 bestaggrcand = bestcands[0];
    496 bestval = -SCIP_INVALID;
    497
    498 /* loop over cands, find bestcands[0], and store corresponding candsols value in bestval */
    499 for( c = 0; c < ncands; ++c )
    500 {
    501 if( bestaggrcand == cands[c] )
    502 {
    503 bestval = candsols[c];
    504 break;
    505 }
    506 }
    507
    508 assert(bestval != -SCIP_INVALID);
    509
    510 /* free temporary memory */
    511 SCIPfreeBufferArray(scip, &bestcands);
    512
    513 assert(bestaggrcand != NULL);
    514
    515 SCIPdebugMsg(scip, " -> %d candidates, selected variable <%s>[%g,%g] (prio=%d, solval=%.12f, conflict=%g cutoff=%g, inference=%g)\n",
    516 ncands, SCIPvarGetName(bestaggrcand), SCIPvarGetLbLocal (bestaggrcand), SCIPvarGetUbLocal(bestaggrcand), SCIPvarGetBranchPriority(bestaggrcand),
    517 bestval == SCIP_UNKNOWN ? SCIPgetVarSol(scip, bestaggrcand) : bestval, /*lint !e777*/
    518 SCIPgetVarConflictScore(scip, bestaggrcand), SCIPgetVarAvgInferenceCutoffScore(scip, bestaggrcand, cutoffweight),
    519 SCIPgetVarAvgInferenceScore(scip, bestaggrcand));
    520
    521 assert(candsols != NULL);
    522 /* perform the branching */
    523 SCIP_CALL( SCIPbranchVarVal(scip, bestaggrcand, SCIPgetBranchingPoint(scip, bestaggrcand, bestval), &downchild, &eqchild, &upchild) );
    524
    525 if( downchild != NULL || eqchild != NULL || upchild != NULL )
    526 {
    527 *result = SCIP_BRANCHED;
    528 }
    529 else
    530 {
    531 /* if there are no children, then variable should have been fixed by SCIPbranchVar(Val) */
    532 assert(SCIPisEQ(scip, SCIPvarGetLbLocal(bestaggrcand), SCIPvarGetUbLocal(bestaggrcand)));
    533 *result = SCIP_REDUCEDDOM;
    534 }
    535
    536 return SCIP_OKAY;
    537}
    538
    539
    540/** selects a variable out of the given candidate array and performs the branching */
    541static
    543 SCIP* scip, /**< SCIP data structure */
    544 SCIP_VAR** cands, /**< candidate array */
    545 int ncands, /**< number of candidates */
    546 SCIP_Real conflictweight, /**< weight in score calculations for conflict score */
    547 SCIP_Real inferenceweight, /**< weight in score calculations for inference score */
    548 SCIP_Real cutoffweight, /**< weight in score calculations for cutoff score */
    549 SCIP_Real reliablescore, /**< score which is seen to be reliable for a branching decision */
    550 SCIP_Bool useweightedsum, /**< should a weighted sum of inference, conflict and cutoff weights be used? */
    551 SCIP_RESULT* result /**< buffer to store result (branched, reduced domain, ...) */
    552 )
    553{
    554 SCIP_VAR* bestaggrcand;
    555 SCIP_VAR* bestvaluecand;
    556 SCIP_Real bestval;
    557 SCIP_Real bestaggrscore;
    558 SCIP_Real bestvaluescore;
    559 SCIP_Real bestbranchpoint;
    560 SCIP_BRANCHDIR bestbranchdir;
    561 SCIP_NODE* downchild;
    562 SCIP_NODE* eqchild;
    563 SCIP_NODE* upchild;
    564 SCIP_VAR** bestcands;
    565 int nbestcands;
    566
    567 bestbranchpoint = SCIP_UNKNOWN;
    568 bestbranchdir = SCIP_BRANCHDIR_DOWNWARDS;
    569 bestvaluecand = NULL;
    570
    571 assert(ncands > 0);
    572 assert(result != NULL);
    573
    574 *result = SCIP_DIDNOTFIND;
    575
    576 /* allocate temporary memory */
    577 SCIP_CALL( SCIPallocBufferArray(scip, &bestcands, ncands) );
    578 nbestcands = 0;
    579
    580 /* check if the weighted sum between the average inferences and conflict score should be used */
    581 if( useweightedsum )
    582 {
    583 int c;
    584
    585 bestaggrcand = cands[0];
    586 bestvaluecand = cands[0];
    587 assert(cands[0] != NULL);
    588
    589 bestval = SCIP_UNKNOWN;
    590
    591 /* get domain value score for the first candidate */
    592 bestvaluescore = getValueScore(cands[0], conflictweight, cutoffweight, reliablescore, &bestbranchpoint, &bestbranchdir);
    593 SCIPdebugMsg(scip, "current best value candidate <%s>[%g,%g] %s <%g> (value %g)\n",
    594 SCIPvarGetName(bestvaluecand), SCIPvarGetLbLocal(bestvaluecand), SCIPvarGetUbLocal(bestvaluecand),
    595 bestbranchdir == SCIP_BRANCHDIR_DOWNWARDS ? "<=" : ">=", bestbranchpoint, bestvaluescore);
    596
    597 /* get aggregated score for the first candidate */
    598 bestaggrscore = getAggrScore(scip, cands[0], conflictweight, inferenceweight, cutoffweight, reliablescore);
    599
    600 for( c = 1; c < ncands; ++c )
    601 {
    602 SCIP_VAR* cand;
    603 SCIP_Real val;
    604 SCIP_Real aggrscore;
    605 SCIP_Real branchpoint;
    606 SCIP_BRANCHDIR branchdir;
    607 SCIP_Real valuescore;
    608
    609 cand = cands[c];
    610 assert(cand != NULL);
    611
    612 val = SCIP_UNKNOWN;
    613
    614 /* get domain value score for the candidate */
    615 valuescore = getValueScore(cand, conflictweight, cutoffweight, reliablescore, &branchpoint, &branchdir);
    616
    617 /* evaluate the candidate against the currently best candidate w.r.t. domain value score */
    618 evaluateValueCand(cand, valuescore, branchpoint, branchdir, &bestvaluecand, &bestvaluescore, &bestbranchpoint, &bestbranchdir);
    619
    620 SCIPdebugMsg(scip, "current best value candidate <%s>[%g,%g] %s <%g> (value %g)\n",
    621 SCIPvarGetName(bestvaluecand), SCIPvarGetLbLocal(bestvaluecand), SCIPvarGetUbLocal(bestvaluecand),
    622 bestbranchdir == SCIP_BRANCHDIR_DOWNWARDS ? "<=" : ">=", bestbranchpoint, bestvaluescore);
    623
    624 /* get aggregated score for the candidate */
    625 aggrscore = getAggrScore(scip, cand, conflictweight, inferenceweight, cutoffweight, reliablescore);
    626
    627 /*lint -e777*/
    628 SCIPdebugMsg(scip, " -> cand <%s>: prio=%d, solval=%g, score=%g\n", SCIPvarGetName(cand), SCIPvarGetBranchPriority(cand),
    629 val == SCIP_UNKNOWN ? SCIPgetVarSol(scip, cand) : val, aggrscore);
    630
    631 /* evaluate the candidate against the currently best candidate w.r.t. aggregated score */
    632 evaluateAggrCand(scip, cand, aggrscore, val, &bestaggrcand, &bestaggrscore, &bestval, bestcands, &nbestcands);
    633 }
    634 }
    635 else
    636 {
    637 int c;
    638
    639 bestaggrcand = cands[0];
    640 assert(cands[0] != NULL);
    641
    642 bestval = SCIP_UNKNOWN;
    643
    644 bestaggrscore = SCIPgetVarAvgInferenceScore(scip, cands[0]);
    645
    646 /* search for variable with best score w.r.t. average inferences per branching */
    647 for( c = 1; c < ncands; ++c )
    648 {
    649 SCIP_VAR* cand;
    650 SCIP_Real val;
    651 SCIP_Real aggrscore;
    652
    653 cand = cands[c];
    654 assert(cand != NULL);
    655
    656 val = SCIP_UNKNOWN;
    657
    658 aggrscore = SCIPgetVarAvgInferenceScore(scip, cand);
    659
    660 /* in case the average inferences score is below the reliable score we set it to zero since it is seen to be
    661 * unreliable
    662 */
    663 if( aggrscore < reliablescore )
    664 aggrscore = 0.0;
    665
    666 SCIPdebugMsg(scip, " -> cand <%s>: prio=%d, solval=%g, score=%g\n", SCIPvarGetName(cand), SCIPvarGetBranchPriority(cand),
    667 val == SCIP_UNKNOWN ? SCIPgetVarSol(scip, cand) : val, aggrscore); /*lint !e777*/
    668
    669 /* evaluate the candidate against the currently best candidate */
    670 evaluateAggrCand(scip, cand, aggrscore, val, &bestaggrcand, &bestaggrscore, &bestval, bestcands, &nbestcands);
    671 }
    672 }
    673
    674 /* free temporary memory */
    675 SCIPfreeBufferArray(scip, &bestcands);
    676
    677 assert(bestaggrcand != NULL);
    678
    679 SCIPdebugMsg(scip, " -> %d candidates, selected variable <%s>[%g,%g] (prio=%d, solval=%.12f, score=%g, conflict=%g cutoff=%g, inference=%g)\n",
    680 ncands, SCIPvarGetName(bestaggrcand), SCIPvarGetLbLocal (bestaggrcand), SCIPvarGetUbLocal(bestaggrcand), SCIPvarGetBranchPriority(bestaggrcand),
    681 bestval == SCIP_UNKNOWN ? SCIPgetVarSol(scip, bestaggrcand) : bestval, bestaggrscore, /*lint !e777*/
    682 SCIPgetVarConflictScore(scip, bestaggrcand), SCIPgetVarAvgInferenceCutoffScore(scip, bestaggrcand, cutoffweight),
    683 SCIPgetVarAvgInferenceScore(scip, bestaggrcand));
    684
    685 if( bestbranchpoint == SCIP_UNKNOWN ) /*lint !e777*/
    686 {
    687 SCIP_CALL( SCIPbranchVar(scip, bestaggrcand, &downchild, &eqchild, &upchild) );
    688 }
    689 else
    690 {
    691 /* perform the branching */
    692 SCIP_Real estimate;
    693 SCIP_Real downprio;
    694 SCIP_Real upprio;
    695 SCIP_Real downub;
    696 SCIP_Real uplb;
    697
    698 assert(bestvaluecand != NULL);
    699
    700 downprio = 0.0;
    701 upprio = 0.0;
    702
    703 if( bestbranchdir == SCIP_BRANCHDIR_DOWNWARDS )
    704 {
    705 downprio = 1.0;
    706 downub = bestbranchpoint;
    707 uplb = bestbranchpoint + 1.0;
    708 }
    709 else
    710 {
    711 upprio = 1.0;
    712 downub = bestbranchpoint - 1.0;
    713 uplb = bestbranchpoint;
    714 }
    715
    716 /* calculate the child estimate */
    717 estimate = SCIPcalcChildEstimate(scip, bestvaluecand, downub);
    718
    719 /* create down child */
    720 SCIP_CALL( SCIPcreateChild(scip, &downchild, downprio, estimate) );
    721
    722 /* change upper bound in down child */
    723 SCIP_CALL( SCIPchgVarUbNode(scip, downchild, bestvaluecand, downub) );
    724
    725 /* calculate the child estimate */
    726 estimate = SCIPcalcChildEstimate(scip, bestvaluecand, uplb);
    727
    728 /* create up child */
    729 SCIP_CALL( SCIPcreateChild(scip, &upchild, upprio, estimate) );
    730
    731 /* change lower bound in up child */
    732 SCIP_CALL( SCIPchgVarLbNode(scip, upchild, bestvaluecand, uplb) );
    733
    734 SCIPdebugMsg(scip, "branch on variable <%s> and value <%g>\n", SCIPvarGetName(bestvaluecand), bestbranchpoint);
    735
    736 eqchild = NULL;
    737 }
    738 if( downchild != NULL || eqchild != NULL || upchild != NULL )
    739 {
    740 *result = SCIP_BRANCHED;
    741 }
    742 else
    743 {
    744 /* if there are no children, then variable should have been fixed by SCIPbranchVar(Val) */
    745 assert(SCIPisEQ(scip, SCIPvarGetLbLocal(bestaggrcand), SCIPvarGetUbLocal(bestaggrcand)));
    746 *result = SCIP_REDUCEDDOM;
    747 }
    748
    749 return SCIP_OKAY;
    750}
    751
    752/*
    753 * Callback methods
    754 */
    755
    756/** copy method for branchrule plugins (called when SCIP copies plugins) */
    757static
    758SCIP_DECL_BRANCHCOPY(branchCopyInference)
    759{ /*lint --e{715}*/
    760 assert(scip != NULL);
    761 assert(branchrule != NULL);
    762
    764
    765 /* call inclusion method of branchrule */
    767
    768 return SCIP_OKAY;
    769}
    770
    771/** destructor of branching rule to free user data (called when SCIP is exiting) */
    772static
    773SCIP_DECL_BRANCHFREE(branchFreeInference)
    774{ /*lint --e{715}*/
    775 SCIP_BRANCHRULEDATA* branchruledata;
    776
    777 /* free branching rule data */
    778 branchruledata = SCIPbranchruleGetData(branchrule);
    779 SCIPfreeBlockMemory(scip, &branchruledata);
    780 SCIPbranchruleSetData(branchrule, NULL);
    781
    782 return SCIP_OKAY;
    783}
    784
    785/** branching execution method for fractional LP solutions */
    786static
    787SCIP_DECL_BRANCHEXECLP(branchExeclpInference)
    788{ /*lint --e{715}*/
    789 SCIP_BRANCHRULEDATA* branchruledata;
    790 SCIP_VAR** cands;
    791 int ncands;
    792
    793 SCIPdebugMsg(scip, "Execlp method of inference branching\n");
    794
    795 /* get branching rule data */
    796 branchruledata = SCIPbranchruleGetData(branchrule);
    797 assert(branchruledata != NULL);
    798
    799 if( branchruledata->fractionals )
    800 {
    801 /* get LP candidates (fractional integer variables) */
    802 SCIP_CALL( SCIPgetLPBranchCands(scip, &cands, NULL, NULL, NULL, &ncands, NULL) );
    803 }
    804 else
    805 {
    806 /* get pseudo candidates (non-fixed integer variables) */
    807 SCIP_CALL( SCIPgetPseudoBranchCands(scip, &cands, NULL, &ncands) );
    808 }
    809
    810 /* perform the branching */
    811 SCIP_CALL( performBranchingNoSol(scip, cands, ncands, branchruledata->conflictweight,
    812 branchruledata->inferenceweight, branchruledata->cutoffweight, branchruledata->reliablescore,
    813 branchruledata->useweightedsum, result) );
    814
    815 return SCIP_OKAY;
    816}
    817
    818
    819/** branching execution method for external candidates */
    820static
    821SCIP_DECL_BRANCHEXECEXT(branchExecextInference)
    822{ /*lint --e{715}*/
    823 SCIP_BRANCHRULEDATA* branchruledata;
    824 SCIP_VAR** cands;
    825 SCIP_Real* candsols;
    826 int ncands;
    827
    828 SCIPdebugMsg(scip, "Execext method of inference branching\n");
    829
    830 /* get branching rule data */
    831 branchruledata = SCIPbranchruleGetData(branchrule);
    832 assert(branchruledata != NULL);
    833
    834 /* get branching candidates */
    835 SCIP_CALL( SCIPgetExternBranchCands(scip, &cands, &candsols, NULL, &ncands, NULL, NULL, NULL, NULL) );
    836 assert(ncands > 0);
    837
    838 /* perform the branching */
    839 SCIP_CALL( performBranchingSol(scip, cands, candsols, ncands, branchruledata->conflictweight,
    840 branchruledata->inferenceweight, branchruledata->cutoffweight, branchruledata->reliablescore,
    841 branchruledata->useweightedsum, result, branchruledata->conflictprio, branchruledata->cutoffprio) );
    842
    843 return SCIP_OKAY;
    844}
    845
    846/** branching execution method for not completely fixed pseudo solutions */
    847static
    848SCIP_DECL_BRANCHEXECPS(branchExecpsInference)
    849{ /*lint --e{715}*/
    850 SCIP_BRANCHRULEDATA* branchruledata;
    851 SCIP_VAR** cands;
    852 int ncands;
    853
    854 SCIPdebugMsg(scip, "Execps method of inference branching\n");
    855
    856 /* get branching rule data */
    857 branchruledata = SCIPbranchruleGetData(branchrule);
    858 assert(branchruledata != NULL);
    859
    860 /* get pseudo candidates (non-fixed integer variables) */
    861 SCIP_CALL( SCIPgetPseudoBranchCands(scip, &cands, NULL, &ncands) );
    862
    863 /* perform the branching */
    864 SCIP_CALL( performBranchingNoSol(scip, cands, ncands, branchruledata->conflictweight,
    865 branchruledata->inferenceweight, branchruledata->cutoffweight, branchruledata->reliablescore,
    866 branchruledata->useweightedsum, result) );
    867
    868 return SCIP_OKAY;
    869}
    870
    871
    872/*
    873 * branching specific interface methods
    874 */
    875
    876/** creates the inference history branching rule and includes it in SCIP */
    878 SCIP* scip /**< SCIP data structure */
    879 )
    880{
    881 SCIP_BRANCHRULEDATA* branchruledata;
    882 SCIP_BRANCHRULE* branchrule;
    883
    884 /* create inference branching rule data */
    885 SCIP_CALL( SCIPallocBlockMemory(scip, &branchruledata) );
    886
    887 /* include branching rule */
    890
    891 assert(branchrule != NULL);
    892
    893 /* set non-fundamental callbacks via specific setter functions*/
    894 SCIP_CALL( SCIPsetBranchruleCopy(scip, branchrule, branchCopyInference) );
    895 SCIP_CALL( SCIPsetBranchruleFree(scip, branchrule, branchFreeInference) );
    896 SCIP_CALL( SCIPsetBranchruleExecLp(scip, branchrule, branchExeclpInference) );
    897 SCIP_CALL( SCIPsetBranchruleExecExt(scip, branchrule, branchExecextInference) );
    898 SCIP_CALL( SCIPsetBranchruleExecPs(scip, branchrule, branchExecpsInference) );
    899
    900 /* inference branching rule parameters */
    902 "branching/inference/conflictweight",
    903 "weight in score calculations for conflict score",
    904 &branchruledata->conflictweight, TRUE, DEFAULT_CONFLICTWEIGHT, 0.0, SCIP_REAL_MAX, NULL, NULL) );
    906 "branching/inference/inferenceweight",
    907 "weight in score calculations for inference score",
    908 &branchruledata->inferenceweight, TRUE, DEFAULT_INFERENCEWEIGHT, SCIP_REAL_MIN, SCIP_REAL_MAX, NULL, NULL) );
    910 "branching/inference/cutoffweight",
    911 "weight in score calculations for cutoff score",
    912 &branchruledata->cutoffweight, TRUE, DEFAULT_CUTOFFWEIGHT, 0.0, SCIP_REAL_MAX, NULL, NULL) );
    914 "branching/inference/fractionals",
    915 "should branching on LP solution be restricted to the fractional variables?",
    916 &branchruledata->fractionals, TRUE, DEFAULT_FRACTIONALS, NULL, NULL) );
    918 "branching/inference/useweightedsum",
    919 "should a weighted sum of inference, conflict and cutoff weights be used?",
    920 &branchruledata->useweightedsum, FALSE, DEFAULT_USEWEIGHTEDSUM, NULL, NULL) );
    921 /* inference branching rule parameters */
    923 "branching/inference/reliablescore",
    924 "weight in score calculations for conflict score",
    925 &branchruledata->reliablescore, TRUE, DEFAULT_RELIABLESCORE, 0.0, SCIP_REAL_MAX, NULL, NULL) );
    926 /* parameters for lexicographical ordering */
    928 "branching/inference/conflictprio",
    929 "priority value for using conflict weights in lex. order",
    930 &branchruledata->conflictprio, FALSE, DEFAULT_CONFLICTPRIO, 0, INT_MAX, NULL, NULL) );
    932 "branching/inference/cutoffprio",
    933 "priority value for using cutoff weights in lex. order",
    934 &branchruledata->cutoffprio, FALSE, DEFAULT_CUTOFFPRIO, 0, INT_MAX, NULL, NULL) );
    935
    936 return SCIP_OKAY;
    937}
    #define BRANCHRULE_DESC
    static void evaluateAggrCand(SCIP *scip, SCIP_VAR *cand, SCIP_Real score, SCIP_Real val, SCIP_VAR **bestcand, SCIP_Real *bestscore, SCIP_Real *bestval, SCIP_VAR **bestcands, int *nbestcands)
    static SCIP_DECL_BRANCHCOPY(branchCopyInference)
    static SCIP_DECL_BRANCHEXECPS(branchExecpsInference)
    static void tiebreakAggrCand(SCIP_VAR **bestcands, int nbestcands)
    static SCIP_RETCODE performBranchingSol(SCIP *scip, SCIP_VAR **cands, SCIP_Real *candsols, int ncands, SCIP_Real conflictweight, SCIP_Real inferenceweight, SCIP_Real cutoffweight, SCIP_Real reliablescore, SCIP_Bool useweightedsum, SCIP_RESULT *result, int conflictprio, int cutoffprio)
    #define BRANCHRULE_PRIORITY
    static void evaluateValueCand(SCIP_VAR *cand, SCIP_Real score, SCIP_Real branchpoint, SCIP_BRANCHDIR branchdir, SCIP_VAR **bestcand, SCIP_Real *bestscore, SCIP_Real *bestbranchpoint, SCIP_BRANCHDIR *bestbranchdir)
    #define DEFAULT_CONFLICTPRIO
    static void selectBestCands(SCIP *scip, SCIP_VAR **cands, SCIP_Real *candsols, int ncands, SCIP_Real conflictweight, SCIP_Real inferenceweight, SCIP_Real cutoffweight, SCIP_Real reliablescore, SCIP_VAR **bestcands, int *nbestcands)
    #define DEFAULT_INFERENCEWEIGHT
    #define BRANCHRULE_NAME
    static SCIP_Real getAggrScore(SCIP *scip, SCIP_VAR *var, SCIP_Real conflictweight, SCIP_Real inferenceweight, SCIP_Real cutoffweight, SCIP_Real reliablescore)
    #define DEFAULT_USEWEIGHTEDSUM
    #define DEFAULT_CONFLICTWEIGHT
    static void checkValueScore(SCIP_Real value, SCIP_HISTORY *history, SCIP_BRANCHDIR dir, SCIP_Real conflictweight, SCIP_Real cutoffweight, SCIP_Real reliablescore, SCIP_Real *bestscore, SCIP_Real *branchpoint, SCIP_BRANCHDIR *branchdir)
    #define DEFAULT_FRACTIONALS
    #define DEFAULT_CUTOFFWEIGHT
    static SCIP_Real getValueScore(SCIP_VAR *var, SCIP_Real conflictweight, SCIP_Real cutoffweight, SCIP_Real reliablescore, SCIP_Real *branchpoint, SCIP_BRANCHDIR *branchdir)
    static SCIP_DECL_BRANCHEXECLP(branchExeclpInference)
    #define DEFAULT_RELIABLESCORE
    static SCIP_DECL_BRANCHFREE(branchFreeInference)
    static SCIP_RETCODE performBranchingNoSol(SCIP *scip, SCIP_VAR **cands, int ncands, SCIP_Real conflictweight, SCIP_Real inferenceweight, SCIP_Real cutoffweight, SCIP_Real reliablescore, SCIP_Bool useweightedsum, SCIP_RESULT *result)
    static SCIP_DECL_BRANCHEXECEXT(branchExecextInference)
    #define DEFAULT_CUTOFFPRIO
    #define BRANCHRULE_MAXDEPTH
    #define BRANCHRULE_MAXBOUNDDIST
    inference history branching rule
    #define NULL
    Definition: def.h:257
    #define SCIP_REAL_MAX
    Definition: def.h:167
    #define SCIP_INVALID
    Definition: def.h:187
    #define SCIP_Bool
    Definition: def.h:100
    #define SCIP_STRINGEQ(name, reference, retcode)
    Definition: def.h:454
    #define SCIP_Real
    Definition: def.h:165
    #define SCIP_UNKNOWN
    Definition: def.h:188
    #define TRUE
    Definition: def.h:102
    #define FALSE
    Definition: def.h:103
    #define SCIP_REAL_MIN
    Definition: def.h:168
    #define REALABS(x)
    Definition: def.h:191
    #define SCIP_CALL(x)
    Definition: def.h:364
    SCIP_RETCODE SCIPincludeBranchruleInference(SCIP *scip)
    #define SCIPdebugMsg
    Definition: scip_message.h:78
    SCIP_RETCODE SCIPaddIntParam(SCIP *scip, const char *name, const char *desc, int *valueptr, SCIP_Bool isadvanced, int defaultvalue, int minvalue, int maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
    Definition: scip_param.c:83
    SCIP_RETCODE SCIPaddRealParam(SCIP *scip, const char *name, const char *desc, SCIP_Real *valueptr, SCIP_Bool isadvanced, SCIP_Real defaultvalue, SCIP_Real minvalue, SCIP_Real maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
    Definition: scip_param.c:139
    SCIP_RETCODE SCIPaddBoolParam(SCIP *scip, const char *name, const char *desc, SCIP_Bool *valueptr, SCIP_Bool isadvanced, SCIP_Bool defaultvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
    Definition: scip_param.c:57
    SCIP_RETCODE SCIPsetBranchruleExecExt(SCIP *scip, SCIP_BRANCHRULE *branchrule, SCIP_DECL_BRANCHEXECEXT((*branchexecext)))
    Definition: scip_branch.c:272
    SCIP_RETCODE SCIPsetBranchruleExecLp(SCIP *scip, SCIP_BRANCHRULE *branchrule, SCIP_DECL_BRANCHEXECLP((*branchexeclp)))
    Definition: scip_branch.c:256
    SCIP_RETCODE SCIPsetBranchruleCopy(SCIP *scip, SCIP_BRANCHRULE *branchrule, SCIP_DECL_BRANCHCOPY((*branchcopy)))
    Definition: scip_branch.c:160
    SCIP_RETCODE SCIPincludeBranchruleBasic(SCIP *scip, SCIP_BRANCHRULE **branchruleptr, const char *name, const char *desc, int priority, int maxdepth, SCIP_Real maxbounddist, SCIP_BRANCHRULEDATA *branchruledata)
    Definition: scip_branch.c:123
    SCIP_RETCODE SCIPsetBranchruleExecPs(SCIP *scip, SCIP_BRANCHRULE *branchrule, SCIP_DECL_BRANCHEXECPS((*branchexecps)))
    Definition: scip_branch.c:288
    const char * SCIPbranchruleGetName(SCIP_BRANCHRULE *branchrule)
    Definition: branch.c:2018
    SCIP_BRANCHRULEDATA * SCIPbranchruleGetData(SCIP_BRANCHRULE *branchrule)
    Definition: branch.c:1886
    SCIP_RETCODE SCIPsetBranchruleFree(SCIP *scip, SCIP_BRANCHRULE *branchrule, SCIP_DECL_BRANCHFREE((*branchfree)))
    Definition: scip_branch.c:176
    void SCIPbranchruleSetData(SCIP_BRANCHRULE *branchrule, SCIP_BRANCHRULEDATA *branchruledata)
    Definition: branch.c:1896
    SCIP_RETCODE SCIPgetExternBranchCands(SCIP *scip, SCIP_VAR ***externcands, SCIP_Real **externcandssol, SCIP_Real **externcandsscore, int *nexterncands, int *nprioexterncands, int *nprioexternbins, int *nprioexternints, int *nprioexternimpls)
    Definition: scip_branch.c:519
    SCIP_Real SCIPgetBranchingPoint(SCIP *scip, SCIP_VAR *var, SCIP_Real suggestion)
    Definition: scip_branch.c:905
    SCIP_Real SCIPcalcChildEstimate(SCIP *scip, SCIP_VAR *var, SCIP_Real targetvalue)
    Definition: scip_branch.c:955
    SCIP_RETCODE SCIPbranchVarVal(SCIP *scip, SCIP_VAR *var, SCIP_Real val, SCIP_NODE **downchild, SCIP_NODE **eqchild, SCIP_NODE **upchild)
    Definition: scip_branch.c:1134
    SCIP_RETCODE SCIPgetLPBranchCands(SCIP *scip, SCIP_VAR ***lpcands, SCIP_Real **lpcandssol, SCIP_Real **lpcandsfrac, int *nlpcands, int *npriolpcands, int *nfracimplvars)
    Definition: scip_branch.c:402
    SCIP_RETCODE SCIPbranchVar(SCIP *scip, SCIP_VAR *var, SCIP_NODE **downchild, SCIP_NODE **eqchild, SCIP_NODE **upchild)
    Definition: scip_branch.c:1058
    SCIP_RETCODE SCIPgetPseudoBranchCands(SCIP *scip, SCIP_VAR ***pseudocands, int *npseudocands, int *npriopseudocands)
    Definition: scip_branch.c:741
    SCIP_RETCODE SCIPcreateChild(SCIP *scip, SCIP_NODE **node, SCIP_Real nodeselprio, SCIP_Real estimate)
    Definition: scip_branch.c:1025
    #define SCIPallocClearBufferArray(scip, ptr, num)
    Definition: scip_mem.h:126
    #define SCIPallocBufferArray(scip, ptr, num)
    Definition: scip_mem.h:124
    #define SCIPfreeBufferArray(scip, ptr)
    Definition: scip_mem.h:136
    #define SCIPfreeBlockMemory(scip, ptr)
    Definition: scip_mem.h:108
    #define SCIPallocBlockMemory(scip, ptr)
    Definition: scip_mem.h:89
    SCIP_Bool SCIPisEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Real SCIPgetVarAvgInferenceScore(SCIP *scip, SCIP_VAR *var)
    Definition: scip_var.c:11945
    SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
    Definition: var.c:24300
    SCIP_RETCODE SCIPchgVarUbNode(SCIP *scip, SCIP_NODE *node, SCIP_VAR *var, SCIP_Real newbound)
    Definition: scip_var.c:6088
    SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
    Definition: var.c:23932
    int SCIPvarGetIndex(SCIP_VAR *var)
    Definition: var.c:23684
    const char * SCIPvarGetName(SCIP_VAR *var)
    Definition: var.c:23299
    SCIP_Real SCIPgetVarSol(SCIP *scip, SCIP_VAR *var)
    Definition: scip_var.c:3051
    SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
    Definition: var.c:24266
    int SCIPvarGetBranchPriority(SCIP_VAR *var)
    Definition: var.c:24494
    SCIP_Real SCIPgetVarConflictScore(SCIP *scip, SCIP_VAR *var)
    Definition: scip_var.c:11713
    SCIP_RETCODE SCIPchgVarLbNode(SCIP *scip, SCIP_NODE *node, SCIP_VAR *var, SCIP_Real newbound)
    Definition: scip_var.c:6044
    SCIP_Real SCIPgetVarAvgInferenceCutoffScore(SCIP *scip, SCIP_VAR *var, SCIP_Real cutoffweight)
    Definition: scip_var.c:12262
    SCIP_VALUEHISTORY * SCIPvarGetValuehistory(SCIP_VAR *var)
    Definition: var.c:24778
    int SCIPvaluehistoryGetNValues(SCIP_VALUEHISTORY *valuehistory)
    Definition: history.c:445
    SCIP_HISTORY ** SCIPvaluehistoryGetHistories(SCIP_VALUEHISTORY *valuehistory)
    Definition: history.c:455
    SCIP_Real * SCIPvaluehistoryGetValues(SCIP_VALUEHISTORY *valuehistory)
    Definition: history.c:465
    SCIP_Real SCIPhistoryGetCutoffSum(SCIP_HISTORY *history, SCIP_BRANCHDIR dir)
    Definition: history.c:806
    SCIP_Real SCIPhistoryGetVSIDS(SCIP_HISTORY *history, SCIP_BRANCHDIR dir)
    Definition: history.c:664
    public methods for branching rules
    public methods for branching and inference history structure
    public methods for message output
    public methods for problem variables
    public methods for branching rule plugins and branching
    public methods for memory management
    public methods for message handling
    public methods for numerical tolerances
    public methods for SCIP parameter handling
    public methods for SCIP variables
    struct SCIP_BranchruleData SCIP_BRANCHRULEDATA
    Definition: type_branch.h:57
    @ SCIP_BRANCHDIR_DOWNWARDS
    Definition: type_history.h:43
    @ SCIP_BRANCHDIR_UPWARDS
    Definition: type_history.h:44
    enum SCIP_BranchDir SCIP_BRANCHDIR
    Definition: type_history.h:48
    @ SCIP_REDUCEDDOM
    Definition: type_result.h:51
    @ SCIP_DIDNOTFIND
    Definition: type_result.h:44
    @ SCIP_BRANCHED
    Definition: type_result.h:54
    enum SCIP_Result SCIP_RESULT
    Definition: type_result.h:61
    @ SCIP_OKAY
    Definition: type_retcode.h:42
    @ SCIP_INVALIDCALL
    Definition: type_retcode.h:51
    enum SCIP_Retcode SCIP_RETCODE
    Definition: type_retcode.h:63