Scippy

    SCIP

    Solving Constraint Integer Programs

    solve.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 solve.c
    26 * @ingroup OTHER_CFILES
    27 * @brief main solving loop and node processing
    28 * @author Tobias Achterberg
    29 * @author Timo Berthold
    30 * @author Marc Pfetsch
    31 * @author Gerald Gamrath
    32 */
    33/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
    34#include <assert.h>
    35
    36#include "lpi/lpi.h"
    37#include "scip/branch.h"
    38#include "scip/certificate.h"
    39#include "scip/clock.h"
    40#include "scip/concurrent.h"
    41#include "scip/conflict.h"
    42#include "scip/cons.h"
    43#include "scip/cutpool.h"
    44#include "scip/disp.h"
    45#include "scip/event.h"
    46#include "scip/heur.h"
    47#include "scip/interrupt.h"
    48#include "scip/lp.h"
    49#include "scip/lpexact.h"
    51#include "scip/nodesel.h"
    52#include "scip/pricer.h"
    53#include "scip/pricestore.h"
    54#include "scip/primal.h"
    55#include "scip/prob.h"
    56#include "scip/prop.h"
    57#include "scip/pub_cons.h"
    58#include "scip/pub_heur.h"
    59#include "scip/pub_message.h"
    60#include "scip/pub_misc.h"
    61#include "scip/pub_pricer.h"
    62#include "scip/pub_prop.h"
    63#include "scip/pub_relax.h"
    64#include "scip/pub_sepa.h"
    65#include "scip/pub_tree.h"
    66#include "scip/pub_var.h"
    67#include "scip/relax.h"
    68#include "scip/reopt.h"
    71#include "scip/scip_exact.h"
    72#include "scip/scip_lp.h"
    73#include "scip/scip_mem.h"
    74#include "scip/scip_prob.h"
    75#include "scip/scip_sol.h"
    77#include "scip/sepa.h"
    78#include "scip/sepastore.h"
    79#include "scip/sepastoreexact.h"
    80#include "scip/struct_scip.h"
    81#include "scip/set.h"
    82#include "scip/sol.h"
    83#include "scip/solve.h"
    84#include "scip/stat.h"
    85#include "scip/struct_cons.h"
    86#include "scip/struct_event.h"
    87#include "scip/struct_lp.h"
    88#include "scip/struct_lpexact.h"
    89#include "scip/struct_mem.h"
    90#include "scip/struct_primal.h"
    91#include "scip/struct_prob.h"
    92#include "scip/struct_set.h"
    93#include "scip/struct_stat.h"
    94#include "scip/struct_tree.h"
    95#include "scip/struct_var.h"
    96#include "scip/syncstore.h"
    97#include "scip/tree.h"
    98#include "scip/var.h"
    99#include "scip/visual.h"
    100
    101
    102#define MAXNLPERRORS 10 /**< maximal number of LP error loops in a single node */
    103#define MAXNCLOCKSKIPS 64 /**< maximum number of SCIPsolveIsStopped() calls without checking the clock */
    104#define NINITCALLS 1000L /**< minimum number of calls to SCIPsolveIsStopped() prior to dynamic clock skips */
    105#define SAFETYFACTOR 1e-2 /**< the probability that SCIP skips the clock call after the time limit has already been reached */
    106
    107/** returns whether the solving process will be / was stopped before proving optimality;
    108 * if the solving process was stopped, stores the reason as status in stat
    109 */
    111 SCIP_SET* set, /**< global SCIP settings */
    112 SCIP_STAT* stat, /**< dynamic problem statistics */
    113 SCIP_Bool checknodelimits /**< should the node limits be involved in the check? */
    114 )
    115{
    116 assert(set != NULL);
    117 assert(stat != NULL);
    118
    119 /* increase the number of calls to this method */
    120 SCIPstatIncrement(stat, set, nisstoppedcalls);
    121
    122 /* in case lowerbound >= upperbound, we do not want to terminate with SCIP_STATUS_GAPLIMIT but with the ordinary
    123 * SCIP_STATUS_OPTIMAL/INFEASIBLE/...
    124 */
    125 if( !set->exact_enable && set->stage >= SCIP_STAGE_SOLVING && SCIPsetIsLE(set, SCIPgetUpperbound(set->scip), SCIPgetLowerbound(set->scip)) )
    126 return TRUE;
    127 if( set->exact_enable && set->stage >= SCIP_STAGE_SOLVING && SCIPgetUpperbound(set->scip) <= SCIPgetLowerbound(set->scip) )
    128 return TRUE;
    129
    130 /* if some limit has been changed since the last call, we reset the status */
    131 if( set->limitchanged )
    132 {
    134 set->limitchanged = FALSE;
    135 }
    136
    137 if( SCIPinterrupted() || stat->userinterrupt )
    138 {
    140 stat->userinterrupt = FALSE;
    141
    142 /* only reset the interrupted counter if this is the main SCIP catching CTRL-C */
    143 if( set->misc_catchctrlc )
    144 {
    146 }
    147 }
    148 else if( SCIPterminated() )
    149 {
    151
    152 return TRUE;
    153 }
    154 /* only measure the clock if a time limit is set */
    155 else if( set->istimelimitfinite )
    156 {
    157 /* check if we have already called this function sufficiently often for a valid estimation of its average call interval */
    158 if( stat->nclockskipsleft <= 0 || stat->nisstoppedcalls < NINITCALLS )
    159 {
    160 SCIP_Real currtime = SCIPclockGetTime(stat->solvingtime);
    161
    162 /* use the measured time to update the average time interval between two calls to this method */
    163 if( set->time_rareclockcheck && stat->nisstoppedcalls >= NINITCALLS )
    164 {
    165 SCIP_Real avgisstoppedfreq;
    166 int nclockskips = MAXNCLOCKSKIPS;
    167
    168 avgisstoppedfreq = currtime / stat->nisstoppedcalls;
    169
    170 /* if we are approaching the time limit, reset the number of clock skips to 0 */
    171 if( (SAFETYFACTOR * (set->limit_time - currtime) / (avgisstoppedfreq + 1e-6)) < nclockskips )
    172 nclockskips = 0;
    173
    174 stat->nclockskipsleft = nclockskips;
    175 }
    176 else
    177 stat->nclockskipsleft = 0;
    178
    179 /* set the status if the time limit was hit */
    180 if( currtime >= set->limit_time )
    181 {
    183 return TRUE;
    184 }
    185 }
    186 else if( SCIPclockGetLastTime(stat->solvingtime) >= set->limit_time )
    187 {
    188 /* use information if clock has been updated more recently */
    190 return TRUE;
    191 }
    192 else
    193 --stat->nclockskipsleft;
    194 }
    195 if( SCIPgetConcurrentMemTotal(set->scip) >= set->limit_memory*1048576.0 - stat->externmemestim * (1.0 + SCIPgetNConcurrentSolvers(set->scip)) )
    197 else if( SCIPgetNLimSolsFound(set->scip) > 0
    198 && (SCIPsetIsLT(set, SCIPgetGap(set->scip), set->limit_gap)
    199 || SCIPsetIsLT(set, (SCIPgetUpperbound(set->scip) - SCIPgetLowerbound(set->scip)) * SCIPgetTransObjscale(set->scip), set->limit_absgap )) )
    201 else if( set->limit_primal != SCIP_INVALID && !SCIPsetIsPositive(set, (int)SCIPgetObjsense(set->scip) * (SCIPgetPrimalbound(set->scip) - set->limit_primal)) ) /*lint !e777*/
    203 else if( set->limit_dual != SCIP_INVALID && !SCIPsetIsNegative(set, (int)SCIPgetObjsense(set->scip) * (SCIPgetDualbound(set->scip) - set->limit_dual)) ) /*lint !e777*/
    205 else if( set->limit_solutions >= 0 && set->stage >= SCIP_STAGE_PRESOLVING
    206 && SCIPgetNLimSolsFound(set->scip) >= set->limit_solutions )
    208 else if( set->limit_bestsol >= 0 && set->stage >= SCIP_STAGE_PRESOLVING
    209 && SCIPgetNBestSolsFound(set->scip) >= set->limit_bestsol )
    211 else if( checknodelimits && set->limit_nodes >= 0 && stat->nnodes >= set->limit_nodes )
    213 else if( checknodelimits && set->limit_totalnodes >= 0 && stat->ntotalnodes >= set->limit_totalnodes )
    215 else if( checknodelimits && set->limit_stallnodes >= 0 && stat->nnodes >= stat->bestsolnode + set->limit_stallnodes )
    217
    218 /* If stat->status was initialized to SCIP_STATUS_NODELIMIT or SCIP_STATUS_STALLNODELIMIT due to a previous call to SCIPsolveIsStopped(,,TRUE),
    219 * in the case of checknodelimits == FALSE, we do not want to report here that the solve will be stopped due to a nodelimit.
    220 */
    221 if( !checknodelimits )
    223 else
    225}
    226
    227/** calls primal heuristics */
    229 SCIP_SET* set, /**< global SCIP settings */
    230 SCIP_STAT* stat, /**< dynamic problem statistics */
    231 SCIP_PROB* prob, /**< transformed problem after presolve */
    232 SCIP_PRIMAL* primal, /**< primal data */
    233 SCIP_TREE* tree, /**< branch and bound tree, or NULL if called during presolving */
    234 SCIP_LP* lp, /**< LP data, or NULL if called during presolving or propagation */
    235 SCIP_NODE* nextnode, /**< next node that will be processed, or NULL if no more nodes left
    236 * (only needed when calling after node heuristics) */
    237 SCIP_HEURTIMING heurtiming, /**< current point in the node solving process */
    238 SCIP_Bool nodeinfeasible, /**< was the current node already detected to be infeasible? */
    239 SCIP_Bool* foundsol, /**< pointer to store whether a solution has been found */
    240 SCIP_Bool* unbounded /**< pointer to store whether an unbounded ray was found in the LP */
    241 )
    242{ /*lint --e{715}*/
    243 SCIP_RESULT result;
    244 SCIP_Longint oldnbestsolsfound;
    245 SCIP_Real lowerbound;
    246 int ndelayedheurs;
    247 int depth;
    248 int lpstateforkdepth;
    249 int h;
    250#ifndef NDEBUG
    251 SCIP_Bool inprobing;
    252 SCIP_Bool indiving;
    253#endif
    254
    255 assert(set != NULL);
    256 assert(primal != NULL);
    257 assert(tree != NULL || heurtiming == SCIP_HEURTIMING_BEFOREPRESOL || heurtiming == SCIP_HEURTIMING_DURINGPRESOLLOOP);
    258 assert(lp != NULL || heurtiming == SCIP_HEURTIMING_BEFOREPRESOL || heurtiming == SCIP_HEURTIMING_DURINGPRESOLLOOP
    259 || heurtiming == SCIP_HEURTIMING_AFTERPROPLOOP);
    260 assert(heurtiming == SCIP_HEURTIMING_BEFORENODE || heurtiming == SCIP_HEURTIMING_DURINGLPLOOP
    261 || heurtiming == SCIP_HEURTIMING_AFTERLPLOOP || heurtiming == SCIP_HEURTIMING_AFTERNODE
    265 assert(heurtiming != SCIP_HEURTIMING_AFTERNODE || (nextnode == NULL) == (SCIPtreeGetNNodes(tree) == 0));
    266 assert(foundsol != NULL);
    267
    268 *foundsol = FALSE;
    269
    270 /* nothing to do, if no heuristics are available, or if the branch-and-bound process is finished */
    271 if( set->nheurs == 0 || (heurtiming == SCIP_HEURTIMING_AFTERNODE && nextnode == NULL) )
    272 return SCIP_OKAY;
    273
    274 /* do not continue if we reached a time limit */
    275 if( SCIPsolveIsStopped(set, stat, FALSE) )
    276 return SCIP_OKAY;
    277
    278 /* sort heuristics by priority, but move the delayed heuristics to the front */
    280
    281 /* specialize the AFTERNODE timing flag */
    283 {
    284 SCIP_Bool plunging;
    285 SCIP_Bool pseudonode;
    286
    287 /* clear the AFTERNODE flags and replace them by the right ones */
    288 heurtiming &= ~SCIP_HEURTIMING_AFTERNODE;
    289
    290 /* we are in plunging mode iff the next node is a sibling or a child, and no leaf */
    291 assert(nextnode == NULL
    294 || SCIPnodeGetType(nextnode) == SCIP_NODETYPE_LEAF);
    295 plunging = (nextnode != NULL && SCIPnodeGetType(nextnode) != SCIP_NODETYPE_LEAF);
    296 pseudonode = !SCIPtreeHasFocusNodeLP(tree);
    297 if( plunging && SCIPtreeGetCurrentDepth(tree) > 0 ) /* call plunging heuristics also at root node */
    298 {
    299 if( !pseudonode )
    300 heurtiming |= SCIP_HEURTIMING_AFTERLPNODE;
    301 else
    303 }
    304 else
    305 {
    306 if( !pseudonode )
    308 else
    310 }
    311 }
    312
    313 /* initialize the tree related data, if we are not in presolving */
    314 if( heurtiming == SCIP_HEURTIMING_BEFOREPRESOL || heurtiming == SCIP_HEURTIMING_DURINGPRESOLLOOP )
    315 {
    316 depth = -1;
    317 lpstateforkdepth = -1;
    318
    319 SCIPsetDebugMsg(set, "calling primal heuristics %s presolving\n",
    320 heurtiming == SCIP_HEURTIMING_BEFOREPRESOL ? "before" : "during");
    321 }
    322 else
    323 {
    324 assert(tree != NULL); /* for lint */
    325 depth = SCIPtreeGetFocusDepth(tree);
    326 lpstateforkdepth = (tree->focuslpstatefork != NULL ? SCIPnodeGetDepth(tree->focuslpstatefork) : -1);
    327
    328 SCIPsetDebugMsg(set, "calling primal heuristics in depth %d (timing: %u)\n", depth, heurtiming);
    329 }
    330
    331 /* call heuristics */
    332 ndelayedheurs = 0;
    333 oldnbestsolsfound = primal->nbestsolsfound;
    334
    335#ifndef NDEBUG
    336 /* remember old probing and diving status */
    337 inprobing = tree != NULL && SCIPtreeProbing(tree);
    338 indiving = lp != NULL && SCIPlpDiving(lp);
    339
    340 /* heuristics should currently not be called in diving mode */
    341 assert(!indiving);
    342#endif
    343
    344 /* collect lower bound of current node */
    345 if( tree != NULL )
    346 {
    347 assert(SCIPtreeGetFocusNode(tree) != NULL);
    349 }
    350 else if( lp != NULL )
    351 lowerbound = SCIPlpGetPseudoObjval(lp, set, prob);
    352 else
    353 lowerbound = -SCIPsetInfinity(set);
    354
    355 for( h = 0; h < set->nheurs; ++h )
    356 {
    357#ifndef NDEBUG
    358 size_t nusedbuffer = BMSgetNUsedBufferMemory(SCIPbuffer(set->scip));
    359#endif
    360 /* it might happen that a diving heuristic renders the previously solved node LP invalid
    361 * such that additional calls to LP heuristics will fail; better abort the loop in this case
    362 */
    363 if( lp != NULL && lp->resolvelperror)
    364 break;
    365
    366#ifdef SCIP_DEBUG
    367 {
    368 SCIP_Bool delayed;
    369 if( SCIPheurShouldBeExecuted(set->heurs[h], depth, lpstateforkdepth, heurtiming, &delayed) )
    370 {
    371 SCIPsetDebugMsg(set, " -> executing heuristic <%s> with priority %d\n",
    372 SCIPheurGetName(set->heurs[h]), SCIPheurGetPriority(set->heurs[h]));
    373 }
    374 }
    375#endif
    376
    377 SCIP_CALL( SCIPheurExec(set->heurs[h], set, primal, depth, lpstateforkdepth, heurtiming, nodeinfeasible,
    378 &ndelayedheurs, &result) );
    379
    380#ifndef NDEBUG
    381 if( BMSgetNUsedBufferMemory(SCIPbuffer(set->scip)) > nusedbuffer )
    382 {
    383 SCIPerrorMessage("Buffer not completely freed after executing heuristic <%s>\n", SCIPheurGetName(set->heurs[h]));
    384 SCIPABORT();
    385 }
    386#endif
    387
    388 /* if the new solution cuts off the current node due to a new primal solution (via the cutoff bound) interrupt
    389 * calling the remaining heuristics
    390 */
    391 if( SCIPsolveIsStopped(set, stat, FALSE) || ( result == SCIP_FOUNDSOL && SCIPsetIsGE(set, lowerbound, primal->cutoffbound) ) )
    392 break;
    393
    394 /* check if the problem is proven to be unbounded, currently this happens only in reoptimization */
    395 if( result == SCIP_UNBOUNDED )
    396 {
    397 *unbounded = TRUE;
    398 break;
    399 }
    400
    401 /* make sure that heuristic did not change probing or diving status */
    402 assert(tree == NULL || inprobing == SCIPtreeProbing(tree));
    403 assert(lp == NULL || indiving == SCIPlpDiving(lp));
    404 }
    405 assert(0 <= ndelayedheurs && ndelayedheurs <= set->nheurs);
    406
    407 *foundsol = (primal->nbestsolsfound > oldnbestsolsfound);
    408
    409 return SCIP_OKAY;
    410}
    411
    412/** applies one round of propagation */
    413static
    415 BMS_BLKMEM* blkmem, /**< block memory buffers */
    416 SCIP_SET* set, /**< global SCIP settings */
    417 SCIP_STAT* stat, /**< dynamic problem statistics */
    418 SCIP_TREE* tree, /**< branch and bound tree */
    419 int depth, /**< depth level to use for propagator frequency checks */
    420 SCIP_Bool fullpropagation, /**< should all constraints be propagated (or only new ones)? */
    421 SCIP_Bool onlydelayed, /**< should only delayed propagators be called? */
    422 SCIP_Bool* delayed, /**< pointer to store whether a propagator was delayed */
    423 SCIP_Bool* propagain, /**< pointer to store whether propagation should be applied again */
    424 SCIP_PROPTIMING timingmask, /**< timing mask to decide which propagators are executed */
    425 SCIP_Bool* cutoff, /**< pointer to store whether the node can be cut off */
    426 SCIP_Bool* postpone /**< pointer to store whether the node should be postponed */
    427 )
    428{ /*lint --e{715}*/
    429 SCIP_RESULT result;
    430 SCIP_Bool abortoncutoff;
    431 int i;
    432
    433 assert(set != NULL);
    434 assert(delayed != NULL);
    435 assert(propagain != NULL);
    436 assert(cutoff != NULL);
    437 assert(postpone != NULL);
    438
    439 *delayed = FALSE;
    440 *propagain = FALSE;
    441
    442 /* sort propagators */
    444
    445 /* check if we want to abort on a cutoff; if we are not in the solving stage (e.g., in presolving), we want to abort
    446 * anyway
    447 */
    448 abortoncutoff = set->prop_abortoncutoff || (set->stage != SCIP_STAGE_SOLVING);
    449
    450 /* call additional propagators with nonnegative priority */
    451 for( i = 0; i < set->nprops && !(*postpone) && (!(*cutoff) || !abortoncutoff); ++i )
    452 {
    453#ifndef NDEBUG
    454 size_t nusedbuffer = BMSgetNUsedBufferMemory(SCIPbuffer(set->scip));
    455#endif
    456 /* timing needs to fit */
    457 if( (SCIPpropGetTimingmask(set->props[i]) & timingmask) == 0 )
    458 continue;
    459
    460 if( SCIPpropGetPriority(set->props[i]) < 0 )
    461 continue;
    462
    463 if( onlydelayed && !SCIPpropWasDelayed(set->props[i]) )
    464 continue;
    465
    466 SCIPsetDebugMsg(set, "calling propagator <%s>\n", SCIPpropGetName(set->props[i]));
    467
    468 SCIP_CALL( SCIPpropExec(set->props[i], set, stat, depth, onlydelayed, tree->sbprobing, timingmask, &result) );
    469
    470#ifndef NDEBUG
    471 if( BMSgetNUsedBufferMemory(SCIPbuffer(set->scip)) > nusedbuffer )
    472 {
    473 SCIPerrorMessage("Buffer not completely freed after executing propagator <%s>\n", SCIPpropGetName(set->props[i]));
    474 SCIPABORT();
    475 }
    476#endif
    477
    478 *delayed = *delayed || (result == SCIP_DELAYED);
    479 *propagain = *propagain || (result == SCIP_REDUCEDDOM);
    480
    481 /* beside the result pointer of the propagator we have to check if an internal cutoff was detected; this can
    482 * happen when a global bound change was applied which is globally valid and leads locally (for the current node
    483 * and others) to an infeasible problem;
    484 */
    485 *cutoff = *cutoff || (result == SCIP_CUTOFF) || (tree->cutoffdepth <= SCIPtreeGetCurrentDepth(tree));
    486 *postpone = (result == SCIP_DELAYNODE) && !(*cutoff);
    487
    488 if( result == SCIP_CUTOFF )
    489 {
    490 SCIPsetDebugMsg(set, " -> propagator <%s> detected cutoff\n", SCIPpropGetName(set->props[i]));
    491 }
    492
    493 /* if we work off the delayed propagators, we stop immediately if a reduction was found */
    494 if( onlydelayed && result == SCIP_REDUCEDDOM )
    495 {
    496 *delayed = TRUE;
    497 return SCIP_OKAY;
    498 }
    499 }
    500
    501 /* propagate constraints */
    502 for( i = 0; i < set->nconshdlrs && !(*postpone) && (!(*cutoff) || !abortoncutoff); ++i )
    503 {
    504 /* timing needs to fit */
    505 if( (SCIPconshdlrGetPropTiming(set->conshdlrs[i]) & timingmask) == 0 )
    506 continue;
    507
    508 if( onlydelayed && !SCIPconshdlrWasPropagationDelayed(set->conshdlrs[i]) )
    509 continue;
    510
    511 SCIPsetDebugMsg(set, "calling propagation method of constraint handler <%s>\n", SCIPconshdlrGetName(set->conshdlrs[i]));
    512
    513 SCIP_CALL( SCIPconshdlrPropagate(set->conshdlrs[i], blkmem, set, stat, depth, fullpropagation, onlydelayed,
    514 tree->sbprobing, timingmask, &result) );
    515 *delayed = *delayed || (result == SCIP_DELAYED);
    516 *propagain = *propagain || (result == SCIP_REDUCEDDOM);
    517
    518 /* beside the result pointer of the propagator we have to check if an internal cutoff was detected; this can
    519 * happen when a global bound change was applied which is globally valid and leads locally (for the current node
    520 * and others) to an infeasible problem;
    521 */
    522 *cutoff = *cutoff || (result == SCIP_CUTOFF) || (tree->cutoffdepth <= SCIPtreeGetCurrentDepth(tree));
    523 *postpone = (result == SCIP_DELAYNODE) && !(*cutoff);
    524
    525 if( result == SCIP_CUTOFF )
    526 {
    527 SCIPsetDebugMsg(set, " -> constraint handler <%s> detected cutoff in propagation\n",
    528 SCIPconshdlrGetName(set->conshdlrs[i]));
    529 }
    530
    531 /* if we work off the delayed propagators, we stop immediately if a reduction was found */
    532 if( onlydelayed && result == SCIP_REDUCEDDOM )
    533 {
    534 *delayed = TRUE;
    535 return SCIP_OKAY;
    536 }
    537 }
    538
    539 /* call additional propagators with negative priority */
    540 for( i = 0; i < set->nprops && !(*postpone) && (!(*cutoff) || !abortoncutoff); ++i )
    541 {
    542 /* timing needs to fit */
    543 if( (SCIPpropGetTimingmask(set->props[i]) & timingmask) == 0 )
    544 continue;
    545
    546 if( SCIPpropGetPriority(set->props[i]) >= 0 )
    547 continue;
    548
    549 if( onlydelayed && !SCIPpropWasDelayed(set->props[i]) )
    550 continue;
    551
    552 SCIPsetDebugMsg(set, "calling propagator <%s>\n", SCIPpropGetName(set->props[i]));
    553
    554 SCIP_CALL( SCIPpropExec(set->props[i], set, stat, depth, onlydelayed, tree->sbprobing, timingmask, &result) );
    555 *delayed = *delayed || (result == SCIP_DELAYED);
    556 *propagain = *propagain || (result == SCIP_REDUCEDDOM);
    557
    558 /* beside the result pointer of the propagator we have to check if an internal cutoff was detected; this can
    559 * happen when a global bound change was applied which is globally valid and leads locally (for the current node
    560 * and others) to an infeasible problem;
    561 */
    562 *cutoff = *cutoff || (result == SCIP_CUTOFF) || (tree->cutoffdepth <= SCIPtreeGetCurrentDepth(tree));
    563 *postpone = (result == SCIP_DELAYNODE) && !(*cutoff);
    564
    565 if( result == SCIP_CUTOFF )
    566 {
    567 SCIPsetDebugMsg(set, " -> propagator <%s> detected cutoff\n", SCIPpropGetName(set->props[i]));
    568 }
    569
    570 /* if we work off the delayed propagators, we stop immediately if a reduction was found */
    571 if( onlydelayed && result == SCIP_REDUCEDDOM )
    572 {
    573 *delayed = TRUE;
    574 return SCIP_OKAY;
    575 }
    576 }
    577
    578 return SCIP_OKAY;
    579}
    580
    581/** applies domain propagation on current node */
    582static
    584 BMS_BLKMEM* blkmem, /**< block memory buffers */
    585 SCIP_SET* set, /**< global SCIP settings */
    586 SCIP_STAT* stat, /**< dynamic problem statistics */
    587 SCIP_TREE* tree, /**< branch and bound tree */
    588 int depth, /**< depth level to use for propagator frequency checks */
    589 int maxproprounds, /**< maximal number of propagation rounds (-1: no limit, 0: parameter settings) */
    590 SCIP_Bool fullpropagation, /**< should all constraints be propagated (or only new ones)? */
    591 SCIP_PROPTIMING timingmask, /**< timing mask to decide which propagators are executed */
    592 SCIP_Bool* cutoff, /**< pointer to store whether the node can be cut off */
    593 SCIP_Bool* postpone /**< pointer to store whether the node should be postponed */
    594 )
    595{
    596 SCIP_NODE* node;
    597 SCIP_Bool delayed;
    598 SCIP_Bool propagain;
    599 int propround;
    600
    601 assert(set != NULL);
    602 assert(tree != NULL);
    603 assert(depth >= 0);
    604 assert(cutoff != NULL);
    605
    606 node = SCIPtreeGetCurrentNode(tree);
    607 assert(node != NULL && SCIPnodeIsActive(node));
    611
    612 /* adjust maximal number of propagation rounds */
    613 if( maxproprounds == 0 )
    614 maxproprounds = (depth == 0 ? set->prop_maxroundsroot : set->prop_maxrounds);
    615 if( maxproprounds == -1 )
    616 maxproprounds = INT_MAX;
    617
    618 SCIPsetDebugMsg(set, "domain propagation of node %p in depth %d (using depth %d, maxrounds %d, proptiming %u)\n",
    619 (void*)node, SCIPnodeGetDepth(node), depth, maxproprounds, timingmask);
    620
    621 /* propagate as long new bound changes were found and the maximal number of propagation rounds is not exceeded */
    622 *cutoff = FALSE;
    623 *postpone = FALSE;
    624 propround = 0;
    625 propagain = TRUE;
    626 while( propagain && !(*cutoff) && !(*postpone) && propround < maxproprounds && !SCIPsolveIsStopped(set, stat, FALSE))
    627 {
    628 propround++;
    629
    630 /* perform the propagation round by calling the propagators and constraint handlers */
    631 SCIP_CALL( propagationRound(blkmem, set, stat, tree, depth, fullpropagation, FALSE, &delayed, &propagain, timingmask, cutoff, postpone) );
    632
    633 /* if the propagation will be terminated, call the delayed propagators */
    634 while( delayed && (!propagain || propround >= maxproprounds) && !(*cutoff) )
    635 {
    636 /* call the delayed propagators and constraint handlers */
    637 SCIP_CALL( propagationRound(blkmem, set, stat, tree, depth, fullpropagation, TRUE, &delayed, &propagain, timingmask, cutoff, postpone) );
    638 }
    639
    640 /* if a reduction was found, we want to do another full propagation round (even if the propagator only claimed
    641 * to have done a domain reduction without applying a domain change)
    642 */
    643 fullpropagation = TRUE;
    644 }
    645
    646 /* mark the node to be completely propagated in the current repropagation subtree level */
    647 SCIPnodeMarkPropagated(node, tree);
    648
    649 if( *cutoff )
    650 {
    651 SCIPsetDebugMsg(set, " --> domain propagation of node %p finished: cutoff!\n", (void*)node);
    652 }
    653
    654 return SCIP_OKAY;
    655}
    656
    657/** applies domain propagation on current node and flushes the conflict store afterwards */
    659 BMS_BLKMEM* blkmem, /**< block memory buffers */
    660 SCIP_SET* set, /**< global SCIP settings */
    661 SCIP_STAT* stat, /**< dynamic problem statistics */
    662 SCIP_PROB* transprob, /**< transformed problem */
    663 SCIP_PROB* origprob, /**< original problem */
    664 SCIP_TREE* tree, /**< branch and bound tree */
    665 SCIP_REOPT* reopt, /**< reoptimization data structure */
    666 SCIP_LP* lp, /**< LP data */
    667 SCIP_BRANCHCAND* branchcand, /**< branching candidate storage */
    668 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
    669 SCIP_EVENTFILTER* eventfilter, /**< global event filter */
    670 SCIP_CONFLICT* conflict, /**< conflict analysis data */
    671 SCIP_CLIQUETABLE* cliquetable, /**< clique table data structure */
    672 int depth, /**< depth level to use for propagator frequency checks */
    673 int maxrounds, /**< maximal number of propagation rounds (-1: no limit, 0: parameter settings) */
    674 SCIP_PROPTIMING timingmask, /**< timing mask to decide which propagators are executed */
    675 SCIP_Bool* cutoff /**< pointer to store whether the node can be cut off */
    676 )
    677{
    678 SCIP_Bool postpone;
    679
    680 /* apply domain propagation */
    681 SCIP_CALL( propagateDomains(blkmem, set, stat, tree, depth, maxrounds, TRUE, timingmask, cutoff, &postpone) );
    682
    683 /* flush the conflict set storage */
    684 SCIP_CALL( SCIPconflictFlushConss(conflict, blkmem, set, stat, transprob, origprob, tree, reopt, lp, branchcand, eventqueue, eventfilter, cliquetable) );
    685
    686 return SCIP_OKAY;
    687}
    688
    689/** returns whether the given variable with the old LP solution value should lead to an update of the pseudo cost entry */
    690static
    692 SCIP_VAR* var, /**< problem variable */
    693 SCIP_SET* set, /**< global SCIP settings */
    694 SCIP_Real oldlpsolval, /**< solution value of variable in old LP */
    695 SCIP_Bool updateintegers, /**< whether to update pseudo costs for integer variables */
    696 SCIP_Bool updatecontinuous /**< whether to update pseudo costs for continuous variables */
    697 )
    698{
    699 SCIP_Real newlpsolval;
    700
    701 assert(var != NULL);
    702
    703 if( !updatecontinuous && !SCIPvarIsIntegral(var) )
    704 return FALSE;
    705
    706 if( !updateintegers && SCIPvarIsIntegral(var) )
    707 return FALSE;
    708
    709 if( !SCIPvarIsIntegral(var) && set->branch_lpgainnorm != 'l' )
    710 {
    711 /* if the variable is fixed at +/- infinity or it has an unbounded domain, then the domain-based update strategies will not work */
    713 return FALSE;
    714
    715 /* @todo if set->branch_lpgainnorm == 's', then we would need to know then domain before branching
    716 * since this is difficult to get, we don't check for unboundedness here and let the pscost update fail later
    717 * however, this makes the weights used to spread a pseudo cost update over all domain changes inaccurate
    718 */
    719
    720 return TRUE;
    721 }
    722
    723 /* if the old LP solution value is unknown, the pseudo cost update cannot be performed */
    724 if( oldlpsolval >= SCIP_INVALID )
    725 return FALSE;
    726
    727 /* the bound change on the given variable was responsible for the gain in the dual bound, if the variable's
    728 * old solution value is outside the current bounds, and the new solution value is equal to the bound
    729 * closest to the old solution value
    730 */
    731
    732 /* find out, which of the current bounds is violated by the old LP solution value */
    733 if( SCIPsetIsLT(set, oldlpsolval, SCIPvarGetLbLocal(var)) )
    734 {
    735 newlpsolval = SCIPvarGetLPSol(var);
    736 return SCIPsetIsEQ(set, newlpsolval, SCIPvarGetLbLocal(var));
    737 }
    738 else if( SCIPsetIsGT(set, oldlpsolval, SCIPvarGetUbLocal(var)) )
    739 {
    740 newlpsolval = SCIPvarGetLPSol(var);
    741 return SCIPsetIsEQ(set, newlpsolval, SCIPvarGetUbLocal(var));
    742 }
    743 else
    744 return FALSE;
    745}
    746
    747/** pseudo cost flag stored in the variables to mark them for the pseudo cost update */
    749{
    750 PSEUDOCOST_NONE = 0, /**< variable's bounds were not changed */
    751 PSEUDOCOST_IGNORE = 1, /**< bound changes on variable should be ignored for pseudo cost updates */
    752 PSEUDOCOST_UPDATE = 2 /**< pseudo cost value of variable should be updated */
    755
    756/** updates the variable's pseudo cost values after the node's initial LP was solved */
    757static
    759 SCIP_SET* set, /**< global SCIP settings */
    760 SCIP_STAT* stat, /**< dynamic problem statistics */
    761 SCIP_PROB* prob, /**< transformed problem after presolve */
    762 SCIP_TREE* tree, /**< branch and bound tree */
    763 SCIP_LP* lp, /**< LP data */
    764 SCIP_Bool updateintegers, /**< whether to update pseudo costs for integer variables */
    765 SCIP_Bool updatecontinuous /**< whether to update pseudo costs for continuous variables */
    766 )
    767{
    768 SCIP_NODE* focusnode;
    769 int actdepth;
    770
    771 assert(lp != NULL);
    772 assert(tree != NULL);
    773 assert(tree->path != NULL);
    774
    775 focusnode = SCIPtreeGetFocusNode(tree);
    776 assert(SCIPnodeIsActive(focusnode));
    777 assert(SCIPnodeGetType(focusnode) == SCIP_NODETYPE_FOCUSNODE);
    778 actdepth = SCIPnodeGetDepth(focusnode);
    779 assert(tree->path[actdepth] == focusnode);
    780
    781 if( (updateintegers || updatecontinuous) && lp->solved && SCIPlpGetSolstat(lp) == SCIP_LPSOLSTAT_OPTIMAL && tree->focuslpstatefork != NULL )
    782 {
    783 SCIP_BOUNDCHG** updates;
    784 SCIP_NODE* node;
    785 SCIP_VAR* var;
    786 SCIP_Real weight;
    787 SCIP_Real lpgain;
    788 int nupdates;
    789 int nvalidupdates;
    790 int d;
    791 int i;
    792 int ancestordepth;
    793
    794 assert(SCIPnodeIsActive(tree->focuslpstatefork));
    795 assert(tree->path[tree->focuslpstatefork->depth] == tree->focuslpstatefork);
    796
    797 /* get a buffer for the collected bound changes; start with a size twice as large as the number of nodes between
    798 * current node and LP fork
    799 */
    800 SCIP_CALL( SCIPsetAllocBufferArray(set, &updates, (int)(2*(actdepth - tree->focuslpstatefork->depth))) );
    801 nupdates = 0;
    802 nvalidupdates = 0;
    803
    804 /* search the nodes from LP fork down to current node for bound changes in between; move in this direction,
    805 * because the bound changes closer to the LP fork are more likely to have a valid LP solution information
    806 * attached; collect the bound changes for pseudo cost value updates and mark the corresponding variables such
    807 * that they are not updated twice in case of more than one bound change on the same variable
    808 */
    809 for( d = tree->focuslpstatefork->depth+1; d <= actdepth; ++d )
    810 {
    811 node = tree->path[d];
    812
    813 if( node->domchg != NULL )
    814 {
    815 SCIP_BOUNDCHG* boundchgs;
    816 int nboundchgs;
    817
    818 boundchgs = node->domchg->domchgbound.boundchgs;
    819 nboundchgs = (int) node->domchg->domchgbound.nboundchgs;
    820 for( i = 0; i < nboundchgs; ++i )
    821 {
    822 var = boundchgs[i].var;
    823 assert(var != NULL);
    824
    825 /* we even collect redundant bound changes, since they were not redundant in the LP branching decision
    826 * and therefore should be regarded in the pseudocost updates
    827 *
    828 * however, if the variable is continuous and we normalize the pseudo costs by the domain reduction,
    829 * then getting the variable bound before the branching is not possible by looking at the variables branching information (since redundant branchings are not applied)
    830 * thus, in this case we ignore the boundchange
    831 */
    832 if( (SCIP_BOUNDCHGTYPE)boundchgs[i].boundchgtype == SCIP_BOUNDCHGTYPE_BRANCHING &&
    834 )
    835 {
    836 /* remember the bound change and mark the variable */
    837 SCIP_CALL( SCIPsetReallocBufferArray(set, &updates, nupdates+1) );
    838 updates[nupdates] = &boundchgs[i];
    839 nupdates++;
    840
    841 /* check, if the bound change would lead to a valid pseudo cost update
    842 * and see comment above (however, ...) */
    843 if( isPseudocostUpdateValid(var, set, boundchgs[i].data.branchingdata.lpsolval, updateintegers, updatecontinuous)
    844 && ( SCIPvarIsIntegral(var) || !boundchgs[i].redundant || set->branch_lpgainnorm != 'd' ) )
    845 {
    846 var->pseudocostflag = PSEUDOCOST_UPDATE; /*lint !e641*/
    847 nvalidupdates++;
    848 }
    849 else
    850 var->pseudocostflag = PSEUDOCOST_IGNORE; /*lint !e641*/
    851 }
    852 }
    853 }
    854 }
    855
    856 /* update the pseudo cost values and reset the variables' flags; assume, that the responsibility for the dual gain
    857 * is equally spread on all bound changes that lead to valid pseudo cost updates
    858 */
    860 weight = (nvalidupdates > 0 ? 1.0 / (SCIP_Real)nvalidupdates : 1.0);
    861 lpgain = (SCIPlpGetObjval(lp, set, prob) - tree->focuslpstatefork->data.fork->lpobjval) * weight;
    862 lpgain = MAX(lpgain, 0.0);
    863
    864 for( i = 0; i < nupdates; ++i )
    865 {
    866 assert((SCIP_BOUNDCHGTYPE)updates[i]->boundchgtype == SCIP_BOUNDCHGTYPE_BRANCHING);
    867
    868 var = updates[i]->var;
    869 assert(var != NULL);
    871
    873 {
    874 if( SCIPvarIsIntegral(var) || set->branch_lpgainnorm == 'l' )
    875 {
    876 SCIPsetDebugMsg(set, "updating pseudocosts of <%s>: sol: %g -> %g, LP: %e -> %e => solvaldelta = %g, gain=%g, weight: %g\n",
    877 SCIPvarGetName(var), updates[i]->data.branchingdata.lpsolval, SCIPvarGetLPSol(var),
    879 SCIPvarGetLPSol(var) - updates[i]->data.branchingdata.lpsolval, lpgain, weight);
    881 SCIPvarGetLPSol(var) - updates[i]->data.branchingdata.lpsolval, lpgain, weight) );
    882 }
    883 else
    884 {
    885 /* set->branch_lpgainnorm == 'd':
    886 * For continuous variables, we want to pseudocosts to be the average of the gain in the LP value
    887 * if the domain is reduced from x% of its original width to y% of its original (e.g., global) width, i.e.,
    888 * to be the average of LPgain / (oldwidth/origwidth - newwidth/origwidth) = LPgain * origwidth / (oldwidth - newwidth).
    889 * Then an expected improvement in the LP value by a reduction of the domain width
    890 * from x% to y% of its original width can be computed by pseudocost * (oldwidth - newwidth) / origwidth.
    891 * Since the original width cancels out, we can also define the pseudocosts as average of LPgain / (oldwidth - newwidth)
    892 * and compute the expected improvement as pseudocost * (oldwidth - newwidth).
    893 *
    894 * Let var have bounds [a,c] before the branching and assume we branched on some value b.
    895 * b is given by updates[i]->newbound.
    896 *
    897 * If updates[i]->boundtype = upper, then node corresponds to the child [a,b].
    898 * Thus, we have oldwidth = c-a, newwidth = b-a, and oldwidth - newwidth = c-b.
    899 * To get c (the previous upper bound), we look into the var->ubchginfos array.
    900 *
    901 * If updates[i]->boundtype = lower, then node corresponds to the child [b,c].
    902 * Thus, we have oldwidth = c-a, newwidth = c-b, and oldwidth - newwidth = b-a.
    903 * To get c (the previous lower bound), we look into the var->lbchginfos array.
    904 */
    905 SCIP_BDCHGINFO* bdchginfo;
    906 SCIP_Real oldbound;
    907 SCIP_Real delta;
    908 int j;
    909 int nbdchginfos;
    910
    911 assert(set->branch_lpgainnorm == 'd' || set->branch_lpgainnorm == 's');
    912
    913 oldbound = SCIP_INVALID;
    914
    915 if( set->branch_lpgainnorm == 'd' )
    916 {
    917 assert(!updates[i]->redundant);
    918
    919 if( (SCIP_BOUNDTYPE)updates[i]->boundtype == SCIP_BOUNDTYPE_UPPER )
    920 {
    921 nbdchginfos = SCIPvarGetNBdchgInfosUb(var);
    922
    923 /* walk backwards through bound change information array to find the bound change corresponding to branching in updates[i]
    924 * usually it will be the first one we look at */
    925 for( j = nbdchginfos-1; j >= 0; --j )
    926 {
    927 bdchginfo = SCIPvarGetBdchgInfoUb(var, j);
    928
    929 if( bdchginfo->oldbound > updates[i]->newbound )
    930 {
    931 /* first boundchange which upper bound is above the upper bound set by the branching in updates[i]
    932 * if bdchginfo->boundchgtype == SCIP_BOUNDCHGTYPE_BRANCHING, then this should be exactly the bound change that we are looking for
    933 * if bdchginfo->boundchgtype != SCIP_BOUNDCHGTYPE_BRANCHING, then this should be because the branching domain change has not been applied to the variable due to redundancy
    934 * in this case, i.e., if there was another boundchange coming from somewhere else, I am not sure whether oldbound is an accurate value to compute the old domain size, so we skip the pseudocosts update
    935 */
    937 {
    938 assert(bdchginfo->newbound == updates[i]->newbound); /*lint !e777*/
    939 oldbound = bdchginfo->oldbound;
    940 }
    941 else
    942 assert(updates[i]->redundant);
    943
    944 break;
    945 }
    946 }
    947 /* if the bound change was redundant (e.g., due to a change in the global bound), then it was not applied, so there exists no corresponding bound change info
    948 * if it is not redundant, then we should have found at least one corresponding boundchange */
    949 assert(j >= 0 || updates[i]->redundant);
    950 if( oldbound != SCIP_INVALID ) /*lint !e777*/
    951 {
    952 assert(!SCIPsetIsInfinity(set, -oldbound)); /* branching on a variable fixed to -infinity does not make sense */
    953 assert(!SCIPsetIsInfinity(set, updates[i]->newbound)); /* branching to infinity does not make sense */
    954
    955 /* if the old upper bound is at infinity or the new upper bound is at -infinity, then we say the delta (c-b) is infinity */
    956 if( SCIPsetIsInfinity(set, oldbound) || SCIPsetIsInfinity(set, -updates[i]->newbound) )
    957 delta = SCIP_INVALID;
    958 else
    959 delta = updates[i]->newbound - oldbound;
    960 }
    961 else
    962 delta = SCIP_INVALID;
    963 }
    964 else
    965 {
    966 assert((SCIP_BOUNDTYPE)updates[i]->boundtype == SCIP_BOUNDTYPE_LOWER);
    967 nbdchginfos = SCIPvarGetNBdchgInfosLb(var);
    968
    969 /* walk backwards through bound change information array to find the bound change corresponding to branching in updates[i]
    970 * usually it will be the first one we look at */
    971 for( j = nbdchginfos-1; j >= 0; --j )
    972 {
    973 bdchginfo = SCIPvarGetBdchgInfoLb(var, j);
    974
    975 if( bdchginfo->oldbound < updates[i]->newbound )
    976 {
    977 /* first boundchange which lower bound is below the lower bound set by the branching in updates[i]
    978 * if bdchginfo->boundchgtype == SCIP_BOUNDCHGTYPE_BRANCHING, then this should be exactly the bound change that we are looking for
    979 * if bdchginfo->boundchgtype != SCIP_BOUNDCHGTYPE_BRANCHING, then this should be because the branching domain change has not been applied to the variable due to redundancy
    980 * in this case, i.e., if there was another boundchange coming from somewhere else, I am not sure whether oldbound is an accurate value to compute the old domain size, so we skip the pseudocosts update
    981 */
    983 {
    984 assert(bdchginfo->newbound == updates[i]->newbound); /*lint !e777*/
    985 oldbound = bdchginfo->oldbound;
    986 }
    987 else
    988 assert(updates[i]->redundant);
    989
    990 break;
    991 }
    992 }
    993 /* if the bound change was redundant (e.g., due to a change in the global bound), then it was not applied, so there exists no corresponding bound change info
    994 * if it is not redundant, then we should have found at least one corresponding boundchange */
    995 assert(j >= 0 || updates[i]->redundant);
    996 if( oldbound != SCIP_INVALID ) /*lint !e777*/
    997 {
    998 assert(!SCIPsetIsInfinity(set, oldbound)); /* branching on a variable fixed to +infinity does not make sense */
    999 assert(!SCIPsetIsInfinity(set, -updates[i]->newbound)); /* branching to infinity does not make sense */
    1000
    1001 /* if the old lower bound is at -infinity or the new lower bound is at +infinity, then we say the delta (b-a) is infinity */
    1002 if( SCIPsetIsInfinity(set, -oldbound) || SCIPsetIsInfinity(set, updates[i]->newbound) )
    1003 delta = SCIP_INVALID;
    1004 else
    1005 delta = updates[i]->newbound - oldbound;
    1006 }
    1007 else
    1008 delta = SCIP_INVALID;
    1009 }
    1010 }
    1011 else
    1012 {
    1013 /* set->branch_lpgainnorm == 's':
    1014 * Here, we divide the LPgain by the reduction in the sibling node.
    1015 *
    1016 * If updates[i]->boundtype = upper, then node corresponds to the child [a,b].
    1017 * Thus, we have oldwidth = c-a, newwidth = c-b, and oldwidth - newwidth = b-a.
    1018 * Conveniently, we just use the current lower bound for a (it may have been tightened, though).
    1019 *
    1020 * If updates[i]->boundtype = lower, then node corresponds to the child [b,a].
    1021 * Thus, we have oldwidth = c-a, newwidth = b-a, and oldwidth - newwidth = c-b.
    1022 * Conveniently, we just use the current upper bound for c (it may have been tightened, though).
    1023 */
    1024 if( (SCIP_BOUNDTYPE)updates[i]->boundtype == SCIP_BOUNDTYPE_UPPER )
    1025 {
    1026 assert(!SCIPsetIsInfinity(set, updates[i]->newbound)); /* branching on a variable fixed to +infinity does not make sense */
    1027 assert(!SCIPsetIsInfinity(set, SCIPvarGetLbLocal(var))); /* branching to infinity does not make sense */
    1028 if( SCIPsetIsInfinity(set, -updates[i]->newbound) || SCIPsetIsInfinity(set, -SCIPvarGetLbLocal(var)) )
    1029 delta = SCIP_INVALID;
    1030 else
    1031 delta = updates[i]->newbound - SCIPvarGetLbLocal(var);
    1032 }
    1033 else
    1034 {
    1035 assert((SCIP_BOUNDTYPE)updates[i]->boundtype == SCIP_BOUNDTYPE_LOWER);
    1036 assert(!SCIPsetIsInfinity(set, -updates[i]->newbound)); /* branching on a variable fixed to -infinity does not make sense */
    1037 assert(!SCIPsetIsInfinity(set, -SCIPvarGetUbLocal(var))); /* branching to -infinity does not make sense */
    1038 if( SCIPsetIsInfinity(set, updates[i]->newbound) || SCIPsetIsInfinity(set, SCIPvarGetUbLocal(var)) )
    1039 delta = SCIP_INVALID;
    1040 else
    1041 delta = -(SCIPvarGetUbLocal(var) - updates[i]->newbound);
    1042 }
    1043 }
    1044
    1045 if( delta != SCIP_INVALID ) /*lint !e777*/
    1046 {
    1047 SCIPsetDebugMsg(set, "updating pseudocosts of <%s> with strategy %c: domain: [%g,%g] -> [%g,%g], LP: %e -> %e => "
    1048 "delta = %g, gain=%g, weight: %g\n",
    1049 SCIPvarGetName(var), set->branch_lpgainnorm,
    1050 (SCIP_BOUNDTYPE)updates[i]->boundtype == SCIP_BOUNDTYPE_UPPER ? SCIPvarGetLbLocal(var) : oldbound,
    1051 (SCIP_BOUNDTYPE)updates[i]->boundtype == SCIP_BOUNDTYPE_UPPER ? oldbound : SCIPvarGetUbLocal(var),
    1052 (SCIP_BOUNDTYPE)updates[i]->boundtype == SCIP_BOUNDTYPE_UPPER ? SCIPvarGetLbLocal(var) : updates[i]->newbound,
    1053 (SCIP_BOUNDTYPE)updates[i]->boundtype == SCIP_BOUNDTYPE_UPPER ? updates[i]->newbound : SCIPvarGetUbLocal(var),
    1055 delta, lpgain, weight);
    1056
    1057 SCIP_CALL( SCIPvarUpdatePseudocost(var, set, stat, delta, lpgain, weight) );
    1058 }
    1059 }
    1060 }
    1061 var->pseudocostflag = PSEUDOCOST_NONE; /*lint !e641*/
    1062 }
    1063
    1064 /* free the buffer for the collected bound changes */
    1065 SCIPsetFreeBufferArray(set, &updates);
    1066
    1067 /* update the ancestor pscost fields */
    1068 if( tree->focuslpstatefork->depth >= 1 && set->branch_collectancpscost )
    1069 {
    1070 /* if the last fork is not the root node, we have more ancestors */
    1071 ancestordepth = -1;
    1072 for ( d = tree->focuslpstatefork->depth - 1; d >=0; --d )
    1073 {
    1074 node = tree->path[d];
    1075 if ( SCIPnodeGetType(node) == SCIP_NODETYPE_FORK )
    1076 {
    1077 ancestordepth = d;
    1078 break;
    1079 }
    1080 }
    1081 if( ancestordepth >= 0 )
    1082 {
    1083 /* ancestor pseudo cost updates for an ancestor */
    1084 assert(SCIPnodeIsActive(tree->path[ancestordepth]));
    1085
    1086 /* get a buffer for the collected bound changes; start with a size twice as large as the number of nodes between
    1087 * current LP fork and the previous LP fork
    1088 */
    1089 SCIP_CALL( SCIPsetAllocBufferArray(set, &updates, (int)(2*(tree->focuslpstatefork->depth - ancestordepth))) );
    1090 nupdates = 0;
    1091 nvalidupdates = 0;
    1092 for( d = ancestordepth + 1; d <= tree->focuslpstatefork->depth; ++d )
    1093 {
    1094 node = tree->path[d];
    1095
    1096 if( node->domchg != NULL )
    1097 {
    1098 SCIP_BOUNDCHG* boundchgs;
    1099 int nboundchgs;
    1100
    1101 boundchgs = node->domchg->domchgbound.boundchgs;
    1102 nboundchgs = (int) node->domchg->domchgbound.nboundchgs;
    1103 for( i = 0; i < nboundchgs; ++i )
    1104 {
    1105 var = boundchgs[i].var;
    1106 assert(var != NULL);
    1107
    1108 /* we even collect redundant bound changes, since they were not redundant in the LP branching decision
    1109 * and therefore should be regarded in the ancestor pseudocost updates
    1110 */
    1111 if( (SCIP_BOUNDCHGTYPE)boundchgs[i].boundchgtype == SCIP_BOUNDCHGTYPE_BRANCHING &&
    1113 {
    1114 /* remember the bound change and mark the variable */
    1115 SCIP_CALL( SCIPsetReallocBufferArray(set, &updates, nupdates+1) );
    1116 updates[nupdates] = &boundchgs[i];
    1117 nupdates++;
    1118
    1119 /* check for valid pseudocost updates for integer variables */
    1120 if( isPseudocostUpdateValid(var, set, boundchgs[i].data.branchingdata.lpsolval, updateintegers, updatecontinuous)
    1121 && SCIPvarIsIntegral(var) )
    1122 {
    1123 var->pseudocostflag = PSEUDOCOST_UPDATE; /*lint !e641*/
    1124 nvalidupdates++;
    1125 }
    1126 else
    1127 var->pseudocostflag = PSEUDOCOST_IGNORE; /*lint !e641*/
    1128 }
    1129 }
    1130 }
    1131 }
    1132
    1133 /* update the ancestor pseudo cost values and reset the variables' flags; assume, that the
    1134 * responsibility for the dual gain is equally spread on all bound changes that lead to valid
    1135 * ancestor pseudo cost updates
    1136 */
    1137 assert(SCIPnodeGetType(tree->path[ancestordepth]) == SCIP_NODETYPE_FORK);
    1138 weight = (nvalidupdates > 0 ? 1.0 / (SCIP_Real)nvalidupdates : 1.0);
    1139 /* lp gain is same as above but with different weight */
    1140 lpgain = (SCIPlpGetObjval(lp, set, prob) - tree->focuslpstatefork->data.fork->lpobjval) * weight;
    1141 lpgain = MAX(lpgain, 0.0);
    1142
    1143 for( i = 0; i < nupdates; ++i )
    1144 {
    1145 assert((SCIP_BOUNDCHGTYPE)updates[i]->boundchgtype == SCIP_BOUNDCHGTYPE_BRANCHING);
    1146
    1147 var = updates[i]->var;
    1148 assert(var != NULL);
    1150
    1152 {
    1153 assert( SCIPvarIsIntegral(var) );
    1154 /* we use updates[i]->newbound as new lp value for measuring change in the LP value. */
    1155 SCIPsetDebugMsg(set, "updating ancestor pseudocosts of <%s>: sol: %g -> %g, LP: %e -> %e => solvaldelta = %g, gain=%g, weight: %g\n",
    1156 SCIPvarGetName(var), updates[i]->data.branchingdata.lpsolval, updates[i]->newbound,
    1158 updates[i]->newbound - updates[i]->data.branchingdata.lpsolval, lpgain, weight);
    1160 updates[i]->newbound - updates[i]->data.branchingdata.lpsolval, lpgain, weight) );
    1161 }
    1162 var->pseudocostflag = PSEUDOCOST_NONE; /*lint !e641*/
    1163 }
    1164 /* free the buffer for the collected bound changes */
    1165 SCIPsetFreeBufferArray(set, &updates);
    1166 }
    1167 }
    1168 }
    1169
    1170 return SCIP_OKAY;
    1171}
    1172
    1173/** updates the estimated value of a primal feasible solution for the focus node after the LP was solved */
    1174static
    1176 SCIP_SET* set, /**< global SCIP settings */
    1177 SCIP_STAT* stat, /**< problem statistics */
    1178 SCIP_TREE* tree, /**< branch and bound tree */
    1179 SCIP_LP* lp, /**< current LP data */
    1180 SCIP_BRANCHCAND* branchcand /**< branching candidate storage */
    1181 )
    1182{
    1183 SCIP_NODE* focusnode;
    1184 SCIP_VAR** lpcands;
    1185 SCIP_Real* lpcandsfrac;
    1186 SCIP_Real estimate;
    1187 int nlpcands;
    1188 int i;
    1189
    1190 /* estimate is only available if LP was solved to optimality */
    1192 return SCIP_OKAY;
    1193
    1194 focusnode = SCIPtreeGetFocusNode(tree);
    1195 assert(focusnode != NULL);
    1196
    1197 /* get the fractional variables */
    1198 SCIP_CALL( SCIPbranchcandGetLPCands(branchcand, set, stat, lp, &lpcands, NULL, &lpcandsfrac, &nlpcands, NULL, NULL) );
    1199
    1200 /* calculate the estimate: lowerbound + sum(min{f_j * pscdown_j, (1-f_j) * pscup_j}) */
    1201 estimate = SCIPnodeGetLowerbound(focusnode);
    1202
    1203 /* an infinite lower bound implies an infinite estimate */
    1204 if( SCIPsetIsInfinity(set, estimate) )
    1205 {
    1206 SCIPnodeSetEstimate(focusnode, set, estimate);
    1207 return SCIP_OKAY;
    1208 }
    1209
    1210 for( i = 0; i < nlpcands; ++i )
    1211 {
    1212 SCIP_Real pscdown;
    1213 SCIP_Real pscup;
    1214
    1215 pscdown = SCIPvarGetPseudocost(lpcands[i], stat, 0.0-lpcandsfrac[i]);
    1216 pscup = SCIPvarGetPseudocost(lpcands[i], stat, 1.0-lpcandsfrac[i]);
    1217 estimate += MIN(pscdown, pscup);
    1218 }
    1219 SCIPnodeSetEstimate(focusnode, set, estimate);
    1220
    1221 return SCIP_OKAY;
    1222}
    1223
    1224/** puts all constraints with initial flag TRUE into the LP */
    1226 BMS_BLKMEM* blkmem, /**< block memory buffers */
    1227 SCIP_SET* set, /**< global SCIP settings */
    1228 SCIP_SEPASTORE* sepastore, /**< separation storage */
    1229 SCIP_CUTPOOL* cutpool, /**< global cutpool */
    1230 SCIP_STAT* stat, /**< dynamic problem statistics */
    1231 SCIP_PROB* transprob, /**< transformed problem */
    1232 SCIP_PROB* origprob, /**< original problem */
    1233 SCIP_TREE* tree, /**< branch and bound tree */
    1234 SCIP_REOPT* reopt, /**< reoptimization data structure */
    1235 SCIP_LP* lp, /**< LP data */
    1236 SCIP_BRANCHCAND* branchcand, /**< branching candidate storage */
    1237 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
    1238 SCIP_EVENTFILTER* eventfilter, /**< global event filter */
    1239 SCIP_CLIQUETABLE* cliquetable, /**< clique table data structure */
    1240 SCIP_Bool root, /**< is this the initial root LP? */
    1241 SCIP_Bool firstsubtreeinit, /**< is this the first call in the current subtree after jumping through the tree? */
    1242 SCIP_Bool* cutoff /**< pointer to store whether the node can be cut off */
    1243 )
    1244{
    1245 int h;
    1246
    1247 assert(set != NULL);
    1248 assert(lp != NULL);
    1249 assert(cutoff != NULL);
    1250
    1251 *cutoff = FALSE;
    1252
    1253 /* inform separation storage, that LP is now filled with initial data */
    1254 SCIPsepastoreStartInitialLP(sepastore);
    1255
    1256 /* add LP relaxations of all initial constraints to LP */
    1257 SCIPsetDebugMsg(set, "init LP: initial rows\n");
    1258 for( h = 0; h < set->nconshdlrs && !(*cutoff); ++h )
    1259 {
    1260 SCIP_CALL( SCIPconshdlrInitLP(set->conshdlrs[h], blkmem, set, stat, tree, firstsubtreeinit, cutoff) );
    1261 }
    1262
    1263 if( set->reopt_enable && set->reopt_usecuts && firstsubtreeinit && !(*cutoff) )
    1264 {
    1265 /* add stored cuts from last reoptimization run */
    1266 SCIP_CALL( SCIPreoptApplyCuts(reopt, tree->focusnode, sepastore, cutpool, blkmem, set, stat, eventqueue,
    1267 eventfilter, lp, root) );
    1268 }
    1269
    1270 if( !(*cutoff) )
    1271 {
    1272 /* apply cuts */
    1273 SCIP_CALL( SCIPsepastoreApplyCuts(sepastore, blkmem, set, stat, transprob, origprob, tree, reopt, lp, branchcand,
    1274 eventqueue, eventfilter, cliquetable, root, SCIP_EFFICIACYCHOICE_LP, cutoff) );
    1275 }
    1276 else
    1277 {
    1278 /* the current node will be cut off; we clear the sepastore */
    1279 SCIP_CALL( SCIPsepastoreClearCuts(sepastore, blkmem, set, eventqueue, eventfilter, lp) );
    1280 }
    1281
    1282 /* inform separation storage, that initial LP setup is now finished */
    1283 SCIPsepastoreEndInitialLP(sepastore);
    1284
    1285 return SCIP_OKAY;
    1286}
    1287
    1288/** constructs the initial LP of the current node */
    1289static
    1291 BMS_BLKMEM* blkmem, /**< block memory buffers */
    1292 SCIP_SET* set, /**< global SCIP settings */
    1293 SCIP_STAT* stat, /**< dynamic problem statistics */
    1294 SCIP_PROB* transprob, /**< transformed problem */
    1295 SCIP_PROB* origprob, /**< original problem */
    1296 SCIP_TREE* tree, /**< branch and bound tree */
    1297 SCIP_REOPT* reopt, /**< reoptimization data structure */
    1298 SCIP_LP* lp, /**< LP data */
    1299 SCIP_PRICESTORE* pricestore, /**< pricing storage */
    1300 SCIP_SEPASTORE* sepastore, /**< separation storage */
    1301 SCIP_CUTPOOL* cutpool, /**< global cut pool */
    1302 SCIP_BRANCHCAND* branchcand, /**< branching candidate storage */
    1303 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
    1304 SCIP_EVENTFILTER* eventfilter, /**< global event filter */
    1305 SCIP_CLIQUETABLE* cliquetable, /**< clique table data structure */
    1306 SCIP_Bool root, /**< is this the initial root LP? */
    1307 SCIP_Bool* cutoff /**< pointer to store whether the node can be cut off */
    1308 )
    1309{
    1310 SCIP_VAR* var;
    1311 int oldnvars = 0;
    1312 int v;
    1313
    1314 assert(set != NULL);
    1315 assert(transprob != NULL);
    1316 assert(lp != NULL);
    1317 assert(cutoff != NULL);
    1318
    1319 *cutoff = FALSE;
    1320
    1321 /* at the root node, we have to add the initial variables as columns */
    1322 if( root )
    1323 {
    1324 assert(SCIPlpGetNCols(lp) == 0);
    1325 assert(SCIPlpGetNRows(lp) == 0);
    1326
    1327 /* store number of variables for later */
    1328 oldnvars = transprob->nvars;
    1329
    1330 /* inform pricing storage, that LP is now filled with initial data */
    1331 SCIPpricestoreStartInitialLP(pricestore);
    1332
    1333 /* add all initial variables to LP */
    1334 SCIPsetDebugMsg(set, "init LP: initial columns\n");
    1335 for( v = 0; v < transprob->nvars; ++v )
    1336 {
    1337 var = transprob->vars[v];
    1338 assert(SCIPvarGetProbindex(var) >= 0);
    1339
    1340 if( SCIPvarIsInitial(var) )
    1341 {
    1342 SCIP_CALL( SCIPpricestoreAddVar(pricestore, blkmem, set, eventqueue, lp, var, 0.0, TRUE) );
    1343
    1344 /* check for empty domains (necessary if no presolving was performed) */
    1346 {
    1347 *cutoff = TRUE;
    1348 break;
    1349 }
    1350 }
    1351 }
    1352
    1353 assert(lp->nremovablecols == 0);
    1354 SCIP_CALL( SCIPpricestoreApplyVars(pricestore, blkmem, set, stat, eventqueue, transprob, tree, lp) );
    1355 assert(lp->nremovablerows == 0);
    1356
    1357 /* inform pricing storage, that initial LP setup is now finished */
    1358 SCIPpricestoreEndInitialLP(pricestore);
    1359
    1360 if( *cutoff )
    1361 return SCIP_OKAY;
    1362 }
    1363
    1364 /* put all initial constraints into the LP */
    1365 /* @todo check whether we jumped through the tree */
    1366 SCIP_CALL( SCIPinitConssLP(blkmem, set, sepastore, cutpool, stat, transprob, origprob, tree, reopt, lp, branchcand, eventqueue,
    1367 eventfilter, cliquetable, root, TRUE, cutoff) );
    1368
    1369 if( *cutoff )
    1370 return SCIP_OKAY;
    1371
    1372 /* putting all initial constraints into the LP might have added new variables */
    1373 if( root && transprob->nvars > oldnvars )
    1374 {
    1375 /* inform pricing storage, that LP is now filled with initial data */
    1376 SCIPpricestoreStartInitialLP(pricestore);
    1377
    1378 /* check all initial variables */
    1379 for( v = 0; v < transprob->nvars; ++v )
    1380 {
    1381 var = transprob->vars[v];
    1382 assert(SCIPvarGetProbindex(var) >= 0);
    1383
    1385 {
    1386 SCIP_CALL( SCIPpricestoreAddVar(pricestore, blkmem, set, eventqueue, lp, var, 0.0, TRUE) );
    1387
    1388 /* check for empty domains (necessary if no presolving was performed) */
    1390 {
    1391 *cutoff = TRUE;
    1392 break;
    1393 }
    1394 }
    1395 }
    1396
    1397 SCIP_CALL( SCIPpricestoreApplyVars(pricestore, blkmem, set, stat, eventqueue, transprob, tree, lp) );
    1398
    1399 /* inform pricing storage, that initial LP setup is now finished */
    1400 SCIPpricestoreEndInitialLP(pricestore);
    1401 }
    1402
    1403 return SCIP_OKAY;
    1404}
    1405
    1406/** constructs the LP of the current node, but does not load the LP state and warmstart information */
    1408 BMS_BLKMEM* blkmem, /**< block memory buffers */
    1409 SCIP_SET* set, /**< global SCIP settings */
    1410 SCIP_STAT* stat, /**< dynamic problem statistics */
    1411 SCIP_PROB* transprob, /**< transformed problem */
    1412 SCIP_PROB* origprob, /**< original problem */
    1413 SCIP_TREE* tree, /**< branch and bound tree */
    1414 SCIP_REOPT* reopt, /**< reoptimization data structure */
    1415 SCIP_LP* lp, /**< LP data */
    1416 SCIP_PRICESTORE* pricestore, /**< pricing storage */
    1417 SCIP_SEPASTORE* sepastore, /**< separation storage */
    1418 SCIP_CUTPOOL* cutpool, /**< global cutpool */
    1419 SCIP_BRANCHCAND* branchcand, /**< branching candidate storage */
    1420 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
    1421 SCIP_EVENTFILTER* eventfilter, /**< global event filter */
    1422 SCIP_CLIQUETABLE* cliquetable, /**< clique table data structure */
    1423 SCIP_Bool newinitconss, /**< do we have to add new initial constraints? */
    1424 SCIP_Bool* cutoff /**< pointer to store whether the node can be cut off */
    1425 )
    1426{
    1427 SCIP_Bool initroot = FALSE;
    1428
    1429 assert(tree != NULL);
    1430 assert(cutoff != NULL);
    1431
    1432 *cutoff = FALSE;
    1433
    1435 {
    1436 /* inform separation storage, that LP is now filled with initial data */
    1437 SCIPsepastoreStartInitialLP(sepastore);
    1438
    1439 if( tree->correctlpdepth >= 0 )
    1440 {
    1441 int i;
    1442
    1443 for( i = tree->pathnlprows[tree->correctlpdepth]; i < lp->nrows; ++i )
    1444 {
    1445 /* keep all active global cuts that where applied in the previous node in the lp */
    1446 if( !lp->rows[i]->local && lp->rows[i]->age == 0 )
    1447 {
    1448 lp->rows[i]->fromcutpool = TRUE; /* this has no effect inside initial LP, but is set for consistency */
    1449 SCIP_CALL( SCIPsepastoreAddCut(sepastore, blkmem, set, stat, eventqueue, eventfilter, lp, lp->rows[i],
    1450 TRUE, (SCIPtreeGetCurrentDepth(tree) == 0), cutoff) );
    1451 }
    1452 }
    1453 }
    1454
    1455 if( !(*cutoff) )
    1456 {
    1457 /* load the LP into the solver and load the LP state */
    1458 SCIPsetDebugMsg(set, "loading LP\n");
    1459 SCIP_CALL( SCIPtreeLoadLP(tree, blkmem, set, eventqueue, eventfilter, lp, &initroot) );
    1460 assert(initroot || SCIPnodeGetDepth(SCIPtreeGetFocusNode(tree)) > 0);
    1462
    1463 /* apply cuts */
    1464 SCIP_CALL( SCIPsepastoreApplyCuts(sepastore, blkmem, set, stat, transprob, origprob, tree, reopt, lp, branchcand,
    1465 eventqueue, eventfilter, cliquetable, (SCIPtreeGetCurrentDepth(tree) == 0), SCIP_EFFICIACYCHOICE_LP, cutoff) );
    1466 }
    1467 else
    1468 {
    1469 /* the current node will be cut off; we clear the sepastore */
    1470 SCIP_CALL( SCIPsepastoreClearCuts(sepastore, blkmem, set, eventqueue, eventfilter, lp) );
    1471 }
    1472
    1473 /* inform separation storage, that initial LP setup is now finished */
    1474 SCIPsepastoreEndInitialLP(sepastore);
    1475
    1476 if( !(*cutoff) )
    1477 {
    1478 /* setup initial LP relaxation of node */
    1479 SCIP_CALL( initLP(blkmem, set, stat, transprob, origprob, tree, reopt, lp, pricestore, sepastore, cutpool, branchcand,
    1480 eventqueue, eventfilter, cliquetable, initroot, cutoff) );
    1481 }
    1482 }
    1483 else if( newinitconss )
    1484 {
    1485 SCIP_CALL( SCIPinitConssLP(blkmem, set, sepastore, cutpool, stat, transprob,
    1486 origprob, tree, reopt, lp, branchcand, eventqueue, eventfilter, cliquetable, FALSE, FALSE,
    1487 cutoff) );
    1488 }
    1489
    1490 return SCIP_OKAY;
    1491}
    1492
    1493/** updates the primal ray stored in primal data
    1494 * clears previously stored primal ray, if existing and there was no LP error
    1495 * stores current primal ray, if LP is unbounded and there has been no error
    1496 */
    1497static
    1499 BMS_BLKMEM* blkmem, /**< block memory buffers */
    1500 SCIP_SET* set, /**< global SCIP settings */
    1501 SCIP_STAT* stat, /**< dynamic problem statistics */
    1502 SCIP_PROB* prob, /**< transformed problem after presolve */
    1503 SCIP_PRIMAL* primal, /**< primal data */
    1504 SCIP_TREE* tree, /**< branch and bound tree */
    1505 SCIP_LP* lp, /**< LP data */
    1506 SCIP_Bool lperror /**< has there been an LP error? */
    1507 )
    1508{
    1509 assert(blkmem != NULL);
    1510 assert(set != NULL);
    1511 assert(stat != NULL);
    1512 assert(prob != NULL);
    1513 assert(primal != NULL);
    1514 assert(tree != NULL);
    1515 assert(lp != NULL);
    1516
    1517 if( lperror )
    1518 return SCIP_OKAY;
    1519
    1520 /* clear previously stored primal ray, if any */
    1521 if( primal->primalray != NULL )
    1522 {
    1523 SCIP_CALL( SCIPsolFree(&primal->primalray, blkmem, primal) );
    1524 }
    1525
    1526 /* store unbounded ray, if LP is unbounded */
    1528 {
    1529 SCIP_VAR** vars;
    1530 SCIP_Real* ray;
    1531 int nvars;
    1532 int i;
    1533
    1534 SCIPsetDebugMsg(set, "LP is unbounded, store primal ray\n");
    1535
    1536 vars = prob->vars;
    1537 nvars = prob->nvars;
    1538
    1539 /* get buffer memory for storing the ray and load the ray values into it */
    1540 SCIP_CALL( SCIPsetAllocBufferArray(set, &ray, nvars) );
    1541 BMSclearMemoryArray(ray, nvars);
    1542 SCIP_CALL( SCIPlpGetPrimalRay(lp, set, ray) );
    1543
    1544 /* create solution to store the primal ray in */
    1545 assert(primal->primalray == NULL);
    1546 SCIP_CALL( SCIPsolCreate(&primal->primalray, blkmem, set, stat, primal, tree, NULL) );
    1547
    1548 /* set values of all active variable in the solution that represents the primal ray */
    1549 for( i = 0; i < nvars; i++ )
    1550 {
    1551 SCIP_CALL( SCIPsolSetVal(primal->primalray, set, stat, tree, vars[i], ray[i]) );
    1552 }
    1553
    1554 SCIPdebug( SCIP_CALL( SCIPprintRay(set->scip, primal->primalray, NULL, FALSE) ) );
    1555
    1556 /* free memory for buffering the ray values */
    1558 }
    1559
    1560 return SCIP_OKAY;
    1561}
    1562
    1563/** load and solve the initial LP of a node */
    1564static
    1566 BMS_BLKMEM* blkmem, /**< block memory buffers */
    1567 SCIP_SET* set, /**< global SCIP settings */
    1568 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
    1569 SCIP_STAT* stat, /**< dynamic problem statistics */
    1570 SCIP_PROB* transprob, /**< transformed problem after presolve */
    1571 SCIP_PROB* origprob, /**< original problem */
    1572 SCIP_PRIMAL* primal, /**< primal data */
    1573 SCIP_TREE* tree, /**< branch and bound tree */
    1574 SCIP_REOPT* reopt, /**< reoptimization data structure */
    1575 SCIP_LP* lp, /**< LP data */
    1576 SCIP_PRICESTORE* pricestore, /**< pricing storage */
    1577 SCIP_SEPASTORE* sepastore, /**< separation storage */
    1578 SCIP_CUTPOOL* cutpool, /**< global cutpool */
    1579 SCIP_BRANCHCAND* branchcand, /**< branching candidate storage */
    1580 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
    1581 SCIP_EVENTFILTER* eventfilter, /**< global event filter */
    1582 SCIP_CLIQUETABLE* cliquetable, /**< clique table data structure */
    1583 SCIP_Bool newinitconss, /**< do we have to add new initial constraints? */
    1584 SCIP_Bool forcedlpsolve, /**< would SCIP abort if the LP is not solved? */
    1585 SCIP_Bool* cutoff, /**< pointer to store whether the node can be cut off */
    1586 SCIP_Bool* lperror /**< pointer to store whether an unresolved error in LP solving occured */
    1587 )
    1588{
    1589 /* initializing variables for compiler warnings, which are not correct */
    1590 SCIP_Real starttime = 0.0;
    1591 SCIP_Longint nlpiterations = 0;
    1592 SCIP_NODE* focusnode;
    1593
    1594 assert(stat != NULL);
    1595 assert(tree != NULL);
    1596 assert(lp != NULL);
    1597 assert(cutoff != NULL);
    1598 assert(lperror != NULL);
    1599 assert(SCIPtreeGetFocusNode(tree) != NULL);
    1601
    1602 *cutoff = FALSE;
    1603 *lperror = FALSE;
    1604
    1605 /* load the LP into the solver */
    1606 SCIP_CALL( SCIPconstructCurrentLP(blkmem, set, stat, transprob, origprob, tree, reopt, lp, pricestore, sepastore, cutpool,
    1607 branchcand, eventqueue, eventfilter, cliquetable, newinitconss, cutoff) );
    1608
    1609 if( *cutoff )
    1610 return SCIP_OKAY;
    1611
    1612 /* load the LP state */
    1613 SCIP_CALL( SCIPtreeLoadLPState(tree, blkmem, set, transprob, stat, eventqueue, lp) );
    1614
    1615 focusnode = SCIPtreeGetFocusNode(tree);
    1616
    1617 /* store current LP iteration count and solving time if we are at the root node */
    1618 if( focusnode->depth == 0 )
    1619 {
    1620 nlpiterations = stat->nlpiterations;
    1621 starttime = SCIPclockGetTime(stat->solvingtime);
    1622 }
    1623
    1624 /* solve initial LP */
    1625 SCIPsetDebugMsg(set, "node: solve initial LP\n");
    1626 SCIP_CALL( SCIPlpSolveAndEval(lp, set, messagehdlr, blkmem, stat, eventqueue, eventfilter, transprob,
    1627 SCIPnodeGetDepth(SCIPtreeGetFocusNode(tree)) == 0 ? set->lp_rootiterlim : set->lp_iterlim, TRUE, TRUE, FALSE, forcedlpsolve, lperror) );
    1628 assert(lp->flushed);
    1629 assert(lp->solved || *lperror);
    1630
    1631 /* save time for very first LP in root node */
    1632 if ( stat->nnodelps == 0 && focusnode->depth == 0 )
    1633 {
    1634 stat->firstlptime = SCIPclockGetTime(stat->solvingtime) - starttime;
    1635 }
    1636
    1637 /* remove previous primal ray, store new one if LP is unbounded */
    1638 SCIP_CALL( updatePrimalRay(blkmem, set, stat, transprob, primal, tree, lp, *lperror) );
    1639
    1640 if( !(*lperror) )
    1641 {
    1643 {
    1644 /* issue FIRSTLPSOLVED event */
    1645 SCIP_EVENT event;
    1648 SCIP_CALL( SCIPeventProcess(&event, set, NULL, NULL, NULL, eventfilter) );
    1649 }
    1650
    1651 /* update pseudo cost values for integer variables (always) and for continuous variables (if not delayed) */
    1652 SCIP_CALL( updatePseudocost(set, stat, transprob, tree, lp, TRUE, !set->branch_delaypscost) );
    1653
    1654 /* update lower bound of current node w.r.t. initial lp */
    1655 assert(!(*cutoff));
    1658 && SCIPprobAllColsInLP(transprob, set, lp) && SCIPlpIsRelax(lp) )
    1659 {
    1660 SCIP_CALL( SCIPnodeUpdateLowerboundLP(focusnode, set, stat, messagehdlr, eventfilter, tree, transprob, origprob, lp) );
    1661
    1662 /* if this is the first LP solved at the root, store its iteration count and solution value */
    1663 if( stat->nnodelps == 0 && focusnode->depth == 0 )
    1664 {
    1665 SCIP_Real lowerbound;
    1666
    1667 assert(stat->nrootfirstlpiterations == 0);
    1668 stat->nrootfirstlpiterations = stat->nlpiterations - nlpiterations;
    1669
    1670 lowerbound = SCIPnodeGetLowerbound(focusnode);
    1671
    1672 stat->firstlpdualbound = SCIPprobExternObjval(transprob, origprob, set, lowerbound);
    1673 }
    1674 }
    1675 }
    1676
    1677 return SCIP_OKAY;
    1678}
    1679
    1680/** makes sure the LP is flushed and solved */
    1681static
    1683 BMS_BLKMEM* blkmem, /**< block memory buffers */
    1684 SCIP_SET* set, /**< global SCIP settings */
    1685 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
    1686 SCIP_STAT* stat, /**< dynamic problem statistics */
    1687 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
    1688 SCIP_EVENTFILTER* eventfilter, /**< global event filter */
    1689 SCIP_PROB* prob, /**< transformed problem after presolve */
    1690 SCIP_PRIMAL* primal, /**< primal data */
    1691 SCIP_TREE* tree, /**< branch and bound tree */
    1692 SCIP_LP* lp, /**< LP data */
    1693 SCIP_Bool* lperror, /**< pointer to store whether an unresolved error in LP solving occured */
    1694 SCIP_Bool* mustsepa, /**< pointer to store TRUE if additional separation rounds should be performed */
    1695 SCIP_Bool* mustprice /**< pointer to store TRUE if additional pricing rounds should be performed */
    1696 )
    1697{
    1698 assert(lp != NULL);
    1699 assert(lperror != NULL);
    1700 assert(mustsepa != NULL);
    1701 assert(mustprice != NULL);
    1702
    1703 /* if bound changes were applied in the separation round, we have to resolve the LP */
    1704 if( !lp->flushed )
    1705 {
    1706 /* solve LP (with dual simplex) */
    1707 SCIPsetDebugMsg(set, "separation: resolve LP\n");
    1708 SCIP_CALL( SCIPlpSolveAndEval(lp, set, messagehdlr, blkmem, stat, eventqueue, eventfilter, prob, set->lp_iterlim, FALSE, TRUE, FALSE, FALSE, lperror) );
    1709 assert(lp->flushed);
    1710 assert(lp->solved || *lperror);
    1711 *mustsepa = TRUE;
    1712 *mustprice = TRUE;
    1713
    1714 /* remove previous primal ray, store new one if LP is unbounded */
    1715 SCIP_CALL( updatePrimalRay(blkmem, set, stat, prob, primal, tree, lp, *lperror) );
    1716 }
    1717
    1718 return SCIP_OKAY;
    1719}
    1720
    1721/** applies one round of LP separation */
    1722static
    1724 BMS_BLKMEM* blkmem, /**< block memory buffers */
    1725 SCIP_SET* set, /**< global SCIP settings */
    1726 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
    1727 SCIP_STAT* stat, /**< dynamic problem statistics */
    1728 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
    1729 SCIP_EVENTFILTER* eventfilter, /**< global event filter */
    1730 SCIP_PROB* prob, /**< transformed problem after presolve */
    1731 SCIP_PRIMAL* primal, /**< primal data */
    1732 SCIP_TREE* tree, /**< branch and bound tree */
    1733 SCIP_LP* lp, /**< LP data */
    1734 SCIP_SEPASTORE* sepastore, /**< separation storage */
    1735 int actdepth, /**< current depth in the tree */
    1736 SCIP_Real bounddist, /**< current relative distance of local dual bound to global dual bound */
    1737 SCIP_Bool allowlocal, /**< should the separators be asked to separate local cuts */
    1738 SCIP_Bool onlydelayed, /**< should only delayed separators be called? */
    1739 SCIP_Bool* delayed, /**< pointer to store whether a separator was delayed */
    1740 SCIP_Bool* enoughcuts, /**< pointer to store whether enough cuts have been found this round */
    1741 SCIP_Bool* cutoff, /**< pointer to store whether the node can be cut off */
    1742 SCIP_Bool* lperror, /**< pointer to store whether an unresolved error in LP solving occured */
    1743 SCIP_Bool* mustsepa, /**< pointer to store TRUE if additional separation rounds should be performed */
    1744 SCIP_Bool* mustprice /**< pointer to store TRUE if additional pricing rounds should be performed */
    1745 )
    1746{
    1747 SCIP_RESULT result;
    1748 int i;
    1749 SCIP_Bool consadded;
    1750 SCIP_Bool root;
    1751
    1752 assert(set != NULL);
    1753 assert(lp != NULL);
    1754 assert(set->conshdlrs_sepa != NULL);
    1755 assert(delayed != NULL);
    1756 assert(enoughcuts != NULL);
    1757 assert(cutoff != NULL);
    1758 assert(lperror != NULL);
    1759
    1760 root = (actdepth == 0);
    1761 *delayed = FALSE;
    1763 *enoughcuts = TRUE;
    1765 *enoughcuts = FALSE;
    1766 else
    1767 *enoughcuts = (SCIPsepastoreGetNCuts(sepastore) >= (SCIP_Longint)SCIPsetCeil(set,
    1769 *lperror = FALSE;
    1770 consadded = FALSE;
    1771
    1772 SCIPsetDebugMsg(set, "calling separators on LP solution in depth %d (onlydelayed: %u)\n", actdepth, onlydelayed);
    1773
    1774 /* sort separators by priority */
    1776
    1777 /* call LP separators with nonnegative priority */
    1778 for( i = 0; i < set->nsepas && !(*cutoff) && !(*lperror) && !(*enoughcuts) && lp->flushed && lp->solved
    1780 ++i )
    1781 {
    1782#ifndef NDEBUG
    1783 size_t nusedbuffer = BMSgetNUsedBufferMemory(SCIPbuffer(set->scip));
    1784#endif
    1785
    1786 if( SCIPsepaGetPriority(set->sepas[i]) < 0 )
    1787 continue;
    1788
    1789 if( onlydelayed && !SCIPsepaWasLPDelayed(set->sepas[i]) )
    1790 continue;
    1791
    1792 SCIPsetDebugMsg(set, " -> executing separator <%s> with priority %d\n",
    1793 SCIPsepaGetName(set->sepas[i]), SCIPsepaGetPriority(set->sepas[i]));
    1794 SCIP_CALL( SCIPsepaExecLP(set->sepas[i], set, stat, sepastore, actdepth, bounddist, allowlocal, onlydelayed, &result) );
    1795#ifndef NDEBUG
    1796 if( BMSgetNUsedBufferMemory(SCIPbuffer(set->scip)) > nusedbuffer )
    1797 {
    1798 SCIPerrorMessage("Buffer not completely freed after executing separator <%s>\n", SCIPsepaGetName(set->sepas[i]));
    1799 SCIPABORT();
    1800 }
    1801#endif
    1802 *cutoff = *cutoff || (result == SCIP_CUTOFF);
    1803 consadded = consadded || (result == SCIP_CONSADDED);
    1805 *enoughcuts = TRUE;
    1807 *enoughcuts = *enoughcuts || (result == SCIP_NEWROUND);
    1808 else
    1809 {
    1810 *enoughcuts = *enoughcuts || (SCIPsepastoreGetNCuts(sepastore) >= (SCIP_Longint)SCIPsetCeil(set,
    1812 || (result == SCIP_NEWROUND);
    1813 }
    1814 *delayed = *delayed || (result == SCIP_DELAYED);
    1815
    1816 if( !(*cutoff) )
    1817 {
    1818 /* make sure the LP is solved (after adding bound changes, LP has to be flushed and resolved) */
    1819 SCIP_CALL( separationRoundResolveLP(blkmem, set, messagehdlr, stat, eventqueue, eventfilter, prob, primal, tree, lp, lperror, mustsepa, mustprice) );
    1820 }
    1821 else
    1822 {
    1823 SCIPsetDebugMsg(set, " -> separator <%s> detected cutoff\n", SCIPsepaGetName(set->sepas[i]));
    1824 }
    1825
    1826 /* if we work off the delayed separators, we stop immediately if a cut was found */
    1827 if( onlydelayed && (result == SCIP_CONSADDED || result == SCIP_REDUCEDDOM || result == SCIP_SEPARATED || result == SCIP_NEWROUND) )
    1828 {
    1829 SCIPsetDebugMsg(set, " -> delayed separator <%s> found a cut\n", SCIPsepaGetName(set->sepas[i]));
    1830 *delayed = TRUE;
    1831 return SCIP_OKAY;
    1832 }
    1833 }
    1834
    1835 /* try separating constraints of the constraint handlers */
    1836 for( i = 0; i < set->nconshdlrs && !(*cutoff) && !(*lperror) && !(*enoughcuts) && lp->flushed && lp->solved
    1838 ++i )
    1839 {
    1840 if( onlydelayed && !SCIPconshdlrWasLPSeparationDelayed(set->conshdlrs_sepa[i]) )
    1841 continue;
    1842
    1843 SCIPsetDebugMsg(set, " -> executing separation of constraint handler <%s> with priority %d\n",
    1844 SCIPconshdlrGetName(set->conshdlrs_sepa[i]), SCIPconshdlrGetSepaPriority(set->conshdlrs_sepa[i]));
    1845 SCIP_CALL( SCIPconshdlrSeparateLP(set->conshdlrs_sepa[i], blkmem, set, stat, sepastore, actdepth, onlydelayed,
    1846 &result) );
    1847
    1848 *cutoff = *cutoff || (result == SCIP_CUTOFF);
    1849 consadded = consadded || (result == SCIP_CONSADDED);
    1851 *enoughcuts = TRUE;
    1853 *enoughcuts = *enoughcuts || (result == SCIP_NEWROUND);
    1854 else
    1855 {
    1856 *enoughcuts = *enoughcuts || (SCIPsepastoreGetNCuts(sepastore) >= (SCIP_Longint)SCIPsetCeil(set,
    1858 || (result == SCIP_NEWROUND);
    1859 }
    1860 *delayed = *delayed || (result == SCIP_DELAYED);
    1861
    1862 if( !(*cutoff) )
    1863 {
    1864 /* make sure the LP is solved (after adding bound changes, LP has to be flushed and resolved) */
    1865 SCIP_CALL( separationRoundResolveLP(blkmem, set, messagehdlr, stat, eventqueue, eventfilter, prob, primal, tree, lp, lperror, mustsepa, mustprice) );
    1866 }
    1867 else
    1868 {
    1869 SCIPsetDebugMsg(set, " -> constraint handler <%s> detected cutoff in separation\n", SCIPconshdlrGetName(set->conshdlrs_sepa[i]));
    1870 }
    1871
    1872 /* if we work off the delayed separators, we stop immediately if a cut was found */
    1873 if( onlydelayed && (result == SCIP_CONSADDED || result == SCIP_REDUCEDDOM || result == SCIP_SEPARATED || result == SCIP_NEWROUND) )
    1874 {
    1875 SCIPsetDebugMsg(set, " -> delayed constraint handler <%s> found a cut\n",
    1876 SCIPconshdlrGetName(set->conshdlrs_sepa[i]));
    1877 *delayed = TRUE;
    1878 return SCIP_OKAY;
    1879 }
    1880 }
    1881
    1882 /* call LP separators with negative priority */
    1883 for( i = 0; i < set->nsepas && !(*cutoff) && !(*lperror) && !(*enoughcuts) && lp->flushed && lp->solved
    1885 ++i )
    1886 {
    1887 if( SCIPsepaGetPriority(set->sepas[i]) >= 0 )
    1888 continue;
    1889
    1890 if( onlydelayed && !SCIPsepaWasLPDelayed(set->sepas[i]) )
    1891 continue;
    1892
    1893 SCIPsetDebugMsg(set, " -> executing separator <%s> with priority %d\n",
    1894 SCIPsepaGetName(set->sepas[i]), SCIPsepaGetPriority(set->sepas[i]));
    1895 SCIP_CALL( SCIPsepaExecLP(set->sepas[i], set, stat, sepastore, actdepth, bounddist, allowlocal, onlydelayed, &result) );
    1896
    1897 *cutoff = *cutoff || (result == SCIP_CUTOFF);
    1898 consadded = consadded || (result == SCIP_CONSADDED);
    1900 *enoughcuts = TRUE;
    1902 *enoughcuts = *enoughcuts || (result == SCIP_NEWROUND);
    1903 else
    1904 {
    1905 *enoughcuts = *enoughcuts || (SCIPsepastoreGetNCuts(sepastore) >= (SCIP_Longint)SCIPsetCeil(set,
    1907 || (result == SCIP_NEWROUND);
    1908 }
    1909 *delayed = *delayed || (result == SCIP_DELAYED);
    1910
    1911 if( !(*cutoff) )
    1912 {
    1913 /* make sure the LP is solved (after adding bound changes, LP has to be flushed and resolved) */
    1914 SCIP_CALL( separationRoundResolveLP(blkmem, set, messagehdlr, stat, eventqueue, eventfilter, prob, primal, tree, lp, lperror, mustsepa, mustprice) );
    1915 }
    1916 else
    1917 {
    1918 SCIPsetDebugMsg(set, " -> separator <%s> detected cutoff\n", SCIPsepaGetName(set->sepas[i]));
    1919 }
    1920
    1921 /* if we work off the delayed separators, we stop immediately if a cut was found */
    1922 if( onlydelayed && (result == SCIP_CONSADDED || result == SCIP_REDUCEDDOM || result == SCIP_SEPARATED || result == SCIP_NEWROUND) )
    1923 {
    1924 SCIPsetDebugMsg(set, " -> delayed separator <%s> found a cut\n", SCIPsepaGetName(set->sepas[i]));
    1925 *delayed = TRUE;
    1926 return SCIP_OKAY;
    1927 }
    1928 }
    1929
    1930 /* process the constraints that were added during this separation round */
    1931 while( consadded )
    1932 {
    1933 assert(!onlydelayed);
    1934 consadded = FALSE;
    1935
    1936 for( i = 0; i < set->nconshdlrs && !(*cutoff) && !(*lperror) && !(*enoughcuts) && lp->flushed && lp->solved
    1938 ++i )
    1939 {
    1940 SCIPsetDebugMsg(set, " -> executing separation of constraint handler <%s> with priority %d\n",
    1941 SCIPconshdlrGetName(set->conshdlrs_sepa[i]), SCIPconshdlrGetSepaPriority(set->conshdlrs_sepa[i]));
    1942 SCIP_CALL( SCIPconshdlrSeparateLP(set->conshdlrs_sepa[i], blkmem, set, stat, sepastore, actdepth, onlydelayed,
    1943 &result) );
    1944
    1945 *cutoff = *cutoff || (result == SCIP_CUTOFF);
    1946 consadded = consadded || (result == SCIP_CONSADDED);
    1948 *enoughcuts = TRUE;
    1950 *enoughcuts = *enoughcuts || (result == SCIP_NEWROUND);
    1951 else
    1952 {
    1953 *enoughcuts = *enoughcuts || (SCIPsepastoreGetNCuts(sepastore) >= (SCIP_Longint)SCIPsetCeil(set,
    1955 || (result == SCIP_NEWROUND);
    1956 }
    1957 *delayed = *delayed || (result == SCIP_DELAYED);
    1958
    1959 if( !(*cutoff) )
    1960 {
    1961 /* make sure the LP is solved (after adding bound changes, LP has to be flushed and resolved) */
    1962 SCIP_CALL( separationRoundResolveLP(blkmem, set, messagehdlr, stat, eventqueue, eventfilter, prob, primal, tree, lp, lperror, mustsepa, mustprice) );
    1963 }
    1964 else
    1965 {
    1966 SCIPsetDebugMsg(set, " -> constraint handler <%s> detected cutoff in separation\n", SCIPconshdlrGetName(set->conshdlrs_sepa[i]));
    1967 }
    1968 }
    1969 }
    1970
    1971 SCIPsetDebugMsg(set, " -> separation round finished: delayed=%u, enoughcuts=%u, lpflushed=%u, cutoff=%u\n",
    1972 *delayed, *enoughcuts, lp->flushed, *cutoff);
    1973
    1974 return SCIP_OKAY;
    1975}
    1976
    1977/** applies one round of separation on the given primal solution */
    1978static
    1980 BMS_BLKMEM* blkmem, /**< block memory buffers */
    1981 SCIP_SET* set, /**< global SCIP settings */
    1982 SCIP_STAT* stat, /**< dynamic problem statistics */
    1983 SCIP_SEPASTORE* sepastore, /**< separation storage */
    1984 SCIP_SOL* sol, /**< primal solution that should be separated, or NULL for LP solution */
    1985 int actdepth, /**< current depth in the tree */
    1986 SCIP_Bool allowlocal, /**< should the separator be asked to separate local cuts */
    1987 SCIP_Bool onlydelayed, /**< should only delayed separators be called? */
    1988 SCIP_Bool* delayed, /**< pointer to store whether a separator was delayed */
    1989 SCIP_Bool* enoughcuts, /**< pointer to store whether enough cuts have been found this round */
    1990 SCIP_Bool* cutoff /**< pointer to store whether the node can be cut off */
    1991 )
    1992{
    1993 SCIP_RESULT result;
    1994 int i;
    1995 SCIP_Bool consadded;
    1996 SCIP_Bool root;
    1997
    1998 assert(set != NULL);
    1999 assert(set->conshdlrs_sepa != NULL);
    2000 assert(delayed != NULL);
    2001 assert(enoughcuts != NULL);
    2002 assert(cutoff != NULL);
    2003
    2004 *delayed = FALSE;
    2005 *enoughcuts = FALSE;
    2006 consadded = FALSE;
    2007 root = (actdepth == 0);
    2008
    2009 SCIPsetDebugMsg(set, "calling separators on primal solution in depth %d (onlydelayed: %u)\n", actdepth, onlydelayed);
    2010
    2011 /* sort separators by priority */
    2013
    2014 /* call separators with nonnegative priority */
    2015 for( i = 0; i < set->nsepas && !(*cutoff) && !(*enoughcuts) && !SCIPsolveIsStopped(set, stat, FALSE); ++i )
    2016 {
    2017 if( SCIPsepaGetPriority(set->sepas[i]) < 0 )
    2018 continue;
    2019
    2020 if( onlydelayed && !SCIPsepaWasSolDelayed(set->sepas[i]) )
    2021 continue;
    2022
    2023 SCIP_CALL( SCIPsepaExecSol(set->sepas[i], set, stat, sepastore, sol, actdepth, allowlocal, onlydelayed, &result) );
    2024 *cutoff = *cutoff || (result == SCIP_CUTOFF);
    2025 consadded = consadded || (result == SCIP_CONSADDED);
    2027 *enoughcuts = TRUE;
    2029 *enoughcuts = *enoughcuts || (result == SCIP_NEWROUND);
    2030 else
    2031 {
    2032 *enoughcuts = *enoughcuts || (SCIPsepastoreGetNCuts(sepastore) >= (SCIP_Longint)SCIPsetCeil(set,
    2034 || (result == SCIP_NEWROUND);
    2035 }
    2036 *delayed = *delayed || (result == SCIP_DELAYED);
    2037 if( *cutoff )
    2038 {
    2039 SCIPsetDebugMsg(set, " -> separator <%s> detected cutoff\n", SCIPsepaGetName(set->sepas[i]));
    2040 }
    2041
    2042 /* if we work off the delayed separators, we stop immediately if a cut was found */
    2043 if( onlydelayed && (result == SCIP_CONSADDED || result == SCIP_REDUCEDDOM || result == SCIP_SEPARATED || result == SCIP_NEWROUND) )
    2044 {
    2045 *delayed = TRUE;
    2046 return SCIP_OKAY;
    2047 }
    2048 }
    2049
    2050 /* try separating constraints of the constraint handlers */
    2051 for( i = 0; i < set->nconshdlrs && !(*cutoff) && !(*enoughcuts) && !SCIPsolveIsStopped(set, stat, FALSE); ++i )
    2052 {
    2053 if( onlydelayed && !SCIPconshdlrWasSolSeparationDelayed(set->conshdlrs_sepa[i]) )
    2054 continue;
    2055
    2056 SCIP_CALL( SCIPconshdlrSeparateSol(set->conshdlrs_sepa[i], blkmem, set, stat, sepastore, sol, actdepth, onlydelayed,
    2057 &result) );
    2058 *cutoff = *cutoff || (result == SCIP_CUTOFF);
    2059 consadded = consadded || (result == SCIP_CONSADDED);
    2061 *enoughcuts = TRUE;
    2063 *enoughcuts = *enoughcuts || (result == SCIP_NEWROUND);
    2064 else
    2065 {
    2066 *enoughcuts = *enoughcuts || (SCIPsepastoreGetNCuts(sepastore) >= (SCIP_Longint)SCIPsetCeil(set,
    2068 || (result == SCIP_NEWROUND);
    2069 }
    2070 *delayed = *delayed || (result == SCIP_DELAYED);
    2071 if( *cutoff )
    2072 {
    2073 SCIPsetDebugMsg(set, " -> constraint handler <%s> detected cutoff in separation\n",
    2074 SCIPconshdlrGetName(set->conshdlrs_sepa[i]));
    2075 }
    2076
    2077 /* if we work off the delayed separators, we stop immediately if a cut was found */
    2078 if( onlydelayed && (result == SCIP_CONSADDED || result == SCIP_REDUCEDDOM || result == SCIP_SEPARATED || result == SCIP_NEWROUND) )
    2079 {
    2080 *delayed = TRUE;
    2081 return SCIP_OKAY;
    2082 }
    2083 }
    2084
    2085 /* call separators with negative priority */
    2086 for( i = 0; i < set->nsepas && !(*cutoff) && !(*enoughcuts) && !SCIPsolveIsStopped(set, stat, FALSE); ++i )
    2087 {
    2088 if( SCIPsepaGetPriority(set->sepas[i]) >= 0 )
    2089 continue;
    2090
    2091 if( onlydelayed && !SCIPsepaWasSolDelayed(set->sepas[i]) )
    2092 continue;
    2093
    2094 SCIP_CALL( SCIPsepaExecSol(set->sepas[i], set, stat, sepastore, sol, actdepth, allowlocal, onlydelayed, &result) );
    2095 *cutoff = *cutoff || (result == SCIP_CUTOFF);
    2096 consadded = consadded || (result == SCIP_CONSADDED);
    2098 *enoughcuts = TRUE;
    2100 *enoughcuts = *enoughcuts || (result == SCIP_NEWROUND);
    2101 else
    2102 {
    2103 *enoughcuts = *enoughcuts || (SCIPsepastoreGetNCuts(sepastore) >= (SCIP_Longint)SCIPsetCeil(set,
    2105 || (result == SCIP_NEWROUND);
    2106 }
    2107 *delayed = *delayed || (result == SCIP_DELAYED);
    2108 if( *cutoff )
    2109 {
    2110 SCIPsetDebugMsg(set, " -> separator <%s> detected cutoff\n", SCIPsepaGetName(set->sepas[i]));
    2111 }
    2112
    2113 /* if we work off the delayed separators, we stop immediately if a cut was found */
    2114 if( onlydelayed && (result == SCIP_CONSADDED || result == SCIP_REDUCEDDOM || result == SCIP_SEPARATED || result == SCIP_NEWROUND) )
    2115 {
    2116 *delayed = TRUE;
    2117 return SCIP_OKAY;
    2118 }
    2119 }
    2120
    2121 /* process the constraints that were added during this separation round */
    2122 while( consadded )
    2123 {
    2124 assert(!onlydelayed);
    2125 consadded = FALSE;
    2126
    2127 for( i = 0; i < set->nconshdlrs && !(*cutoff) && !(*enoughcuts) && !SCIPsolveIsStopped(set, stat, FALSE); ++i )
    2128 {
    2129 SCIP_CALL( SCIPconshdlrSeparateSol(set->conshdlrs_sepa[i], blkmem, set, stat, sepastore, sol, actdepth, onlydelayed, &result) );
    2130 *cutoff = *cutoff || (result == SCIP_CUTOFF);
    2131 consadded = consadded || (result == SCIP_CONSADDED);
    2133 *enoughcuts = TRUE;
    2135 *enoughcuts = *enoughcuts || (result == SCIP_NEWROUND);
    2136 else
    2137 {
    2138 *enoughcuts = *enoughcuts || (SCIPsepastoreGetNCuts(sepastore) >= (SCIP_Longint)SCIPsetCeil(set,
    2140 || (result == SCIP_NEWROUND);
    2141 }
    2142 *delayed = *delayed || (result == SCIP_DELAYED);
    2143 if( *cutoff )
    2144 {
    2145 SCIPsetDebugMsg(set, " -> constraint handler <%s> detected cutoff in separation\n",
    2146 SCIPconshdlrGetName(set->conshdlrs_sepa[i]));
    2147 }
    2148 }
    2149 }
    2150
    2151 SCIPsetDebugMsg(set, " -> separation round finished: delayed=%u, enoughcuts=%u, cutoff=%u\n",
    2152 *delayed, *enoughcuts, *cutoff);
    2153
    2154 return SCIP_OKAY;
    2155}
    2156
    2157/** applies one round of separation on the given primal solution or on the LP solution */
    2159 BMS_BLKMEM* blkmem, /**< block memory buffers */
    2160 SCIP_SET* set, /**< global SCIP settings */
    2161 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
    2162 SCIP_STAT* stat, /**< dynamic problem statistics */
    2163 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
    2164 SCIP_EVENTFILTER* eventfilter, /**< global event filter */
    2165 SCIP_PROB* prob, /**< transformed problem after presolve */
    2166 SCIP_PRIMAL* primal, /**< primal data */
    2167 SCIP_TREE* tree, /**< branch and bound tree */
    2168 SCIP_LP* lp, /**< LP data */
    2169 SCIP_SEPASTORE* sepastore, /**< separation storage */
    2170 SCIP_SOL* sol, /**< primal solution that should be separated, or NULL for LP solution */
    2171 int actdepth, /**< current depth in the tree */
    2172 SCIP_Bool allowlocal, /**< should the separator be asked to separate local cuts */
    2173 SCIP_Bool onlydelayed, /**< should only delayed separators be called? */
    2174 SCIP_Bool* delayed, /**< pointer to store whether a separator was delayed */
    2175 SCIP_Bool* cutoff /**< pointer to store whether the node can be cut off */
    2176 )
    2177{
    2178 SCIP_Bool enoughcuts;
    2179
    2180 assert(delayed != NULL);
    2181 assert(cutoff != NULL);
    2182
    2183 *delayed = FALSE;
    2184 *cutoff = FALSE;
    2185 enoughcuts = FALSE;
    2186
    2187 if( sol == NULL )
    2188 {
    2189 SCIP_Bool lperror;
    2190 SCIP_Bool mustsepa;
    2191 SCIP_Bool mustprice;
    2192
    2193 /* apply a separation round on the LP solution */
    2194 lperror = FALSE;
    2195 mustsepa = FALSE;
    2196 mustprice = FALSE;
    2197 SCIP_CALL( separationRoundLP(blkmem, set, messagehdlr, stat, eventqueue, eventfilter, prob, primal, tree, lp, sepastore,
    2198 actdepth, 0.0, allowlocal, onlydelayed, delayed, &enoughcuts, cutoff, \
    2199 &lperror, &mustsepa, &mustprice) );
    2200 }
    2201 else
    2202 {
    2203 /* apply a separation round on the given primal solution */
    2204 SCIP_CALL( separationRoundSol(blkmem, set, stat, sepastore, sol, actdepth, allowlocal, onlydelayed, delayed, &enoughcuts, cutoff) );
    2205 }
    2206
    2207 return SCIP_OKAY;
    2208}
    2209
    2210/** solves the current LP completely with pricing in new variables */
    2212 BMS_BLKMEM* blkmem, /**< block memory buffers */
    2213 SCIP_SET* set, /**< global SCIP settings */
    2214 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
    2215 SCIP_STAT* stat, /**< dynamic problem statistics */
    2216 SCIP_PROB* transprob, /**< transformed problem */
    2217 SCIP_PROB* origprob, /**< original problem */
    2218 SCIP_PRIMAL* primal, /**< primal data */
    2219 SCIP_TREE* tree, /**< branch and bound tree */
    2220 SCIP_REOPT* reopt, /**< reoptimization data structure */
    2221 SCIP_LP* lp, /**< LP data */
    2222 SCIP_PRICESTORE* pricestore, /**< pricing storage */
    2223 SCIP_SEPASTORE* sepastore, /**< separation storage */
    2224 SCIP_CUTPOOL* cutpool, /**< global cutpool */
    2225 SCIP_BRANCHCAND* branchcand, /**< branching candidate storage */
    2226 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
    2227 SCIP_EVENTFILTER* eventfilter, /**< global event filter */
    2228 SCIP_CLIQUETABLE* cliquetable, /**< clique table data structure */
    2229 SCIP_Bool pretendroot, /**< should the pricers be called as if we are at the root node? */
    2230 SCIP_Bool displayinfo, /**< should info lines be displayed after each pricing round? */
    2231 int maxpricerounds, /**< maximal number of pricing rounds (-1: no limit);
    2232 * a finite limit means that the LP might not be solved to optimality! */
    2233 int* npricedcolvars, /**< pointer to store number of column variables after problem vars were priced */
    2234 SCIP_Bool* mustsepa, /**< pointer to store TRUE if a separation round should follow */
    2235 SCIP_Bool* lperror, /**< pointer to store whether an unresolved error in LP solving occured */
    2236 SCIP_Bool* aborted /**< pointer to store whether the pricing was aborted and the lower bound must
    2237 * not be used */
    2238 )
    2239{
    2240 SCIP_NODE* currentnode;
    2241 int npricerounds;
    2242 SCIP_Bool mustprice;
    2243 SCIP_Bool cutoff;
    2244 SCIP_Bool unbounded;
    2245
    2246 assert(transprob != NULL);
    2247 assert(lp != NULL);
    2248 assert(lp->flushed);
    2249 assert(lp->solved);
    2250 assert(npricedcolvars != NULL);
    2251 assert(mustsepa != NULL);
    2252 assert(lperror != NULL);
    2253 assert(aborted != NULL);
    2254
    2255 currentnode = SCIPtreeGetCurrentNode(tree);
    2256 assert(currentnode == SCIPtreeGetFocusNode(tree) || SCIPtreeProbing(tree));
    2257 *npricedcolvars = transprob->ncolvars;
    2258 *lperror = FALSE;
    2259 *aborted = FALSE;
    2260
    2261 /* if the LP is unbounded, we don't need to price */
    2262 mustprice = (SCIPlpGetSolstat(lp) == SCIP_LPSOLSTAT_OPTIMAL
    2265
    2266 /* if all the variables are already in the LP, we don't need to price */
    2267 mustprice = mustprice && !SCIPprobAllColsInLP(transprob, set, lp);
    2268
    2269 /* check if infinite number of pricing rounds should be used */
    2270 if( maxpricerounds == -1 )
    2271 maxpricerounds = INT_MAX;
    2272
    2273 /* pricing (has to be done completely to get a valid lower bound) */
    2274 npricerounds = 0;
    2275 while( !(*lperror) && mustprice && npricerounds < maxpricerounds )
    2276 {
    2277 SCIP_Bool enoughvars;
    2278 SCIP_RESULT result;
    2279 SCIP_Real lb;
    2280 SCIP_Bool foundsol;
    2281 SCIP_Bool stopearly;
    2282 SCIP_Bool stoppricing;
    2283 int p;
    2284
    2285 assert(lp->flushed);
    2286 assert(lp->solved);
    2288
    2289 /* check if pricing loop should be aborted */
    2290 if( SCIPsolveIsStopped(set, stat, FALSE) )
    2291 {
    2292 /* do not print the warning message if we stopped because the problem is solved */
    2294 SCIPmessagePrintWarning(messagehdlr, "pricing has been interrupted -- LP of current node is invalid\n");
    2295
    2296 *aborted = TRUE;
    2297 break;
    2298 }
    2299
    2300 /* call primal heuristics which are callable during pricing */
    2301 SCIP_CALL( SCIPprimalHeuristics(set, stat, transprob, primal, tree, lp, NULL, SCIP_HEURTIMING_DURINGPRICINGLOOP,
    2302 FALSE, &foundsol, &unbounded) );
    2303
    2304 /* price problem variables */
    2305 SCIPsetDebugMsg(set, "problem variable pricing\n");
    2306 assert(SCIPpricestoreGetNVars(pricestore) == 0);
    2307 assert(SCIPpricestoreGetNBoundResets(pricestore) == 0);
    2308 SCIP_CALL( SCIPpricestoreAddProbVars(pricestore, blkmem, set, stat, transprob, tree, lp, branchcand, eventqueue) );
    2309 *npricedcolvars = transprob->ncolvars;
    2310
    2311 /* call external pricers to create additional problem variables */
    2312 SCIPsetDebugMsg(set, "external variable pricing\n");
    2313
    2314 /* sort pricer algorithms by priority */
    2316
    2317 /* call external pricer algorithms, that are active for the current problem */
    2318 enoughvars = (SCIPsetGetPriceMaxvars(set, pretendroot) == INT_MAX ?
    2319 FALSE : SCIPpricestoreGetNVars(pricestore) >= SCIPsetGetPriceMaxvars(set, pretendroot) + 1);
    2320 stoppricing = FALSE;
    2321 for( p = 0; p < set->nactivepricers && !enoughvars; ++p )
    2322 {
    2323 SCIP_CALL( SCIPpricerExec(set->pricers[p], set, transprob, lp, pricestore, &lb, &stopearly, &result) );
    2324 switch ( result )
    2325 {
    2326 case SCIP_DIDNOTRUN:
    2327 {
    2328 /* pricer did not run */
    2329 SCIPsetDebugMsg(set, "pricing: pricer %s did not run\n", SCIPpricerGetName(set->pricers[p]));
    2330 *aborted = TRUE;
    2331 break;
    2332 }
    2333 case SCIP_SUCCESS:
    2334 {
    2335 /* pricer found new variables or proved that no variable with negative reduced cost exists */
    2336 SCIPsetDebugMsg(set, "pricing: pricer %s succeeded, lowerbound = %f\n",
    2337 SCIPpricerGetName(set->pricers[p]), lb);
    2338
    2339 enoughvars = SCIPpricestoreGetNVars(pricestore) > SCIPsetGetPriceMaxvars(set, pretendroot);
    2340
    2341 /* set stoppricing to TRUE, if the first pricer wants to stop pricing */
    2342 if( p == 0 && stopearly )
    2343 stoppricing = TRUE;
    2344
    2345 /* stoppricing only remains TRUE, if all other pricers want to stop pricing as well */
    2346 if( stoppricing && !stopearly )
    2347 stoppricing = FALSE;
    2348
    2349 /* update lower bound w.r.t. the lower bound given by the pricer */
    2350 SCIP_CALL( SCIPnodeUpdateLowerbound(currentnode, stat, set, eventfilter, tree, transprob, origprob, lb, NULL) );
    2351 SCIPsetDebugMsg(set, " -> new lower bound given by pricer %s: %g", SCIPpricerGetName(set->pricers[p]), lb);
    2352 break;
    2353 }
    2354 default:
    2355 {
    2356 SCIPerrorMessage("pricer <%s> returned invalid result <%d>\n", SCIPpricerGetName(set->pricers[p]), result);
    2357 return SCIP_INVALIDRESULT;
    2358 }
    2359 } /*lint !e788*/
    2360 }
    2361
    2362 /* apply the priced variables to the LP */
    2363 SCIP_CALL( SCIPpricestoreApplyVars(pricestore, blkmem, set, stat, eventqueue, transprob, tree, lp) );
    2364 assert(SCIPpricestoreGetNVars(pricestore) == 0);
    2365 assert(!lp->flushed || lp->solved);
    2366 mustprice = !lp->flushed || (transprob->ncolvars != *npricedcolvars);
    2367 *mustsepa = *mustsepa || !lp->flushed;
    2368
    2369 /* after adding columns, the LP should be primal feasible such that the primal simplex is applicable;
    2370 * if LP was infeasible, we have to use dual simplex
    2371 */
    2372 SCIPsetDebugMsg(set, "pricing: solve LP\n");
    2373 SCIP_CALL( SCIPlpSolveAndEval(lp, set, messagehdlr, blkmem, stat, eventqueue, eventfilter, transprob, -1LL, FALSE, TRUE, FALSE, FALSE, lperror) );
    2374 assert(lp->flushed);
    2375 assert(lp->solved || *lperror);
    2376
    2377 /* reset bounds temporarily set by pricer to their original values */
    2378 SCIPsetDebugMsg(set, "pricing: reset bounds\n");
    2379 SCIP_CALL( SCIPpricestoreResetBounds(pricestore, blkmem, set, stat, lp, branchcand, eventqueue) );
    2380 assert(SCIPpricestoreGetNVars(pricestore) == 0);
    2381 assert(SCIPpricestoreGetNBoundResets(pricestore) == 0);
    2382 assert(!lp->flushed || lp->solved || *lperror);
    2383
    2384 /* put all initial constraints into the LP */
    2385 SCIP_CALL( SCIPinitConssLP(blkmem, set, sepastore, cutpool, stat, transprob, origprob, tree, reopt, lp, branchcand, eventqueue,
    2386 eventfilter, cliquetable, FALSE, FALSE, &cutoff) );
    2387 assert(cutoff == FALSE);
    2388
    2389 mustprice = mustprice || !lp->flushed || (transprob->ncolvars != *npricedcolvars);
    2390 *mustsepa = *mustsepa || !lp->flushed;
    2391
    2392 /* if all pricers wanted to stop pricing, do not do another pricing round (LP value is no valid dual bound in this case) */
    2393 if( stoppricing )
    2394 {
    2395 SCIPsetDebugMsg(set, "pricing: stop pricing and perform early branching\n");
    2396 mustprice = FALSE;
    2397 *aborted = TRUE;
    2398 }
    2399
    2400 /* solve LP again after resetting bounds and adding new initial constraints (with dual simplex) */
    2401 SCIPsetDebugMsg(set, "pricing: solve LP after resetting bounds and adding new initial constraints\n");
    2402 SCIP_CALL( SCIPlpSolveAndEval(lp, set, messagehdlr, blkmem, stat, eventqueue, eventfilter, transprob, -1LL, FALSE, FALSE, FALSE, FALSE, lperror) );
    2403 assert(lp->flushed);
    2404 assert(lp->solved || *lperror);
    2405
    2406 /* remove previous primal ray, store new one if LP is unbounded */
    2407 SCIP_CALL( updatePrimalRay(blkmem, set, stat, transprob, primal, tree, lp, *lperror) );
    2408
    2409 /* increase pricing round counter */
    2410 stat->npricerounds++;
    2411 npricerounds++;
    2412
    2413 /* display node information line */
    2414 if( displayinfo && mustprice )
    2415 {
    2416 if( (SCIP_VERBLEVEL)set->disp_verblevel >= SCIP_VERBLEVEL_FULL
    2417 || ((SCIP_VERBLEVEL)set->disp_verblevel >= SCIP_VERBLEVEL_HIGH && npricerounds % 100 == 1) )
    2418 {
    2419 SCIP_CALL( SCIPdispPrintLine(set, messagehdlr, stat, NULL, TRUE, TRUE) );
    2420 }
    2421 }
    2422
    2423 /* if the LP is unbounded, we can stop pricing */
    2424 mustprice = mustprice &&
    2428
    2429 /* if the lower bound is already higher than the cutoff bound, we can stop pricing */
    2430 mustprice = mustprice && SCIPsetIsLT(set, SCIPnodeGetLowerbound(currentnode), primal->cutoffbound);
    2431 } /*lint !e438*/
    2432 assert(lp->flushed);
    2433 assert(lp->solved || *lperror);
    2434
    2435 *aborted = ( (*aborted) || (*lperror) || SCIPlpGetSolstat(lp) == SCIP_LPSOLSTAT_NOTSOLVED
    2436 || SCIPlpGetSolstat(lp) == SCIP_LPSOLSTAT_ERROR || npricerounds == maxpricerounds );
    2437
    2438 /* set information, whether the current lp is a valid relaxation of the current problem */
    2439 SCIPlpSetIsRelax(lp, !(*aborted));
    2440
    2441 return SCIP_OKAY; /*lint !e438*/
    2442}
    2443
    2444/** separates cuts of the cut pool */
    2445static
    2447 SCIP_CUTPOOL* cutpool, /**< cut pool */
    2448 BMS_BLKMEM* blkmem, /**< block memory */
    2449 SCIP_SET* set, /**< global SCIP settings */
    2450 SCIP_STAT* stat, /**< problem statistics data */
    2451 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
    2452 SCIP_EVENTFILTER* eventfilter, /**< event filter for global events */
    2453 SCIP_LP* lp, /**< current LP data */
    2454 SCIP_SEPASTORE* sepastore, /**< separation storage */
    2455 SCIP_Bool cutpoolisdelayed, /**< is the cutpool delayed (count cuts found)? */
    2456 SCIP_Bool root, /**< are we at the root node? */
    2457 int actdepth, /**< the depth of the focus node */
    2458 SCIP_Bool* enoughcuts, /**< pointer to store if enough cuts were found in current separation round */
    2459 SCIP_Bool* cutoff /**< pointer to store if a cutoff was detected */
    2460 )
    2461{
    2462 if( (set->sepa_poolfreq == 0 && actdepth == 0)
    2463 || (set->sepa_poolfreq > 0 && actdepth % set->sepa_poolfreq == 0) )
    2464 {
    2465 SCIP_RESULT result;
    2466
    2467 SCIP_CALL( SCIPcutpoolSeparate(cutpool, blkmem, set, stat, eventqueue, eventfilter, lp, sepastore, NULL, cutpoolisdelayed, root, &result) );
    2468 *cutoff = *cutoff || (result == SCIP_CUTOFF);
    2470 *enoughcuts = TRUE;
    2472 *enoughcuts = *enoughcuts || (result == SCIP_NEWROUND);
    2473 else
    2474 {
    2475 *enoughcuts = *enoughcuts || (SCIPsepastoreGetNCuts(sepastore) >= (SCIP_Longint)SCIPsetCeil(set,
    2477 || (result == SCIP_NEWROUND);
    2478 }
    2479 }
    2480
    2481 return SCIP_OKAY;
    2482}
    2483
    2484/** solve the current LP of a node with a price-and-cut loop */
    2485static
    2487 BMS_BLKMEM* blkmem, /**< block memory buffers */
    2488 SCIP_SET* set, /**< global SCIP settings */
    2489 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
    2490 SCIP_STAT* stat, /**< dynamic problem statistics */
    2491 SCIP_MEM* mem, /**< block memory pools */
    2492 SCIP_PROB* transprob, /**< transformed problem */
    2493 SCIP_PROB* origprob, /**< original problem */
    2494 SCIP_PRIMAL* primal, /**< primal data */
    2495 SCIP_TREE* tree, /**< branch and bound tree */
    2496 SCIP_REOPT* reopt, /**< reoptimization data structure */
    2497 SCIP_LP* lp, /**< LP data */
    2498 SCIP_PRICESTORE* pricestore, /**< pricing storage */
    2499 SCIP_SEPASTORE* sepastore, /**< separation storage */
    2500 SCIP_CUTPOOL* cutpool, /**< global cut pool */
    2501 SCIP_CUTPOOL* delayedcutpool, /**< global delayed cut pool */
    2502 SCIP_BRANCHCAND* branchcand, /**< branching candidate storage */
    2503 SCIP_CONFLICT* conflict, /**< conflict analysis data */
    2504 SCIP_CONFLICTSTORE* conflictstore, /**< conflict store */
    2505 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
    2506 SCIP_EVENTFILTER* eventfilter, /**< global event filter */
    2507 SCIP_CLIQUETABLE* cliquetable, /**< clique table data structure */
    2508 SCIP_Bool fullseparation, /**< are we in the first prop-and-cut-and-price loop? */
    2509 SCIP_Bool forcedlpsolve, /**< would SCIP abort if the LP is not solved? */
    2510 SCIP_Bool* propagateagain, /**< pointer to store whether we want to propagate again */
    2511 SCIP_Bool* cutoff, /**< pointer to store whether the node can be cut off */
    2512 SCIP_Bool* unbounded, /**< pointer to store whether an unbounded ray was found in the LP */
    2513 SCIP_Bool* lperror, /**< pointer to store whether an unresolved error in LP solving occured */
    2514 SCIP_Bool* pricingaborted /**< pointer to store whether the pricing was aborted and the lower bound must
    2515 * not be used */
    2516 )
    2517{
    2518 SCIP_NODE* focusnode;
    2519 SCIP_EVENT event;
    2520 SCIP_LPSOLSTAT stalllpsolstat;
    2521 SCIP_Real loclowerbound;
    2522 SCIP_Real glblowerbound;
    2523 SCIP_Real bounddist;
    2524 SCIP_Real stalllpobjval;
    2526 SCIP_Bool mustprice;
    2527 SCIP_Bool mustsepa;
    2528 SCIP_Bool delayedsepa;
    2529 SCIP_Bool root;
    2530 SCIP_Bool allowlocal;
    2531 int maxseparounds;
    2532 int maxsepapartialrounds;
    2533 int nsepastallrounds;
    2534 int maxsepastallrounds;
    2535 int stallnfracs;
    2536 int actdepth;
    2537 int npricedcolvars;
    2538
    2539 assert(set != NULL);
    2540 assert(blkmem != NULL);
    2541 assert(stat != NULL);
    2542 assert(transprob != NULL);
    2543 assert(tree != NULL);
    2544 assert(lp != NULL);
    2545 assert(pricestore != NULL);
    2546 assert(sepastore != NULL);
    2547 assert(cutpool != NULL);
    2548 assert(delayedcutpool != NULL);
    2549 assert(primal != NULL);
    2550 assert(cutoff != NULL);
    2551 assert(unbounded != NULL);
    2552 assert(lperror != NULL);
    2553
    2554 focusnode = SCIPtreeGetFocusNode(tree);
    2555 assert(focusnode != NULL);
    2556 assert(SCIPnodeGetType(focusnode) == SCIP_NODETYPE_FOCUSNODE);
    2557 actdepth = SCIPnodeGetDepth(focusnode);
    2558 root = (actdepth == 0);
    2559
    2560 /* check, if we want to separate at this node */
    2561 loclowerbound = SCIPnodeGetLowerbound(focusnode);
    2562 glblowerbound = SCIPtreeGetLowerbound(tree, set);
    2563 assert(primal->cutoffbound > glblowerbound);
    2564 bounddist = (loclowerbound - glblowerbound)/(primal->cutoffbound - glblowerbound);
    2565 allowlocal = SCIPsetIsLE(set, bounddist, set->sepa_maxlocalbounddist);
    2566 separate = (set->sepa_maxruns == -1 || stat->nruns < set->sepa_maxruns);
    2567
    2568 /* determine maximal number of separation rounds */
    2569 maxseparounds = (root ? set->sepa_maxroundsroot : set->sepa_maxrounds);
    2570 if( maxseparounds == -1 )
    2571 maxseparounds = INT_MAX;
    2572 if( stat->nruns > 1 && root && set->sepa_maxroundsrootsubrun >= 0 )
    2573 maxseparounds = MIN(maxseparounds, set->sepa_maxroundsrootsubrun);
    2574
    2575 /* determine maximal number of partial rounds excluding delayed round */
    2576 maxsepapartialrounds = INT_MAX;
    2577 if( !fullseparation && set->sepa_maxaddrounds >= 0 )
    2578 maxsepapartialrounds = stat->nseparounds + set->sepa_maxaddrounds;
    2579
    2580 /* determine maximal number of stalling rounds */
    2581 maxsepastallrounds = root ? set->sepa_maxstallroundsroot : set->sepa_maxstallrounds;
    2582 if( maxsepastallrounds == -1 )
    2583 maxsepastallrounds = INT_MAX;
    2584
    2585 /* solve initial LP of price-and-cut loop */
    2586 SCIPsetDebugMsg(set, "node: solve LP with price and cut\n");
    2587 SCIP_CALL( SCIPlpSolveAndEval(lp, set, messagehdlr, blkmem, stat, eventqueue, eventfilter, transprob,
    2588 set->lp_iterlim, FALSE, TRUE, FALSE, forcedlpsolve, lperror) );
    2589 assert(lp->flushed);
    2590 assert(lp->solved || *lperror);
    2591
    2592 /* remove previous primal ray, store new one if LP is unbounded */
    2593 SCIP_CALL( updatePrimalRay(blkmem, set, stat, transprob, primal, tree, lp, *lperror) );
    2594
    2595 /* price-and-cut loop */
    2596 npricedcolvars = transprob->ncolvars;
    2597 mustprice = TRUE;
    2598 mustsepa = separate;
    2599 delayedsepa = FALSE;
    2600 *cutoff = FALSE;
    2601 *unbounded = (SCIPlpGetSolstat(lp) == SCIP_LPSOLSTAT_UNBOUNDEDRAY);
    2602 nsepastallrounds = 0;
    2603 stalllpsolstat = SCIP_LPSOLSTAT_NOTSOLVED;
    2604 stalllpobjval = SCIP_REAL_MIN;
    2605 stallnfracs = INT_MAX;
    2606 lp->installing = FALSE;
    2607 while( !(*cutoff) && !(*unbounded) && !(*lperror) && ( mustprice || mustsepa ) )
    2608 {
    2609 SCIPsetDebugMsg(set, "-------- node solving loop --------\n");
    2610 assert(lp->flushed);
    2611 assert(lp->solved);
    2612
    2613 /* solve the LP with pricing in new variables */
    2614 while( mustprice && !(*lperror) )
    2615 {
    2616 SCIP_CALL( SCIPpriceLoop(blkmem, set, messagehdlr, stat, transprob, origprob, primal, tree, reopt, lp,
    2617 pricestore, sepastore, cutpool, branchcand, eventqueue, eventfilter, cliquetable, root, root, -1, &npricedcolvars,
    2618 &mustsepa, lperror, pricingaborted) );
    2619
    2620 mustprice = FALSE;
    2621
    2622 assert(lp->flushed);
    2623 assert(lp->solved || *lperror);
    2624
    2625 /* update lower bound w.r.t. the LP solution */
    2626 if( !(*lperror) && !(*pricingaborted) && SCIPlpIsRelax(lp) )
    2627 {
    2628 SCIP_CALL( SCIPnodeUpdateLowerboundLP(focusnode, set, stat, messagehdlr, eventfilter, tree, transprob, origprob, lp) );
    2629 SCIPsetDebugMsg(set, " -> new lower bound: %g (LP status: %d, LP obj: %g)\n",
    2630 SCIPnodeGetLowerbound(focusnode), SCIPlpGetSolstat(lp), SCIPlpGetObjval(lp, set, transprob));
    2631
    2632 /* update node estimate */
    2633 SCIP_CALL( updateEstimate(set, stat, tree, lp, branchcand) );
    2634
    2635 if( root && SCIPlpGetSolstat(lp) == SCIP_LPSOLSTAT_OPTIMAL )
    2636 SCIPprobUpdateBestRootSol(transprob, set, stat, lp);
    2637 }
    2638 else
    2639 {
    2640 SCIPsetDebugMsg(set, " -> error solving LP or pricing aborted. keeping old bound: %g\n", SCIPnodeGetLowerbound(focusnode));
    2641 }
    2642
    2643 /* display node information line for root node */
    2644 if( root && (SCIP_VERBLEVEL)set->disp_verblevel >= SCIP_VERBLEVEL_HIGH )
    2645 {
    2646 SCIP_CALL( SCIPdispPrintLine(set, messagehdlr, stat, NULL, TRUE, TRUE) );
    2647 }
    2648
    2649 if( !(*lperror) )
    2650 {
    2651 /* call propagators that are applicable during LP solving loop only if the node is not cut off */
    2652 if( SCIPsetIsLT(set, SCIPnodeGetLowerbound(focusnode), primal->cutoffbound) )
    2653 {
    2654 SCIP_Longint oldnboundchgs;
    2655 SCIP_Longint oldninitconssadded;
    2656 SCIP_Bool postpone;
    2657
    2658 oldnboundchgs = stat->nboundchgs;
    2659 oldninitconssadded = stat->ninitconssadded;
    2660
    2661 SCIPsetDebugMsg(set, " -> LP solved: call propagators that are applicable during LP solving loop\n");
    2662
    2663 SCIP_CALL( propagateDomains(blkmem, set, stat, tree, SCIPtreeGetCurrentDepth(tree), 0, FALSE,
    2664 SCIP_PROPTIMING_DURINGLPLOOP, cutoff, &postpone) );
    2665 assert(BMSgetNUsedBufferMemory(mem->buffer) == 0);
    2666 assert(!postpone);
    2667
    2668 if( stat->ninitconssadded != oldninitconssadded )
    2669 {
    2670 SCIPsetDebugMsg(set, "new initial constraints added during propagation: old=%" SCIP_LONGINT_FORMAT ", new=%" SCIP_LONGINT_FORMAT "\n", oldninitconssadded, stat->ninitconssadded);
    2671
    2672 SCIP_CALL( SCIPinitConssLP(blkmem, set, sepastore, cutpool, stat, transprob, origprob, tree, reopt, lp,
    2673 branchcand, eventqueue, eventfilter, cliquetable, FALSE, FALSE, cutoff) );
    2674 }
    2675
    2676 if( !(*cutoff) && !(*unbounded) )
    2677 {
    2678 /* if we found something, solve LP again */
    2679 if( !lp->flushed )
    2680 {
    2681 SCIPsetDebugMsg(set, " -> found reduction: resolve LP\n");
    2682
    2683 /* in the root node, remove redundant rows permanently from the LP */
    2684 if( root )
    2685 {
    2686 SCIP_CALL( SCIPlpFlush(lp, blkmem, set, transprob, eventqueue) );
    2687 SCIP_CALL( SCIPlpRemoveRedundantRows(lp, blkmem, set, stat, eventqueue, eventfilter) );
    2688 }
    2689
    2690 /* resolve LP */
    2691 SCIP_CALL( SCIPlpSolveAndEval(lp, set, messagehdlr, blkmem, stat, eventqueue, eventfilter, transprob,
    2692 set->lp_iterlim, FALSE, TRUE, FALSE, FALSE, lperror) );
    2693 assert(lp->flushed);
    2694 assert(lp->solved || *lperror);
    2695
    2696 /* remove previous primal ray, store new one if LP is unbounded */
    2697 SCIP_CALL( updatePrimalRay(blkmem, set, stat, transprob, primal, tree, lp, *lperror) );
    2698
    2699 mustprice = TRUE;
    2700 *propagateagain = TRUE;
    2701 }
    2702 /* propagation might have changed the best bound of loose variables, thereby changing the loose objective
    2703 * value which is added to the LP value; because of the loose status, the LP might not be reoptimized,
    2704 * but the lower bound of the node needs to be updated
    2705 */
    2706 else if( stat->nboundchgs > oldnboundchgs )
    2707 {
    2708 *propagateagain = TRUE;
    2709
    2710 if( lp->solved && SCIPprobAllColsInLP(transprob, set, lp) && SCIPlpIsRelax(lp) )
    2711 {
    2712 assert(lp->flushed);
    2713 assert(lp->solved);
    2714
    2715 SCIP_CALL( SCIPnodeUpdateLowerboundLP(focusnode, set, stat, messagehdlr, eventfilter, tree, transprob, origprob, lp) );
    2716 SCIPsetDebugMsg(set, " -> new lower bound: %g (LP status: %d, LP obj: %g)\n",
    2717 SCIPnodeGetLowerbound(focusnode), SCIPlpGetSolstat(lp), SCIPlpGetObjval(lp, set, transprob));
    2718
    2719 /* update node estimate */
    2720 SCIP_CALL( updateEstimate(set, stat, tree, lp, branchcand) );
    2721
    2722 if( root && SCIPlpGetSolstat(lp) == SCIP_LPSOLSTAT_OPTIMAL )
    2723 SCIPprobUpdateBestRootSol(transprob, set, stat, lp);
    2724 }
    2725 }
    2726 }
    2727 }
    2728 }
    2729
    2730 /* call primal heuristics that are applicable during node LP solving loop */
    2731 if( !*cutoff && !(*unbounded) && SCIPlpGetSolstat(lp) == SCIP_LPSOLSTAT_OPTIMAL )
    2732 {
    2733 SCIP_Bool foundsol;
    2734
    2735 SCIP_CALL( SCIPprimalHeuristics(set, stat, transprob, primal, tree, lp, NULL, SCIP_HEURTIMING_DURINGLPLOOP,
    2736 FALSE, &foundsol, unbounded) );
    2737 assert(BMSgetNUsedBufferMemory(mem->buffer) == 0);
    2738
    2739 *lperror = *lperror || lp->resolvelperror;
    2740 } /*lint !e438*/
    2741 }
    2742 assert(lp->flushed || *cutoff || *unbounded);
    2743 assert(lp->solved || *lperror || *cutoff || *unbounded);
    2744
    2745 /* if we are infeasible, unbounded, exceeded a separation round, the objective, or a global performance limit,
    2746 * we don't need to separate cuts
    2747 * (the global limits are only checked at the root node in order to not query system time too often)
    2748 */
    2749 mustsepa = mustsepa && separate && !(*cutoff) && !(*unbounded)
    2750 && stat->nseparounds < maxseparounds
    2751 && ( delayedsepa || stat->nseparounds < maxsepapartialrounds )
    2752 && nsepastallrounds < maxsepastallrounds
    2754 && SCIPsetIsLT(set, SCIPnodeGetLowerbound(focusnode), primal->cutoffbound)
    2755 && ( !root || !SCIPsolveIsStopped(set, stat, FALSE) );
    2756
    2757 /* separation (needs not to be done completely, because we just want to increase the lower bound) */
    2758 if( mustsepa )
    2759 {
    2760 SCIP_Longint olddomchgcount;
    2761 SCIP_Longint oldninitconssadded;
    2762 SCIP_Bool enoughcuts;
    2763
    2764 assert(lp->flushed);
    2765 assert(lp->solved);
    2767 assert(!(*lperror));
    2768 assert(!(*cutoff));
    2769
    2770 olddomchgcount = stat->domchgcount;
    2771 oldninitconssadded = stat->ninitconssadded;
    2772
    2773 mustsepa = FALSE;
    2774 delayedsepa = delayedsepa && stat->nseparounds >= maxsepapartialrounds;
    2776
    2777 /* global cut pool separation */
    2778 if( !enoughcuts && !delayedsepa )
    2779 {
    2780 SCIP_CALL( cutpoolSeparate(cutpool, blkmem, set, stat, eventqueue, eventfilter, lp, sepastore, FALSE, root,
    2781 actdepth, &enoughcuts, cutoff) );
    2782
    2783 if( *cutoff )
    2784 {
    2785 SCIPsetDebugMsg(set, " -> global cut pool detected cutoff\n");
    2786 }
    2787 }
    2788 assert(lp->flushed);
    2789 assert(lp->solved);
    2791 assert(!(*lperror));
    2792
    2793 /* separate constraints and LP */
    2794 if( !(*cutoff) && !enoughcuts )
    2795 {
    2796 /* constraint and LP separation */
    2797 SCIPsetDebugMsg(set, "constraint and LP separation\n");
    2798
    2799 /* apply a separation round */
    2800 SCIP_CALL( separationRoundLP(blkmem, set, messagehdlr, stat, eventqueue, eventfilter, transprob, primal, tree,
    2801 lp, sepastore, actdepth, bounddist, allowlocal, delayedsepa,
    2802 &delayedsepa, &enoughcuts, cutoff, lperror, &mustsepa, &mustprice) );
    2803 assert(BMSgetNUsedBufferMemory(mem->buffer) == 0);
    2804
    2805 /* if we are in the last separation or stall round, also call the delayed separators */
    2806 if( !(*cutoff) && !(*lperror) && lp->solved && !enoughcuts && delayedsepa
    2807 && ( stat->nseparounds + 1 >= maxseparounds || nsepastallrounds + 1 >= maxsepastallrounds )
    2809 {
    2810 SCIP_CALL( separationRoundLP(blkmem, set, messagehdlr, stat, eventqueue, eventfilter, transprob, primal,
    2811 tree, lp, sepastore, actdepth, bounddist, allowlocal, delayedsepa,
    2812 &delayedsepa, &enoughcuts, cutoff, lperror, &mustsepa, &mustprice) );
    2813 assert(BMSgetNUsedBufferMemory(mem->buffer) == 0);
    2814 }
    2815 }
    2816
    2817 /* call global cut pool separation again since separators may add cuts to the pool instead of the sepastore */
    2818 if( !(*cutoff) && !(*lperror) && lp->solved && SCIPlpGetSolstat(lp) == SCIP_LPSOLSTAT_OPTIMAL && !enoughcuts )
    2819 {
    2820 SCIP_CALL( cutpoolSeparate(cutpool, blkmem, set, stat, eventqueue, eventfilter, lp, sepastore, FALSE, root,
    2821 actdepth, &enoughcuts, cutoff) );
    2822
    2823 if( *cutoff )
    2824 {
    2825 SCIPsetDebugMsg(set, " -> global cut pool detected cutoff\n");
    2826 }
    2827 }
    2828
    2829 /* delayed global cut pool separation */
    2830 if( !(*cutoff) && !(*lperror) && lp->solved && SCIPlpGetSolstat(lp) == SCIP_LPSOLSTAT_OPTIMAL && SCIPsepastoreGetNCuts(sepastore) == 0 && !enoughcuts )
    2831 {
    2832 SCIP_CALL( cutpoolSeparate(delayedcutpool, blkmem, set, stat, eventqueue, eventfilter, lp, sepastore, TRUE,
    2833 root, actdepth, &enoughcuts, cutoff) );
    2834
    2835 if( *cutoff )
    2836 {
    2837 SCIPsetDebugMsg(set, " -> delayed global cut pool detected cutoff\n");
    2838 }
    2839 assert(lp->solved);
    2841 assert(lp->flushed);
    2842 }
    2843
    2844 /* delayed separation if no cuts where produced */
    2845 if( !(*cutoff) && !(*lperror) && SCIPlpGetSolstat(lp) == SCIP_LPSOLSTAT_OPTIMAL && SCIPsepastoreGetNCuts(sepastore) == 0 && delayedsepa )
    2846 {
    2847 SCIP_CALL( separationRoundLP(blkmem, set, messagehdlr, stat, eventqueue, eventfilter, transprob, primal,
    2848 tree, lp, sepastore, actdepth, bounddist, allowlocal, delayedsepa,
    2849 &delayedsepa, &enoughcuts, cutoff, lperror, &mustsepa, &mustprice) );
    2850 assert(BMSgetNUsedBufferMemory(mem->buffer) == 0);
    2851
    2852 /* call delayed cut pool separation again, since separators may add cuts to the pool instead of the sepastore */
    2853 if( !(*cutoff) && SCIPlpGetSolstat(lp) == SCIP_LPSOLSTAT_OPTIMAL )
    2854 {
    2855 assert( !(*lperror) );
    2856
    2857 SCIP_CALL( cutpoolSeparate(delayedcutpool, blkmem, set, stat, eventqueue, eventfilter, lp, sepastore, TRUE,
    2858 root, actdepth, &enoughcuts, cutoff) );
    2859
    2860 if( *cutoff )
    2861 {
    2862 SCIPsetDebugMsg(set, " -> delayed global cut pool detected cutoff\n");
    2863 }
    2865 assert(lp->flushed);
    2866 assert(lp->solved);
    2867 }
    2868 }
    2869
    2870 assert(*cutoff || *lperror || SCIPlpIsSolved(lp));
    2871 assert(!SCIPlpIsSolved(lp)
    2878
    2879 if( *cutoff || *lperror
    2882 {
    2883 /* the found cuts are of no use, because the node is infeasible anyway (or we have an error in the LP) */
    2884 SCIP_CALL( SCIPsepastoreClearCuts(sepastore, blkmem, set, eventqueue, eventfilter, lp) );
    2885 }
    2886 else
    2887 {
    2888 /* apply found cuts */
    2889 SCIP_CALL( SCIPsepastoreApplyCuts(sepastore, blkmem, set, stat, transprob, origprob, tree, reopt, lp,
    2890 branchcand, eventqueue, eventfilter, cliquetable, root, SCIP_EFFICIACYCHOICE_LP, cutoff) );
    2891
    2892 if( !(*cutoff) )
    2893 {
    2894 mustprice = mustprice || !lp->flushed || (transprob->ncolvars != npricedcolvars);
    2895 mustsepa = mustsepa || !lp->flushed;
    2896
    2897 /* if a new bound change (e.g. a cut with only one column) was found, propagate domains again */
    2898 if( stat->domchgcount != olddomchgcount )
    2899 {
    2900 SCIPsetDebugMsg(set, " -> separation changed bound: propagate again\n");
    2901
    2902 *propagateagain = TRUE;
    2903
    2904 /* in the root node, remove redundant rows permanently from the LP */
    2905 if( root )
    2906 {
    2907 SCIP_CALL( SCIPlpFlush(lp, blkmem, set, transprob, eventqueue) );
    2908 SCIP_CALL( SCIPlpRemoveRedundantRows(lp, blkmem, set, stat, eventqueue, eventfilter) );
    2909 }
    2910 }
    2911
    2912 if( stat->ninitconssadded != oldninitconssadded )
    2913 {
    2914 SCIPsetDebugMsg(set, "new initial constraints added during propagation: old=%" SCIP_LONGINT_FORMAT ", new=%" SCIP_LONGINT_FORMAT "\n",
    2915 oldninitconssadded, stat->ninitconssadded);
    2916
    2917 SCIP_CALL( SCIPinitConssLP(blkmem, set, sepastore, cutpool, stat, transprob, origprob, tree, reopt, lp,
    2918 branchcand, eventqueue, eventfilter, cliquetable, FALSE, FALSE, cutoff) );
    2919 }
    2920
    2921 if( !(*cutoff) )
    2922 {
    2923 SCIP_Real lpobjval;
    2924
    2925 /* solve LP (with dual simplex) */
    2926 SCIPsetDebugMsg(set, "separation: solve LP\n");
    2927 SCIP_CALL( SCIPlpSolveAndEval(lp, set, messagehdlr, blkmem, stat, eventqueue, eventfilter, transprob,
    2928 set->lp_iterlim, FALSE, TRUE, FALSE, FALSE, lperror) );
    2929 assert(lp->flushed);
    2930 assert(lp->solved || *lperror);
    2931
    2932 /* remove previous primal ray, store new one if LP is unbounded */
    2933 SCIP_CALL( updatePrimalRay(blkmem, set, stat, transprob, primal, tree, lp, *lperror) );
    2934
    2935 if( !(*lperror) )
    2936 {
    2937 SCIP_Bool stalling;
    2938
    2939 /* propagation might have changed the best bound of loose variables, thereby changing the loose objective value
    2940 * which is added to the LP value; because of the loose status, the LP might not be reoptimized, but the lower
    2941 * bound of the node needs to be updated
    2942 */
    2943 if( stat->domchgcount != olddomchgcount && (!mustprice || mustsepa) && !(*cutoff)
    2944 && SCIPprobAllColsInLP(transprob, set, lp) && SCIPlpIsRelax(lp) )
    2945 {
    2946 SCIP_CALL( SCIPnodeUpdateLowerboundLP(focusnode, set, stat, messagehdlr, eventfilter, tree, transprob, origprob, lp) );
    2947 SCIPsetDebugMsg(set, " -> new lower bound: %g (LP status: %d, LP obj: %g)\n",
    2948 SCIPnodeGetLowerbound(focusnode), SCIPlpGetSolstat(lp), SCIPlpGetObjval(lp, set, transprob));
    2949
    2950 /* update node estimate */
    2951 SCIP_CALL( updateEstimate(set, stat, tree, lp, branchcand) );
    2952
    2953 if( root && SCIPlpGetSolstat(lp) == SCIP_LPSOLSTAT_OPTIMAL )
    2954 SCIPprobUpdateBestRootSol(transprob, set, stat, lp);
    2955 }
    2956
    2957 /* check if we are stalling
    2958 * If we have an LP solution, then we are stalling if
    2959 * we had an LP solution before and
    2960 * the LP value did not improve and
    2961 * the number of fractional variables did not decrease.
    2962 * If we do not have an LP solution, then we are stalling if the solution status of the LP did not change.
    2963 */
    2965 {
    2966 SCIP_Real objreldiff;
    2967 int nfracs;
    2968
    2969 SCIP_CALL( SCIPbranchcandGetLPCands(branchcand, set, stat, lp, NULL, NULL, NULL, &nfracs, NULL,
    2970 NULL) );
    2971 lpobjval = SCIPlpGetObjval(lp, set, transprob);
    2972
    2973 objreldiff = SCIPrelDiff(lpobjval, stalllpobjval);
    2974 SCIPsetDebugMsg(set, " -> LP bound moved from %g to %g (reldiff: %g)\n",
    2975 stalllpobjval, lpobjval, objreldiff);
    2976
    2977 stalling = (stalllpsolstat == SCIP_LPSOLSTAT_OPTIMAL &&
    2978 objreldiff <= 1e-04 &&
    2979 nfracs >= (0.9 - 0.1 * nsepastallrounds) * stallnfracs);
    2980
    2981 stalllpobjval = lpobjval;
    2982 stallnfracs = nfracs;
    2983 } /*lint !e438*/
    2984 else
    2985 {
    2986 stalling = (stalllpsolstat == SCIPlpGetSolstat(lp));
    2987 }
    2988
    2989 if( !stalling )
    2990 {
    2991 nsepastallrounds = 0;
    2992 lp->installing = FALSE;
    2993 }
    2994 else
    2995 {
    2996 ++nsepastallrounds;
    2997 }
    2998 stalllpsolstat = SCIPlpGetSolstat(lp);
    2999
    3000 /* tell LP that we are stalling */
    3001 if( nsepastallrounds + 1 >= maxsepastallrounds )
    3002 lp->installing = TRUE;
    3003
    3004 SCIPsetDebugMsg(set, " -> nsepastallrounds=%d/%d\n", nsepastallrounds, maxsepastallrounds);
    3005 }
    3006 }
    3007 }
    3008 }
    3009 assert(*cutoff || *lperror || (lp->flushed && lp->solved)); /* cutoff: LP may be unsolved due to bound changes */
    3010
    3011 /* increase separation round counter */
    3012 ++stat->nseparounds;
    3013
    3014 SCIPsetDebugMsg(set, "separation round %d/%d finished (%d/%d stall rounds): mustprice=%u, mustsepa=%u, delayedsepa=%u, propagateagain=%u\n",
    3015 stat->nseparounds, maxseparounds, nsepastallrounds, maxsepastallrounds, mustprice, mustsepa, delayedsepa, *propagateagain);
    3016 }
    3017
    3018 /* in exact solving mode, solve the LP once more after all separation rounds are finished, now allowing one exact
    3019 * LP solve if desired (solving the LP exactly after each separation round can be prohibitively slow and is
    3020 * therefore disabled)
    3021 */
    3022 if( set->exact_enable && !mustsepa )
    3023 {
    3024 lp->solved = FALSE;
    3026 SCIP_CALL( SCIPlpSolveAndEval(lp, set, messagehdlr, blkmem, stat, eventqueue, eventfilter, transprob,
    3027 set->lp_iterlim, FALSE, FALSE, FALSE, FALSE, lperror) );
    3028 if( !(*lperror) )
    3030 }
    3031 }
    3032
    3033 if( root && nsepastallrounds >= maxsepastallrounds )
    3034 {
    3035 SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
    3036 "Truncate separation round because of stalling (%d stall rounds).\n", maxsepastallrounds);
    3037 }
    3038
    3039 if( !*lperror )
    3040 {
    3041 /* update pseudo cost values for continuous variables, if it should be delayed */
    3042 SCIP_CALL( updatePseudocost(set, stat, transprob, tree, lp, FALSE, set->branch_delaypscost) );
    3043 }
    3044
    3045 /* update lower bound w.r.t. the LP solution */
    3046 if( !(*cutoff) && !(*lperror) )
    3047 {
    3048 assert(lp->flushed);
    3049 assert(lp->solved);
    3050
    3051 if( SCIPlpIsRelax(lp) )
    3052 {
    3053 SCIP_CALL( SCIPnodeUpdateLowerboundLP(focusnode, set, stat, messagehdlr, eventfilter, tree, transprob, origprob, lp) );
    3054 }
    3055
    3056 /* update node estimate */
    3057 SCIP_CALL( updateEstimate(set, stat, tree, lp, branchcand) );
    3058
    3059 /* issue LPSOLVED event */
    3061 {
    3063 SCIP_CALL( SCIPeventChgNode(&event, focusnode) );
    3064 SCIP_CALL( SCIPeventProcess(&event, set, NULL, NULL, NULL, eventfilter) );
    3065 }
    3066
    3067 /* if the LP is a relaxation and we are not solving exactly, then we may analyze an infeasible or bound exceeding
    3068 * LP (not necessary in the root node) and cut off the current node
    3069 */
    3070 if( !root && SCIPlpIsRelax(lp) && SCIPprobAllColsInLP(transprob, set, lp)
    3072 {
    3073 SCIP_CALL( SCIPconflictAnalyzeLP(conflict, conflictstore, blkmem, set, stat, transprob, origprob, tree, reopt,
    3074 lp, branchcand, eventqueue, eventfilter, cliquetable, NULL) );
    3075 *cutoff = TRUE;
    3076 }
    3077 }
    3078
    3079 /* check for unboundedness */
    3080 if( !(*lperror) )
    3081 *unbounded = (SCIPlpGetSolstat(lp) == SCIP_LPSOLSTAT_UNBOUNDEDRAY);
    3082
    3083 lp->installing = FALSE;
    3084
    3085 /* check for cutoff */
    3086 if( *cutoff )
    3087 {
    3088 SCIP_CALL( SCIPnodeCutoff(focusnode, set, stat, eventfilter, tree, transprob, origprob, reopt, lp, blkmem) );
    3089
    3090 if( SCIPisCertified(set->scip) )
    3091 {
    3092 if( !(lp->solved && lp->flushed) )
    3096 else if( tree->focusnodehaslp )
    3098 }
    3099 }
    3100
    3101 SCIPsetDebugMsg(set, " -> final lower bound: %g (LP status: %d, LP obj: %g)\n",
    3103 (*cutoff || *unbounded) ? SCIPsetInfinity(set) : *lperror ? -SCIPsetInfinity(set) : SCIPlpGetObjval(lp, set, transprob));
    3104
    3105 return SCIP_OKAY; /*lint !e438*/
    3106}
    3107
    3108/** updates the current lower bound with the pseudo objective value, cuts off node by bounding, and applies conflict
    3109 * analysis if the pseudo objective lead to the cutoff
    3110 */
    3111static
    3113 BMS_BLKMEM* blkmem, /**< block memory buffers */
    3114 SCIP_SET* set, /**< global SCIP settings */
    3115 SCIP_STAT* stat, /**< dynamic problem statistics */
    3116 SCIP_PROB* transprob, /**< tranformed problem after presolve */
    3117 SCIP_PROB* origprob, /**< original problem */
    3118 SCIP_PRIMAL* primal, /**< primal data */
    3119 SCIP_TREE* tree, /**< branch and bound tree */
    3120 SCIP_REOPT* reopt, /**< reoptimization data structure */
    3121 SCIP_LP* lp, /**< LP data */
    3122 SCIP_BRANCHCAND* branchcand, /**< branching candidate storage */
    3123 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
    3124 SCIP_EVENTFILTER* eventfilter, /**< global event filter */
    3125 SCIP_CONFLICT* conflict, /**< conflict analysis data */
    3126 SCIP_CLIQUETABLE* cliquetable, /**< clique table data structure */
    3127 SCIP_Bool* cutoff /**< pointer to store TRUE, if the node can be cut off */
    3128 )
    3129{
    3130 assert(transprob != NULL);
    3131 assert(origprob != NULL);
    3132 assert(primal != NULL);
    3133 assert(cutoff != NULL);
    3134
    3135 if( !(*cutoff) )
    3136 {
    3137 SCIP_NODE* focusnode;
    3138 SCIP_Real pseudoobjval;
    3139
    3140 /* get current focus node */
    3141 focusnode = SCIPtreeGetFocusNode(tree);
    3142
    3143 /* update lower bound w.r.t. the pseudo solution */
    3144 pseudoobjval = SCIPlpGetPseudoObjval(lp, set, transprob);
    3145 /* we don't need print the pseudoobj to certificate here (when using exact solving mode), since we have to print it immediatly when branching anyway */
    3146 SCIP_CALL( SCIPnodeUpdateLowerbound(focusnode, stat, set, eventfilter, tree, transprob, origprob, pseudoobjval, NULL) );
    3147 SCIPsetDebugMsg(set, " -> lower bound: %g [%g] (pseudoobj: %g [%g]), cutoff bound: %g [%g]\n",
    3148 SCIPnodeGetLowerbound(focusnode), SCIPprobExternObjval(transprob, origprob, set, SCIPnodeGetLowerbound(focusnode)) + SCIPgetOrigObjoffset(set->scip),
    3149 pseudoobjval, SCIPprobExternObjval(transprob, origprob, set, pseudoobjval) + SCIPgetOrigObjoffset(set->scip),
    3150 primal->cutoffbound, SCIPprobExternObjval(transprob, origprob, set, primal->cutoffbound) + SCIPgetOrigObjoffset(set->scip));
    3151
    3152 if( pseudoobjval == SCIPnodeGetLowerbound(focusnode) && focusnode->number != 1 ) /*lint !e777*/
    3153 {
    3154 SCIP_CALL( SCIPcertificatePrintDualboundPseudo(stat->certificate, lp->lpexact, focusnode, set, transprob, FALSE, -1, -1L, pseudoobjval) );
    3155 }
    3156
    3157#ifdef SCIP_DEBUG
    3158 if( set->exact_enable )
    3159 SCIPrationalDebugMessage(" -> exact lower bound: %q, exact cutoff bound: %q\n",
    3160 SCIPnodeGetLowerboundExact(focusnode), primal->cutoffboundexact);
    3161#endif
    3162
    3163 /* check for infeasible node by bounding */
    3164 if( (!set->exact_enable && SCIPsetIsGE(set, SCIPnodeGetLowerbound(focusnode), primal->cutoffbound))
    3165 || (set->exact_enable && SCIPrationalIsGE(SCIPnodeGetLowerboundExact(focusnode), primal->cutoffboundexact)) )
    3166 {
    3167 *cutoff = TRUE;
    3168
    3169 /* call pseudo conflict analysis, if the node is cut off due to the pseudo objective value */
    3170 if( !SCIPsetIsInfinity(set, -pseudoobjval) && !SCIPsetIsInfinity(set, primal->cutoffbound) && SCIPsetIsGE(set, pseudoobjval, primal->cutoffbound) )
    3171 {
    3172 SCIP_CALL( SCIPconflictAnalyzePseudo(conflict, blkmem, set, stat, transprob, origprob, tree, reopt, lp, branchcand, eventqueue, eventfilter, cliquetable, NULL) );
    3173 }
    3174 }
    3175 }
    3176
    3177 return SCIP_OKAY;
    3178}
    3179
    3180/** marks all relaxators to be unsolved */
    3181static
    3183 SCIP_SET* set, /**< global SCIP settings */
    3184 SCIP_RELAXATION* relaxation /**< global relaxation data */
    3185 )
    3186{
    3187 int r;
    3188
    3189 assert(set != NULL);
    3190 assert(relaxation != NULL);
    3191
    3193
    3194 for( r = 0; r < set->nrelaxs; ++r )
    3195 SCIPrelaxMarkUnsolved(set->relaxs[r]);
    3196}
    3197
    3198/** solves the current node's LP in a price-and-cut loop */
    3199static
    3201 BMS_BLKMEM* blkmem, /**< block memory buffers */
    3202 SCIP_SET* set, /**< global SCIP settings */
    3203 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
    3204 SCIP_STAT* stat, /**< dynamic problem statistics */
    3205 SCIP_MEM* mem, /**< block memory pools */
    3206 SCIP_PROB* origprob, /**< original problem */
    3207 SCIP_PROB* transprob, /**< transformed problem after presolve */
    3208 SCIP_PRIMAL* primal, /**< primal data */
    3209 SCIP_TREE* tree, /**< branch and bound tree */
    3210 SCIP_REOPT* reopt, /**< reoptimization data structure */
    3211 SCIP_LP* lp, /**< LP data */
    3212 SCIP_RELAXATION* relaxation, /**< relaxators */
    3213 SCIP_PRICESTORE* pricestore, /**< pricing storage */
    3214 SCIP_SEPASTORE* sepastore, /**< separation storage */
    3215 SCIP_CUTPOOL* cutpool, /**< global cut pool */
    3216 SCIP_CUTPOOL* delayedcutpool, /**< global delayed cut pool */
    3217 SCIP_BRANCHCAND* branchcand, /**< branching candidate storage */
    3218 SCIP_CONFLICT* conflict, /**< conflict analysis data */
    3219 SCIP_CONFLICTSTORE* conflictstore, /**< conflict store */
    3220 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
    3221 SCIP_EVENTFILTER* eventfilter, /**< global event filter */
    3222 SCIP_CLIQUETABLE* cliquetable, /**< clique table data structure */
    3223 SCIP_Bool initiallpsolved, /**< was the initial LP already solved? */
    3224 SCIP_Bool fullseparation, /**< are we in the first prop-and-cut-and-price loop? */
    3225 SCIP_Bool newinitconss, /**< do we have to add new initial constraints? */
    3226 SCIP_Bool forcedlpsolve, /**< would SCIP abort if the LP is not solved? */
    3227 SCIP_Bool* propagateagain, /**< pointer to store whether we want to propagate again */
    3228 SCIP_Bool* solverelaxagain, /**< pointer to store TRUE, if the external relaxators should be called again */
    3229 SCIP_Bool* cutoff, /**< pointer to store TRUE, if the node can be cut off */
    3230 SCIP_Bool* unbounded, /**< pointer to store TRUE, if an unbounded ray was found in the LP */
    3231 SCIP_Bool* lperror, /**< pointer to store TRUE, if an unresolved error in LP solving occured */
    3232 SCIP_Bool* pricingaborted /**< pointer to store TRUE, if the pricing was aborted and the lower bound
    3233 * must not be used */
    3234 )
    3235{
    3236 SCIP_Longint nlpiterations;
    3237 SCIP_Longint nlps;
    3238 SCIP_Longint nzeroitlps;
    3239
    3240 assert(stat != NULL);
    3241 assert(tree != NULL);
    3242 assert(SCIPtreeHasFocusNodeLP(tree));
    3243 assert(cutoff != NULL);
    3244 assert(unbounded != NULL);
    3245 assert(lperror != NULL);
    3246 assert(*cutoff == FALSE);
    3247 assert(*unbounded == FALSE);
    3248 assert(*lperror == FALSE);
    3249
    3250 nlps = stat->nlps;
    3251 nzeroitlps = stat->ndualzeroitlps + stat->nprimalzeroitlps + stat->nbarrierzeroitlps;
    3252 nlpiterations = stat->nlpiterations;
    3253
    3254 if( !initiallpsolved )
    3255 {
    3256 /* load and solve the initial LP of the node */
    3257 SCIP_CALL( solveNodeInitialLP(blkmem, set, messagehdlr, stat, transprob, origprob, primal, tree, reopt, lp,
    3258 pricestore, sepastore, cutpool, branchcand, eventqueue, eventfilter, cliquetable, newinitconss,
    3259 forcedlpsolve, cutoff, lperror) );
    3260
    3261 assert(*cutoff || *lperror || (lp->flushed && lp->solved));
    3262 SCIPsetDebugMsg(set, "price-and-cut-loop: initial LP status: %d, LP obj: %g\n",
    3263 SCIPlpGetSolstat(lp),
    3264 *cutoff ? SCIPsetInfinity(set) : *lperror ? -SCIPsetInfinity(set) : SCIPlpGetObjval(lp, set, transprob));
    3265
    3266 /* update initial LP iteration counter */
    3267 stat->ninitlps += stat->nlps - nlps;
    3268 stat->ninitlpiterations += stat->nlpiterations - nlpiterations;
    3269
    3270 /* In the root node, we try if the initial LP solution is feasible to avoid expensive setup of data structures in
    3271 * separators; in case the root LP is aborted, e.g., by hitting the time limit, we do not check the LP solution
    3272 * since the corresponding data structures have not been updated.
    3273 */
    3274 if( SCIPtreeGetCurrentDepth(tree) == 0 && !(*cutoff) && !(*lperror)
    3276 && !SCIPsolveIsStopped(set, stat, FALSE) )
    3277 {
    3278 SCIP_Bool checklprows;
    3279 SCIP_Bool stored;
    3280 SCIP_SOL* sol;
    3281 SCIP_Longint oldnbestsolsfound = primal->nbestsolsfound;
    3282
    3283 if( set->exact_enable && lp->lpexact->solved )
    3284 {
    3285 SCIP_CALL( SCIPsolCreateLPSolExact(&sol, blkmem, set, stat, primal, tree, lp->lpexact, NULL) );
    3286
    3287 SCIP_CALL( SCIPprimalTrySolFreeExact(primal, blkmem, set, messagehdlr, stat, origprob, transprob, tree, reopt, lp->lpexact,
    3288 eventqueue, eventfilter, &sol, FALSE, FALSE, TRUE, TRUE, TRUE, &stored) );
    3289 }
    3290 else
    3291 {
    3292 SCIP_CALL( SCIPsolCreateLPSol(&sol, blkmem, set, stat, transprob, primal, tree, lp, NULL) );
    3293
    3295 checklprows = FALSE;
    3296 else
    3297 checklprows = TRUE;
    3298
    3299#ifndef NDEBUG
    3300 /* in the debug mode we want to explicitly check if the solution is feasible if it was stored */
    3301 SCIP_CALL( SCIPprimalTrySol(primal, blkmem, set, messagehdlr, stat, origprob, transprob, tree, reopt, lp,
    3302 eventqueue, eventfilter, sol, FALSE, FALSE, TRUE, TRUE, checklprows, &stored) );
    3303
    3304 if( stored )
    3305 {
    3306 SCIP_Bool feasible;
    3307
    3308 SCIP_CALL( SCIPsolCheck(sol, set, messagehdlr, blkmem, stat, transprob, FALSE, FALSE, TRUE, TRUE,
    3309 checklprows, &feasible) );
    3310 assert(feasible);
    3311 }
    3312
    3313 SCIP_CALL( SCIPsolFree(&sol, blkmem, primal) );
    3314#else
    3315 SCIP_CALL( SCIPprimalTrySolFree(primal, blkmem, set, messagehdlr, stat, origprob, transprob, tree, reopt, lp,
    3316 eventqueue, eventfilter, &sol, FALSE, FALSE, TRUE, TRUE, checklprows, &stored) );
    3317#endif
    3318 }
    3319 if( stored )
    3320 {
    3321 stat->nlpsolsfound++;
    3322
    3323 if( primal->nbestsolsfound != oldnbestsolsfound )
    3324 {
    3325 stat->nlpbestsolsfound++;
    3327 }
    3328
    3329 if( set->reopt_enable )
    3330 {
    3331 assert(reopt != NULL);
    3333 SCIPlpGetSolstat(lp), tree->root == tree->focusnode, TRUE, tree->focusnode->lowerbound,
    3334 tree->effectiverootdepth) );
    3335 }
    3336 }
    3337
    3339 *unbounded = TRUE;
    3340 }
    3341 }
    3342 else
    3343 {
    3344 SCIP_CALL( SCIPinitConssLP(blkmem, set, sepastore, cutpool, stat, transprob,
    3345 origprob, tree, reopt, lp, branchcand, eventqueue, eventfilter, cliquetable, FALSE, FALSE,
    3346 cutoff) );
    3347 }
    3348 assert(SCIPsepastoreGetNCuts(sepastore) == 0);
    3349
    3350 /* check for infeasible node by bounding */
    3351 SCIP_CALL( applyBounding(blkmem, set, stat, transprob, origprob, primal, tree, reopt, lp, branchcand, eventqueue, eventfilter, conflict, cliquetable, cutoff) );
    3352#ifdef SCIP_DEBUG
    3353 if( *cutoff )
    3354 {
    3355 if( SCIPtreeGetCurrentDepth(tree) == 0 )
    3356 {
    3357 SCIPsetDebugMsg(set, "solution cuts off root node, stop solution process\n");
    3358 }
    3359 else
    3360 {
    3361 SCIPsetDebugMsg(set, "solution cuts off node\n");
    3362 }
    3363 }
    3364#endif
    3365
    3366 if( !(*cutoff) && !(*lperror) )
    3367 {
    3368 SCIP_Longint oldninitconssadded;
    3369 SCIP_Longint oldnboundchgs;
    3370 SCIP_Longint olddomchgcount;
    3371 int oldnpricedvars;
    3372 int oldncutsapplied;
    3373
    3374 oldnpricedvars = transprob->ncolvars;
    3375 oldninitconssadded = stat->ninitconssadded;
    3376 oldncutsapplied = SCIPsepastoreGetNCutsApplied(sepastore);
    3377 oldnboundchgs = stat->nboundchgs;
    3378 olddomchgcount = stat->domchgcount;
    3379
    3380 /* solve the LP with price-and-cut*/
    3381 SCIP_CALL( priceAndCutLoop(blkmem, set, messagehdlr, stat, mem, transprob, origprob, primal, tree, reopt, lp,
    3382 pricestore, sepastore, cutpool, delayedcutpool, branchcand, conflict, conflictstore, eventqueue,
    3383 eventfilter, cliquetable, fullseparation, forcedlpsolve, propagateagain, cutoff, unbounded, lperror, pricingaborted) );
    3384
    3385 /* check if the problem was changed and the relaxation needs to be resolved */
    3386 if( (transprob->ncolvars != oldnpricedvars) || (stat->ninitconssadded != oldninitconssadded) ||
    3387 (SCIPsepastoreGetNCutsApplied(sepastore) != oldncutsapplied) || (stat->nboundchgs != oldnboundchgs) ||
    3388 (stat->domchgcount != olddomchgcount) )
    3389 {
    3390 *solverelaxagain = TRUE;
    3391 markRelaxsUnsolved(set, relaxation);
    3392 }
    3393 }
    3394 assert(*cutoff || *lperror || (lp->flushed && lp->solved));
    3395
    3396 /* if there is no LP error, then *unbounded should be TRUE, iff the LP solution status is unboundedray */
    3397 assert(*lperror || ((SCIPlpGetSolstat(lp) == SCIP_LPSOLSTAT_UNBOUNDEDRAY) == *unbounded));
    3398
    3399 /* If pricing was aborted while solving the LP of the node and the node cannot be cut off due to the lower bound computed by the pricer,
    3400 * the solving of the LP might be stopped due to the objective limit, but the node may not be cut off, since the LP objective
    3401 * is not a feasible lower bound for the solutions in the current subtree.
    3402 * In this case, the LP has to be solved to optimality by temporarily removing the cutoff bound.
    3403 */
    3404 if( (*pricingaborted) && (SCIPlpGetSolstat(lp) == SCIP_LPSOLSTAT_OBJLIMIT || SCIPlpGetSolstat(lp) == SCIP_LPSOLSTAT_ITERLIMIT)
    3405 && !(*cutoff) )
    3406 {
    3407 SCIP_Real tmpcutoff;
    3408
    3409 /* temporarily disable cutoffbound, which also disables the objective limit */
    3410 tmpcutoff = lp->cutoffbound;
    3412
    3413 lp->solved = FALSE;
    3414 SCIP_CALL( SCIPlpSolveAndEval(lp, set, messagehdlr, blkmem, stat, eventqueue, eventfilter, transprob, -1LL, FALSE, FALSE, FALSE, forcedlpsolve, lperror) );
    3415
    3416 /* reinstall old cutoff bound */
    3417 lp->cutoffbound = tmpcutoff;
    3418
    3419 SCIPsetDebugMsg(set, "re-optimized LP without cutoff bound: LP status: %d, LP obj: %g\n",
    3420 SCIPlpGetSolstat(lp), *lperror ? -SCIPsetInfinity(set) : SCIPlpGetObjval(lp, set, transprob));
    3421
    3422 /* lp solstat should not be objlimit, since the cutoff bound was removed temporarily */
    3424 /* lp solstat should not be unboundedray, since the lp was dual feasible */
    3426 /* there should be no primal ray, since the lp was dual feasible */
    3427 assert(primal->primalray == NULL);
    3429 {
    3430 if( !set->exact_enable || lp->hasprovedbound )
    3431 *cutoff = TRUE;
    3432 }
    3433 }
    3434
    3435 assert(!(*pricingaborted) || SCIPlpGetSolstat(lp) == SCIP_LPSOLSTAT_OPTIMAL
    3436 || SCIPlpGetSolstat(lp) == SCIP_LPSOLSTAT_NOTSOLVED || SCIPsolveIsStopped(set, stat, FALSE) || (*cutoff)); /* cppcheck-suppress assertWithSideEffect */
    3437
    3438 assert(*cutoff || *lperror || (lp->flushed && lp->solved));
    3439
    3440 /* update node's LP iteration counter */
    3441 stat->nnodelps += stat->nlps - nlps;
    3442 stat->nnodezeroitlps += stat->ndualzeroitlps + stat->nprimalzeroitlps + stat->nbarrierzeroitlps - nzeroitlps;
    3443 stat->nnodelpiterations += stat->nlpiterations - nlpiterations;
    3444
    3445 /* update number of root node LPs and iterations if the root node was processed */
    3446 if( SCIPnodeGetDepth(tree->focusnode) == 0 )
    3447 {
    3448 stat->nrootlps += stat->nlps - nlps;
    3449 stat->nrootlpiterations += stat->nlpiterations - nlpiterations;
    3450 }
    3451
    3452 return SCIP_OKAY;
    3453}
    3454
    3455/** calls relaxators */
    3456static
    3458 SCIP_SET* set, /**< global SCIP settings */
    3459 SCIP_STAT* stat, /**< dynamic problem statistics */
    3460 SCIP_EVENTFILTER* eventfilter, /**< global event filter */
    3461 SCIP_TREE* tree, /**< branch and bound tree */
    3462 SCIP_RELAXATION* relaxation, /**< relaxators */
    3463 SCIP_PROB* transprob, /**< transformed problem */
    3464 SCIP_PROB* origprob, /**< original problem */
    3465 int depth, /**< depth of current node */
    3466 SCIP_Bool beforelp, /**< should the relaxators with non-negative or negative priority be called? */
    3467 SCIP_Bool* cutoff, /**< pointer to store TRUE, if the node can be cut off */
    3468 SCIP_Bool* propagateagain, /**< pointer to store TRUE, if domain propagation should be applied again */
    3469 SCIP_Bool* solvelpagain, /**< pointer to store TRUE, if the node's LP has to be solved again */
    3470 SCIP_Bool* solverelaxagain, /**< pointer to store TRUE, if the external relaxators should be called
    3471 * again */
    3472 SCIP_Bool* relaxcalled /**< pointer to store TRUE, if at least one relaxator was called (unmodified
    3473 * otherwise) */
    3474 )
    3475{
    3476 SCIP_RESULT result;
    3477 SCIP_Real lowerbound;
    3478 int r;
    3479
    3480 assert(set != NULL);
    3481 assert(relaxation != NULL);
    3482 assert(cutoff != NULL);
    3483 assert(solvelpagain != NULL);
    3484 assert(propagateagain != NULL);
    3485 assert(solverelaxagain != NULL);
    3486 assert(relaxcalled != NULL);
    3487 assert(!(*cutoff));
    3488
    3489 /* sort by priority */
    3491
    3492 for( r = 0; r < set->nrelaxs && !(*cutoff); ++r )
    3493 {
    3494 if( beforelp != (SCIPrelaxGetPriority(set->relaxs[r]) >= 0) )
    3495 continue;
    3496
    3497 *relaxcalled = TRUE;
    3498
    3499 lowerbound = -SCIPsetInfinity(set);
    3500
    3501 SCIP_CALL( SCIPrelaxExec(set->relaxs[r], set, tree, stat, depth, &lowerbound, &result) );
    3502
    3503 switch( result )
    3504 {
    3505 case SCIP_CUTOFF:
    3506 *cutoff = TRUE;
    3507 SCIPsetDebugMsg(set, " -> relaxator <%s> detected cutoff\n", SCIPrelaxGetName(set->relaxs[r]));
    3508 /* @todo does it make sense to proceed if the node is proven to be infeasible? */
    3509 return SCIP_OKAY;
    3510
    3511 case SCIP_CONSADDED:
    3512 *solvelpagain = TRUE; /* the separation for new constraints should be called */
    3513 *propagateagain = TRUE; /* the propagation for new constraints should be called */
    3514 break;
    3515
    3516 case SCIP_REDUCEDDOM:
    3517 *solvelpagain = TRUE;
    3518 *propagateagain = TRUE;
    3519 break;
    3520
    3521 case SCIP_SEPARATED:
    3522 *solvelpagain = TRUE;
    3523 break;
    3524
    3525 case SCIP_SUSPENDED:
    3526 *solverelaxagain = TRUE;
    3527 break;
    3528
    3529 case SCIP_SUCCESS:
    3530 case SCIP_DIDNOTRUN:
    3531 break;
    3532
    3533 default:
    3534 SCIPerrorMessage("invalid result code <%d> of relaxator <%s>\n", result, SCIPrelaxGetName(set->relaxs[r]));
    3535 return SCIP_INVALIDRESULT;
    3536 } /*lint !e788*/
    3537
    3538 if( result != SCIP_CUTOFF && result != SCIP_DIDNOTRUN && result != SCIP_SUSPENDED )
    3539 {
    3540 SCIP_NODE* focusnode;
    3541
    3542 focusnode = SCIPtreeGetFocusNode(tree);
    3543 assert(focusnode != NULL);
    3544 assert(SCIPnodeGetType(focusnode) == SCIP_NODETYPE_FOCUSNODE);
    3545
    3546 /* update lower bound w.r.t. the lower bound given by the relaxator */
    3547 SCIP_CALL( SCIPnodeUpdateLowerbound(focusnode, stat, set, eventfilter, tree, transprob, origprob, lowerbound, NULL) );
    3548 SCIPsetDebugMsg(set, " -> new lower bound given by relaxator %s: %g\n",
    3549 SCIPrelaxGetName(set->relaxs[r]), lowerbound);
    3550 }
    3551 }
    3552
    3553 return SCIP_OKAY;
    3554}
    3555
    3556/** enforces constraints by branching, separation, or domain reduction */
    3557static
    3559 BMS_BLKMEM* blkmem, /**< block memory buffers */
    3560 SCIP_SET* set, /**< global SCIP settings */
    3561 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
    3562 SCIP_STAT* stat, /**< dynamic problem statistics */
    3563 SCIP_PROB* prob, /**< transformed problem after presolve */
    3564 SCIP_PRIMAL* primal, /**< primal data */
    3565 SCIP_TREE* tree, /**< branch and bound tree */
    3566 SCIP_LP* lp, /**< LP data */
    3567 SCIP_RELAXATION* relaxation, /**< global relaxation data */
    3568 SCIP_SEPASTORE* sepastore, /**< separation storage */
    3569 SCIP_BRANCHCAND* branchcand, /**< branching candidate storage */
    3570 SCIP_Bool* branched, /**< pointer to store whether a branching was created */
    3571 SCIP_Bool* cutoff, /**< pointer to store TRUE, if the node can be cut off */
    3572 SCIP_Bool* infeasible, /**< pointer to store TRUE, if the LP/pseudo solution is infeasible */
    3573 SCIP_Bool* propagateagain, /**< pointer to store TRUE, if domain propagation should be applied again */
    3574 SCIP_Bool* solvelpagain, /**< pointer to store TRUE, if the node's LP has to be solved again */
    3575 SCIP_Bool* solverelaxagain, /**< pointer to store TRUE, if the external relaxators should be called again */
    3576 SCIP_Bool forced /**< should enforcement of pseudo solution be forced? */
    3577 )
    3578{
    3579 SCIP_RESULT result;
    3580 SCIP_SOL* relaxsol = NULL;
    3581 SCIP_Real pseudoobjval;
    3582 SCIP_Bool resolved;
    3583 SCIP_Bool objinfeasible;
    3584 SCIP_Bool enforcerelaxsol;
    3585 int h;
    3586
    3587 assert(set != NULL);
    3588 assert(stat != NULL);
    3589 assert(tree != NULL);
    3590 assert(SCIPtreeGetFocusNode(tree) != NULL);
    3591 assert(branched != NULL);
    3592 assert(cutoff != NULL);
    3593 assert(infeasible != NULL);
    3594 assert(propagateagain != NULL);
    3595 assert(solvelpagain != NULL);
    3596 assert(solverelaxagain != NULL);
    3597 assert(!(*cutoff));
    3598 assert(!(*propagateagain));
    3599 assert(!(*solvelpagain));
    3600 assert(!(*solverelaxagain));
    3601
    3602 *branched = FALSE;
    3603 /**@todo avoid checking the same pseudosolution twice */
    3604
    3605 /* enforce (best) relaxation solution if the LP has a worse objective value */
    3606 enforcerelaxsol = SCIPrelaxationIsSolValid(relaxation) && SCIPrelaxationIsLpIncludedForSol(relaxation) && (!SCIPtreeHasFocusNodeLP(tree)
    3607 || SCIPsetIsGT(set, SCIPrelaxationGetSolObj(relaxation), SCIPlpGetObjval(lp, set, prob)));
    3608
    3609 /* check if all constraint handlers implement the enforelax callback, otherwise enforce the LP solution */
    3610 for( h = 0; h < set->nconshdlrs && enforcerelaxsol; ++h )
    3611 {
    3612 if( set->conshdlrs_enfo[h]->consenforelax == NULL && ((! set->conshdlrs_enfo[h]->needscons) ||
    3613 (set->conshdlrs_enfo[h]->nconss > 0)) )
    3614 {
    3615 SCIP_VERBLEVEL verblevel;
    3616
    3617 enforcerelaxsol = FALSE;
    3618
    3619 verblevel = SCIP_VERBLEVEL_FULL;
    3620
    3621 if( !stat->disableenforelaxmsg && set->disp_verblevel == SCIP_VERBLEVEL_HIGH )
    3622 {
    3623 verblevel = SCIP_VERBLEVEL_HIGH;
    3624
    3625 /* remember that the disable relaxation enforcement message was posted and only post it again if the
    3626 * verblevel is SCIP_VERBLEVEL_FULL
    3627 */
    3628 stat->disableenforelaxmsg = TRUE;
    3629 }
    3630 SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, verblevel, "Disable enforcement of relaxation solutions"
    3631 " since constraint handler %s does not implement enforelax-callback\n",
    3632 SCIPconshdlrGetName(set->conshdlrs_enfo[h]));
    3633 }
    3634 }
    3635
    3636 /* enforce constraints by branching, applying additional cutting planes (if LP is being processed),
    3637 * introducing new constraints, or tighten the domains
    3638 */
    3639#ifndef SCIP_NDEBUG
    3640 if( enforcerelaxsol )
    3641 {
    3642 SCIPsetDebugMsg(set, "enforcing constraints on relaxation solution\n");
    3643 }
    3644 else
    3645 {
    3646 SCIPsetDebugMsg(set, "enforcing constraints on %s solution\n", SCIPtreeHasFocusNodeLP(tree) ? "LP" : "pseudo");
    3647 }
    3648#endif
    3649
    3650 /* check, if the solution is infeasible anyway due to it's objective value */
    3651 if( SCIPtreeHasFocusNodeLP(tree) || enforcerelaxsol )
    3652 objinfeasible = FALSE;
    3653 else
    3654 {
    3655 pseudoobjval = SCIPlpGetPseudoObjval(lp, set, prob);
    3656 objinfeasible = SCIPsetIsDualfeasLT(set, pseudoobjval, SCIPnodeGetLowerbound(SCIPtreeGetFocusNode(tree)));
    3657 }
    3658
    3659 /* during constraint enforcement, generated cuts should enter the LP in any case; otherwise, a constraint handler
    3660 * would fail to enforce its constraints if it relies on the modification of the LP relaxation
    3661 */
    3662 SCIPsepastoreStartForceCuts(sepastore);
    3663
    3664 /* enforce constraints until a handler resolved an infeasibility with cutting off the node, branching,
    3665 * reducing a domain, or separating a cut
    3666 * if a constraint handler introduced new constraints to enforce his constraints, the newly added constraints
    3667 * have to be enforced themselves
    3668 */
    3669 resolved = FALSE;
    3670
    3671 /* in case the relaxation solution should be enforced, we need to create the corresponding solution for the enforelax callbacks */
    3672 if( enforcerelaxsol )
    3673 {
    3674 SCIP_CALL( SCIPsolCreateRelaxSol(&relaxsol, blkmem, set, stat, primal, tree, relaxation, NULL) );
    3675 }
    3676
    3677 for( h = 0; h < set->nconshdlrs && !resolved; ++h )
    3678 {
    3679 assert(SCIPsepastoreGetNCuts(sepastore) == 0); /* otherwise, the LP should have been resolved first */
    3680
    3681 /* enforce LP, pseudo, or relaxation solution */
    3682 if( enforcerelaxsol )
    3683 {
    3684 SCIPsetDebugMsg(set, "enforce relaxation solution with value %g\n", SCIPrelaxationGetSolObj(relaxation));
    3685
    3686 SCIP_CALL( SCIPconshdlrEnforceRelaxSol(set->conshdlrs_enfo[h], blkmem, set, stat, tree, sepastore,
    3687 relaxsol, *infeasible, &result) );
    3688 }
    3689 else if( SCIPtreeHasFocusNodeLP(tree) )
    3690 {
    3691 SCIPsetDebugMsg(set, "enforce LP solution with value %g\n", SCIPlpGetObjval(lp, set, prob));
    3692
    3693 // NOTE: May be called with lp->primalfeasible=FALSE. But then enforcement is called for infinite points?!
    3694
    3695 assert(lp->flushed);
    3696 assert(lp->solved);
    3698 SCIP_CALL( SCIPconshdlrEnforceLPSol(set->conshdlrs_enfo[h], blkmem, set, stat, tree, sepastore, *infeasible,
    3699 &result) );
    3700 }
    3701 else
    3702 {
    3703 SCIP_CALL( SCIPconshdlrEnforcePseudoSol(set->conshdlrs_enfo[h], blkmem, set, stat, tree, branchcand, *infeasible,
    3704 objinfeasible, forced, &result) );
    3705 if( SCIPsepastoreGetNCuts(sepastore) != 0 )
    3706 {
    3707 SCIPerrorMessage("pseudo enforcing method of constraint handler <%s> separated cuts\n",
    3708 SCIPconshdlrGetName(set->conshdlrs_enfo[h]));
    3709 return SCIP_INVALIDRESULT;
    3710 }
    3711 }
    3712 SCIPsetDebugMsg(set, "enforcing of <%s> returned result %d\n", SCIPconshdlrGetName(set->conshdlrs_enfo[h]), result);
    3713
    3714 switch( result )
    3715 {
    3716 case SCIP_CUTOFF:
    3717 assert(tree->nchildren == 0);
    3718 *cutoff = TRUE;
    3719 *infeasible = TRUE;
    3720 resolved = TRUE;
    3721 SCIPsetDebugMsg(set, " -> constraint handler <%s> detected cutoff in enforcement\n",
    3722 SCIPconshdlrGetName(set->conshdlrs_enfo[h]));
    3723 break;
    3724
    3725 case SCIP_CONSADDED:
    3726 assert(tree->nchildren == 0);
    3727 *infeasible = TRUE;
    3728 *propagateagain = TRUE; /* the propagation for new constraints should be called */
    3729 *solvelpagain = TRUE; /* the separation for new constraints should be called */
    3730 *solverelaxagain = TRUE;
    3731 markRelaxsUnsolved(set, relaxation);
    3732 resolved = TRUE;
    3733 break;
    3734
    3735 case SCIP_REDUCEDDOM:
    3736 assert(tree->nchildren == 0);
    3737 *infeasible = TRUE;
    3738 *propagateagain = TRUE;
    3739 *solvelpagain = TRUE;
    3740 *solverelaxagain = TRUE;
    3741 markRelaxsUnsolved(set, relaxation);
    3742 resolved = TRUE;
    3743 break;
    3744
    3745 case SCIP_SEPARATED:
    3746 assert(tree->nchildren == 0);
    3747 assert(SCIPsepastoreGetNCuts(sepastore) > 0);
    3748 *infeasible = TRUE;
    3749 *solvelpagain = TRUE;
    3750 *solverelaxagain = TRUE;
    3751 markRelaxsUnsolved(set, relaxation);
    3752 resolved = TRUE;
    3753 break;
    3754
    3755 case SCIP_BRANCHED:
    3756 assert(tree->nchildren >= 1);
    3757 assert(!SCIPtreeHasFocusNodeLP(tree) || (lp->flushed && lp->solved));
    3758 assert(SCIPsepastoreGetNCuts(sepastore) == 0);
    3759 *infeasible = TRUE;
    3760 *branched = TRUE;
    3761 resolved = TRUE;
    3762
    3763 /* increase the number of internal nodes */
    3764 stat->ninternalnodes++;
    3765 stat->ntotalinternalnodes++;
    3766 break;
    3767
    3768 case SCIP_SOLVELP:
    3769 /* either LP was not solved, or it is not solved anymore (e.g., because feastol has been tightened by some constraint handler) */
    3770 assert(!SCIPtreeHasFocusNodeLP(tree) || !lp->solved);
    3771 assert(tree->nchildren == 0);
    3772 assert(SCIPsepastoreGetNCuts(sepastore) == 0);
    3773 *infeasible = TRUE;
    3774 *solvelpagain = TRUE;
    3775 resolved = TRUE;
    3776 SCIPtreeSetFocusNodeLP(tree, TRUE); /* the node's LP must be solved */
    3777 break;
    3778
    3779 case SCIP_INFEASIBLE:
    3780 assert(tree->nchildren == 0);
    3781 assert(!SCIPtreeHasFocusNodeLP(tree) || (lp->flushed && lp->solved));
    3782 assert(SCIPsepastoreGetNCuts(sepastore) == 0);
    3783 *infeasible = TRUE;
    3784 break;
    3785
    3786 case SCIP_FEASIBLE:
    3787 assert(tree->nchildren == 0);
    3788 assert(!SCIPtreeHasFocusNodeLP(tree) || (lp->flushed && lp->solved));
    3789 assert(SCIPsepastoreGetNCuts(sepastore) == 0);
    3790 break;
    3791
    3792 case SCIP_DIDNOTRUN:
    3793 assert(tree->nchildren == 0);
    3794 assert(!SCIPtreeHasFocusNodeLP(tree) || (lp->flushed && lp->solved));
    3795 assert(SCIPsepastoreGetNCuts(sepastore) == 0);
    3796 assert(objinfeasible);
    3797 *infeasible = TRUE;
    3798 break;
    3799
    3800 default:
    3801 SCIPerrorMessage("invalid result code <%d> from enforcing method of constraint handler <%s>\n",
    3802 result, SCIPconshdlrGetName(set->conshdlrs_enfo[h]));
    3803 return SCIP_INVALIDRESULT;
    3804 } /*lint !e788*/
    3805
    3806 /* the enforcement method may add a primal solution, after which the LP status could be set to
    3807 * objective limit reached
    3808 */
    3810 {
    3811 *cutoff = TRUE;
    3812 *infeasible = TRUE;
    3813 resolved = TRUE;
    3814 SCIPsetDebugMsg(set, " -> LP exceeded objective limit\n");
    3815
    3816 /* If we used the probing mode during branching, it might happen that we added a constraint or global bound
    3817 * and returned SCIP_CONSADDED or SCIP_REDUCEDDOM, but when reoptimizing the LP after ending the probing mode,
    3818 * this leads to hitting the objective limit. In this case, we do not need to propagate or solve the LP again.
    3819 */
    3820 *propagateagain = FALSE;
    3821 *solvelpagain = FALSE;
    3822 }
    3823
    3824 assert(!(*branched) || (resolved && !(*cutoff) && *infeasible && !(*propagateagain) && !(*solvelpagain)));
    3825 assert(!(*cutoff) || (resolved && !(*branched) && *infeasible && !(*propagateagain) && !(*solvelpagain)));
    3826 assert(*infeasible || (!resolved && !(*branched) && !(*cutoff) && !(*propagateagain) && !(*solvelpagain)));
    3827 assert(!(*propagateagain) || (resolved && !(*branched) && !(*cutoff) && *infeasible));
    3828 assert(!(*solvelpagain) || (resolved && !(*branched) && !(*cutoff) && *infeasible));
    3829 }
    3830 assert(!objinfeasible || *infeasible);
    3831 assert(resolved == (*branched || *cutoff || *propagateagain || *solvelpagain));
    3832 assert(*cutoff || *solvelpagain || SCIPsepastoreGetNCuts(sepastore) == 0);
    3833
    3834 /* in case the relaxation solution was enforced, free the created solution */
    3835 if( enforcerelaxsol )
    3836 {
    3837 SCIP_CALL( SCIPsolFree(&relaxsol, blkmem, primal) );
    3838 }
    3839
    3840 /* deactivate the cut forcing of the constraint enforcement */
    3841 SCIPsepastoreEndForceCuts(sepastore);
    3842
    3843 SCIPsetDebugMsg(set, " -> enforcing result: branched=%u, cutoff=%u, infeasible=%u, propagateagain=%u, solvelpagain=%u, resolved=%u\n",
    3844 *branched, *cutoff, *infeasible, *propagateagain, *solvelpagain, resolved);
    3845
    3846 return SCIP_OKAY;
    3847}
    3848
    3849/** applies the cuts stored in the separation store, or clears the store if the node can be cut off */
    3850static
    3852 BMS_BLKMEM* blkmem, /**< block memory buffers */
    3853 SCIP_SET* set, /**< global SCIP settings */
    3854 SCIP_STAT* stat, /**< dynamic problem statistics */
    3855 SCIP_PROB* transprob, /**< transformed problem */
    3856 SCIP_PROB* origprob, /**< original problem */
    3857 SCIP_TREE* tree, /**< branch and bound tree */
    3858 SCIP_REOPT* reopt, /**< reotimization data structure */
    3859 SCIP_LP* lp, /**< LP data */
    3860 SCIP_RELAXATION* relaxation, /**< relaxators */
    3861 SCIP_SEPASTORE* sepastore, /**< separation storage */
    3862 SCIP_BRANCHCAND* branchcand, /**< branching candidate storage */
    3863 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
    3864 SCIP_EVENTFILTER* eventfilter, /**< global event filter */
    3865 SCIP_CLIQUETABLE* cliquetable, /**< clique table data structure */
    3866 SCIP_Bool root, /**< is this the initial root LP? */
    3867 SCIP_EFFICIACYCHOICE efficiacychoice, /**< type of solution to base efficiacy computation on */
    3868 SCIP_Bool* cutoff, /**< pointer to whether the node can be cut off */
    3869 SCIP_Bool* propagateagain, /**< pointer to store TRUE, if domain propagation should be applied again */
    3870 SCIP_Bool* solvelpagain, /**< pointer to store TRUE, if the node's LP has to be solved again */
    3871 SCIP_Bool* solverelaxagain /**< pointer to store TRUE, if the node's relaxation has to be solved again */
    3872 )
    3873{
    3874 assert(stat != NULL);
    3875 assert(cutoff != NULL);
    3876 assert(propagateagain != NULL);
    3877 assert(solvelpagain != NULL);
    3878
    3879 if( *cutoff )
    3880 {
    3881 /* the found cuts are of no use, because the node is infeasible anyway (or we have an error in the LP) */
    3882 SCIP_CALL( SCIPsepastoreClearCuts(sepastore, blkmem, set, eventqueue, eventfilter, lp) );
    3883 }
    3884 else if( SCIPsepastoreGetNCuts(sepastore) > 0 )
    3885 {
    3886 SCIP_Longint olddomchgcount;
    3887 int oldncutsapplied;
    3888
    3889 olddomchgcount = stat->domchgcount;
    3890 oldncutsapplied = SCIPsepastoreGetNCutsApplied(sepastore);
    3891 SCIP_CALL( SCIPsepastoreApplyCuts(sepastore, blkmem, set, stat, transprob, origprob, tree, reopt, lp, branchcand,
    3892 eventqueue, eventfilter, cliquetable, root, efficiacychoice, cutoff) );
    3893 *propagateagain = *propagateagain || (stat->domchgcount != olddomchgcount);
    3894 *solvelpagain = TRUE;
    3895 if( (stat->domchgcount != olddomchgcount) || (SCIPsepastoreGetNCutsApplied(sepastore) != oldncutsapplied) )
    3896 {
    3897 *solverelaxagain = TRUE;
    3898 markRelaxsUnsolved(set, relaxation);
    3899 }
    3900 }
    3901
    3902 return SCIP_OKAY;
    3903}
    3904
    3905/** updates the cutoff, propagateagain, and solverelaxagain status of the current solving loop */
    3906static
    3908 SCIP_SET* set, /**< global SCIP settings */
    3909 SCIP_STAT* stat, /**< dynamic problem statistics */
    3910 SCIP_TREE* tree, /**< branch and bound tree */
    3911 int depth, /**< depth of current node */
    3912 SCIP_Bool* cutoff, /**< pointer to store TRUE, if the node can be cut off */
    3913 SCIP_Bool* propagateagain, /**< pointer to store TRUE, if domain propagation should be applied again */
    3914 SCIP_Bool* solverelaxagain /**< pointer to store TRUE, if at least one relaxator should be called again */
    3915 )
    3916{
    3917 SCIP_NODE* focusnode;
    3918 int r;
    3919
    3920 assert(set != NULL);
    3921 assert(stat != NULL);
    3922 assert(cutoff != NULL);
    3923 assert(propagateagain != NULL);
    3924 assert(solverelaxagain != NULL);
    3925
    3926 /* check, if the path was cutoff */
    3927 *cutoff = *cutoff || (tree->cutoffdepth <= depth);
    3928
    3929 /* check if branching was already performed */
    3930 if( tree->nchildren == 0 )
    3931 {
    3932 /* check, if the focus node should be repropagated */
    3933 focusnode = SCIPtreeGetFocusNode(tree);
    3934 *propagateagain = *propagateagain || SCIPnodeIsPropagatedAgain(focusnode);
    3935
    3936 /* check, if one of the external relaxations should be solved again */
    3937 for( r = 0; r < set->nrelaxs && !(*solverelaxagain); ++r )
    3938 *solverelaxagain = *solverelaxagain || ( !SCIPrelaxIsSolved(set->relaxs[r], stat) );
    3939 }
    3940 else
    3941 {
    3942 /* if branching was performed, avoid another node loop iteration */
    3943 *propagateagain = FALSE;
    3944 *solverelaxagain = FALSE;
    3945 }
    3946}
    3947
    3948/** propagate domains and solve relaxation and lp */
    3949static
    3951 BMS_BLKMEM* blkmem, /**< block memory buffers */
    3952 SCIP_SET* set, /**< global SCIP settings */
    3953 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
    3954 SCIP_STAT* stat, /**< dynamic problem statistics */
    3955 SCIP_MEM* mem, /**< block memory pools */
    3956 SCIP_PROB* origprob, /**< original problem */
    3957 SCIP_PROB* transprob, /**< transformed problem after presolve */
    3958 SCIP_PRIMAL* primal, /**< primal data */
    3959 SCIP_TREE* tree, /**< branch and bound tree */
    3960 SCIP_REOPT* reopt, /**< reoptimization data structure */
    3961 SCIP_LP* lp, /**< LP data */
    3962 SCIP_RELAXATION* relaxation, /**< global relaxation data */
    3963 SCIP_PRICESTORE* pricestore, /**< pricing storage */
    3964 SCIP_SEPASTORE* sepastore, /**< separation storage */
    3965 SCIP_BRANCHCAND* branchcand, /**< branching candidate storage */
    3966 SCIP_CUTPOOL* cutpool, /**< global cut pool */
    3967 SCIP_CUTPOOL* delayedcutpool, /**< global delayed cut pool */
    3968 SCIP_CONFLICT* conflict, /**< conflict analysis data */
    3969 SCIP_CONFLICTSTORE* conflictstore, /**< conflict store */
    3970 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
    3971 SCIP_EVENTFILTER* eventfilter, /**< global event filter */
    3972 SCIP_CLIQUETABLE* cliquetable, /**< clique table data structure */
    3973 SCIP_NODE* focusnode, /**< focused node */
    3974 int actdepth, /**< depth in the b&b tree */
    3975 SCIP_Bool propagate, /**< should we propagate */
    3976 SCIP_Bool solvelp, /**< should we solve the lp */
    3977 SCIP_Bool solverelax, /**< should we solve the relaxation */
    3978 SCIP_Bool forcedlpsolve, /**< would SCIP abort if the LP is not solved? */
    3979 SCIP_Bool initiallpsolved, /**< was the initial LP already solved? */
    3980 SCIP_Bool fullseparation, /**< are we in the first prop-and-cut-and-price loop? */
    3981 SCIP_Longint* afterlpproplps, /**< pointer to store the last LP count for which AFTERLP propagation was performed */
    3982 SCIP_HEURTIMING* heurtiming, /**< timing for running heuristics after propagation call */
    3983 int* nlperrors, /**< pointer to store the number of lp errors */
    3984 SCIP_Bool* fullpropagation, /**< pointer to store whether we want to do a fullpropagation next time */
    3985 SCIP_Bool* propagateagain, /**< pointer to store whether we want to propagate again */
    3986 SCIP_Bool* lpsolved, /**< pointer to store whether the lp was solved */
    3987 SCIP_Bool* relaxcalled, /**< pointer to store whether a relaxator was called; initialized with last loop's result */
    3988 SCIP_Bool* solvelpagain, /**< pointer to store whether we want to solve the lp again */
    3989 SCIP_Bool* solverelaxagain, /**< pointer to store whether we want to solve the relaxation again */
    3990 SCIP_Bool* cutoff, /**< pointer to store whether the node can be cut off */
    3991 SCIP_Bool* postpone, /**< pointer to store whether the node should be postponed */
    3992 SCIP_Bool* unbounded, /**< pointer to store whether the focus node is unbounded */
    3993 SCIP_Bool* stopped, /**< pointer to store whether solving was interrupted */
    3994 SCIP_Bool* lperror, /**< pointer to store TRUE, if an unresolved error in LP solving occured */
    3995 SCIP_Bool* pricingaborted, /**< pointer to store TRUE, if the pricing was aborted and the lower bound must not be used */
    3996 SCIP_Bool* forcedenforcement /**< pointer to store whether the enforcement of pseudo solution should be forced */
    3997 )
    3998{
    3999 SCIP_Bool newinitconss;
    4000
    4001 assert(set != NULL);
    4002 assert(stat != NULL);
    4003 assert(origprob != NULL);
    4004 assert(transprob != NULL);
    4005 assert(tree != NULL);
    4006 assert(lp != NULL);
    4007 assert(primal != NULL);
    4008 assert(pricestore != NULL);
    4009 assert(sepastore != NULL);
    4010 assert(SCIPsepastoreGetNCuts(sepastore) == 0);
    4011 assert(branchcand != NULL);
    4012 assert(cutpool != NULL);
    4013 assert(delayedcutpool != NULL);
    4014 assert(conflict != NULL);
    4015 assert(SCIPconflictGetNConflicts(conflict) == 0);
    4016 assert(eventfilter != NULL);
    4017 assert(eventqueue != NULL);
    4018 assert(focusnode != NULL);
    4019 assert(heurtiming != NULL);
    4020 assert(nlperrors != NULL);
    4021 assert(fullpropagation != NULL);
    4022 assert(propagateagain != NULL);
    4023 assert(afterlpproplps != NULL);
    4024 assert(lpsolved != NULL);
    4025 assert(solvelpagain != NULL);
    4026 assert(solverelaxagain != NULL);
    4027 assert(cutoff != NULL);
    4028 assert(postpone != NULL);
    4029 assert(unbounded != NULL);
    4030 assert(lperror != NULL);
    4031 assert(pricingaborted != NULL);
    4032 assert(forcedenforcement != NULL);
    4033
    4034 newinitconss = FALSE;
    4035
    4036 if( !(*cutoff) && !(*postpone) )
    4037 {
    4038 SCIP_Longint oldninitconssadded;
    4039 SCIP_Longint oldnboundchgs;
    4040 SCIP_Bool lpwasflushed;
    4041
    4042 lpwasflushed = lp->flushed;
    4043 oldnboundchgs = stat->nboundchgs;
    4044 oldninitconssadded = stat->ninitconssadded;
    4045
    4046 /* call after LP propagators */
    4047 if( ((*afterlpproplps) < stat->nnodelps && (*lpsolved)) || (*relaxcalled) )
    4048 {
    4049 SCIP_CALL( propagateDomains(blkmem, set, stat, tree, SCIPtreeGetCurrentDepth(tree), 0, *fullpropagation,
    4050 SCIP_PROPTIMING_AFTERLPLOOP, cutoff, postpone) );
    4051 assert(BMSgetNUsedBufferMemory(mem->buffer) == 0);
    4052
    4053 /* check, if the path was cutoff */
    4054 *cutoff = *cutoff || (tree->cutoffdepth <= actdepth);
    4055 *afterlpproplps = stat->nnodelps;
    4056 propagate = propagate || (stat->nboundchgs > oldnboundchgs);
    4057 }
    4058
    4059 /* call before LP propagators */
    4060 if( propagate && !(*cutoff) )
    4061 {
    4062 SCIP_CALL( propagateDomains(blkmem, set, stat, tree, SCIPtreeGetCurrentDepth(tree), 0, *fullpropagation,
    4063 SCIP_PROPTIMING_BEFORELP, cutoff, postpone) );
    4064 assert(BMSgetNUsedBufferMemory(mem->buffer) == 0);
    4065 }
    4066
    4067 newinitconss = (stat->ninitconssadded != oldninitconssadded);
    4068 *fullpropagation = FALSE;
    4069
    4070 /* check, if the path was cutoff */
    4071 *cutoff = *cutoff || (tree->cutoffdepth <= actdepth);
    4072
    4073 /* if the LP was flushed and is now no longer flushed, a bound change occurred, and the LP has to be resolved;
    4074 * we also have to solve the LP if new intial constraints were added which need to be added to the LP
    4075 */
    4076 solvelp = solvelp || (lpwasflushed && (!lp->flushed || newinitconss));
    4077 solverelax = solverelax || newinitconss;
    4078
    4079 /* the number of bound changes was increased by the propagation call, thus the relaxation should be solved again */
    4080 if( stat->nboundchgs > oldnboundchgs )
    4081 {
    4082 /* propagation might have changed the best bound of loose variables, thereby changing the loose objective value
    4083 * which is added to the LP value; because of the loose status, the LP might not be reoptimized, but the lower
    4084 * bound of the node needs to be updated
    4085 */
    4086 if( !solvelp && lp->flushed && lp->solved && SCIPprobAllColsInLP(transprob, set, lp) && SCIPlpIsRelax(lp) )
    4087 {
    4088 SCIP_CALL( SCIPnodeUpdateLowerboundLP(focusnode, set, stat, messagehdlr, eventfilter, tree, transprob, origprob, lp) );
    4089 SCIPsetDebugMsg(set, " -> new lower bound: %g (LP status: %d, LP obj: %g)\n",
    4090 SCIPnodeGetLowerbound(focusnode), SCIPlpGetSolstat(lp), SCIPlpGetObjval(lp, set, transprob));
    4091
    4092 if( SCIPtreeHasFocusNodeLP(tree) )
    4093 {
    4094 /* update node estimate */
    4095 SCIP_CALL( updateEstimate(set, stat, tree, lp, branchcand) );
    4096
    4097 if( actdepth == 0 && SCIPlpGetSolstat(lp) == SCIP_LPSOLSTAT_OPTIMAL )
    4098 SCIPprobUpdateBestRootSol(transprob, set, stat, lp);
    4099 }
    4100 }
    4101
    4102 solverelax = TRUE;
    4103 markRelaxsUnsolved(set, relaxation);
    4104 }
    4105
    4106 /* update lower bound with the pseudo objective value, and cut off node by bounding */
    4107 SCIP_CALL( applyBounding(blkmem, set, stat, transprob, origprob, primal, tree, reopt, lp, branchcand, eventqueue,
    4108 eventfilter, conflict, cliquetable, cutoff) );
    4109 }
    4110 assert(SCIPsepastoreGetNCuts(sepastore) == 0);
    4111
    4112 if( *postpone )
    4113 return SCIP_OKAY;
    4114
    4115 /* call primal heuristics that are applicable after propagation loop before lp solve;
    4116 * the first time we go here, we call the before node heuristics instead
    4117 */
    4118 if( !(*cutoff) && !SCIPtreeProbing(tree) )
    4119 {
    4120 /* if the heuristics find a new incumbent solution, propagate again */
    4121 SCIP_CALL( SCIPprimalHeuristics(set, stat, transprob, primal, tree, lp, NULL, *heurtiming,
    4122 FALSE, propagateagain, unbounded) );
    4123 assert(BMSgetNUsedBufferMemory(mem->buffer) == 0);
    4124
    4125 *heurtiming = SCIP_HEURTIMING_AFTERPROPLOOP;
    4126
    4127 /* check if primal heuristics found a solution and we therefore reached a solution limit */
    4128 if( SCIPsolveIsStopped(set, stat, FALSE) )
    4129 {
    4130 SCIP_NODE* node;
    4131
    4132 /* we reached a solution limit and do not want to continue the processing of the current node, but in order to
    4133 * allow restarting the optimization process later, we need to create a "branching" with only one child node that
    4134 * is a copy of the focusnode
    4135 */
    4137 SCIP_CALL( SCIPnodeCreateChild(&node, blkmem, set, stat, tree, 1.0, focusnode->estimate) );
    4138 assert(tree->nchildren >= 1);
    4139 *stopped = TRUE;
    4140 return SCIP_OKAY;
    4141 }
    4142
    4143 /* if diving produced an LP error, switch back to non-LP node */
    4144 if( lp->resolvelperror )
    4145 {
    4147 lp->resolvelperror = FALSE;
    4148 }
    4149
    4150 if( *propagateagain )
    4151 {
    4152 *solvelpagain = solvelp;
    4153 *solverelaxagain = solverelax;
    4154
    4155 return SCIP_OKAY;
    4156 }
    4157 }
    4158
    4159 /* solve external relaxations with non-negative priority */
    4160 *relaxcalled = FALSE;
    4161 if( solverelax && !(*cutoff) )
    4162 {
    4163 /* clear the storage of external branching candidates */
    4165
    4166 SCIP_CALL( solveNodeRelax(set, stat, eventfilter, tree, relaxation, transprob, origprob, actdepth, TRUE,
    4167 cutoff, propagateagain, solvelpagain, solverelaxagain, relaxcalled) );
    4168 assert(BMSgetNUsedBufferMemory(mem->buffer) == 0);
    4169
    4170 /* check, if the path was cutoff */
    4171 *cutoff = *cutoff || (tree->cutoffdepth <= actdepth);
    4172
    4173 /* apply found cuts */
    4174 SCIP_CALL( applyCuts(blkmem, set, stat, transprob, origprob, tree, reopt, lp, relaxation, sepastore, branchcand,
    4175 eventqueue, eventfilter, cliquetable, (actdepth == 0), SCIP_EFFICIACYCHOICE_RELAX, cutoff, propagateagain,
    4176 solvelpagain, solverelaxagain) );
    4177
    4178 /* update lower bound with the pseudo objective value, and cut off node by bounding */
    4179 SCIP_CALL( applyBounding(blkmem, set, stat, transprob, origprob, primal, tree, reopt, lp, branchcand, eventqueue,
    4180 eventfilter, conflict, cliquetable, cutoff) );
    4181 }
    4182 assert(SCIPsepastoreGetNCuts(sepastore) == 0);
    4183
    4184 /* check, if we want to solve the LP at this node */
    4185 if( solvelp && !(*cutoff) && SCIPtreeHasFocusNodeLP(tree) )
    4186 {
    4187 *lperror = FALSE;
    4188 *unbounded = FALSE;
    4189
    4190 /* solve the node's LP */
    4191 SCIP_CALL( solveNodeLP(blkmem, set, messagehdlr, stat, mem, origprob, transprob, primal, tree, reopt, lp, relaxation, pricestore,
    4192 sepastore, cutpool, delayedcutpool, branchcand, conflict, conflictstore, eventqueue, eventfilter, cliquetable,
    4193 initiallpsolved, fullseparation, newinitconss, forcedlpsolve, propagateagain, solverelaxagain, cutoff, unbounded, lperror, pricingaborted) );
    4194
    4195 if( focusnode->parent == NULL )
    4196 {
    4198 transprob, FALSE, -1, -1L, SCIPlpGetPseudoObjval(lp, set, transprob)) );
    4199 }
    4200
    4201 *lpsolved = TRUE;
    4202 *solvelpagain = FALSE;
    4203 SCIPsetDebugMsg(set, " -> LP status: %d, LP obj: %g, iter: %" SCIP_LONGINT_FORMAT ", count: %" SCIP_LONGINT_FORMAT "\n",
    4204 SCIPlpGetSolstat(lp),
    4205 *cutoff ? SCIPsetInfinity(set) : (*lperror ? -SCIPsetInfinity(set) : SCIPlpGetObjval(lp, set, transprob)),
    4206 stat->nlpiterations, stat->lpcount);
    4207
    4208 /* check, if the path was cutoff */
    4209 *cutoff = *cutoff || (tree->cutoffdepth <= actdepth);
    4210
    4211 /* if an error occured during LP solving, switch to pseudo solution */
    4212 if( *lperror )
    4213 {
    4214 if( forcedlpsolve )
    4215 {
    4216 SCIPerrorMessage("(node %" SCIP_LONGINT_FORMAT ") unresolved numerical troubles in LP %" SCIP_LONGINT_FORMAT " cannot be dealt with\n",
    4217 stat->nnodes, stat->nlps);
    4218 return SCIP_LPERROR;
    4219 }
    4221 ++(*nlperrors);
    4222 SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, actdepth == 0 ? SCIP_VERBLEVEL_HIGH : SCIP_VERBLEVEL_FULL,
    4223 "(node %" SCIP_LONGINT_FORMAT ") unresolved numerical troubles in LP %" SCIP_LONGINT_FORMAT " -- using pseudo solution instead (loop %d)\n",
    4224 stat->nnodes, stat->nlps, *nlperrors);
    4225 }
    4226
    4228 {
    4230 *forcedenforcement = TRUE;
    4231
    4232 SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, actdepth == 0 ? SCIP_VERBLEVEL_HIGH : SCIP_VERBLEVEL_FULL,
    4233 "(node %" SCIP_LONGINT_FORMAT ") LP solver hit %s limit in LP %" SCIP_LONGINT_FORMAT " -- using pseudo solution instead\n",
    4234 stat->nnodes, SCIPlpGetSolstat(lp) == SCIP_LPSOLSTAT_TIMELIMIT ? "time" : "iteration", stat->nlps);
    4235 }
    4236
    4238 {
    4239 SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
    4240 "(node %" SCIP_LONGINT_FORMAT ") LP relaxation is unbounded (LP %" SCIP_LONGINT_FORMAT ")\n", stat->nnodes, stat->nlps);
    4241 }
    4242
    4243 /* if we solve exactly, and the LP claims to be infeasible but the infeasibility could not be proved,
    4244 * we have to forget about the LP and use the pseudo solution instead.
    4245 * this "not proved" condition is monitored by the last check. normally if the LP is infeasible, the lowerbound would be infinity
    4246 */
    4247 if( !(*cutoff) && !(*lperror) && (set->exact_enable || *pricingaborted) && SCIPlpGetSolstat(lp) == SCIP_LPSOLSTAT_INFEASIBLE
    4248 && SCIPnodeGetLowerbound(focusnode) < primal->cutoffbound )
    4249 {
    4250 if( SCIPbranchcandGetNPseudoCands(branchcand) == 0 && transprob->ncontvars > 0 )
    4251 {
    4252 SCIPerrorMessage("(node %" SCIP_LONGINT_FORMAT ") could not prove infeasibility of LP %" SCIP_LONGINT_FORMAT " (exactsolve=%u, pricingaborted=%u), all variables are fixed, %d continuous vars\n",
    4253 stat->nnodes, stat->nlps, set->exact_enable, *pricingaborted, transprob->ncontvars);
    4254 return SCIP_LPERROR;
    4255 }
    4256 else
    4257 {
    4259 *forcedenforcement = TRUE;
    4260
    4261 SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
    4262 "(node %" SCIP_LONGINT_FORMAT ") could not prove infeasibility of LP %" SCIP_LONGINT_FORMAT " (exactsolve=%u, pricingaborted=%u) -- using pseudo solution (%d unfixed vars) instead\n",
    4263 stat->nnodes, stat->nlps, set->exact_enable, *pricingaborted, SCIPbranchcandGetNPseudoCands(branchcand));
    4264 }
    4265 }
    4266
    4267 /* update lower bound with the pseudo objective value, and cut off node by bounding */
    4268 SCIP_CALL( applyBounding(blkmem, set, stat, transprob, origprob, primal, tree, reopt, lp, branchcand, eventqueue, eventfilter,
    4269 conflict, cliquetable, cutoff) );
    4270 }
    4271 assert(SCIPsepastoreGetNCuts(sepastore) == 0);
    4272 assert(*cutoff || !SCIPtreeHasFocusNodeLP(tree) || (lp->flushed && lp->solved));
    4273
    4274 /* reset solverelaxagain if no relaxations were solved up to this point (the LP-changes are already included in
    4275 * relaxators called after the LP)
    4276 */
    4277 *solverelaxagain = *solverelaxagain && *relaxcalled;
    4278
    4279 /* solve external relaxations with negative priority */
    4280 if( solverelax && !(*cutoff) )
    4281 {
    4282 SCIP_CALL( solveNodeRelax(set, stat, eventfilter, tree, relaxation, transprob, origprob, actdepth, FALSE, cutoff,
    4283 propagateagain, solvelpagain, solverelaxagain, relaxcalled) );
    4284 assert(BMSgetNUsedBufferMemory(mem->buffer) == 0);
    4285
    4286 /* check, if the path was cutoff */
    4287 *cutoff = *cutoff || (tree->cutoffdepth <= actdepth);
    4288
    4289 /* apply found cuts */
    4290 SCIP_CALL( applyCuts(blkmem, set, stat, transprob, origprob, tree, reopt, lp, relaxation, sepastore, branchcand,
    4291 eventqueue, eventfilter, cliquetable, (actdepth == 0), SCIP_EFFICIACYCHOICE_RELAX, cutoff, propagateagain,
    4292 solvelpagain, solverelaxagain) );
    4293
    4294 /* update lower bound with the pseudo objective value, and cut off node by bounding */
    4295 SCIP_CALL( applyBounding(blkmem, set, stat, transprob, origprob, primal, tree, reopt, lp, branchcand, eventqueue,
    4296 eventfilter, conflict, cliquetable, cutoff) );
    4297 }
    4298 assert(SCIPsepastoreGetNCuts(sepastore) == 0);
    4299
    4300 return SCIP_OKAY;
    4301}
    4302
    4303/** check if a restart can be performed */
    4304#ifndef NDEBUG
    4305static
    4307 SCIP_SET* set, /**< global SCIP settings */
    4308 SCIP_STAT* stat /**< dynamic problem statistics */
    4309 )
    4310{
    4311 assert(set != NULL);
    4312 assert(stat != NULL);
    4313
    4314 /**@todo implement restarts during exact solving mode by transferring rational data correctly */
    4315 /**@todo enable certification for restarts */
    4316 return set->nactivepricers == 0 && !set->reopt_enable
    4317 && ( set->presol_maxrestarts == -1 || stat->nruns <= set->presol_maxrestarts )
    4318 && !(set->exact_enable);
    4319}
    4320#else
    4321#define restartAllowed(set,stat) ((set)->nactivepricers == 0 && !set->reopt_enable \
    4322 && ((set)->presol_maxrestarts == -1 || (stat)->nruns <= (set)->presol_maxrestarts)) \
    4323 && (!set->exact_enable)
    4324#endif
    4325
    4326/** solves the focus node */
    4327static
    4329 BMS_BLKMEM* blkmem, /**< block memory buffers */
    4330 SCIP_SET* set, /**< global SCIP settings */
    4331 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
    4332 SCIP_STAT* stat, /**< dynamic problem statistics */
    4333 SCIP_MEM* mem, /**< block memory pools */
    4334 SCIP_PROB* origprob, /**< original problem */
    4335 SCIP_PROB* transprob, /**< transformed problem after presolve */
    4336 SCIP_PRIMAL* primal, /**< primal data */
    4337 SCIP_TREE* tree, /**< branch and bound tree */
    4338 SCIP_REOPT* reopt, /**< reoptimization data structure */
    4339 SCIP_LP* lp, /**< LP data */
    4340 SCIP_RELAXATION* relaxation, /**< global relaxation data */
    4341 SCIP_PRICESTORE* pricestore, /**< pricing storage */
    4342 SCIP_SEPASTORE* sepastore, /**< separation storage */
    4343 SCIP_BRANCHCAND* branchcand, /**< branching candidate storage */
    4344 SCIP_CUTPOOL* cutpool, /**< global cut pool */
    4345 SCIP_CUTPOOL* delayedcutpool, /**< global delayed cut pool */
    4346 SCIP_CONFLICT* conflict, /**< conflict analysis data */
    4347 SCIP_CONFLICTSTORE* conflictstore, /**< conflict store */
    4348 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
    4349 SCIP_EVENTFILTER* eventfilter, /**< global event filter */
    4350 SCIP_CLIQUETABLE* cliquetable, /**< clique table data structure */
    4351 SCIP_Bool* cutoff, /**< pointer to store whether the node can be cut off */
    4352 SCIP_Bool* postpone, /**< pointer to store whether the node should be postponed */
    4353 SCIP_Bool* unbounded, /**< pointer to store whether the focus node is unbounded */
    4354 SCIP_Bool* infeasible, /**< pointer to store whether the focus node's solution is infeasible */
    4355 SCIP_Bool* restart, /**< should solving process be started again with presolving? */
    4356 SCIP_Bool* afternodeheur, /**< pointer to store whether AFTERNODE heuristics were already called */
    4357 SCIP_Bool* stopped /**< pointer to store whether solving was interrupted */
    4358 )
    4359{
    4360 SCIP_NODE* focusnode;
    4361 SCIP_Longint lastdomchgcount;
    4362 SCIP_Longint afterlpproplps;
    4363 SCIP_Real restartfac;
    4364 SCIP_Longint lastlpcount;
    4365 SCIP_HEURTIMING heurtiming;
    4366 SCIP_Bool foundsol;
    4367 SCIP_Bool focusnodehaslp;
    4368 SCIP_Bool lpsolved;
    4369 SCIP_Bool initiallpsolved;
    4370 SCIP_Bool fullseparation;
    4371 SCIP_Bool solverelaxagain;
    4372 SCIP_Bool solvelpagain;
    4373 SCIP_Bool propagateagain;
    4374 SCIP_Bool fullpropagation;
    4375 SCIP_Bool branched;
    4376 SCIP_Bool forcedlpsolve;
    4377 SCIP_Bool wasforcedlpsolve;
    4378 SCIP_Bool pricingaborted;
    4379 int actdepth;
    4380 int nlperrors;
    4381 int nloops;
    4382 int nlpcands;
    4383
    4384 assert(set != NULL);
    4385 assert(stat != NULL);
    4386 assert(origprob != NULL);
    4387 assert(transprob != NULL);
    4388 assert(tree != NULL);
    4389 assert(primal != NULL);
    4390 assert(SCIPsepastoreGetNCuts(sepastore) == 0);
    4391 assert(SCIPconflictGetNConflicts(conflict) == 0);
    4392 assert(cutoff != NULL);
    4393 assert(postpone != NULL);
    4394 assert(unbounded != NULL);
    4395 assert(infeasible != NULL);
    4396 assert(restart != NULL);
    4397 assert(afternodeheur != NULL);
    4398
    4399 *cutoff = FALSE;
    4400 *postpone = FALSE;
    4401 *unbounded = FALSE;
    4402 *infeasible = FALSE;
    4403 *restart = FALSE;
    4404 *afternodeheur = FALSE;
    4405 *stopped = FALSE;
    4406 pricingaborted = FALSE;
    4407
    4408 focusnode = SCIPtreeGetFocusNode(tree);
    4409 assert(focusnode != NULL);
    4410 assert(SCIPnodeGetType(focusnode) == SCIP_NODETYPE_FOCUSNODE);
    4411 actdepth = SCIPnodeGetDepth(focusnode);
    4412
    4413 /* invalidate relaxation solution */
    4415
    4416 /* clear the storage of external branching candidates */
    4418
    4419 SCIPsetDebugMsg(set, "Processing node %" SCIP_LONGINT_FORMAT " in depth %d, %d siblings\n",
    4420 stat->nnodes, actdepth, tree->nsiblings);
    4421 SCIPsetDebugMsg(set, "current pseudosolution: obj=%g\n", SCIPlpGetPseudoObjval(lp, set, transprob));
    4422 /*debug(SCIPprobPrintPseudoSol(transprob, set));*/
    4423
    4424 /* check, if we want to solve the LP at the selected node:
    4425 * - solve the LP, if the lp solve depth and frequency demand solving
    4426 * - solve the root LP, if the LP solve frequency is set to 0
    4427 * - solve the root LP, if there are continuous variables present
    4428 * - don't solve the node if its cut off by the pseudo objective value anyway
    4429 */
    4430 focusnodehaslp = (set->lp_solvedepth == -1 || actdepth <= set->lp_solvedepth);
    4431 focusnodehaslp = focusnodehaslp && (actdepth >= set->lp_minsolvedepth);
    4432 focusnodehaslp = focusnodehaslp && (set->lp_solvefreq >= 1 && actdepth % set->lp_solvefreq == 0);
    4433 focusnodehaslp = focusnodehaslp || (actdepth == 0 && set->lp_solvefreq == 0);
    4434 focusnodehaslp = focusnodehaslp && SCIPsetIsLT(set, SCIPlpGetPseudoObjval(lp, set, transprob), primal->cutoffbound);
    4435 focusnodehaslp = set->reopt_enable ? focusnodehaslp && SCIPreoptGetSolveLP(reopt, set, focusnode) : focusnodehaslp;
    4436 SCIPtreeSetFocusNodeLP(tree, focusnodehaslp);
    4437
    4438 /* external node solving loop:
    4439 * - propagate domains
    4440 * - solve SCIP_LP
    4441 * - enforce constraints
    4442 * if a constraint handler adds constraints to enforce its own constraints, both, propagation and LP solving
    4443 * is applied again (if applicable on current node); however, if the new constraints don't have the enforce flag set,
    4444 * it is possible, that the current infeasible solution is not cut off; in this case, we have to declare the solution
    4445 * infeasible and perform a branching
    4446 */
    4447 lastdomchgcount = stat->domchgcount;
    4448 lastlpcount = stat->lpcount;
    4449 initiallpsolved = FALSE;
    4450 fullseparation = TRUE;
    4451 heurtiming = SCIP_HEURTIMING_BEFORENODE;
    4452 nlperrors = 0;
    4453 stat->npricerounds = 0;
    4454 stat->nseparounds = 0;
    4455 solverelaxagain = TRUE;
    4456 solvelpagain = TRUE;
    4457 propagateagain = TRUE;
    4458 fullpropagation = TRUE;
    4459 forcedlpsolve = FALSE;
    4460 nloops = 0;
    4461
    4462 while( !(*cutoff) && !(*postpone) && (solverelaxagain || solvelpagain || propagateagain) && nlperrors < MAXNLPERRORS && !(*restart) )
    4463 {
    4464 SCIP_Bool lperror;
    4465 SCIP_Bool solverelax;
    4466 SCIP_Bool solvelp;
    4467 SCIP_Bool propagate;
    4468 SCIP_Bool forcedenforcement;
    4469 SCIP_Bool relaxcalled;
    4470
    4471 assert(SCIPsepastoreGetNCuts(sepastore) == 0);
    4472
    4473 *unbounded = FALSE;
    4474 *infeasible = FALSE;
    4475 foundsol = FALSE;
    4476
    4477 nloops++;
    4478 lperror = FALSE;
    4479 lpsolved = FALSE;
    4480 relaxcalled = FALSE;
    4481 forcedenforcement = FALSE;
    4482 afterlpproplps = -1L;
    4483
    4484 while( !lperror && !(*cutoff) && (propagateagain || solvelpagain || solverelaxagain
    4485 || (afterlpproplps < stat->nnodelps && lpsolved) || relaxcalled) )
    4486 {
    4487 solverelax = solverelaxagain;
    4488 solverelaxagain = FALSE;
    4489 solvelp = solvelpagain;
    4490 solvelpagain = FALSE;
    4491 propagate = propagateagain;
    4492 propagateagain = FALSE;
    4493
    4494 /* update lower bound with the pseudo objective value, and cut off node by bounding */
    4495 SCIP_CALL( applyBounding(blkmem, set, stat, transprob, origprob, primal, tree, reopt, lp, branchcand, eventqueue,
    4496 eventfilter, conflict, cliquetable, cutoff) );
    4497
    4498 if( set->exact_enable && *cutoff && !SCIPsetIsInfinity(set, -SCIPlpGetPseudoObjval(lp, set, transprob)) )
    4499 {
    4501 transprob, FALSE, -1, -1L, SCIPsetInfinity(set)) );
    4502 }
    4503
    4504 /* propagate domains before lp solving and solve relaxation and lp */
    4505 SCIPsetDebugMsg(set, " -> node solving loop: call propagators that are applicable before%s LP is solved\n",
    4506 lpsolved ? " and after" : "");
    4507 SCIP_CALL( propAndSolve(blkmem, set, messagehdlr, stat, mem, origprob, transprob, primal, tree, reopt, lp,
    4508 relaxation, pricestore, sepastore, branchcand, cutpool, delayedcutpool, conflict, conflictstore, eventqueue,
    4509 eventfilter, cliquetable, focusnode, actdepth, propagate, solvelp, solverelax, forcedlpsolve, initiallpsolved,
    4510 fullseparation, &afterlpproplps, &heurtiming, &nlperrors, &fullpropagation, &propagateagain, &lpsolved, &relaxcalled,
    4511 &solvelpagain, &solverelaxagain, cutoff, postpone, unbounded, stopped, &lperror, &pricingaborted, &forcedenforcement) );
    4512 initiallpsolved |= lpsolved;
    4513
    4514 /* time or solution limit was hit and we already created a dummy child node to terminate fast */
    4515 if( *stopped )
    4516 {
    4517 /* reset LP feastol to normal value, in case someone tightened it during node solving */
    4519 return SCIP_OKAY;
    4520 }
    4521 }
    4522 fullseparation = FALSE;
    4523
    4524 /* update the cutoff, propagateagain, and solverelaxagain status of current solving loop */
    4525 updateLoopStatus(set, stat, tree, actdepth, cutoff, &propagateagain, &solverelaxagain);
    4526
    4527 /* call primal heuristics that should be applied after the LP relaxation of the node was solved;
    4528 * if this is the first loop of the root node, call also AFTERNODE heuristics already here, since they might help
    4529 * to improve the primal bound, thereby producing additional reduced cost strengthenings and strong branching
    4530 * bound fixings which also might lead to a restart
    4531 */
    4532 if( !(*postpone) && (!(*cutoff) || SCIPtreeGetNNodes(tree) > 0) )
    4533 {
    4534 if( actdepth == 0 && !(*afternodeheur) )
    4535 {
    4536 SCIP_CALL( SCIPprimalHeuristics(set, stat, transprob, primal, tree, lp, NULL,
    4537 SCIP_HEURTIMING_AFTERLPLOOP | SCIP_HEURTIMING_AFTERNODE, *cutoff, &foundsol, unbounded) );
    4538 *afternodeheur = TRUE; /* the AFTERNODE heuristics should not be called again after the node */
    4539 }
    4540 else if( lpsolved || SCIPrelaxationIsSolValid(relaxation) )
    4541 {
    4542 SCIP_CALL( SCIPprimalHeuristics(set, stat, transprob, primal, tree, lp, NULL, SCIP_HEURTIMING_AFTERLPLOOP,
    4543 *cutoff, &foundsol, unbounded) );
    4544 }
    4545 assert(BMSgetNUsedBufferMemory(mem->buffer) == 0);
    4546
    4547 /* heuristics might have found a solution or set the cutoff bound such that the current node is cut off */
    4548 SCIP_CALL( applyBounding(blkmem, set, stat, transprob, origprob, primal, tree, reopt, lp, branchcand, eventqueue,
    4549 eventfilter, conflict, cliquetable, cutoff) );
    4550 }
    4551
    4552 /* check if heuristics leave us with an invalid LP */
    4553 if( lp->resolvelperror )
    4554 {
    4555 if( forcedlpsolve )
    4556 {
    4557 SCIPerrorMessage("(node %" SCIP_LONGINT_FORMAT ") unresolved numerical troubles in LP %" SCIP_LONGINT_FORMAT " cannot be dealt with\n",
    4558 stat->nnodes, stat->nlps);
    4559 return SCIP_LPERROR;
    4560 }
    4562 lp->resolvelperror = FALSE;
    4563 nlperrors++;
    4564 SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
    4565 "(node %" SCIP_LONGINT_FORMAT ") unresolved numerical troubles in LP %" SCIP_LONGINT_FORMAT " -- using pseudo solution instead (loop %d)\n",
    4566 stat->nnodes, stat->nlps, nlperrors);
    4567 }
    4568
    4569 if( pricingaborted && !(*cutoff) && SCIPlpGetSolstat(lp) != SCIP_LPSOLSTAT_OPTIMAL )
    4570 {
    4572
    4573 /* if we just ran into the time limit this is not really a numerical trouble;
    4574 * however, if this is not the case, we print messages about numerical troubles in the current LP
    4575 */
    4576 if( !SCIPsolveIsStopped(set, stat, FALSE) )
    4577 {
    4578 if( forcedlpsolve )
    4579 {
    4580 SCIPerrorMessage("(node %" SCIP_LONGINT_FORMAT ") unresolved numerical troubles in LP %" SCIP_LONGINT_FORMAT " cannot be dealt with\n",
    4581 stat->nnodes, stat->nlps);
    4582 return SCIP_LPERROR;
    4583 }
    4584 nlperrors++;
    4585 SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
    4586 "(node %" SCIP_LONGINT_FORMAT ") unresolved numerical troubles in LP %" SCIP_LONGINT_FORMAT " -- using pseudo solution instead (loop %d)\n",
    4587 stat->nnodes, stat->nlps, nlperrors);
    4588 }
    4589 }
    4590
    4591 /* if an improved solution was found, propagate and solve the relaxations again */
    4592 if( foundsol && !(*cutoff) )
    4593 {
    4594 propagateagain = TRUE;
    4595 solvelpagain = TRUE;
    4596 solverelaxagain = TRUE;
    4597 markRelaxsUnsolved(set, relaxation);
    4598 }
    4599
    4600 /* check for immediate restart */
    4601 *restart = *restart || (actdepth == 0 && restartAllowed(set, stat) && (stat->userrestart
    4602 || (stat->nrootintfixingsrun > set->presol_immrestartfac * (transprob->nvars - transprob->ncontvars)
    4603 && (stat->nruns == 1 || transprob->nvars <= (1.0-set->presol_restartminred) * stat->prevrunnvars))) );
    4604
    4605 /* enforce constraints */
    4606 branched = FALSE;
    4607 if( !(*postpone) && !(*restart) && !(*cutoff) && !solverelaxagain && !solvelpagain && !propagateagain )
    4608 {
    4609 /* if the solution changed since the last enforcement, we have to completely reenforce it; otherwise, we
    4610 * only have to enforce the additional constraints added in the last enforcement, but keep the infeasible
    4611 * flag TRUE in order to not declare the infeasible solution feasible due to disregarding the already
    4612 * enforced constraints
    4613 */
    4614 if( lastdomchgcount != stat->domchgcount || lastlpcount != stat->lpcount )
    4615 {
    4616 lastdomchgcount = stat->domchgcount;
    4617 lastlpcount = stat->lpcount;
    4618 *infeasible = FALSE;
    4619 }
    4620
    4621 /* call constraint enforcement */
    4622 SCIP_CALL( enforceConstraints(blkmem, set, messagehdlr, stat, transprob, primal, tree, lp, relaxation, sepastore,
    4623 branchcand, &branched, cutoff, infeasible, &propagateagain, &solvelpagain, &solverelaxagain,
    4624 forcedenforcement) );
    4625 assert(branched == (tree->nchildren > 0));
    4626 assert(!branched || (!(*cutoff) && *infeasible && !propagateagain && !solvelpagain));
    4627 assert(!(*cutoff) || (!branched && *infeasible && !propagateagain && !solvelpagain));
    4628 assert(*infeasible || (!branched && !(*cutoff) && !propagateagain && !solvelpagain));
    4629 assert(!propagateagain || (!branched && !(*cutoff) && *infeasible));
    4630 assert(!solvelpagain || (!branched && !(*cutoff) && *infeasible));
    4631
    4632 assert(BMSgetNUsedBufferMemory(mem->buffer) == 0);
    4633
    4634 /* apply found cuts */
    4635 SCIP_CALL( applyCuts(blkmem, set, stat, transprob, origprob, tree, reopt, lp, relaxation, sepastore, branchcand,
    4636 eventqueue, eventfilter, cliquetable, (actdepth == 0), SCIP_EFFICIACYCHOICE_LP, cutoff, &propagateagain,
    4637 &solvelpagain, &solverelaxagain) );
    4638
    4639 /* update lower bound with the pseudo objective value, and cut off node by bounding */
    4640 SCIP_CALL( applyBounding(blkmem, set, stat, transprob, origprob, primal, tree, reopt, lp, branchcand, eventqueue,
    4641 eventfilter, conflict, cliquetable, cutoff) );
    4642
    4643 /* update the cutoff, propagateagain, and solverelaxagain status of current solving loop */
    4644 updateLoopStatus(set, stat, tree, actdepth, cutoff, &propagateagain, &solverelaxagain);
    4645 }
    4646 assert(SCIPsepastoreGetNCuts(sepastore) == 0);
    4647
    4648 /* The enforcement detected no infeasibility, so, no branching was performed,
    4649 * but the pricing was aborted and the current feasible solution does not have to be the
    4650 * best solution in the current subtree --> we have to do a pseudo branching,
    4651 * so we set infeasible TRUE and add the current solution to the solution pool
    4652 */
    4653 if( pricingaborted && !(*infeasible) && !(*cutoff) && !(*postpone) && !(*restart) )
    4654 {
    4655 SCIP_Longint oldnbestsolsfound = primal->nbestsolsfound;
    4656 SCIP_SOL* sol;
    4657 SCIP_Bool stored;
    4658
    4659 /* in case the relaxation was enforced add this solution, otherwise decide between LP and pseudosol */
    4661 || SCIPsetIsGT(set, SCIPrelaxationGetSolObj(relaxation), SCIPlpGetObjval(lp, set, transprob))) )
    4662 {
    4663 SCIP_SOL* relaxsol;
    4664
    4665 SCIP_CALL( SCIPsolCreateRelaxSol(&relaxsol, blkmem, set, stat, primal, tree, relaxation, NULL) );
    4666
    4667 SCIP_CALL( SCIPprimalTrySol(primal, blkmem, set, messagehdlr, stat, origprob, transprob, tree, reopt, lp,
    4668 eventqueue, eventfilter, relaxsol, FALSE, FALSE, TRUE, TRUE, TRUE,
    4669 &stored) );
    4670
    4671 SCIP_CALL( SCIPsolFree(&relaxsol, blkmem, primal) );
    4672
    4673 if( stored )
    4674 {
    4675 stat->nrelaxsolsfound++;
    4676
    4677 if( primal->nbestsolsfound != oldnbestsolsfound )
    4678 {
    4679 stat->nrelaxbestsolsfound++;
    4681 }
    4682 }
    4683 }
    4684 else
    4685 {
    4686 SCIP_CALL( SCIPsolCreateCurrentSol(&sol, blkmem, set, stat, transprob, primal, tree, lp, NULL) );
    4687 SCIP_CALL( SCIPprimalTrySolFree(primal, blkmem, set, messagehdlr, stat, origprob, transprob, tree, reopt, lp,
    4688 eventqueue, eventfilter, &sol, FALSE, FALSE, TRUE, TRUE, TRUE, &stored) );
    4689
    4690 if( stored )
    4691 {
    4692 stat->nlpsolsfound++;
    4693
    4694 if( primal->nbestsolsfound != oldnbestsolsfound )
    4695 {
    4696 stat->nlpbestsolsfound++;
    4698 }
    4699 }
    4700 }
    4701
    4702 *infeasible = TRUE;
    4703 }
    4704
    4705 /* if the node is infeasible, but no constraint handler could resolve the infeasibility
    4706 * -> branch on LP, external candidates, or the pseudo solution
    4707 * -> e.g. select non-fixed binary or integer variable x with value x', create three
    4708 * sons: x <= x'-1, x = x', and x >= x'+1.
    4709 * In the left and right branch, the current solution is cut off. In the middle
    4710 * branch, the constraints can hopefully reduce domains of other variables to cut
    4711 * off the current solution.
    4712 * In LP branching, we cannot allow adding constraints, because this does not necessary change the LP and can
    4713 * therefore lead to an infinite loop.
    4714 */
    4715 wasforcedlpsolve = forcedlpsolve;
    4716 forcedlpsolve = FALSE;
    4717 if( (*infeasible) && !(*cutoff) && !(*postpone) && !(*restart)
    4718 && (!(*unbounded) || SCIPbranchcandGetNExternCands(branchcand) > 0 || SCIPbranchcandGetNPseudoCands(branchcand) > 0)
    4719 && !solverelaxagain && !solvelpagain && !propagateagain && !branched )
    4720 {
    4721 SCIP_RESULT result = SCIP_DIDNOTRUN;
    4722
    4723 if( SCIPtreeHasFocusNodeLP(tree) )
    4724 {
    4725 SCIP_CALL( SCIPbranchcandGetLPCands(branchcand, set, stat, lp, NULL, NULL, NULL, &nlpcands, NULL, NULL) );
    4726 }
    4727 else
    4728 nlpcands = 0;
    4729
    4730 if ( nlpcands > 0 || SCIPbranchcandGetNExternCands(branchcand) > 0 )
    4731 {
    4732 /* If there are LP candidates and their maximal priority is at least the maximal priority of the external
    4733 * candidates, then branch on the LP candidates. Note that due to implicit integer variables,
    4734 * SCIPbranchcandGetLPMaxPrio(branchcand) might be finite and SCIPbranchcandGetNPrioLPCands(branchcand) > 0,
    4735 * but nlpcands == 0. */
    4736 if ( SCIPbranchcandGetLPMaxPrio(branchcand) >= SCIPbranchcandGetExternMaxPrio(branchcand) && nlpcands > 0 )
    4737 {
    4738 assert( SCIPbranchcandGetNPrioLPCands(branchcand) > 0 );
    4739 assert( nlpcands > 0 );
    4740
    4741 /* branch on LP solution */
    4742 SCIPsetDebugMsg(set, "infeasibility in depth %d was not resolved: branch on LP solution with %d fractionals\n",
    4743 SCIPnodeGetDepth(focusnode), nlpcands);
    4744 SCIP_CALL( SCIPbranchExecLP(blkmem, set, stat, transprob, origprob, tree, reopt, lp, sepastore, branchcand,
    4745 eventqueue, eventfilter, primal->cutoffbound, FALSE, &result) );
    4746 assert(BMSgetNUsedBufferMemory(mem->buffer) == 0);
    4747 assert(result != SCIP_DIDNOTRUN && result != SCIP_DIDNOTFIND);
    4748 }
    4749 else
    4750 {
    4751 assert( SCIPbranchcandGetNPrioExternCands(branchcand) > 0 );
    4752 assert( SCIPbranchcandGetNExternCands(branchcand) > 0 );
    4753
    4754 /* branch on external candidates */
    4755 SCIPsetDebugMsg(set, "infeasibility in depth %d was not resolved: branch on %d external branching candidates.\n",
    4756 SCIPnodeGetDepth(focusnode), SCIPbranchcandGetNExternCands(branchcand));
    4757 SCIP_CALL( SCIPbranchExecExtern(blkmem, set, stat, transprob, origprob, tree, reopt, lp, sepastore, branchcand,
    4758 eventqueue, eventfilter, primal->cutoffbound, TRUE, &result) );
    4759 assert(BMSgetNUsedBufferMemory(mem->buffer) == 0);
    4760 }
    4761 }
    4762
    4763 if( result == SCIP_DIDNOTRUN || result == SCIP_DIDNOTFIND )
    4764 {
    4765 /* branch on pseudo solution */
    4766 SCIPsetDebugMsg(set, "infeasibility in depth %d was not resolved: branch on pseudo solution with %d unfixed integers\n",
    4767 SCIPnodeGetDepth(focusnode), SCIPbranchcandGetNPseudoCands(branchcand));
    4768 SCIP_CALL( SCIPbranchExecPseudo(blkmem, set, stat, transprob, origprob, tree, reopt, lp, branchcand, eventqueue,
    4769 eventfilter, primal->cutoffbound, TRUE, &result) );
    4770 assert(BMSgetNUsedBufferMemory(mem->buffer) == 0);
    4771 }
    4772
    4773 /* SCIP cannot guarantee convergence if it is necessary to branch on unbounded variables */
    4774 if( result == SCIP_BRANCHED )
    4775 {
    4776 SCIP_VAR* var = stat->lastbranchvar;
    4777
    4778 if( var != NULL && !stat->branchedunbdvar && !SCIPvarIsIntegral(var)
    4780 {
    4781 SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_NORMAL,
    4782 "Starting spatial branch-and-bound on unbounded variable <%s> ([%g,%g]) - cannot guarantee finite termination.\n",
    4784 stat->branchedunbdvar = TRUE;
    4785 }
    4786 }
    4787
    4788 switch( result )
    4789 {
    4790 case SCIP_CUTOFF:
    4791 assert(tree->nchildren == 0);
    4792 *cutoff = TRUE;
    4793 SCIPsetDebugMsg(set, " -> branching rule detected cutoff\n");
    4794 break;
    4795 case SCIP_CONSADDED:
    4796 assert(tree->nchildren == 0);
    4797 if( nlpcands > 0 )
    4798 {
    4799 SCIPerrorMessage("LP branching rule added constraint, which was not allowed this time\n");
    4800 return SCIP_INVALIDRESULT;
    4801 }
    4802 propagateagain = TRUE;
    4803 solvelpagain = TRUE;
    4804 solverelaxagain = TRUE;
    4805 markRelaxsUnsolved(set, relaxation);
    4806 break;
    4807 case SCIP_REDUCEDDOM:
    4808 assert(tree->nchildren == 0);
    4809 propagateagain = TRUE;
    4810 solvelpagain = TRUE;
    4811 solverelaxagain = TRUE;
    4812 markRelaxsUnsolved(set, relaxation);
    4813 break;
    4814 case SCIP_SEPARATED:
    4815 assert(tree->nchildren == 0);
    4816 assert(SCIPsepastoreGetNCuts(sepastore) > 0);
    4817 solvelpagain = TRUE;
    4818 solverelaxagain = TRUE;
    4819 markRelaxsUnsolved(set, relaxation);
    4820 break;
    4821 case SCIP_BRANCHED:
    4822 assert(tree->nchildren >= 1);
    4823 assert(SCIPsepastoreGetNCuts(sepastore) == 0);
    4824 branched = TRUE;
    4825
    4826 /* increase the number of internal nodes */
    4827 stat->ninternalnodes++;
    4828 stat->ntotalinternalnodes++;
    4829 break;
    4830 case SCIP_DIDNOTFIND: /*lint -fallthrough*/
    4831 case SCIP_DIDNOTRUN:
    4832 /* all integer variables in the infeasible solution are fixed,
    4833 * - if no continuous variables exist and all variables are known, the infeasible pseudo solution is completely
    4834 * fixed, and the node can be cut off
    4835 * - if at least one continuous variable exists or we do not know all variables due to external pricers, we
    4836 * cannot resolve the infeasibility by branching -> solve LP (and maybe price in additional variables)
    4837 */
    4838 assert(tree->nchildren == 0);
    4839 assert(SCIPsepastoreGetNCuts(sepastore) == 0);
    4840 assert(SCIPbranchcandGetNPseudoCands(branchcand) == 0);
    4841
    4842 if( transprob->ncontvars == 0 && set->nactivepricers == 0 )
    4843 {
    4844 *cutoff = TRUE;
    4845 SCIPsetDebugMsg(set, " -> cutoff because all variables are fixed in current node\n");
    4846 }
    4847 else
    4848 {
    4849 /* feasible LP solutions with all integers fixed must be feasible
    4850 * if also no external branching candidates were available
    4851 */
    4852 assert(!SCIPtreeHasFocusNodeLP(tree) || pricingaborted);
    4853
    4855 {
    4856 SCIP_NODE* node;
    4857
    4858 /* as we hit the time or iteration limit or another interrupt (e.g., gap limit), we do not want to solve the LP again.
    4859 * in order to terminate correctly, we create a "branching" with only one child node
    4860 * that is a copy of the focusnode
    4861 */
    4862 SCIP_CALL( SCIPnodeCreateChild(&node, blkmem, set, stat, tree, 1.0, focusnode->estimate) );
    4863 assert(tree->nchildren >= 1);
    4864 assert(SCIPsepastoreGetNCuts(sepastore) == 0);
    4865 branched = TRUE;
    4866 }
    4867 else
    4868 {
    4869 SCIP_VERBLEVEL verblevel;
    4870
    4871 if( pricingaborted )
    4872 {
    4873 SCIPerrorMessage("pricing was aborted, but no branching could be created!\n");
    4874 return SCIP_INVALIDRESULT;
    4875 }
    4876
    4877 if( wasforcedlpsolve )
    4878 {
    4879 assert(SCIPtreeHasFocusNodeLP(tree));
    4880 SCIPerrorMessage("LP was solved, all integers fixed, some constraint still infeasible, but no branching could be created!\n");
    4881 return SCIP_INVALIDRESULT;
    4882 }
    4883
    4884 verblevel = SCIP_VERBLEVEL_FULL;
    4885
    4886 if( !tree->forcinglpmessage && set->disp_verblevel == SCIP_VERBLEVEL_HIGH )
    4887 {
    4888 verblevel = SCIP_VERBLEVEL_HIGH;
    4889
    4890 /* remember that the forcing LP solving message was posted and do only post it again if the
    4891 * verblevel is SCIP_VERBLEVEL_FULL
    4892 */
    4893 tree->forcinglpmessage = TRUE;
    4894 }
    4895
    4896 SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, verblevel,
    4897 "(node %" SCIP_LONGINT_FORMAT ") forcing the solution of an LP (last LP %" SCIP_LONGINT_FORMAT ")...\n", stat->nnodes, stat->nlps);
    4898
    4899 /* solve the LP in the next loop */
    4901 solvelpagain = TRUE;
    4902 forcedlpsolve = TRUE; /* this LP must be solved without error - otherwise we have to abort */
    4904 }
    4905 }
    4906 break;
    4907 default:
    4908 SCIPerrorMessage("invalid result code <%d> from SCIPbranchLP(), SCIPbranchExt() or SCIPbranchPseudo()\n", result);
    4909 return SCIP_INVALIDRESULT;
    4910 } /*lint !e788*/
    4911 assert(*cutoff || solvelpagain || propagateagain || branched); /* something must have been done */
    4912 assert(!(*cutoff) || (!solvelpagain && !propagateagain && !branched));
    4913 assert(!solvelpagain || (!(*cutoff) && !branched));
    4914 assert(!propagateagain || (!(*cutoff) && !branched));
    4915 assert(!branched || (!solvelpagain && !propagateagain));
    4916 assert(branched == (tree->nchildren > 0));
    4917
    4918 /* apply found cuts */
    4919 SCIP_CALL( applyCuts(blkmem, set, stat, transprob, origprob, tree, reopt, lp, relaxation, sepastore, branchcand,
    4920 eventqueue, eventfilter, cliquetable, (actdepth == 0), SCIP_EFFICIACYCHOICE_LP, cutoff, &propagateagain,
    4921 &solvelpagain, &solverelaxagain) );
    4922
    4923 /* update lower bound with the pseudo objective value, and cut off node by bounding */
    4924 SCIP_CALL( applyBounding(blkmem, set, stat, transprob, origprob, primal, tree, reopt, lp, branchcand, eventqueue,
    4925 eventfilter, conflict, cliquetable, cutoff) );
    4926
    4927 /* update the cutoff, propagateagain, and solverelaxagain status of current solving loop */
    4928 updateLoopStatus(set, stat, tree, actdepth, cutoff, &propagateagain, &solverelaxagain);
    4929 }
    4930
    4931 /* check for immediate restart */
    4932 *restart = *restart || (actdepth == 0 && restartAllowed(set, stat) && (stat->userrestart
    4933 || (stat->nrootintfixingsrun > set->presol_immrestartfac * (transprob->nvars - transprob->ncontvars)
    4934 && (stat->nruns == 1 || transprob->nvars <= (1.0-set->presol_restartminred) * stat->prevrunnvars))) );
    4935
    4936 SCIPsetDebugMsg(set, "node solving iteration %d finished: cutoff=%u, postpone=%u, propagateagain=%u, solverelaxagain=%u, solvelpagain=%u, nlperrors=%d, restart=%u\n",
    4937 nloops, *cutoff, *postpone, propagateagain, solverelaxagain, solvelpagain, nlperrors, *restart);
    4938 }
    4939 assert(SCIPsepastoreGetNCuts(sepastore) == 0);
    4940 assert(*cutoff || SCIPconflictGetNConflicts(conflict) == 0);
    4941
    4942 /* flush the conflict set storage */
    4943 SCIP_CALL( SCIPconflictFlushConss(conflict, blkmem, set, stat, transprob, origprob, tree, reopt, lp, branchcand, eventqueue, eventfilter, cliquetable) );
    4944
    4945 /* check for too many LP errors */
    4946 if( nlperrors >= MAXNLPERRORS )
    4947 {
    4948 SCIPerrorMessage("(node %" SCIP_LONGINT_FORMAT ") unresolved numerical troubles in LP %" SCIP_LONGINT_FORMAT " -- aborting\n", stat->nnodes, stat->nlps);
    4949 return SCIP_LPERROR;
    4950 }
    4951
    4952 /* check for final restart */
    4953 restartfac = set->presol_subrestartfac;
    4954 if( actdepth == 0 )
    4955 restartfac = MIN(restartfac, set->presol_restartfac);
    4956 *restart = *restart || (restartAllowed(set, stat) && (stat->userrestart
    4957 || (stat->nrootintfixingsrun > restartfac * (transprob->nvars - transprob->ncontvars)
    4958 && (stat->nruns == 1 || transprob->nvars <= (1.0-set->presol_restartminred) * stat->prevrunnvars))) );
    4959
    4960 /* remember the last root LP solution */
    4961 if( actdepth == 0 && !(*cutoff) && !(*unbounded) && !(*postpone) )
    4962 {
    4963 /* the root pseudo objective value and pseudo objective value should be equal in the root node */
    4964 assert(SCIPsetIsRelEQ(set, SCIPlpGetGlobalPseudoObjval(lp, set, transprob), SCIPlpGetPseudoObjval(lp, set, transprob)));
    4965
    4966 SCIPprobStoreRootSol(transprob, set, stat, lp, SCIPtreeHasFocusNodeLP(tree));
    4967 }
    4968
    4969 /* check for cutoff */
    4970 if( *cutoff )
    4971 {
    4972 SCIP_CALL( SCIPnodeCutoff(focusnode, set, stat, eventfilter, tree, transprob, origprob, reopt, lp, blkmem) );
    4973
    4974 if( !(lp->solved && lp->flushed) )
    4975 {
    4977 }
    4978 else if( SCIPlpGetSolstat(lp) == SCIP_LPSOLSTAT_INFEASIBLE && focusnodehaslp )
    4979 {
    4981 }
    4982 else if( focusnodehaslp )
    4983 {
    4985 }
    4986
    4987 /* the LP might have been unbounded but not enforced, because the node is cut off anyway */
    4988 *unbounded = FALSE;
    4989 *infeasible = TRUE;
    4990 }
    4991 /* update the regression statistic nlpbranchcands and LP objective value */
    4992 else if( !(*unbounded) && SCIPlpGetSolstat(lp) == SCIP_LPSOLSTAT_OPTIMAL && lp->looseobjvalinf == 0 )
    4993 {
    4994 SCIP_Real lpobjval;
    4995
    4996 /* get number of LP candidate variables */
    4997 SCIP_CALL( SCIPbranchcandGetLPCands(branchcand, set, stat, lp, NULL, NULL, NULL, &nlpcands, NULL, NULL) );
    4998
    4999 /* get LP objective value */
    5000 lpobjval = SCIPlpGetObjval(lp, set, transprob);
    5001 assert(lpobjval != SCIP_INVALID); /*lint !e777*/
    5002
    5003 /* add the observation to the regression */
    5005 }
    5006
    5007 /* reset LP feastol to normal value, in case someone tightened it during node solving */
    5009
    5010 return SCIP_OKAY;
    5011}
    5012
    5013/** if feasible, adds current solution to the solution storage */
    5014static
    5016 BMS_BLKMEM* blkmem, /**< block memory buffers */
    5017 SCIP_SET* set, /**< global SCIP settings */
    5018 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
    5019 SCIP_STAT* stat, /**< dynamic problem statistics */
    5020 SCIP_PROB* origprob, /**< original problem */
    5021 SCIP_PROB* transprob, /**< transformed problem after presolve */
    5022 SCIP_PRIMAL* primal, /**< primal data */
    5023 SCIP_RELAXATION* relaxation, /**< global relaxation data */
    5024 SCIP_TREE* tree, /**< branch and bound tree */
    5025 SCIP_REOPT* reopt, /**< reoptimization data structure */
    5026 SCIP_LP* lp, /**< LP data */
    5027 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
    5028 SCIP_EVENTFILTER* eventfilter, /**< global event filter */
    5029 SCIP_Bool checksol /**< should the solution be checked? */
    5030 )
    5031{
    5032 SCIP_Longint oldnbestsolsfound = primal->nbestsolsfound;
    5033 SCIP_SOL* sol;
    5034 SCIP_Bool foundsol;
    5035
    5036 /* found a feasible solution */
    5038 || SCIPsetIsGT(set, SCIPrelaxationGetSolObj(relaxation), SCIPlpGetObjval(lp, set, transprob))) )
    5039 {
    5040 /* start clock for relaxation solutions */
    5042
    5043 SCIP_CALL( SCIPsolCreateRelaxSol(&sol, blkmem, set, stat, primal, tree, relaxation, NULL) );
    5044
    5045 SCIPsetDebugMsg(set, "found relaxation solution with objective %f\n", SCIPsolGetObj(sol, set, transprob, origprob));
    5046
    5047 if( checksol || set->exact_enable )
    5048 {
    5049 /* if we want to solve exactly, we have to check the solution exactly again */
    5050 SCIP_CALL( SCIPprimalTrySolFree(primal, blkmem, set, messagehdlr, stat, origprob, transprob, tree, reopt, lp,
    5051 eventqueue, eventfilter, &sol, FALSE, FALSE, TRUE, TRUE, TRUE, &foundsol) );
    5052 }
    5053 else
    5054 {
    5055 SCIP_CALL( SCIPprimalAddSolFree(primal, blkmem, set, messagehdlr, stat, origprob, transprob, tree, reopt, lp,
    5056 eventqueue, eventfilter, &sol, &foundsol) );
    5057 }
    5058
    5059 if( foundsol )
    5060 {
    5061 stat->nrelaxsolsfound++;
    5062
    5063 if( primal->nbestsolsfound != oldnbestsolsfound )
    5064 {
    5065 stat->nrelaxbestsolsfound++;
    5067 }
    5068 }
    5069
    5070 /* stop clock for relaxation solutions */
    5072 }
    5073 else if( SCIPtreeHasFocusNodeLP(tree) )
    5074 {
    5075 /* Removed assert(lp->primalfeasible); since there can be a solved LP and there is some solution with infinite values,
    5076 * but the lp is not primal feasible. */
    5077
    5078 /* start clock for LP solutions */
    5080
    5081 /* add solution to storage */
    5082 if( set->exact_enable && lp->lpexact->solved )
    5083 {
    5084 SCIP_CALL( SCIPsolCreateLPSolExact(&sol, blkmem, set, stat, set->scip->primal, tree, lp->lpexact, NULL) );
    5085
    5086 SCIP_CALL( SCIPprimalTrySolFreeExact(primal, blkmem, set, messagehdlr, stat, origprob, transprob, tree, reopt, lp->lpexact,
    5087 eventqueue, eventfilter, &sol, FALSE, FALSE, TRUE, TRUE, TRUE, &foundsol) );
    5088 }
    5089 else
    5090 {
    5091 SCIP_CALL( SCIPsolCreateLPSol(&sol, blkmem, set, stat, transprob, primal, tree, lp, NULL) );
    5092 SCIPsetDebugMsg(set, "found lp solution with objective %f\n", SCIPsolGetObj(sol, set, transprob, origprob));
    5093
    5094 if( checksol || set->exact_enable )
    5095 {
    5096 /* if we want to solve exactly, we have to check the solution exactly again */
    5097 SCIP_CALL( SCIPprimalTrySolFree(primal, blkmem, set, messagehdlr, stat, origprob, transprob, tree, reopt, lp,
    5098 eventqueue, eventfilter, &sol, FALSE, FALSE, TRUE, TRUE, TRUE, &foundsol) );
    5099 }
    5100 else
    5101 {
    5102 SCIP_CALL( SCIPprimalAddSolFree(primal, blkmem, set, messagehdlr, stat, origprob, transprob, tree, reopt, lp,
    5103 eventqueue, eventfilter, &sol, &foundsol) );
    5104 }
    5105 }
    5106
    5107 if( foundsol )
    5108 {
    5109 stat->nlpsolsfound++;
    5110
    5111 if( primal->nbestsolsfound != oldnbestsolsfound )
    5112 {
    5113 stat->nlpbestsolsfound++;
    5115 }
    5116 }
    5117
    5118 /* stop clock for LP solutions */
    5119 SCIPclockStop(stat->lpsoltime, set);
    5120 }
    5121 else
    5122 {
    5123 /* start clock for pseudo solutions */
    5125
    5126 /* add solution to storage */
    5127 SCIP_CALL( SCIPsolCreatePseudoSol(&sol, blkmem, set, stat, transprob, primal, tree, lp, NULL) );
    5128
    5129 SCIPsetDebugMsg(set, "found pseudo solution with objective %f\n", SCIPsolGetObj(sol, set, transprob, origprob));
    5130
    5131 if( checksol || set->exact_enable )
    5132 {
    5133 /* if we want to solve exactly, we have to check the solution exactly again */
    5134 SCIP_CALL( SCIPprimalTrySolFree(primal, blkmem, set, messagehdlr, stat, origprob, transprob, tree, reopt, lp,
    5135 eventqueue, eventfilter, &sol, FALSE, FALSE, TRUE, TRUE, TRUE, &foundsol) );
    5136 }
    5137 else
    5138 {
    5139 SCIP_CALL( SCIPprimalAddSolFree(primal, blkmem, set, messagehdlr, stat, origprob, transprob, tree, reopt, lp,
    5140 eventqueue, eventfilter, &sol, &foundsol) );
    5141 }
    5142
    5143 /* stop clock for pseudo solutions */
    5145
    5146 if( foundsol )
    5147 {
    5148 stat->npssolsfound++;
    5149
    5150 if( primal->nbestsolsfound != oldnbestsolsfound )
    5151 {
    5152 stat->npsbestsolsfound++;
    5154 }
    5155 }
    5156 }
    5157
    5158 return SCIP_OKAY;
    5159}
    5160
    5161/** main solving loop */
    5163 BMS_BLKMEM* blkmem, /**< block memory buffers */
    5164 SCIP_SET* set, /**< global SCIP settings */
    5165 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
    5166 SCIP_STAT* stat, /**< dynamic problem statistics */
    5167 SCIP_MEM* mem, /**< block memory pools */
    5168 SCIP_PROB* origprob, /**< original problem */
    5169 SCIP_PROB* transprob, /**< transformed problem after presolve */
    5170 SCIP_PRIMAL* primal, /**< primal data */
    5171 SCIP_TREE* tree, /**< branch and bound tree */
    5172 SCIP_REOPT* reopt, /**< reoptimization data structure */
    5173 SCIP_LP* lp, /**< LP data */
    5174 SCIP_RELAXATION* relaxation, /**< global relaxation data */
    5175 SCIP_PRICESTORE* pricestore, /**< pricing storage */
    5176 SCIP_SEPASTORE* sepastore, /**< separation storage */
    5177 SCIP_CUTPOOL* cutpool, /**< global cut pool */
    5178 SCIP_CUTPOOL* delayedcutpool, /**< global delayed cut pool */
    5179 SCIP_BRANCHCAND* branchcand, /**< branching candidate storage */
    5180 SCIP_CONFLICT* conflict, /**< conflict analysis data */
    5181 SCIP_CONFLICTSTORE* conflictstore, /**< conflict store */
    5182 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
    5183 SCIP_EVENTFILTER* eventfilter, /**< global event filter */
    5184 SCIP_CLIQUETABLE* cliquetable, /**< clique table data structure */
    5185 SCIP_Bool* restart /**< should solving process be started again with presolving? */
    5186 )
    5187{
    5188 SCIP_NODESEL* nodesel;
    5189 SCIP_NODE* focusnode;
    5190 SCIP_NODE* nextnode;
    5191 SCIP_EVENT event;
    5192 SCIP_Real restartfac;
    5193 SCIP_Real restartconfnum;
    5194 int nnodes;
    5195 int depth;
    5196 SCIP_Bool cutoff;
    5197 SCIP_Bool postpone;
    5198 SCIP_Bool unbounded;
    5199 SCIP_Bool infeasible;
    5200 SCIP_Bool foundsol;
    5201
    5202 assert(set != NULL);
    5203 assert(blkmem != NULL);
    5204 assert(stat != NULL);
    5205 assert(transprob != NULL);
    5206 assert(tree != NULL);
    5207 assert(lp != NULL);
    5208 assert(pricestore != NULL);
    5209 assert(sepastore != NULL);
    5210 assert(branchcand != NULL);
    5211 assert(cutpool != NULL);
    5212 assert(delayedcutpool != NULL);
    5213 assert(primal != NULL);
    5214 assert(eventfilter != NULL);
    5215 assert(eventqueue != NULL);
    5216 assert(restart != NULL);
    5217
    5218 /* check for immediate restart (if problem solving marked to be restarted was aborted) */
    5219 restartfac = set->presol_subrestartfac;
    5220 if( SCIPtreeGetCurrentDepth(tree) == 0 )
    5221 restartfac = MIN(restartfac, set->presol_restartfac);
    5222 *restart = restartAllowed(set, stat) && (stat->userrestart
    5223 || (stat->nrootintfixingsrun > restartfac * (transprob->nvars - transprob->ncontvars)
    5224 && (stat->nruns == 1 || transprob->nvars <= (1.0-set->presol_restartminred) * stat->prevrunnvars)) );
    5225
    5226 /* calculate the number of successful conflict analysis calls that should trigger a restart */
    5227 if( set->conf_restartnum > 0 )
    5228 {
    5229 int i;
    5230
    5231 restartconfnum = (SCIP_Real)set->conf_restartnum;
    5232 for( i = 0; i < stat->nconfrestarts; ++i )
    5233 restartconfnum *= set->conf_restartfac;
    5234 }
    5235 else
    5236 restartconfnum = SCIP_REAL_MAX;
    5237 assert(restartconfnum >= 0.0);
    5238
    5239 /* switch status to UNKNOWN */
    5241
    5242 focusnode = NULL;
    5243 nextnode = NULL;
    5244 unbounded = FALSE;
    5245 postpone = FALSE;
    5246
    5247 while( !SCIPsolveIsStopped(set, stat, TRUE) && !(*restart) )
    5248 {
    5249 SCIP_Longint nsuccessconflicts;
    5250 SCIP_Bool afternodeheur;
    5251 SCIP_Bool stopped;
    5252 SCIP_Bool branched;
    5253
    5254 assert(BMSgetNUsedBufferMemory(mem->buffer) == 0);
    5255
    5256 foundsol = FALSE;
    5257 infeasible = FALSE;
    5258
    5259 do
    5260 {
    5261 /* update the memory saving flag, switch algorithms respectively */
    5262 SCIPstatUpdateMemsaveMode(stat, set, messagehdlr, mem);
    5263
    5264 /* get the current node selector */
    5265 nodesel = SCIPsetGetNodesel(set, stat);
    5266
    5267 /* inform tree about the current node selector */
    5268 SCIP_CALL( SCIPtreeSetNodesel(tree, set, messagehdlr, stat, nodesel) );
    5269
    5270 /* the next node was usually already selected in the previous solving loop before the primal heuristics were
    5271 * called, because they need to know, if the next node will be a child/sibling (plunging) or not;
    5272 * if the heuristics found a new best solution that cut off some of the nodes, the node selector must be called
    5273 * again, because the selected next node may be invalid due to cut off
    5274 */
    5275 if( nextnode == NULL )
    5276 {
    5277 /* select next node to process */
    5278 SCIP_CALL( SCIPnodeselSelect(nodesel, set, &nextnode) );
    5279 }
    5280 focusnode = nextnode;
    5281 nextnode = NULL;
    5282 assert(BMSgetNUsedBufferMemory(mem->buffer) == 0);
    5283
    5284 /* start node activation timer */
    5286
    5287 /* focus selected node */
    5288 SCIP_CALL( SCIPnodeFocus(&focusnode, blkmem, set, messagehdlr, stat, transprob, origprob, primal, tree, reopt,
    5289 lp, branchcand, conflict, conflictstore, eventqueue, eventfilter, cliquetable, &cutoff, FALSE, FALSE) );
    5290
    5291 if( SCIPisExact(set->scip) && SCIPisCertified(set->scip) )
    5292 {
    5294 }
    5295
    5296 if( cutoff )
    5297 stat->ndelayedcutoffs++;
    5298
    5299 /* stop node activation timer */
    5301
    5302 assert(BMSgetNUsedBufferMemory(mem->buffer) == 0);
    5303 }
    5304 while( cutoff ); /* select new node, if the current one was located in a cut off subtree */
    5305
    5306 assert(SCIPtreeGetCurrentNode(tree) == focusnode);
    5307 assert(SCIPtreeGetFocusNode(tree) == focusnode);
    5308
    5309 /* if no more node was selected, we finished optimization */
    5310 if( focusnode == NULL )
    5311 {
    5312 assert(SCIPtreeGetNNodes(tree) == 0);
    5313 break;
    5314 }
    5315
    5316 /* update maxdepth and node count statistics */
    5317 depth = SCIPnodeGetDepth(focusnode);
    5318 stat->maxdepth = MAX(stat->maxdepth, depth);
    5319 stat->maxtotaldepth = MAX(stat->maxtotaldepth, depth);
    5320 stat->nnodes++;
    5321 stat->ntotalnodes++;
    5322
    5323 /* update reference bound statistic, if available */
    5324 if( SCIPsetIsGE(set, SCIPnodeGetLowerbound(focusnode), stat->referencebound) )
    5325 stat->nnodesaboverefbound++;
    5326
    5327 /* issue NODEFOCUSED event */
    5329 SCIP_CALL( SCIPeventChgNode(&event, focusnode) );
    5330 SCIP_CALL( SCIPeventProcess(&event, set, NULL, NULL, NULL, eventfilter) );
    5331
    5332 /* solve focus node */
    5333 SCIP_CALL( solveNode(blkmem, set, messagehdlr, stat, mem, origprob, transprob, primal, tree, reopt, lp, relaxation,
    5334 pricestore, sepastore, branchcand, cutpool, delayedcutpool, conflict, conflictstore, eventqueue, eventfilter,
    5335 cliquetable, &cutoff, &postpone, &unbounded, &infeasible, restart, &afternodeheur, &stopped) );
    5336 assert(!cutoff || infeasible);
    5337 assert(BMSgetNUsedBufferMemory(mem->buffer) == 0);
    5338 assert(SCIPtreeGetCurrentNode(tree) == focusnode);
    5339 assert(SCIPtreeGetFocusNode(tree) == focusnode);
    5340
    5341 branched = (tree->nchildren > 0);
    5342
    5343 if( stopped )
    5344 break;
    5345
    5346 /* check for restart */
    5347 if( !(*restart) && !postpone )
    5348 {
    5349 /* change color of node in visualization */
    5350 SCIPvisualSolvedNode(stat->visual, set, stat, focusnode);
    5351
    5352 /* check, if the current solution is feasible */
    5353 if( !infeasible )
    5354 {
    5355 SCIP_Bool feasible;
    5356
    5357 assert(!SCIPtreeHasFocusNodeLP(tree) || (lp->flushed && lp->solved));
    5358 assert(!cutoff);
    5359
    5360 /* in the unbounded case, we check the solution w.r.t. the original problem, because we do not want to rely
    5361 * on the LP feasibility and integrality is not checked for unbounded solutions, anyway
    5362 */
    5363 if( unbounded )
    5364 {
    5365 SCIP_SOL* sol;
    5366
    5368 || SCIPsetIsGT(set, SCIPrelaxationGetSolObj(relaxation), SCIPlpGetObjval(lp, set, transprob))) )
    5369 {
    5370 SCIP_CALL( SCIPsolCreateRelaxSol(&sol, blkmem, set, stat, primal, tree, relaxation, NULL) );
    5371 }
    5372 else if( SCIPtreeHasFocusNodeLP(tree) )
    5373 {
    5374 SCIP_CALL( SCIPsolCreateLPSol(&sol, blkmem, set, stat, transprob, primal, tree, lp, NULL) );
    5375 }
    5376 else
    5377 {
    5378 SCIP_CALL( SCIPsolCreatePseudoSol(&sol, blkmem, set, stat, transprob, primal, tree, lp, NULL) );
    5379 }
    5380 SCIP_CALL( SCIPcheckSolOrig(set->scip, sol, &feasible, FALSE, FALSE) );
    5381
    5382 SCIP_CALL( SCIPsolFree(&sol, blkmem, primal) );
    5383 }
    5384 else
    5385 feasible = TRUE;
    5386
    5387 /* node solution is feasible: add it to the solution store */
    5388 if( feasible )
    5389 {
    5390 SCIP_CALL( addCurrentSolution(blkmem, set, messagehdlr, stat, origprob, transprob, primal, relaxation, tree, reopt,
    5391 lp, eventqueue, eventfilter, FALSE) );
    5392
    5393 /* issue NODEFEASIBLE event */
    5395 SCIP_CALL( SCIPeventChgNode(&event, focusnode) );
    5396 SCIP_CALL( SCIPeventProcess(&event, set, NULL, NULL, NULL, eventfilter) );
    5397
    5398 /* update the cutoff pointer if the new solution made the cutoff bound equal to the lower bound */
    5399 SCIP_CALL( applyBounding(blkmem, set, stat, transprob, origprob, primal, tree, reopt, lp, branchcand, eventqueue,
    5400 eventfilter, conflict, cliquetable, &cutoff) );
    5401
    5402 /* increment number of feasible leaf nodes */
    5403 stat->nfeasleaves++;
    5404
    5405 if( set->reopt_enable )
    5406 {
    5407 assert(reopt != NULL);
    5408 SCIP_CALL( SCIPreoptCheckCutoff(reopt, set, blkmem, focusnode, SCIP_EVENTTYPE_NODEFEASIBLE, lp,
    5409 SCIPlpGetSolstat(lp), tree->root == focusnode, tree->focusnode == focusnode,
    5410 focusnode->lowerbound, tree->effectiverootdepth) );
    5411 }
    5412 }
    5413 }
    5414 else if( !unbounded || branched )
    5415 {
    5416 /* node solution is not feasible */
    5417 if( !branched )
    5418 {
    5419 assert(tree->nchildren == 0);
    5420
    5421 /* change color of node in visualization output */
    5422 SCIPvisualCutoffNode(stat->visual, set, stat, focusnode, TRUE);
    5423
    5424 /* issue NODEINFEASIBLE event */
    5426
    5427 /* we only increase the number of objective leaf nodes if we hit the LP objective limit; we might have also
    5428 * hit the objective limit at a node that is actually infeasible, or a dual reduction led to an infeasibility prior
    5429 * to LP solving such that the node will be marked as infeasible */
    5431 stat->nobjleaves++;
    5432 else
    5433 stat->ninfeasleaves++;
    5434
    5435 if( set->reopt_enable )
    5436 {
    5437 assert(reopt != NULL);
    5438 SCIP_CALL( SCIPreoptCheckCutoff(reopt, set, blkmem, focusnode, SCIP_EVENTTYPE_NODEINFEASIBLE, lp,
    5439 SCIPlpGetSolstat(lp), tree->root == focusnode, tree->focusnode == focusnode,
    5440 focusnode->lowerbound, tree->effectiverootdepth) );
    5441 }
    5442
    5443 /* increase the cutoff counter of the branching variable */
    5444 if( stat->lastbranchvar != NULL )
    5445 {
    5446 SCIP_CALL( SCIPvarIncCutoffSum(stat->lastbranchvar, blkmem, set, stat, stat->lastbranchdir, stat->lastbranchvalue, 1.0) );
    5447 }
    5448 /**@todo if last branching variable is unknown, retrieve it from the nodes' boundchg arrays */
    5449 }
    5450 else
    5451 {
    5452 assert(tree->nchildren > 0);
    5453
    5454 /* issue NODEBRANCHED event */
    5456
    5457 if( set->reopt_enable )
    5458 {
    5459 assert(reopt != NULL);
    5460 SCIP_CALL( SCIPreoptCheckCutoff(reopt, set, blkmem, focusnode, SCIP_EVENTTYPE_NODEBRANCHED, lp,
    5461 SCIPlpGetSolstat(lp), tree->root == focusnode, tree->focusnode == focusnode,
    5462 focusnode->lowerbound, tree->effectiverootdepth) );
    5463 }
    5464 }
    5465 SCIP_CALL( SCIPeventChgNode(&event, focusnode) );
    5466 SCIP_CALL( SCIPeventProcess(&event, set, NULL, NULL, NULL, eventfilter) );
    5467 }
    5468 assert(BMSgetNUsedBufferMemory(mem->buffer) == 0);
    5469
    5470 /* if no branching was created, the node was not cut off, but its lower bound is still smaller than
    5471 * the cutoff bound, we have to branch on a non-fixed variable;
    5472 * this can happen, if we want to solve exactly, the current solution was declared feasible by the
    5473 * constraint enforcement, but in exact solution checking it was found out to be infeasible;
    5474 * in this case, no branching would have been generated by the enforcement of constraints, but we
    5475 * have to further investigate the current sub tree;
    5476 * note that we must not check tree->nchildren > 0 here to determine whether we branched, we rather
    5477 * check it directly after solveNode() and store the result, because an event handler might impose a
    5478 * new cutoff bound (as is the case in ParaSCIP)
    5479 */
    5480 if( !cutoff && !unbounded && !branched && SCIPnodeGetLowerbound(focusnode) < primal->cutoffbound )
    5481 {
    5482 SCIP_RESULT result;
    5483
    5484 do
    5485 {
    5486 result = SCIP_DIDNOTRUN;
    5487 if( SCIPbranchcandGetNPseudoCands(branchcand) == 0 )
    5488 {
    5489 if( transprob->ncontvars > 0 )
    5490 {
    5491 SCIPerrorMessage("cannot branch on all-fixed LP\n");
    5492 }
    5493 }
    5494 else
    5495 {
    5496 SCIP_CALL( SCIPbranchExecPseudo(blkmem, set, stat, transprob, origprob, tree, reopt, lp, branchcand,
    5497 eventqueue, eventfilter, primal->cutoffbound, FALSE, &result) );
    5498 assert(result != SCIP_DIDNOTRUN && result != SCIP_DIDNOTFIND);
    5499 }
    5500 }
    5501 while( result == SCIP_REDUCEDDOM );
    5502 }
    5503 assert(BMSgetNUsedBufferMemory(mem->buffer) == 0);
    5504
    5505 /* select node to process in next solving loop; the primal heuristics need to know whether a child/sibling
    5506 * (plunging) will be selected as next node or not
    5507 */
    5508 SCIP_CALL( SCIPnodeselSelect(nodesel, set, &nextnode) );
    5509 assert(BMSgetNUsedBufferMemory(mem->buffer) == 0);
    5510
    5511 /* call primal heuristics that should be applied after the node was solved */
    5512 nnodes = SCIPtreeGetNNodes(tree);
    5513 stopped = SCIPsolveIsStopped(set, stat, FALSE);
    5514 if( !afternodeheur && (!cutoff || nnodes > 0) && !stopped )
    5515 {
    5516 SCIP_CALL( SCIPprimalHeuristics(set, stat, transprob, primal, tree, lp, nextnode, SCIP_HEURTIMING_AFTERNODE,
    5517 cutoff, &foundsol, &unbounded) );
    5518 assert(BMSgetNUsedBufferMemory(mem->buffer) == 0);
    5519
    5520 stopped = SCIPsolveIsStopped(set, stat, FALSE);
    5521 }
    5522
    5523 /* if the heuristics found a new best solution that cut off some of the nodes, the node selector must be called
    5524 * again, because the selected next node may be invalid due to cut off
    5525 */
    5526 assert(!tree->cutoffdelayed);
    5527
    5528 if( nnodes != SCIPtreeGetNNodes(tree) || stopped )
    5529 nextnode = NULL;
    5530 }
    5531 else if( !infeasible && !postpone )
    5532 {
    5533 /* The current solution was not proven to be infeasible, but due to the restart, this does not mean that it is
    5534 * feasible, we might just have skipped the check. Thus, we try to add it to the solution store, but check it
    5535 * again.
    5536 */
    5537 SCIP_CALL( addCurrentSolution(blkmem, set, messagehdlr, stat, origprob, transprob, primal, relaxation, tree, reopt, lp,
    5538 eventqueue, eventfilter, TRUE) );
    5539
    5540 if( set->reopt_enable )
    5541 {
    5542 assert(reopt != NULL);
    5543 SCIP_CALL( SCIPreoptCheckCutoff(reopt, set, blkmem, focusnode, SCIP_EVENTTYPE_NODEFEASIBLE, lp,
    5544 SCIPlpGetSolstat(lp), tree->root == focusnode, tree->focusnode == focusnode, focusnode->lowerbound,
    5545 tree->effectiverootdepth) );
    5546 }
    5547 }
    5548 /* we want to put the focusnode back into the leaf queue if it was postponed */
    5549 else if( postpone )
    5550 {
    5551 SCIP_NODE* newfocusnode = NULL;
    5552
    5553 /* @todo should we re-install the old focus node in order to somehow set the forks more clever? */
    5554 SCIP_CALL( SCIPnodeFocus(&newfocusnode, blkmem, set, messagehdlr, stat, transprob, origprob, primal, tree, reopt, lp,
    5555 branchcand, conflict, conflictstore, eventqueue, eventfilter, cliquetable, &cutoff, TRUE, FALSE) );
    5556 }
    5557 /* compute number of successfully applied conflicts */
    5558 nsuccessconflicts = SCIPconflictGetNPropSuccess(conflict) + SCIPconflictGetNInfeasibleLPSuccess(conflict)
    5561
    5562 /* trigger restart due to conflicts and the restart parameters allow another restart */
    5563 if( nsuccessconflicts >= restartconfnum && restartAllowed(set, stat) )
    5564 {
    5565 SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_HIGH,
    5566 "(run %d, node %" SCIP_LONGINT_FORMAT ") restarting after %" SCIP_LONGINT_FORMAT " successful conflict analysis calls\n",
    5567 stat->nruns, stat->nnodes, nsuccessconflicts);
    5568 *restart = TRUE;
    5569
    5570 stat->nconfrestarts++;
    5571 }
    5572
    5573 /* restart if the userrestart was set to true, we have still some nodes left and the restart parameters allow
    5574 * another restart
    5575 */
    5576 *restart = *restart || (stat->userrestart && SCIPtreeGetNNodes(tree) > 0 && restartAllowed(set, stat));
    5577 if( restartAllowed(set, stat) && set->limit_autorestartnodes == stat->nnodes && stat->ntotalnodes - stat->nruns + 1 == set->limit_autorestartnodes )
    5578 {
    5579 SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_HIGH,
    5580 "(run %d, node %" SCIP_LONGINT_FORMAT ") restarting: triggering parameter controlled restart)\n",
    5581 stat->nruns, stat->nnodes);
    5582 *restart = TRUE;
    5583 }
    5584 /* if restart limit was exceeded, change the status; if status is different from unknown, ie some other limit was
    5585 * hit, leave it unchanged
    5586 */
    5587 if( *restart && stat->status == SCIP_STATUS_UNKNOWN && set->limit_restarts >= 0 && stat->nruns > set->limit_restarts )
    5588 {
    5589 *restart = FALSE;
    5591 }
    5592
    5593 /* display node information line */
    5594 SCIP_CALL( SCIPdispPrintLine(set, messagehdlr, stat, NULL, (SCIPnodeGetDepth(focusnode) == 0) && infeasible && !foundsol, TRUE) );
    5595
    5596 SCIPsetDebugMsg(set, "Processing of node %" SCIP_LONGINT_FORMAT " in depth %d finished. %d siblings, %d children, %d leaves left\n",
    5597 stat->nnodes, SCIPnodeGetDepth(focusnode), tree->nsiblings, tree->nchildren, SCIPtreeGetNLeaves(tree));
    5598 SCIPsetDebugMsg(set, "**********************************************************************\n");
    5599 }
    5600
    5601 /* update the primal-dual integral if node or time limits were hit or an interruption signal was called */
    5602 if( SCIPsolveIsStopped(set, stat, TRUE) )
    5603 {
    5605 }
    5606
    5607 assert(BMSgetNUsedBufferMemory(mem->buffer) == 0);
    5608
    5609 SCIPsetDebugMsg(set, "Problem solving finished with status %d (restart=%u, userrestart=%u)\n", stat->status, *restart, stat->userrestart);
    5610
    5611 /* cuts off nodes with lower bound is not better than given cutoff bound, manually; this necessary to ensure that
    5612 * SCIP terminates with a proper solve stage
    5613 */
    5614 SCIP_CALL( SCIPtreeCutoff(tree, reopt, blkmem, set, stat, eventqueue, eventfilter, lp, primal->cutoffbound) );
    5615
    5616 /* if the current node is the only remaining node, and if its lower bound exceeds the upper bound, we have
    5617 * to delete it manually in order to get to the SOLVED stage instead of thinking, that only the gap limit
    5618 * was reached (this may happen, if the current node is the one defining the global lower bound and a
    5619 * feasible solution with the same value was found at this node)
    5620 */
    5621 if( tree->focusnode != NULL && SCIPtreeGetNNodes(tree) == 0
    5622 && SCIPsetIsGE(set, tree->focusnode->lowerbound, primal->cutoffbound) )
    5623 {
    5624 if( set->reopt_enable )
    5625 {
    5626 assert(reopt != NULL);
    5628 SCIPlpGetSolstat(lp), tree->root == focusnode, tree->focusnode == focusnode, tree->focusnode->lowerbound,
    5629 tree->effectiverootdepth) );
    5630 }
    5631
    5632 focusnode = NULL;
    5633 SCIP_CALL( SCIPnodeFocus(&focusnode, blkmem, set, messagehdlr, stat, transprob, origprob, primal, tree, reopt, lp,
    5634 branchcand, conflict, conflictstore, eventqueue, eventfilter, cliquetable, &cutoff, FALSE, FALSE) );
    5635 }
    5636
    5637 /* check whether we finished solving */
    5638 if( SCIPtreeGetNNodes(tree) == 0 && SCIPtreeGetCurrentNode(tree) == NULL )
    5639 {
    5640 /* no restart necessary */
    5641 *restart = FALSE;
    5642
    5643 /* set the solution status */
    5644 if( unbounded || SCIPsetIsInfinity(set, -SCIPgetUpperbound(set->scip)) )
    5645 {
    5646 if( primal->nsols > 0 )
    5647 {
    5648 /* switch status to UNBOUNDED */
    5650 }
    5651 else
    5652 {
    5653 /* switch status to INFORUNB */
    5655 }
    5656 }
    5657 else if( primal->nlimsolsfound == 0 )
    5658 {
    5659 assert(primal->nsols == 0 || SCIPsetIsGT(set, SCIPsolGetObj(primal->sols[0], set, transprob, origprob),
    5660 SCIPprobInternObjval(transprob, origprob, set, SCIPprobGetObjlim(transprob, set))));
    5661
    5662 /* switch status to INFEASIBLE */
    5664 }
    5665 else
    5666 {
    5667 /* switch status to OPTIMAL */
    5669 }
    5670 }
    5671
    5672 return SCIP_OKAY;
    5673}
    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 SCIPbranchcandGetNExternCands(SCIP_BRANCHCAND *branchcand)
    Definition: branch.c:527
    int SCIPbranchcandGetNPrioExternCands(SCIP_BRANCHCAND *branchcand)
    Definition: branch.c:537
    void SCIPbranchcandClearExternCands(SCIP_BRANCHCAND *branchcand)
    Definition: branch.c:722
    int SCIPbranchcandGetExternMaxPrio(SCIP_BRANCHCAND *branchcand)
    Definition: branch.c:517
    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 SCIPbranchcandGetNPrioLPCands(SCIP_BRANCHCAND *branchcand)
    Definition: branch.c:507
    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
    internal methods for branching rules and branching candidate storage
    SCIP_RETCODE SCIPcertificatePrintInheritedBound(SCIP_SET *set, SCIP_CERTIFICATE *certificate, SCIP_NODE *node)
    SCIP_RETCODE SCIPcertificatePrintDualboundPseudo(SCIP_CERTIFICATE *certificate, SCIP_LPEXACT *lpexact, SCIP_NODE *node, SCIP_SET *set, SCIP_PROB *prob, SCIP_Bool lowerchanged, int modifiedvarindex, SCIP_Longint boundchangeindex, SCIP_Real psval)
    SCIP_RETCODE SCIPcertificateInitTransFile(SCIP *scip)
    SCIP_RETCODE SCIPcertificatePrintDualboundExactLP(SCIP_CERTIFICATE *certificate, SCIP_LPEXACT *lpexact, SCIP_SET *set, SCIP_NODE *node, SCIP_PROB *prob, SCIP_Bool usefarkas)
    methods for certificate output
    SCIP_VAR * h
    Definition: circlepacking.c:68
    SCIP_Real * r
    Definition: circlepacking.c:59
    void SCIPclockStop(SCIP_CLOCK *clck, SCIP_SET *set)
    Definition: clock.c:360
    void SCIPclockStart(SCIP_CLOCK *clck, SCIP_SET *set)
    Definition: clock.c:290
    SCIP_Real SCIPclockGetLastTime(SCIP_CLOCK *clck)
    Definition: clock.c:529
    SCIP_Real SCIPclockGetTime(SCIP_CLOCK *clck)
    Definition: clock.c:438
    internal methods for clocks and timing issues
    SCIP_Longint SCIPgetConcurrentMemTotal(SCIP *scip)
    Definition: concurrent.c:299
    int SCIPgetNConcurrentSolvers(SCIP *scip)
    Definition: concurrent.c:126
    helper functions for concurrent scip solvers
    internal methods for conflict analysis
    int SCIPconflictGetNConflicts(SCIP_CONFLICT *conflict)
    SCIP_Longint SCIPconflictGetNInfeasibleLPSuccess(SCIP_CONFLICT *conflict)
    SCIP_RETCODE SCIPconflictAnalyzeLP(SCIP_CONFLICT *conflict, SCIP_CONFLICTSTORE *conflictstore, 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_CLIQUETABLE *cliquetable, SCIP_Bool *success)
    SCIP_Longint SCIPconflictGetNBoundexceedingLPSuccess(SCIP_CONFLICT *conflict)
    SCIP_RETCODE SCIPconflictAnalyzePseudo(SCIP_CONFLICT *conflict, 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_CLIQUETABLE *cliquetable, SCIP_Bool *success)
    SCIP_Longint SCIPconflictGetNPseudoSuccess(SCIP_CONFLICT *conflict)
    SCIP_Longint SCIPconflictGetNPropSuccess(SCIP_CONFLICT *conflict)
    SCIP_Longint SCIPconflictGetNStrongbranchSuccess(SCIP_CONFLICT *conflict)
    SCIP_RETCODE SCIPconflictFlushConss(SCIP_CONFLICT *conflict, 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_CLIQUETABLE *cliquetable)
    SCIP_RETCODE SCIPconshdlrSeparateLP(SCIP_CONSHDLR *conshdlr, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_SEPASTORE *sepastore, int depth, SCIP_Bool execdelayed, SCIP_RESULT *result)
    Definition: cons.c:2913
    SCIP_RETCODE SCIPconshdlrEnforceRelaxSol(SCIP_CONSHDLR *conshdlr, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_TREE *tree, SCIP_SEPASTORE *sepastore, SCIP_SOL *relaxsol, SCIP_Bool solinfeasible, SCIP_RESULT *result)
    Definition: cons.c:3209
    SCIP_RETCODE SCIPconshdlrSeparateSol(SCIP_CONSHDLR *conshdlr, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_SEPASTORE *sepastore, SCIP_SOL *sol, int depth, SCIP_Bool execdelayed, SCIP_RESULT *result)
    Definition: cons.c:3075
    SCIP_RETCODE SCIPconshdlrEnforceLPSol(SCIP_CONSHDLR *conshdlr, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_TREE *tree, SCIP_SEPASTORE *sepastore, SCIP_Bool solinfeasible, SCIP_RESULT *result)
    Definition: cons.c:3406
    SCIP_RETCODE SCIPconshdlrInitLP(SCIP_CONSHDLR *conshdlr, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_TREE *tree, SCIP_Bool initkeptconss, SCIP_Bool *cutoff)
    Definition: cons.c:2801
    SCIP_RETCODE SCIPconshdlrPropagate(SCIP_CONSHDLR *conshdlr, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, int depth, SCIP_Bool fullpropagation, SCIP_Bool execdelayed, SCIP_Bool instrongbranching, SCIP_PROPTIMING proptiming, SCIP_RESULT *result)
    Definition: cons.c:3905
    SCIP_RETCODE SCIPconshdlrEnforcePseudoSol(SCIP_CONSHDLR *conshdlr, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_TREE *tree, SCIP_BRANCHCAND *branchcand, SCIP_Bool solinfeasible, SCIP_Bool objinfeasible, SCIP_Bool forced, SCIP_RESULT *result)
    Definition: cons.c:3624
    internal methods for constraints and constraint handlers
    SCIP_RETCODE SCIPcutpoolSeparate(SCIP_CUTPOOL *cutpool, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_LP *lp, SCIP_SEPASTORE *sepastore, SCIP_SOL *sol, SCIP_Bool cutpoolisdelayed, SCIP_Bool root, SCIP_RESULT *result)
    Definition: cutpool.c:827
    internal methods for storing cuts in a cut pool
    #define NULL
    Definition: def.h:248
    #define SCIP_Longint
    Definition: def.h:141
    #define SCIP_REAL_MAX
    Definition: def.h:158
    #define SCIP_INVALID
    Definition: def.h:178
    #define SCIP_Bool
    Definition: def.h:91
    #define MIN(x, y)
    Definition: def.h:224
    #define SCIP_Real
    Definition: def.h:156
    #define TRUE
    Definition: def.h:93
    #define FALSE
    Definition: def.h:94
    #define MAX(x, y)
    Definition: def.h:220
    #define SCIP_LONGINT_FORMAT
    Definition: def.h:148
    #define 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
    SCIP_RETCODE SCIPdispPrintLine(SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, FILE *file, SCIP_Bool forcedisplay, SCIP_Bool endline)
    Definition: disp.c:415
    internal methods for displaying runtime statistics
    SCIP_RETCODE SCIPeventChgNode(SCIP_EVENT *event, SCIP_NODE *node)
    Definition: event.c:1547
    SCIP_RETCODE SCIPeventProcess(SCIP_EVENT *event, SCIP_SET *set, SCIP_PRIMAL *primal, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTFILTER *eventfilter)
    Definition: event.c:1804
    SCIP_RETCODE SCIPeventChgType(SCIP_EVENT *event, SCIP_EVENTTYPE eventtype)
    Definition: event.c:1204
    internal methods for managing events
    #define nnodes
    Definition: gastrans.c:74
    SCIP_Real SCIPgetOrigObjoffset(SCIP *scip)
    Definition: scip_prob.c:1529
    SCIP_OBJSENSE SCIPgetObjsense(SCIP *scip)
    Definition: scip_prob.c:1400
    SCIP_Real SCIPgetTransObjscale(SCIP *scip)
    Definition: scip_prob.c:1629
    SCIP_Real SCIPlpiInfinity(SCIP_LPI *lpi)
    Definition: lpi_clp.cpp:3947
    SCIP_Real SCIPrelDiff(SCIP_Real val1, SCIP_Real val2)
    Definition: misc.c:11162
    SCIP_Bool SCIPisCertified(SCIP *scip)
    SCIP_Bool SCIPcolIsInLP(SCIP_COL *col)
    Definition: lp.c:17509
    SCIP_PROPTIMING SCIPconshdlrGetPropTiming(SCIP_CONSHDLR *conshdlr)
    Definition: cons.c:5403
    SCIP_Bool SCIPconshdlrWasSolSeparationDelayed(SCIP_CONSHDLR *conshdlr)
    Definition: cons.c:5363
    int SCIPconshdlrGetSepaPriority(SCIP_CONSHDLR *conshdlr)
    Definition: cons.c:5242
    const char * SCIPconshdlrGetName(SCIP_CONSHDLR *conshdlr)
    Definition: cons.c:4316
    SCIP_Bool SCIPconshdlrWasLPSeparationDelayed(SCIP_CONSHDLR *conshdlr)
    Definition: cons.c:5353
    SCIP_Bool SCIPconshdlrWasPropagationDelayed(SCIP_CONSHDLR *conshdlr)
    Definition: cons.c:5373
    SCIP_Bool SCIPisExact(SCIP *scip)
    Definition: scip_exact.c:193
    int SCIPheurGetPriority(SCIP_HEUR *heur)
    Definition: heur.c:1528
    const char * SCIPheurGetName(SCIP_HEUR *heur)
    Definition: heur.c:1467
    BMS_BUFMEM * SCIPbuffer(SCIP *scip)
    Definition: scip_mem.c:72
    SCIP_NODETYPE SCIPnodeGetType(SCIP_NODE *node)
    Definition: tree.c:8473
    SCIP_Real SCIPnodeGetLowerbound(SCIP_NODE *node)
    Definition: tree.c:8503
    SCIP_Bool SCIPnodeIsActive(SCIP_NODE *node)
    Definition: tree.c:9274
    SCIP_RATIONAL * SCIPnodeGetLowerboundExact(SCIP_NODE *node)
    Definition: tree.c:8513
    int SCIPnodeGetDepth(SCIP_NODE *node)
    Definition: tree.c:8493
    SCIP_Bool SCIPnodeIsPropagatedAgain(SCIP_NODE *node)
    Definition: tree.c:9284
    SCIP_SYNCSTORE * SCIPgetSyncstore(SCIP *scip)
    const char * SCIPpricerGetName(SCIP_PRICER *pricer)
    Definition: pricer.c:619
    SCIP_Bool SCIPpropWasDelayed(SCIP_PROP *prop)
    Definition: prop.c:1156
    const char * SCIPpropGetName(SCIP_PROP *prop)
    Definition: prop.c:951
    int SCIPpropGetPriority(SCIP_PROP *prop)
    Definition: prop.c:971
    SCIP_PROPTIMING SCIPpropGetTimingmask(SCIP_PROP *prop)
    Definition: prop.c:1286
    #define SCIPrationalDebugMessage
    Definition: rational.h:641
    SCIP_Bool SCIPrationalIsGE(SCIP_RATIONAL *rat1, SCIP_RATIONAL *rat2)
    Definition: rational.cpp:1512
    void SCIPrelaxMarkUnsolved(SCIP_RELAX *relax)
    Definition: relax.c:735
    const char * SCIPrelaxGetName(SCIP_RELAX *relax)
    Definition: relax.c:557
    int SCIPrelaxGetPriority(SCIP_RELAX *relax)
    Definition: relax.c:577
    SCIP_Bool SCIPsepaWasSolDelayed(SCIP_SEPA *sepa)
    Definition: sepa.c:1122
    int SCIPsepaGetPriority(SCIP_SEPA *sepa)
    Definition: sepa.c:766
    const char * SCIPsepaGetName(SCIP_SEPA *sepa)
    Definition: sepa.c:746
    SCIP_Bool SCIPsepaWasLPDelayed(SCIP_SEPA *sepa)
    Definition: sepa.c:1112
    SCIP_RETCODE SCIPcheckSolOrig(SCIP *scip, SCIP_SOL *sol, SCIP_Bool *feasible, SCIP_Bool printreason, SCIP_Bool completely)
    Definition: scip_sol.c:4380
    SCIP_RETCODE SCIPprintRay(SCIP *scip, SCIP_SOL *sol, FILE *file, SCIP_Bool printzeros)
    Definition: scip_sol.c:2845
    SCIP_Real SCIPgetPrimalbound(SCIP *scip)
    SCIP_Real SCIPgetUpperbound(SCIP *scip)
    SCIP_Real SCIPgetGap(SCIP *scip)
    SCIP_Real SCIPgetDualbound(SCIP *scip)
    SCIP_Real SCIPgetLowerbound(SCIP *scip)
    SCIP_Longint SCIPgetNLimSolsFound(SCIP *scip)
    void SCIPstoreSolutionGap(SCIP *scip)
    SCIP_Longint SCIPgetNBestSolsFound(SCIP *scip)
    SCIP_Bool SCIPvarIsInitial(SCIP_VAR *var)
    Definition: var.c:23514
    SCIP_COL * SCIPvarGetCol(SCIP_VAR *var)
    Definition: var.c:23683
    SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
    Definition: var.c:23386
    SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
    Definition: var.c:24268
    int SCIPvarGetProbindex(SCIP_VAR *var)
    Definition: var.c:23662
    const char * SCIPvarGetName(SCIP_VAR *var)
    Definition: var.c:23267
    SCIP_Bool SCIPvarIsIntegral(SCIP_VAR *var)
    Definition: var.c:23490
    SCIP_Real SCIPvarGetLPSol(SCIP_VAR *var)
    Definition: var.c:24664
    SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
    Definition: var.c:24234
    SCIP_BDCHGINFO * SCIPvarGetBdchgInfoLb(SCIP_VAR *var, int pos)
    Definition: var.c:24704
    int SCIPvarGetNBdchgInfosUb(SCIP_VAR *var)
    Definition: var.c:24736
    SCIP_BDCHGINFO * SCIPvarGetBdchgInfoUb(SCIP_VAR *var, int pos)
    Definition: var.c:24724
    int SCIPvarGetNBdchgInfosLb(SCIP_VAR *var)
    Definition: var.c:24716
    void SCIPregressionAddObservation(SCIP_REGRESSION *regression, SCIP_Real x, SCIP_Real y)
    Definition: misc.c:385
    SCIP_RETCODE SCIPheurExec(SCIP_HEUR *heur, SCIP_SET *set, SCIP_PRIMAL *primal, int depth, int lpstateforkdepth, SCIP_HEURTIMING heurtiming, SCIP_Bool nodeinfeasible, int *ndelayedheurs, SCIP_RESULT *result)
    Definition: heur.c:1264
    SCIP_Bool SCIPheurShouldBeExecuted(SCIP_HEUR *heur, int depth, int lpstateforkdepth, SCIP_HEURTIMING heurtiming, SCIP_Bool *delayed)
    Definition: heur.c:1202
    internal methods for primal heuristics
    void SCIPresetInterrupted(void)
    Definition: interrupt.c:190
    SCIP_Bool SCIPterminated(void)
    Definition: interrupt.c:171
    SCIP_Bool SCIPinterrupted(void)
    Definition: interrupt.c:163
    methods for catching the user CTRL-C interrupt
    SCIP_RETCODE SCIPlpFlush(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_PROB *prob, SCIP_EVENTQUEUE *eventqueue)
    Definition: lp.c:8917
    SCIP_LPSOLSTAT SCIPlpGetSolstat(SCIP_LP *lp)
    Definition: lp.c:13420
    void SCIPlpSetIsRelax(SCIP_LP *lp, SCIP_Bool relax)
    Definition: lp.c:18188
    SCIP_Bool SCIPlpIsRelax(SCIP_LP *lp)
    Definition: lp.c:18201
    SCIP_RETCODE SCIPlpSolveAndEval(SCIP_LP *lp, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, BMS_BLKMEM *blkmem, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_PROB *prob, SCIP_Longint itlim, SCIP_Bool limitresolveiters, SCIP_Bool aging, SCIP_Bool keepsol, SCIP_Bool forcedlpsolve, SCIP_Bool *lperror)
    Definition: lp.c:12680
    SCIP_Real SCIPlpGetObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
    Definition: lp.c:13436
    SCIP_LPI * SCIPlpGetLPI(SCIP_LP *lp)
    Definition: lp.c:18178
    SCIP_RETCODE SCIPlpRemoveRedundantRows(SCIP_LP *lp, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter)
    Definition: lp.c:16309
    SCIP_Bool SCIPlpDiving(SCIP_LP *lp)
    Definition: lp.c:18251
    SCIP_Bool SCIPlpIsSolved(SCIP_LP *lp)
    Definition: lp.c:18211
    SCIP_Real SCIPlpGetGlobalPseudoObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
    Definition: lp.c:13587
    int SCIPlpGetNCols(SCIP_LP *lp)
    Definition: lp.c:17979
    void SCIPlpResetFeastol(SCIP_LP *lp, SCIP_SET *set)
    Definition: lp.c:10534
    SCIP_RETCODE SCIPlpGetPrimalRay(SCIP_LP *lp, SCIP_SET *set, SCIP_Real *ray)
    Definition: lp.c:15345
    int SCIPlpGetNRows(SCIP_LP *lp)
    Definition: lp.c:18026
    SCIP_Real SCIPlpGetPseudoObjval(SCIP_LP *lp, SCIP_SET *set, SCIP_PROB *prob)
    Definition: lp.c:13619
    internal methods for LP management
    void SCIPlpExactForceExactSolve(SCIP_LPEXACT *lpexact, SCIP_SET *set)
    Definition: lpexact.c:7598
    void SCIPlpExactAllowExactSolve(SCIP_LPEXACT *lpexact, SCIP_SET *set, SCIP_Bool allowexact)
    Definition: lpexact.c:7630
    internal methods for exact LP management
    safe exact rational bounding methods
    interface methods for specific LP solvers
    size_t BMSgetNUsedBufferMemory(BMS_BUFMEM *buffer)
    Definition: memory.c:3156
    #define BMSclearMemoryArray(ptr, num)
    Definition: memory.h:130
    struct BMS_BlkMem BMS_BLKMEM
    Definition: memory.h:437
    void SCIPmessagePrintWarning(SCIP_MESSAGEHDLR *messagehdlr, const char *formatstr,...)
    Definition: message.c:427
    void SCIPmessagePrintVerbInfo(SCIP_MESSAGEHDLR *messagehdlr, SCIP_VERBLEVEL verblevel, SCIP_VERBLEVEL msgverblevel, const char *formatstr,...)
    Definition: message.c:678
    SCIP_RETCODE SCIPnodeselSelect(SCIP_NODESEL *nodesel, SCIP_SET *set, SCIP_NODE **selnode)
    Definition: nodesel.c:1155
    internal methods for node selectors and node priority queues
    SCIP_RETCODE SCIPpricerExec(SCIP_PRICER *pricer, SCIP_SET *set, SCIP_PROB *prob, SCIP_LP *lp, SCIP_PRICESTORE *pricestore, SCIP_Real *lowerbound, SCIP_Bool *stopearly, SCIP_RESULT *result)
    Definition: pricer.c:483
    internal methods for variable pricers
    void SCIPpricestoreStartInitialLP(SCIP_PRICESTORE *pricestore)
    Definition: pricestore.c:157
    SCIP_RETCODE SCIPpricestoreApplyVars(SCIP_PRICESTORE *pricestore, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_PROB *prob, SCIP_TREE *tree, SCIP_LP *lp)
    Definition: pricestore.c:480
    int SCIPpricestoreGetNVars(SCIP_PRICESTORE *pricestore)
    Definition: pricestore.c:617
    SCIP_RETCODE SCIPpricestoreAddProbVars(SCIP_PRICESTORE *pricestore, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_TREE *tree, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue)
    Definition: pricestore.c:354
    SCIP_RETCODE SCIPpricestoreAddVar(SCIP_PRICESTORE *pricestore, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp, SCIP_VAR *var, SCIP_Real score, SCIP_Bool root)
    Definition: pricestore.c:181
    int SCIPpricestoreGetNBoundResets(SCIP_PRICESTORE *pricestore)
    Definition: pricestore.c:628
    void SCIPpricestoreEndInitialLP(SCIP_PRICESTORE *pricestore)
    Definition: pricestore.c:169
    SCIP_RETCODE SCIPpricestoreResetBounds(SCIP_PRICESTORE *pricestore, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue)
    Definition: pricestore.c:577
    internal methods for storing priced variables
    SCIP_RETCODE SCIPprimalTrySolFreeExact(SCIP_PRIMAL *primal, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, SCIP_PROB *origprob, SCIP_PROB *transprob, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LPEXACT *lpexact, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_SOL **sol, SCIP_Bool printreason, SCIP_Bool completely, SCIP_Bool checkbounds, SCIP_Bool checkintegrality, SCIP_Bool checklprows, SCIP_Bool *stored)
    Definition: primal.c:2382
    SCIP_RETCODE SCIPprimalTrySolFree(SCIP_PRIMAL *primal, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, SCIP_PROB *origprob, SCIP_PROB *transprob, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_SOL **sol, SCIP_Bool printreason, SCIP_Bool completely, SCIP_Bool checkbounds, SCIP_Bool checkintegrality, SCIP_Bool checklprows, SCIP_Bool *stored)
    Definition: primal.c:1893
    SCIP_RETCODE SCIPprimalTrySol(SCIP_PRIMAL *primal, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, SCIP_PROB *origprob, SCIP_PROB *transprob, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_SOL *sol, SCIP_Bool printreason, SCIP_Bool completely, SCIP_Bool checkbounds, SCIP_Bool checkintegrality, SCIP_Bool checklprows, SCIP_Bool *stored)
    Definition: primal.c:1823
    SCIP_RETCODE SCIPprimalAddSolFree(SCIP_PRIMAL *primal, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, SCIP_PROB *origprob, SCIP_PROB *transprob, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_SOL **sol, SCIP_Bool *stored)
    Definition: primal.c:1599
    internal methods for collecting primal CIP solutions and primal informations
    SCIP_Real SCIPprobGetObjlim(SCIP_PROB *prob, SCIP_SET *set)
    Definition: prob.c:2837
    SCIP_Real SCIPprobExternObjval(SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_SET *set, SCIP_Real objval)
    Definition: prob.c:2520
    void SCIPprobStoreRootSol(SCIP_PROB *prob, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp, SCIP_Bool roothaslp)
    Definition: prob.c:2165
    SCIP_Bool SCIPprobAllColsInLP(SCIP_PROB *prob, SCIP_SET *set, SCIP_LP *lp)
    Definition: prob.c:2825
    void SCIPprobUpdateBestRootSol(SCIP_PROB *prob, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp)
    Definition: prob.c:2192
    SCIP_Real SCIPprobInternObjval(SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_SET *set, SCIP_Real objval)
    Definition: prob.c:2573
    internal methods for storing and manipulating the main problem
    SCIP_RETCODE SCIPpropExec(SCIP_PROP *prop, SCIP_SET *set, SCIP_STAT *stat, int depth, SCIP_Bool execdelayed, SCIP_Bool instrongbranching, SCIP_PROPTIMING proptiming, SCIP_RESULT *result)
    Definition: prop.c:646
    internal methods for propagators
    public methods for managing constraints
    public methods for primal heuristics
    public methods for message output
    #define SCIPerrorMessage
    Definition: pub_message.h:64
    #define SCIPdebug(x)
    Definition: pub_message.h:93
    public data structures and miscellaneous methods
    public methods for variable pricers
    public methods for propagators
    public methods for relaxation handlers
    public methods for separators
    public methods for branch and bound tree
    public methods for problem variables
    void SCIPrelaxationSetSolValid(SCIP_RELAXATION *relaxation, SCIP_Bool isvalid, SCIP_Bool includeslp)
    Definition: relax.c:810
    SCIP_Real SCIPrelaxationGetSolObj(SCIP_RELAXATION *relaxation)
    Definition: relax.c:854
    SCIP_Bool SCIPrelaxIsSolved(SCIP_RELAX *relax, SCIP_STAT *stat)
    Definition: relax.c:723
    SCIP_RETCODE SCIPrelaxExec(SCIP_RELAX *relax, SCIP_SET *set, SCIP_TREE *tree, SCIP_STAT *stat, int depth, SCIP_Real *lowerbound, SCIP_RESULT *result)
    Definition: relax.c:354
    SCIP_Bool SCIPrelaxationIsLpIncludedForSol(SCIP_RELAXATION *relaxation)
    Definition: relax.c:833
    SCIP_Bool SCIPrelaxationIsSolValid(SCIP_RELAXATION *relaxation)
    Definition: relax.c:823
    internal methods for relaxators
    SCIP_RETCODE SCIPreoptCheckCutoff(SCIP_REOPT *reopt, SCIP_SET *set, BMS_BLKMEM *blkmem, SCIP_NODE *node, SCIP_EVENTTYPE eventtype, SCIP_LP *lp, SCIP_LPSOLSTAT lpsolstat, SCIP_Bool isrootnode, SCIP_Bool isfocusnode, SCIP_Real lowerbound, int effectiverootdepth)
    Definition: reopt.c:5962
    SCIP_RETCODE SCIPreoptApplyCuts(SCIP_REOPT *reopt, SCIP_NODE *node, SCIP_SEPASTORE *sepastore, SCIP_CUTPOOL *cutpool, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_LP *lp, SCIP_Bool root)
    Definition: reopt.c:7697
    SCIP_Bool SCIPreoptGetSolveLP(SCIP_REOPT *reopt, SCIP_SET *set, SCIP_NODE *node)
    Definition: reopt.c:7827
    data structures and methods for collecting reoptimization information
    public methods for certified solving
    public methods for concurrent solving mode
    public methods for exact solving
    public methods for the LP relaxation, rows and columns
    public methods for memory management
    public methods for global and local (sub)problems
    public methods for solutions
    public methods for querying solving statistics
    SCIP_RETCODE SCIPsepaExecLP(SCIP_SEPA *sepa, SCIP_SET *set, SCIP_STAT *stat, SCIP_SEPASTORE *sepastore, int depth, SCIP_Real bounddist, SCIP_Bool allowlocal, SCIP_Bool execdelayed, SCIP_RESULT *result)
    Definition: sepa.c:404
    SCIP_RETCODE SCIPsepaExecSol(SCIP_SEPA *sepa, SCIP_SET *set, SCIP_STAT *stat, SCIP_SEPASTORE *sepastore, SCIP_SOL *sol, int depth, SCIP_Bool allowlocal, SCIP_Bool execdelayed, SCIP_RESULT *result)
    Definition: sepa.c:523
    internal methods for separators
    static SCIP_RETCODE separate(SCIP *scip, SCIP_SEPA *sepa, SCIP_SOL *sol, SCIP_RESULT *result)
    Main separation function.
    Definition: sepa_flower.c:1221
    void SCIPsepastoreEndInitialLP(SCIP_SEPASTORE *sepastore)
    Definition: sepastore.c:147
    SCIP_RETCODE SCIPsepastoreClearCuts(SCIP_SEPASTORE *sepastore, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_LP *lp)
    Definition: sepastore.c:1061
    int SCIPsepastoreGetNCuts(SCIP_SEPASTORE *sepastore)
    Definition: sepastore.c:1183
    SCIP_RETCODE SCIPsepastoreAddCut(SCIP_SEPASTORE *sepastore, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_LP *lp, SCIP_ROW *cut, SCIP_Bool forcecut, SCIP_Bool root, SCIP_Bool *infeasible)
    Definition: sepastore.c:439
    void SCIPsepastoreStartForceCuts(SCIP_SEPASTORE *sepastore)
    Definition: sepastore.c:159
    void SCIPsepastoreEndForceCuts(SCIP_SEPASTORE *sepastore)
    Definition: sepastore.c:170
    void SCIPsepastoreStartInitialLP(SCIP_SEPASTORE *sepastore)
    Definition: sepastore.c:135
    SCIP_RETCODE SCIPsepastoreApplyCuts(SCIP_SEPASTORE *sepastore, 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_CLIQUETABLE *cliquetable, SCIP_Bool root, SCIP_EFFICIACYCHOICE efficiacychoice, SCIP_Bool *cutoff)
    Definition: sepastore.c:935
    int SCIPsepastoreGetNCutsApplied(SCIP_SEPASTORE *sepastore)
    Definition: sepastore.c:1234
    internal methods for storing separated cuts
    internal methods for storing separated exact cuts
    SCIP_Bool SCIPsetIsGE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
    Definition: set.c:6617
    SCIP_Real SCIPsetCeil(SCIP_SET *set, SCIP_Real val)
    Definition: set.c:6728
    int SCIPsetGetSepaMaxcuts(SCIP_SET *set, SCIP_Bool root)
    Definition: set.c:6233
    SCIP_Bool SCIPsetIsRelEQ(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
    Definition: set.c:7463
    SCIP_Bool SCIPsetIsDualfeasLT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
    Definition: set.c:7196
    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
    void SCIPsetSortRelaxs(SCIP_SET *set)
    Definition: set.c:4455
    SCIP_Bool SCIPsetIsEQ(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
    Definition: set.c:6537
    void SCIPsetSortPricers(SCIP_SET *set)
    Definition: set.c:4002
    void SCIPsetSortSepas(SCIP_SET *set)
    Definition: set.c:4529
    SCIP_Real SCIPsetInfinity(SCIP_SET *set)
    Definition: set.c:6380
    void SCIPsetSortProps(SCIP_SET *set)
    Definition: set.c:4664
    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
    void SCIPsetSortHeurs(SCIP_SET *set)
    Definition: set.c:4884
    SCIP_Real SCIPsetGetSepaMaxcutsGenFactor(SCIP_SET *set, SCIP_Bool root)
    Definition: set.c:6219
    SCIP_Bool SCIPsetIsGT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
    Definition: set.c:6597
    SCIP_Bool SCIPsetIsZero(SCIP_SET *set, SCIP_Real val)
    Definition: set.c:6637
    int SCIPsetGetPriceMaxvars(SCIP_SET *set, SCIP_Bool root)
    Definition: set.c:6205
    SCIP_NODESEL * SCIPsetGetNodesel(SCIP_SET *set, SCIP_STAT *stat)
    Definition: set.c:5082
    SCIP_Bool SCIPsetIsNegative(SCIP_SET *set, SCIP_Real val)
    Definition: set.c:6659
    internal methods for global SCIP settings
    #define SCIPsetFreeBufferArray(set, ptr)
    Definition: set.h:1782
    #define SCIPsetAllocBufferArray(set, ptr, num)
    Definition: set.h:1775
    #define SCIPsetDebugMsg
    Definition: set.h:1811
    #define SCIPsetReallocBufferArray(set, ptr, num)
    Definition: set.h:1779
    SCIP_RETCODE SCIPsolCreateRelaxSol(SCIP_SOL **sol, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PRIMAL *primal, SCIP_TREE *tree, SCIP_RELAXATION *relaxation, SCIP_HEUR *heur)
    Definition: sol.c:914
    SCIP_RETCODE SCIPsolCheck(SCIP_SOL *sol, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, BMS_BLKMEM *blkmem, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_Bool printreason, SCIP_Bool completely, SCIP_Bool checkbounds, SCIP_Bool checkintegrality, SCIP_Bool checklprows, SCIP_Bool *feasible)
    Definition: sol.c:2669
    SCIP_RETCODE SCIPsolFree(SCIP_SOL **sol, BMS_BLKMEM *blkmem, SCIP_PRIMAL *primal)
    Definition: sol.c:1133
    SCIP_RETCODE SCIPsolCreateCurrentSol(SCIP_SOL **sol, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_PRIMAL *primal, SCIP_TREE *tree, SCIP_LP *lp, SCIP_HEUR *heur)
    Definition: sol.c:985
    SCIP_RETCODE SCIPsolSetVal(SCIP_SOL *sol, SCIP_SET *set, SCIP_STAT *stat, SCIP_TREE *tree, SCIP_VAR *var, SCIP_Real val)
    Definition: sol.c:1490
    SCIP_RETCODE SCIPsolCreatePseudoSol(SCIP_SOL **sol, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_PRIMAL *primal, SCIP_TREE *tree, SCIP_LP *lp, SCIP_HEUR *heur)
    Definition: sol.c:940
    SCIP_RETCODE SCIPsolCreateLPSol(SCIP_SOL **sol, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_PRIMAL *primal, SCIP_TREE *tree, SCIP_LP *lp, SCIP_HEUR *heur)
    Definition: sol.c:846
    SCIP_Real SCIPsolGetObj(SCIP_SOL *sol, SCIP_SET *set, SCIP_PROB *transprob, SCIP_PROB *origprob)
    Definition: sol.c:2257
    SCIP_RETCODE SCIPsolCreate(SCIP_SOL **sol, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PRIMAL *primal, SCIP_TREE *tree, SCIP_HEUR *heur)
    Definition: sol.c:428
    SCIP_RETCODE SCIPsolCreateLPSolExact(SCIP_SOL **sol, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PRIMAL *primal, SCIP_TREE *tree, SCIP_LPEXACT *lp, SCIP_HEUR *heur)
    Definition: sol.c:871
    internal methods for storing primal CIP solutions
    static SCIP_RETCODE cutpoolSeparate(SCIP_CUTPOOL *cutpool, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_LP *lp, SCIP_SEPASTORE *sepastore, SCIP_Bool cutpoolisdelayed, SCIP_Bool root, int actdepth, SCIP_Bool *enoughcuts, SCIP_Bool *cutoff)
    Definition: solve.c:2446
    static SCIP_RETCODE solveNodeLP(BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, SCIP_MEM *mem, SCIP_PROB *origprob, SCIP_PROB *transprob, SCIP_PRIMAL *primal, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_RELAXATION *relaxation, SCIP_PRICESTORE *pricestore, SCIP_SEPASTORE *sepastore, SCIP_CUTPOOL *cutpool, SCIP_CUTPOOL *delayedcutpool, SCIP_BRANCHCAND *branchcand, SCIP_CONFLICT *conflict, SCIP_CONFLICTSTORE *conflictstore, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_CLIQUETABLE *cliquetable, SCIP_Bool initiallpsolved, SCIP_Bool fullseparation, SCIP_Bool newinitconss, SCIP_Bool forcedlpsolve, SCIP_Bool *propagateagain, SCIP_Bool *solverelaxagain, SCIP_Bool *cutoff, SCIP_Bool *unbounded, SCIP_Bool *lperror, SCIP_Bool *pricingaborted)
    Definition: solve.c:3200
    static SCIP_RETCODE enforceConstraints(BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_PRIMAL *primal, SCIP_TREE *tree, SCIP_LP *lp, SCIP_RELAXATION *relaxation, SCIP_SEPASTORE *sepastore, SCIP_BRANCHCAND *branchcand, SCIP_Bool *branched, SCIP_Bool *cutoff, SCIP_Bool *infeasible, SCIP_Bool *propagateagain, SCIP_Bool *solvelpagain, SCIP_Bool *solverelaxagain, SCIP_Bool forced)
    Definition: solve.c:3558
    static SCIP_RETCODE applyBounding(BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_PRIMAL *primal, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_CONFLICT *conflict, SCIP_CLIQUETABLE *cliquetable, SCIP_Bool *cutoff)
    Definition: solve.c:3112
    static SCIP_RETCODE updateEstimate(SCIP_SET *set, SCIP_STAT *stat, SCIP_TREE *tree, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand)
    Definition: solve.c:1175
    enum PseudocostFlag PSEUDOCOSTFLAG
    Definition: solve.c:754
    static SCIP_RETCODE updatePseudocost(SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_TREE *tree, SCIP_LP *lp, SCIP_Bool updateintegers, SCIP_Bool updatecontinuous)
    Definition: solve.c:758
    #define SAFETYFACTOR
    Definition: solve.c:105
    static SCIP_RETCODE separationRoundSol(BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_SEPASTORE *sepastore, SCIP_SOL *sol, int actdepth, SCIP_Bool allowlocal, SCIP_Bool onlydelayed, SCIP_Bool *delayed, SCIP_Bool *enoughcuts, SCIP_Bool *cutoff)
    Definition: solve.c:1979
    static void updateLoopStatus(SCIP_SET *set, SCIP_STAT *stat, SCIP_TREE *tree, int depth, SCIP_Bool *cutoff, SCIP_Bool *propagateagain, SCIP_Bool *solverelaxagain)
    Definition: solve.c:3907
    PseudocostFlag
    Definition: solve.c:749
    @ PSEUDOCOST_UPDATE
    Definition: solve.c:752
    @ PSEUDOCOST_IGNORE
    Definition: solve.c:751
    @ PSEUDOCOST_NONE
    Definition: solve.c:750
    static SCIP_RETCODE priceAndCutLoop(BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, SCIP_MEM *mem, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_PRIMAL *primal, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_PRICESTORE *pricestore, SCIP_SEPASTORE *sepastore, SCIP_CUTPOOL *cutpool, SCIP_CUTPOOL *delayedcutpool, SCIP_BRANCHCAND *branchcand, SCIP_CONFLICT *conflict, SCIP_CONFLICTSTORE *conflictstore, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_CLIQUETABLE *cliquetable, SCIP_Bool fullseparation, SCIP_Bool forcedlpsolve, SCIP_Bool *propagateagain, SCIP_Bool *cutoff, SCIP_Bool *unbounded, SCIP_Bool *lperror, SCIP_Bool *pricingaborted)
    Definition: solve.c:2486
    static SCIP_RETCODE separationRoundLP(BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_PROB *prob, SCIP_PRIMAL *primal, SCIP_TREE *tree, SCIP_LP *lp, SCIP_SEPASTORE *sepastore, int actdepth, SCIP_Real bounddist, SCIP_Bool allowlocal, SCIP_Bool onlydelayed, SCIP_Bool *delayed, SCIP_Bool *enoughcuts, SCIP_Bool *cutoff, SCIP_Bool *lperror, SCIP_Bool *mustsepa, SCIP_Bool *mustprice)
    Definition: solve.c:1723
    static SCIP_RETCODE solveNodeInitialLP(BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_PRIMAL *primal, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_PRICESTORE *pricestore, SCIP_SEPASTORE *sepastore, SCIP_CUTPOOL *cutpool, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_CLIQUETABLE *cliquetable, SCIP_Bool newinitconss, SCIP_Bool forcedlpsolve, SCIP_Bool *cutoff, SCIP_Bool *lperror)
    Definition: solve.c:1565
    SCIP_RETCODE SCIPinitConssLP(BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_SEPASTORE *sepastore, SCIP_CUTPOOL *cutpool, 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_CLIQUETABLE *cliquetable, SCIP_Bool root, SCIP_Bool firstsubtreeinit, SCIP_Bool *cutoff)
    Definition: solve.c:1225
    static SCIP_RETCODE applyCuts(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_RELAXATION *relaxation, SCIP_SEPASTORE *sepastore, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_CLIQUETABLE *cliquetable, SCIP_Bool root, SCIP_EFFICIACYCHOICE efficiacychoice, SCIP_Bool *cutoff, SCIP_Bool *propagateagain, SCIP_Bool *solvelpagain, SCIP_Bool *solverelaxagain)
    Definition: solve.c:3851
    static SCIP_RETCODE propAndSolve(BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, SCIP_MEM *mem, SCIP_PROB *origprob, SCIP_PROB *transprob, SCIP_PRIMAL *primal, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_RELAXATION *relaxation, SCIP_PRICESTORE *pricestore, SCIP_SEPASTORE *sepastore, SCIP_BRANCHCAND *branchcand, SCIP_CUTPOOL *cutpool, SCIP_CUTPOOL *delayedcutpool, SCIP_CONFLICT *conflict, SCIP_CONFLICTSTORE *conflictstore, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_CLIQUETABLE *cliquetable, SCIP_NODE *focusnode, int actdepth, SCIP_Bool propagate, SCIP_Bool solvelp, SCIP_Bool solverelax, SCIP_Bool forcedlpsolve, SCIP_Bool initiallpsolved, SCIP_Bool fullseparation, SCIP_Longint *afterlpproplps, SCIP_HEURTIMING *heurtiming, int *nlperrors, SCIP_Bool *fullpropagation, SCIP_Bool *propagateagain, SCIP_Bool *lpsolved, SCIP_Bool *relaxcalled, SCIP_Bool *solvelpagain, SCIP_Bool *solverelaxagain, SCIP_Bool *cutoff, SCIP_Bool *postpone, SCIP_Bool *unbounded, SCIP_Bool *stopped, SCIP_Bool *lperror, SCIP_Bool *pricingaborted, SCIP_Bool *forcedenforcement)
    Definition: solve.c:3950
    static SCIP_RETCODE propagationRound(BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_TREE *tree, int depth, SCIP_Bool fullpropagation, SCIP_Bool onlydelayed, SCIP_Bool *delayed, SCIP_Bool *propagain, SCIP_PROPTIMING timingmask, SCIP_Bool *cutoff, SCIP_Bool *postpone)
    Definition: solve.c:414
    static SCIP_RETCODE propagateDomains(BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_TREE *tree, int depth, int maxproprounds, SCIP_Bool fullpropagation, SCIP_PROPTIMING timingmask, SCIP_Bool *cutoff, SCIP_Bool *postpone)
    Definition: solve.c:583
    SCIP_RETCODE SCIPpriceLoop(BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_PRIMAL *primal, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_PRICESTORE *pricestore, SCIP_SEPASTORE *sepastore, SCIP_CUTPOOL *cutpool, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_CLIQUETABLE *cliquetable, SCIP_Bool pretendroot, SCIP_Bool displayinfo, int maxpricerounds, int *npricedcolvars, SCIP_Bool *mustsepa, SCIP_Bool *lperror, SCIP_Bool *aborted)
    Definition: solve.c:2211
    SCIP_RETCODE SCIPconstructCurrentLP(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_PRICESTORE *pricestore, SCIP_SEPASTORE *sepastore, SCIP_CUTPOOL *cutpool, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_CLIQUETABLE *cliquetable, SCIP_Bool newinitconss, SCIP_Bool *cutoff)
    Definition: solve.c:1407
    #define MAXNLPERRORS
    Definition: solve.c:102
    static SCIP_RETCODE addCurrentSolution(BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, SCIP_PROB *origprob, SCIP_PROB *transprob, SCIP_PRIMAL *primal, SCIP_RELAXATION *relaxation, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_Bool checksol)
    Definition: solve.c:5015
    SCIP_Bool SCIPsolveIsStopped(SCIP_SET *set, SCIP_STAT *stat, SCIP_Bool checknodelimits)
    Definition: solve.c:110
    static SCIP_RETCODE updatePrimalRay(BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_PRIMAL *primal, SCIP_TREE *tree, SCIP_LP *lp, SCIP_Bool lperror)
    Definition: solve.c:1498
    #define NINITCALLS
    Definition: solve.c:104
    static void markRelaxsUnsolved(SCIP_SET *set, SCIP_RELAXATION *relaxation)
    Definition: solve.c:3182
    SCIP_RETCODE SCIPseparationRound(BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_PROB *prob, SCIP_PRIMAL *primal, SCIP_TREE *tree, SCIP_LP *lp, SCIP_SEPASTORE *sepastore, SCIP_SOL *sol, int actdepth, SCIP_Bool allowlocal, SCIP_Bool onlydelayed, SCIP_Bool *delayed, SCIP_Bool *cutoff)
    Definition: solve.c:2158
    static SCIP_Bool restartAllowed(SCIP_SET *set, SCIP_STAT *stat)
    Definition: solve.c:4306
    static SCIP_RETCODE initLP(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_PRICESTORE *pricestore, SCIP_SEPASTORE *sepastore, SCIP_CUTPOOL *cutpool, SCIP_BRANCHCAND *branchcand, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_CLIQUETABLE *cliquetable, SCIP_Bool root, SCIP_Bool *cutoff)
    Definition: solve.c:1290
    static SCIP_RETCODE solveNodeRelax(SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTFILTER *eventfilter, SCIP_TREE *tree, SCIP_RELAXATION *relaxation, SCIP_PROB *transprob, SCIP_PROB *origprob, int depth, SCIP_Bool beforelp, SCIP_Bool *cutoff, SCIP_Bool *propagateagain, SCIP_Bool *solvelpagain, SCIP_Bool *solverelaxagain, SCIP_Bool *relaxcalled)
    Definition: solve.c:3457
    SCIP_RETCODE SCIPpropagateDomains(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_CONFLICT *conflict, SCIP_CLIQUETABLE *cliquetable, int depth, int maxrounds, SCIP_PROPTIMING timingmask, SCIP_Bool *cutoff)
    Definition: solve.c:658
    SCIP_RETCODE SCIPsolveCIP(BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, SCIP_MEM *mem, SCIP_PROB *origprob, SCIP_PROB *transprob, SCIP_PRIMAL *primal, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_RELAXATION *relaxation, SCIP_PRICESTORE *pricestore, SCIP_SEPASTORE *sepastore, SCIP_CUTPOOL *cutpool, SCIP_CUTPOOL *delayedcutpool, SCIP_BRANCHCAND *branchcand, SCIP_CONFLICT *conflict, SCIP_CONFLICTSTORE *conflictstore, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_CLIQUETABLE *cliquetable, SCIP_Bool *restart)
    Definition: solve.c:5162
    static SCIP_RETCODE separationRoundResolveLP(BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_PROB *prob, SCIP_PRIMAL *primal, SCIP_TREE *tree, SCIP_LP *lp, SCIP_Bool *lperror, SCIP_Bool *mustsepa, SCIP_Bool *mustprice)
    Definition: solve.c:1682
    static SCIP_Bool isPseudocostUpdateValid(SCIP_VAR *var, SCIP_SET *set, SCIP_Real oldlpsolval, SCIP_Bool updateintegers, SCIP_Bool updatecontinuous)
    Definition: solve.c:691
    static SCIP_RETCODE solveNode(BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, SCIP_MEM *mem, SCIP_PROB *origprob, SCIP_PROB *transprob, SCIP_PRIMAL *primal, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_RELAXATION *relaxation, SCIP_PRICESTORE *pricestore, SCIP_SEPASTORE *sepastore, SCIP_BRANCHCAND *branchcand, SCIP_CUTPOOL *cutpool, SCIP_CUTPOOL *delayedcutpool, SCIP_CONFLICT *conflict, SCIP_CONFLICTSTORE *conflictstore, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_CLIQUETABLE *cliquetable, SCIP_Bool *cutoff, SCIP_Bool *postpone, SCIP_Bool *unbounded, SCIP_Bool *infeasible, SCIP_Bool *restart, SCIP_Bool *afternodeheur, SCIP_Bool *stopped)
    Definition: solve.c:4328
    SCIP_RETCODE SCIPprimalHeuristics(SCIP_SET *set, SCIP_STAT *stat, SCIP_PROB *prob, SCIP_PRIMAL *primal, SCIP_TREE *tree, SCIP_LP *lp, SCIP_NODE *nextnode, SCIP_HEURTIMING heurtiming, SCIP_Bool nodeinfeasible, SCIP_Bool *foundsol, SCIP_Bool *unbounded)
    Definition: solve.c:228
    #define MAXNCLOCKSKIPS
    Definition: solve.c:103
    internal methods for main solving loop and node processing
    void SCIPstatUpdatePrimalDualIntegrals(SCIP_STAT *stat, SCIP_SET *set, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_Real upperbound, SCIP_Real lowerbound)
    Definition: stat.c:513
    void SCIPstatUpdateMemsaveMode(SCIP_STAT *stat, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_MEM *mem)
    Definition: stat.c:754
    internal methods for problem statistics
    #define SCIPstatIncrement(stat, set, field)
    Definition: stat.h:260
    SCIP_Real newbound
    Definition: struct_var.h:123
    unsigned int boundchgtype
    Definition: struct_var.h:129
    SCIP_Real oldbound
    Definition: struct_var.h:122
    SCIP_Real newbound
    Definition: struct_var.h:96
    unsigned int boundtype
    Definition: struct_var.h:106
    SCIP_VAR * var
    Definition: struct_var.h:104
    SCIP_BRANCHINGDATA branchingdata
    Definition: struct_var.h:100
    SCIP_BOUNDCHG * boundchgs
    Definition: struct_var.h:140
    unsigned int nboundchgs
    Definition: struct_var.h:138
    SCIP_Real lpobjval
    Definition: struct_tree.h:112
    SCIP_Bool solved
    SCIP_ROW ** rows
    Definition: struct_lp.h:308
    SCIP_Real cutoffbound
    Definition: struct_lp.h:289
    int nremovablerows
    Definition: struct_lp.h:341
    SCIP_Bool installing
    Definition: struct_lp.h:382
    SCIP_LPEXACT * lpexact
    Definition: struct_lp.h:309
    SCIP_Bool solved
    Definition: struct_lp.h:373
    SCIP_Bool resolvelperror
    Definition: struct_lp.h:389
    SCIP_Bool hasprovedbound
    Definition: struct_lp.h:409
    int nremovablecols
    Definition: struct_lp.h:337
    int looseobjvalinf
    Definition: struct_lp.h:343
    SCIP_Bool flushed
    Definition: struct_lp.h:372
    BMS_BUFMEM * buffer
    Definition: struct_mem.h:50
    union SCIP_Node::@21 data
    SCIP_DOMCHG * domchg
    Definition: struct_tree.h:160
    SCIP_Longint number
    Definition: struct_tree.h:143
    SCIP_FORK * fork
    Definition: struct_tree.h:155
    SCIP_Real lowerbound
    Definition: struct_tree.h:144
    SCIP_Real estimate
    Definition: struct_tree.h:146
    unsigned int depth
    Definition: struct_tree.h:161
    SCIP_NODE * parent
    Definition: struct_tree.h:158
    SCIP_SOL ** sols
    Definition: struct_primal.h:60
    SCIP_RATIONAL * cutoffboundexact
    Definition: struct_primal.h:59
    SCIP_Longint nbestsolsfound
    Definition: struct_primal.h:52
    SCIP_SOL * primalray
    Definition: struct_primal.h:64
    SCIP_Longint nlimsolsfound
    Definition: struct_primal.h:50
    SCIP_Real cutoffbound
    Definition: struct_primal.h:57
    int ncolvars
    Definition: struct_prob.h:81
    int ncontvars
    Definition: struct_prob.h:80
    SCIP_VAR ** vars
    Definition: struct_prob.h:67
    unsigned int local
    Definition: struct_lp.h:264
    int age
    Definition: struct_lp.h:252
    unsigned int fromcutpool
    Definition: struct_lp.h:254
    SCIP_STATUS status
    Definition: struct_stat.h:201
    SCIP_Longint nrelaxsolsfound
    Definition: struct_stat.h:104
    SCIP_Longint nprimalzeroitlps
    Definition: struct_stat.h:210
    SCIP_Longint nnodes
    Definition: struct_stat.h:84
    SCIP_REGRESSION * regressioncandsobjval
    Definition: struct_stat.h:63
    SCIP_Longint ntotalnodes
    Definition: struct_stat.h:89
    SCIP_Bool disableenforelaxmsg
    Definition: struct_stat.h:320
    SCIP_Longint ninfeasleaves
    Definition: struct_stat.h:88
    SCIP_VAR * lastbranchvar
    Definition: struct_stat.h:197
    int nclockskipsleft
    Definition: struct_stat.h:311
    SCIP_Longint ndelayedcutoffs
    Definition: struct_stat.h:99
    SCIP_CLOCK * nodeactivationtime
    Definition: struct_stat.h:190
    SCIP_Longint nlps
    Definition: struct_stat.h:207
    SCIP_Longint externmemestim
    Definition: struct_stat.h:127
    SCIP_Longint domchgcount
    Definition: struct_stat.h:116
    SCIP_Longint nnodelps
    Definition: struct_stat.h:219
    SCIP_Longint lpcount
    Definition: struct_stat.h:205
    int prevrunnvars
    Definition: struct_stat.h:262
    SCIP_Longint nrootfirstlpiterations
    Definition: struct_stat.h:66
    SCIP_Longint ninitconssadded
    Definition: struct_stat.h:125
    int nseparounds
    Definition: struct_stat.h:270
    SCIP_Longint nlpiterations
    Definition: struct_stat.h:64
    int nconfrestarts
    Definition: struct_stat.h:257
    SCIP_Longint nfeasleaves
    Definition: struct_stat.h:87
    int npricerounds
    Definition: struct_stat.h:269
    SCIP_VISUAL * visual
    Definition: struct_stat.h:198
    SCIP_Longint nnodesaboverefbound
    Definition: struct_stat.h:97
    SCIP_Real firstlpdualbound
    Definition: struct_stat.h:132
    SCIP_Longint nrootlpiterations
    Definition: struct_stat.h:65
    int nrootintfixingsrun
    Definition: struct_stat.h:261
    SCIP_Longint ninternalnodes
    Definition: struct_stat.h:85
    SCIP_CLOCK * relaxsoltime
    Definition: struct_stat.h:187
    SCIP_Longint ntotalinternalnodes
    Definition: struct_stat.h:90
    SCIP_Longint nobjleaves
    Definition: struct_stat.h:86
    SCIP_Real referencebound
    Definition: struct_stat.h:159
    SCIP_BRANCHDIR lastbranchdir
    Definition: struct_stat.h:202
    SCIP_CLOCK * pseudosoltime
    Definition: struct_stat.h:188
    SCIP_Bool userrestart
    Definition: struct_stat.h:315
    SCIP_Longint nlpbestsolsfound
    Definition: struct_stat.h:107
    SCIP_Longint nboundchgs
    Definition: struct_stat.h:117
    SCIP_Real firstlptime
    Definition: struct_stat.h:144
    SCIP_Longint nrelaxbestsolsfound
    Definition: struct_stat.h:108
    SCIP_Longint npsbestsolsfound
    Definition: struct_stat.h:109
    SCIP_Longint ninitlps
    Definition: struct_stat.h:221
    int maxdepth
    Definition: struct_stat.h:272
    SCIP_Longint nisstoppedcalls
    Definition: struct_stat.h:251
    int maxtotaldepth
    Definition: struct_stat.h:273
    SCIP_Longint ndualzeroitlps
    Definition: struct_stat.h:212
    SCIP_Longint nrootlps
    Definition: struct_stat.h:208
    SCIP_CERTIFICATE * certificate
    Definition: struct_stat.h:199
    SCIP_Longint nnodelpiterations
    Definition: struct_stat.h:74
    SCIP_Longint bestsolnode
    Definition: struct_stat.h:115
    SCIP_Longint nnodezeroitlps
    Definition: struct_stat.h:220
    SCIP_Longint npssolsfound
    Definition: struct_stat.h:105
    SCIP_Longint nbarrierzeroitlps
    Definition: struct_stat.h:215
    SCIP_CLOCK * lpsoltime
    Definition: struct_stat.h:186
    SCIP_Bool branchedunbdvar
    Definition: struct_stat.h:319
    SCIP_CLOCK * solvingtime
    Definition: struct_stat.h:168
    SCIP_Longint nlpsolsfound
    Definition: struct_stat.h:103
    SCIP_Real lastbranchvalue
    Definition: struct_stat.h:145
    SCIP_Longint ninitlpiterations
    Definition: struct_stat.h:75
    SCIP_Bool userinterrupt
    Definition: struct_stat.h:314
    int correctlpdepth
    Definition: struct_tree.h:233
    SCIP_NODE * root
    Definition: struct_tree.h:188
    SCIP_Bool cutoffdelayed
    Definition: struct_tree.h:241
    SCIP_NODE * focuslpstatefork
    Definition: struct_tree.h:198
    int cutoffdepth
    Definition: struct_tree.h:234
    int * pathnlprows
    Definition: struct_tree.h:210
    SCIP_NODE ** path
    Definition: struct_tree.h:190
    SCIP_Bool sbprobing
    Definition: struct_tree.h:249
    SCIP_NODE * focusnode
    Definition: struct_tree.h:193
    int nsiblings
    Definition: struct_tree.h:228
    SCIP_Bool focusnodehaslp
    Definition: struct_tree.h:238
    int nchildren
    Definition: struct_tree.h:226
    SCIP_Bool forcinglpmessage
    Definition: struct_tree.h:247
    int effectiverootdepth
    Definition: struct_tree.h:231
    unsigned int pseudocostflag
    Definition: struct_var.h:339
    datastructures for constraints and constraint handlers
    datastructures for managing events
    data structures for LP management
    data structures for exact LP management
    datastructures for block memory pools and memory buffers
    datastructures for collecting primal CIP solutions and primal informations
    datastructures for storing and manipulating the main problem
    SCIP main data structure.
    datastructures for global SCIP settings
    datastructures for problem statistics
    data structures for branch and bound tree
    datastructures for problem variables
    Definition: heur_padm.c:135
    SCIP_Bool SCIPsyncstoreSolveIsStopped(SCIP_SYNCSTORE *syncstore)
    Definition: syncstore.c:241
    the function declarations for the synchronization store
    SCIP_Bool SCIPtreeIsFocusNodeLPConstructed(SCIP_TREE *tree)
    Definition: tree.c:9442
    SCIP_NODE * SCIPtreeGetFocusNode(SCIP_TREE *tree)
    Definition: tree.c:9387
    SCIP_Bool SCIPtreeProbing(SCIP_TREE *tree)
    Definition: tree.c:9361
    int SCIPtreeGetFocusDepth(SCIP_TREE *tree)
    Definition: tree.c:9404
    SCIP_RETCODE SCIPtreeSetNodesel(SCIP_TREE *tree, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, SCIP_NODESEL *nodesel)
    Definition: tree.c:5830
    void SCIPnodeSetEstimate(SCIP_NODE *node, SCIP_SET *set, SCIP_Real newestimate)
    Definition: tree.c:3084
    SCIP_RETCODE SCIPnodeCutoff(SCIP_NODE *node, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTFILTER *eventfilter, SCIP_TREE *tree, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_REOPT *reopt, SCIP_LP *lp, BMS_BLKMEM *blkmem)
    Definition: tree.c:1259
    SCIP_NODE * SCIPtreeGetCurrentNode(SCIP_TREE *tree)
    Definition: tree.c:9462
    void SCIPnodeMarkPropagated(SCIP_NODE *node, SCIP_TREE *tree)
    Definition: tree.c:1394
    int SCIPtreeGetNLeaves(SCIP_TREE *tree)
    Definition: tree.c:9324
    SCIP_RETCODE SCIPnodeCreateChild(SCIP_NODE **node, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_TREE *tree, SCIP_Real nodeselprio, SCIP_Real estimate)
    Definition: tree.c:1050
    SCIP_Bool SCIPtreeHasCurrentNodeLP(SCIP_TREE *tree)
    Definition: tree.c:9496
    SCIP_Real SCIPtreeGetLowerbound(SCIP_TREE *tree, SCIP_SET *set)
    Definition: tree.c:8224
    void SCIPtreeSetFocusNodeLP(SCIP_TREE *tree, SCIP_Bool solvelp)
    Definition: tree.c:9431
    int SCIPtreeGetNNodes(SCIP_TREE *tree)
    Definition: tree.c:9334
    SCIP_RETCODE SCIPtreeCutoff(SCIP_TREE *tree, SCIP_REOPT *reopt, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_LP *lp, SCIP_Real cutoffbound)
    Definition: tree.c:5858
    SCIP_Bool SCIPtreeHasFocusNodeLP(SCIP_TREE *tree)
    Definition: tree.c:9421
    int SCIPtreeGetCurrentDepth(SCIP_TREE *tree)
    Definition: tree.c:9479
    SCIP_RETCODE SCIPnodeUpdateLowerboundLP(SCIP_NODE *node, SCIP_SET *set, SCIP_STAT *stat, SCIP_MESSAGEHDLR *messagehdlr, SCIP_EVENTFILTER *eventfilter, SCIP_TREE *tree, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_LP *lp)
    Definition: tree.c:2973
    SCIP_RETCODE SCIPtreeLoadLPState(SCIP_TREE *tree, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_PROB *prob, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_LP *lp)
    Definition: tree.c:4238
    SCIP_RETCODE SCIPnodeFocus(SCIP_NODE **node, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_PRIMAL *primal, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_CONFLICT *conflict, SCIP_CONFLICTSTORE *conflictstore, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_CLIQUETABLE *cliquetable, SCIP_Bool *cutoff, SCIP_Bool postponed, SCIP_Bool exitsolve)
    Definition: tree.c:5007
    SCIP_RETCODE SCIPnodeUpdateLowerbound(SCIP_NODE *node, SCIP_STAT *stat, SCIP_SET *set, SCIP_EVENTFILTER *eventfilter, SCIP_TREE *tree, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_Real newbound, SCIP_RATIONAL *newboundexact)
    Definition: tree.c:2851
    SCIP_RETCODE SCIPtreeLoadLP(SCIP_TREE *tree, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_LP *lp, SCIP_Bool *initroot)
    Definition: tree.c:4109
    internal methods for branch and bound tree
    #define SCIP_EVENTTYPE_FIRSTLPSOLVED
    Definition: type_event.h:101
    #define SCIP_EVENTTYPE_NODEFEASIBLE
    Definition: type_event.h:94
    #define SCIP_EVENTTYPE_NODEFOCUSED
    Definition: type_event.h:93
    #define SCIP_EVENTTYPE_NODEINFEASIBLE
    Definition: type_event.h:95
    #define SCIP_EVENTTYPE_NODEBRANCHED
    Definition: type_event.h:96
    #define SCIP_EVENTTYPE_LPSOLVED
    Definition: type_event.h:102
    enum SCIP_LPSolStat SCIP_LPSOLSTAT
    Definition: type_lp.h:52
    @ SCIP_BOUNDTYPE_UPPER
    Definition: type_lp.h:58
    @ SCIP_BOUNDTYPE_LOWER
    Definition: type_lp.h:57
    enum SCIP_BoundType SCIP_BOUNDTYPE
    Definition: type_lp.h:60
    @ SCIP_LPSOLSTAT_ERROR
    Definition: type_lp.h:50
    @ SCIP_LPSOLSTAT_NOTSOLVED
    Definition: type_lp.h:43
    @ SCIP_LPSOLSTAT_OPTIMAL
    Definition: type_lp.h:44
    @ SCIP_LPSOLSTAT_TIMELIMIT
    Definition: type_lp.h:49
    @ SCIP_LPSOLSTAT_UNBOUNDEDRAY
    Definition: type_lp.h:46
    @ SCIP_LPSOLSTAT_INFEASIBLE
    Definition: type_lp.h:45
    @ SCIP_LPSOLSTAT_OBJLIMIT
    Definition: type_lp.h:47
    @ SCIP_LPSOLSTAT_ITERLIMIT
    Definition: type_lp.h:48
    enum SCIP_VerbLevel SCIP_VERBLEVEL
    Definition: type_message.h:64
    @ SCIP_VERBLEVEL_HIGH
    Definition: type_message.h:61
    @ SCIP_VERBLEVEL_NORMAL
    Definition: type_message.h:60
    @ SCIP_VERBLEVEL_FULL
    Definition: type_message.h:62
    @ SCIP_DIDNOTRUN
    Definition: type_result.h:42
    @ SCIP_CUTOFF
    Definition: type_result.h:48
    @ SCIP_FEASIBLE
    Definition: type_result.h:45
    @ SCIP_DELAYED
    Definition: type_result.h:43
    @ SCIP_REDUCEDDOM
    Definition: type_result.h:51
    @ SCIP_DIDNOTFIND
    Definition: type_result.h:44
    @ SCIP_CONSADDED
    Definition: type_result.h:52
    @ SCIP_UNBOUNDED
    Definition: type_result.h:47
    @ SCIP_FOUNDSOL
    Definition: type_result.h:56
    @ SCIP_SUSPENDED
    Definition: type_result.h:57
    @ SCIP_BRANCHED
    Definition: type_result.h:54
    @ SCIP_SEPARATED
    Definition: type_result.h:49
    @ SCIP_SOLVELP
    Definition: type_result.h:55
    @ SCIP_NEWROUND
    Definition: type_result.h:50
    @ SCIP_SUCCESS
    Definition: type_result.h:58
    @ SCIP_DELAYNODE
    Definition: type_result.h:59
    @ SCIP_INFEASIBLE
    Definition: type_result.h:46
    enum SCIP_Result SCIP_RESULT
    Definition: type_result.h:61
    @ SCIP_LPERROR
    Definition: type_retcode.h:49
    @ SCIP_INVALIDRESULT
    Definition: type_retcode.h:53
    @ SCIP_OKAY
    Definition: type_retcode.h:42
    enum SCIP_Retcode SCIP_RETCODE
    Definition: type_retcode.h:63
    @ SCIP_EFFICIACYCHOICE_LP
    @ SCIP_EFFICIACYCHOICE_RELAX
    enum SCIP_Efficiacychoice SCIP_EFFICIACYCHOICE
    @ SCIP_STAGE_PRESOLVING
    Definition: type_set.h:49
    @ SCIP_STAGE_SOLVING
    Definition: type_set.h:53
    @ SCIP_STATUS_OPTIMAL
    Definition: type_stat.h:43
    @ SCIP_STATUS_TOTALNODELIMIT
    Definition: type_stat.h:50
    @ SCIP_STATUS_BESTSOLLIMIT
    Definition: type_stat.h:60
    @ SCIP_STATUS_SOLLIMIT
    Definition: type_stat.h:59
    @ SCIP_STATUS_UNBOUNDED
    Definition: type_stat.h:45
    @ SCIP_STATUS_UNKNOWN
    Definition: type_stat.h:42
    @ SCIP_STATUS_PRIMALLIMIT
    Definition: type_stat.h:57
    @ SCIP_STATUS_GAPLIMIT
    Definition: type_stat.h:56
    @ SCIP_STATUS_USERINTERRUPT
    Definition: type_stat.h:47
    @ SCIP_STATUS_TERMINATE
    Definition: type_stat.h:48
    @ SCIP_STATUS_INFORUNBD
    Definition: type_stat.h:46
    @ SCIP_STATUS_STALLNODELIMIT
    Definition: type_stat.h:52
    @ SCIP_STATUS_TIMELIMIT
    Definition: type_stat.h:54
    @ SCIP_STATUS_INFEASIBLE
    Definition: type_stat.h:44
    @ SCIP_STATUS_NODELIMIT
    Definition: type_stat.h:49
    @ SCIP_STATUS_DUALLIMIT
    Definition: type_stat.h:58
    @ SCIP_STATUS_MEMLIMIT
    Definition: type_stat.h:55
    @ SCIP_STATUS_RESTARTLIMIT
    Definition: type_stat.h:62
    #define SCIP_HEURTIMING_BEFOREPRESOL
    Definition: type_timing.h:92
    #define SCIP_HEURTIMING_DURINGPRICINGLOOP
    Definition: type_timing.h:91
    #define SCIP_HEURTIMING_AFTERPSEUDONODE
    Definition: type_timing.h:85
    #define SCIP_HEURTIMING_AFTERPROPLOOP
    Definition: type_timing.h:94
    unsigned int SCIP_PROPTIMING
    Definition: type_timing.h:75
    unsigned int SCIP_HEURTIMING
    Definition: type_timing.h:103
    #define SCIP_HEURTIMING_DURINGLPLOOP
    Definition: type_timing.h:81
    #define SCIP_HEURTIMING_DURINGPRESOLLOOP
    Definition: type_timing.h:93
    #define SCIP_HEURTIMING_AFTERNODE
    Definition: type_timing.h:98
    #define SCIP_PROPTIMING_AFTERLPLOOP
    Definition: type_timing.h:68
    #define SCIP_HEURTIMING_AFTERLPPLUNGE
    Definition: type_timing.h:87
    #define SCIP_HEURTIMING_AFTERPSEUDOPLUNGE
    Definition: type_timing.h:89
    #define SCIP_PROPTIMING_BEFORELP
    Definition: type_timing.h:66
    #define SCIP_HEURTIMING_AFTERLPNODE
    Definition: type_timing.h:83
    #define SCIP_HEURTIMING_AFTERLPLOOP
    Definition: type_timing.h:82
    #define SCIP_HEURTIMING_BEFORENODE
    Definition: type_timing.h:80
    #define SCIP_PROPTIMING_DURINGLPLOOP
    Definition: type_timing.h:67
    @ SCIP_NODETYPE_REFOCUSNODE
    Definition: type_tree.h:51
    @ SCIP_NODETYPE_FORK
    Definition: type_tree.h:49
    @ SCIP_NODETYPE_CHILD
    Definition: type_tree.h:44
    @ SCIP_NODETYPE_PROBINGNODE
    Definition: type_tree.h:42
    @ SCIP_NODETYPE_SIBLING
    Definition: type_tree.h:43
    @ SCIP_NODETYPE_LEAF
    Definition: type_tree.h:45
    @ SCIP_NODETYPE_FOCUSNODE
    Definition: type_tree.h:41
    enum SCIP_BoundchgType SCIP_BOUNDCHGTYPE
    Definition: type_var.h:135
    @ SCIP_BOUNDCHGTYPE_BRANCHING
    Definition: type_var.h:131
    @ SCIP_VARSTATUS_COLUMN
    Definition: type_var.h:53
    SCIP_DOMCHGBOUND domchgbound
    Definition: struct_var.h:168
    SCIP_Real SCIPvarGetPseudocost(SCIP_VAR *var, SCIP_STAT *stat, SCIP_Real solvaldelta)
    Definition: var.c:20437
    SCIP_RETCODE SCIPvarUpdatePseudocost(SCIP_VAR *var, SCIP_SET *set, SCIP_STAT *stat, SCIP_Real solvaldelta, SCIP_Real objdelta, SCIP_Real weight)
    Definition: var.c:20274
    SCIP_RETCODE SCIPvarIncCutoffSum(SCIP_VAR *var, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_BRANCHDIR dir, SCIP_Real value, SCIP_Real weight)
    Definition: var.c:21667
    SCIP_RETCODE SCIPvarUpdateAncPseudocost(SCIP_VAR *var, SCIP_SET *set, SCIP_STAT *stat, SCIP_Real solvaldelta, SCIP_Real objdelta, SCIP_Real weight)
    Definition: var.c:20374
    internal methods for problem variables
    void SCIPvisualSolvedNode(SCIP_VISUAL *visual, SCIP_SET *set, SCIP_STAT *stat, SCIP_NODE *node)
    Definition: visual.c:473
    void SCIPvisualCutoffNode(SCIP_VISUAL *visual, SCIP_SET *set, SCIP_STAT *stat, SCIP_NODE *node, SCIP_Bool infeasible)
    Definition: visual.c:533
    methods for creating output for visualization tools (VBC, BAK)