Scippy

    SCIP

    Solving Constraint Integer Programs

    scip_tree.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 scip_tree.c
    26 * @ingroup OTHER_CFILES
    27 * @brief public methods for the branch-and-bound tree
    28 * @author Tobias Achterberg
    29 * @author Timo Berthold
    30 * @author Gerald Gamrath
    31 * @author Leona Gottwald
    32 * @author Stefan Heinz
    33 * @author Gregor Hendel
    34 * @author Thorsten Koch
    35 * @author Alexander Martin
    36 * @author Marc Pfetsch
    37 * @author Michael Winkler
    38 * @author Kati Wolter
    39 *
    40 * @todo check all SCIP_STAGE_* switches, and include the new stages TRANSFORMED and INITSOLVE
    41 */
    42
    43/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
    44
    46#include "scip/debug.h"
    47#include "scip/nodesel.h"
    48#include "scip/pub_message.h"
    49#include "scip/pub_tree.h"
    50#include "scip/pub_var.h"
    51#include "scip/scip_mem.h"
    52#include "scip/scip_tree.h"
    53#include "scip/scip_numerics.h"
    54#include "scip/struct_mem.h"
    55#include "scip/struct_scip.h"
    56#include "scip/struct_stat.h"
    57#include "scip/struct_tree.h"
    58#include "scip/tree.h"
    59
    60/** gets focus node in the tree
    61 *
    62 * if we are in probing/diving mode this method returns the node in the tree where the probing/diving mode was started.
    63 *
    64 * @return the current node of the search tree
    65 *
    66 * @pre This method can be called if @p scip is in one of the following stages:
    67 * - \ref SCIP_STAGE_INITPRESOLVE
    68 * - \ref SCIP_STAGE_PRESOLVING
    69 * - \ref SCIP_STAGE_EXITPRESOLVE
    70 * - \ref SCIP_STAGE_SOLVING
    71 */
    73 SCIP* scip /**< SCIP data structure */
    74 )
    75{
    77
    78 return SCIPtreeGetFocusNode(scip->tree);
    79}
    80
    81/** gets current node in the tree
    82 *
    83 * @return the current node of the search tree
    84 *
    85 * @pre This method can be called if @p scip is in one of the following stages:
    86 * - \ref SCIP_STAGE_INITPRESOLVE
    87 * - \ref SCIP_STAGE_PRESOLVING
    88 * - \ref SCIP_STAGE_EXITPRESOLVE
    89 * - \ref SCIP_STAGE_SOLVING
    90 */
    92 SCIP* scip /**< SCIP data structure */
    93 )
    94{
    96
    97 return SCIPtreeGetCurrentNode(scip->tree);
    98}
    99
    100/** gets the root node of the tree
    101 *
    102 * @return the root node of the search tree
    103 *
    104 * @pre This method can be called if @p scip is in one of the following stages:
    105 * - \ref SCIP_STAGE_INITPRESOLVE
    106 * - \ref SCIP_STAGE_PRESOLVING
    107 * - \ref SCIP_STAGE_EXITPRESOLVE
    108 * - \ref SCIP_STAGE_SOLVING
    109 */
    111 SCIP* scip /**< SCIP data structure */
    112 )
    113{
    115
    116 return SCIPtreeGetRootNode(scip->tree);
    117}
    118
    119/** gets the effective root depth, i.e., the depth of the deepest node which is part of all paths from the root node
    120 * to the unprocessed nodes.
    121 *
    122 * @return effective root depth
    123 *
    124 * @pre This method can be called if @p scip is in one of the following stages:
    125 * - \ref SCIP_STAGE_SOLVING
    126 */
    128 SCIP* scip /**< SCIP data structure */
    129 )
    130{
    131 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetEffectiveRootDepth", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
    132
    134}
    135
    136/** returns whether the current node is already solved and only propagated again
    137 *
    138 * @return TRUE is returned if \SCIP performance repropagation, otherwise FALSE.
    139 *
    140 * @pre This method can be called if @p scip is in one of the following stages:
    141 * - \ref SCIP_STAGE_INITPRESOLVE
    142 * - \ref SCIP_STAGE_PRESOLVING
    143 * - \ref SCIP_STAGE_EXITPRESOLVE
    144 * - \ref SCIP_STAGE_SOLVING
    145 */
    147 SCIP* scip /**< SCIP data structure */
    148 )
    149{
    151
    152 return SCIPtreeInRepropagation(scip->tree);
    153}
    154
    155/** gets children of focus node along with the number of children
    156 *
    157 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
    158 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
    159 *
    160 * @pre This method can be called if @p scip is in one of the following stages:
    161 * - \ref SCIP_STAGE_SOLVING
    162 * - \ref SCIP_STAGE_SOLVED
    163 */
    165 SCIP* scip, /**< SCIP data structure */
    166 SCIP_NODE*** children, /**< pointer to store children array, or NULL if not needed */
    167 int* nchildren /**< pointer to store number of children, or NULL if not needed */
    168 )
    169{
    171
    172 if( children != NULL )
    173 *children = scip->tree->children;
    174 if( nchildren != NULL )
    175 *nchildren = scip->tree->nchildren;
    176
    177 return SCIP_OKAY;
    178}
    179
    180/** gets number of children of focus node
    181 *
    182 * @return number of children of the focus node
    183 *
    184 * @pre This method can be called if @p scip is in one of the following stages:
    185 * - \ref SCIP_STAGE_SOLVING
    186 * - \ref SCIP_STAGE_SOLVED
    187 */
    189 SCIP* scip /**< SCIP data structure */
    190 )
    191{
    193
    194 return scip->tree->nchildren;
    195}
    196
    197/** gets siblings of focus node along with the number of siblings
    198 *
    199 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
    200 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
    201 *
    202 * @pre This method can be called if @p scip is in one of the following stages:
    203 * - \ref SCIP_STAGE_SOLVING
    204 * - \ref SCIP_STAGE_SOLVED
    205 */
    207 SCIP* scip, /**< SCIP data structure */
    208 SCIP_NODE*** siblings, /**< pointer to store siblings array, or NULL if not needed */
    209 int* nsiblings /**< pointer to store number of siblings, or NULL if not needed */
    210 )
    211{
    213
    214 if( siblings != NULL )
    215 *siblings = scip->tree->siblings;
    216 if( nsiblings != NULL )
    217 *nsiblings = scip->tree->nsiblings;
    218
    219 return SCIP_OKAY;
    220}
    221
    222/** gets number of siblings of focus node
    223 *
    224 * @return the number of siblings of focus node
    225 *
    226 * @pre This method can be called if @p scip is in one of the following stages:
    227 * - \ref SCIP_STAGE_SOLVING
    228 * - \ref SCIP_STAGE_SOLVED
    229 */
    231 SCIP* scip /**< SCIP data structure */
    232 )
    233{
    235
    236 return scip->tree->nsiblings;
    237}
    238
    239/** gets leaves of the tree along with the number of leaves
    240 *
    241 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
    242 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
    243 *
    244 * @pre This method can be called if @p scip is in one of the following stages:
    245 * - \ref SCIP_STAGE_SOLVING
    246 * - \ref SCIP_STAGE_SOLVED
    247 */
    249 SCIP* scip, /**< SCIP data structure */
    250 SCIP_NODE*** leaves, /**< pointer to store leaves array, or NULL if not needed */
    251 int* nleaves /**< pointer to store number of leaves, or NULL if not needed */
    252 )
    253{
    255
    256 if( leaves != NULL )
    257 *leaves = SCIPnodepqNodes(scip->tree->leaves);
    258 if( nleaves != NULL )
    259 *nleaves = SCIPnodepqLen(scip->tree->leaves);
    260
    261 return SCIP_OKAY;
    262}
    263
    264/** gets number of leaves in the tree
    265 *
    266 * @return the number of leaves in the tree
    267 *
    268 * @pre This method can be called if @p scip is in one of the following stages:
    269 * - \ref SCIP_STAGE_SOLVING
    270 * - \ref SCIP_STAGE_SOLVED
    271 */
    273 SCIP* scip /**< SCIP data structure */
    274 )
    275{
    277
    278 return SCIPnodepqLen(scip->tree->leaves);
    279}
    280
    281/** gets the best child of the focus node w.r.t. the node selection priority assigned by the branching rule
    282 *
    283 * @return the best child of the focus node w.r.t. the node selection priority assigned by the branching rule
    284 *
    285 * @pre This method can be called if @p scip is in one of the following stages:
    286 * - \ref SCIP_STAGE_SOLVING
    287 */
    289 SCIP* scip /**< SCIP data structure */
    290 )
    291{
    293
    294 return SCIPtreeGetPrioChild(scip->tree);
    295}
    296
    297/** gets the best sibling of the focus node w.r.t. the node selection priority assigned by the branching rule
    298 *
    299 * @return the best sibling of the focus node w.r.t. the node selection priority assigned by the branching rule
    300 *
    301 * @pre This method can be called if @p scip is in one of the following stages:
    302 * - \ref SCIP_STAGE_SOLVING
    303 */
    305 SCIP* scip /**< SCIP data structure */
    306 )
    307{
    309
    310 return SCIPtreeGetPrioSibling(scip->tree);
    311}
    312
    313/** gets the best child of the focus node w.r.t. the node selection strategy
    314 *
    315 * @return the best child of the focus node w.r.t. the node selection strategy
    316 *
    317 * @pre This method can be called if @p scip is in one of the following stages:
    318 * - \ref SCIP_STAGE_SOLVING
    319 */
    321 SCIP* scip /**< SCIP data structure */
    322 )
    323{
    325
    326 return SCIPtreeGetBestChild(scip->tree, scip->set);
    327}
    328
    329/** gets the best sibling of the focus node w.r.t. the node selection strategy
    330 *
    331 * @return the best sibling of the focus node w.r.t. the node selection strategy
    332 *
    333 * @pre This method can be called if @p scip is in one of the following stages:
    334 * - \ref SCIP_STAGE_SOLVING
    335 */
    337 SCIP* scip /**< SCIP data structure */
    338 )
    339{
    341
    342 return SCIPtreeGetBestSibling(scip->tree, scip->set);
    343}
    344
    345/** gets the best leaf from the node queue w.r.t. the node selection strategy
    346 *
    347 * @return the best leaf from the node queue w.r.t. the node selection strategy
    348 *
    349 * @pre This method can be called if @p scip is in one of the following stages:
    350 * - \ref SCIP_STAGE_SOLVING
    351 */
    353 SCIP* scip /**< SCIP data structure */
    354 )
    355{
    357
    358 return SCIPtreeGetBestLeaf(scip->tree);
    359}
    360
    361/** gets the best node from the tree (child, sibling, or leaf) w.r.t. the node selection strategy
    362 *
    363 * @return the best node from the tree (child, sibling, or leaf) w.r.t. the node selection strategy
    364 *
    365 * @pre This method can be called if @p scip is in one of the following stages:
    366 * - \ref SCIP_STAGE_SOLVING
    367 */
    369 SCIP* scip /**< SCIP data structure */
    370 )
    371{
    373
    374 return SCIPtreeGetBestNode(scip->tree, scip->set);
    375}
    376
    377/** gets the node with smallest lower bound from the tree (child, sibling, or leaf)
    378 *
    379 * @return the node with smallest lower bound from the tree (child, sibling, or leaf)
    380 *
    381 * @pre This method can be called if @p scip is in one of the following stages:
    382 * - \ref SCIP_STAGE_SOLVING
    383 */
    385 SCIP* scip /**< SCIP data structure */
    386 )
    387{
    389
    390 return SCIPtreeGetLowerboundNode(scip->tree, scip->set);
    391}
    392
    393/** access to all data of open nodes (leaves, children, and siblings)
    394 *
    395 * @pre This method can be called if @p scip is in one of the following stages:
    396 * - \ref SCIP_STAGE_SOLVING
    397 */
    399 SCIP* scip, /**< SCIP data structure */
    400 SCIP_NODE*** leaves, /**< pointer to store the leaves, or NULL if not needed */
    401 SCIP_NODE*** children, /**< pointer to store the children, or NULL if not needed */
    402 SCIP_NODE*** siblings, /**< pointer to store the siblings, or NULL if not needed */
    403 int* nleaves, /**< pointer to store the number of leaves, or NULL */
    404 int* nchildren, /**< pointer to store the number of children, or NULL */
    405 int* nsiblings /**< pointer to store the number of siblings, or NULL */
    406 )
    407{
    408 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetOpenNodesData", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
    409
    410 if( leaves != NULL )
    411 *leaves = SCIPnodepqNodes(scip->tree->leaves);
    412 if( children != NULL )
    413 *children = scip->tree->children;
    414 if( siblings != NULL )
    415 *siblings = scip->tree->siblings;
    416 if( nleaves != NULL )
    417 *nleaves = SCIPnodepqLen(scip->tree->leaves);
    418 if( nchildren != NULL )
    419 *nchildren = SCIPtreeGetNChildren(scip->tree);
    420 if( nsiblings != NULL )
    421 *nsiblings = SCIPtreeGetNSiblings(scip->tree);
    422
    423 return SCIP_OKAY;
    424}
    425
    426/** cuts off node and whole sub tree from branch and bound tree
    427 *
    428 * @note must not be used on a leaf because the node priority queue remains untouched
    429 *
    430 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
    431 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
    432 *
    433 * @pre This method can be called if @p scip is in one of the following stages:
    434 * - \ref SCIP_STAGE_SOLVING
    435 */
    437 SCIP* scip, /**< SCIP data structure */
    438 SCIP_NODE* node /**< node that should be cut off */
    439 )
    440{
    442
    443 SCIP_CALL( SCIPnodeCutoff(node, scip->set, scip->stat, scip->eventfilter, scip->tree, scip->transprob, scip->origprob, scip->reopt,
    444 scip->lp, scip->mem->probmem) );
    445
    446 return SCIP_OKAY;
    447}
    448
    449/** removes all nodes from branch and bound tree that were marked to be cut off via SCIPcutoffNode()
    450 *
    451 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
    452 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
    453 *
    454 * @pre This method can be called if @p scip is in one of the following stages:
    455 * - \ref SCIP_STAGE_SOLVING
    456 *
    457 * @note In diving mode, the removal of nodes is delayed until diving ends.
    458 */
    460 SCIP* scip /**< SCIP data structure */
    461 )
    462{
    464
    465 SCIP_CALL( SCIPtreeCutoff(scip->tree, scip->reopt, scip->mem->probmem, scip->set, scip->stat, scip->eventqueue,
    466 scip->eventfilter, scip->lp, SCIPinfinity(scip)) );
    467
    468 return SCIP_OKAY;
    469}
    470
    471/** marks the given node to be propagated again the next time a node of its subtree is processed
    472 *
    473 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
    474 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
    475 *
    476 * @pre This method can be called if @p scip is in one of the following stages:
    477 * - \ref SCIP_STAGE_SOLVING
    478 */
    480 SCIP* scip, /**< SCIP data structure */
    481 SCIP_NODE* node /**< node that should be propagated again */
    482 )
    483{
    485
    486 SCIPnodePropagateAgain(node, scip->set, scip->stat, scip->tree);
    487
    488 return SCIP_OKAY;
    489}
    490
    491/** returns depth of first node in active path that is marked being cutoff
    492 *
    493 * @return depth of first node in active path that is marked being cutoff
    494 *
    495 * @pre This method can be called if @p scip is in one of the following stages:
    496 * - \ref SCIP_STAGE_SOLVING
    497 */
    499 SCIP* scip /**< SCIP data structure */
    500 )
    501{
    503
    504 return scip->tree->cutoffdepth;
    505}
    506
    507/** returns depth of first node in active path that has to be propagated again
    508 *
    509 * @return depth of first node in active path that has to be propagated again
    510 *
    511 * @pre This method can be called if @p scip is in one of the following stages:
    512 * - \ref SCIP_STAGE_SOLVING
    513 */
    515 SCIP* scip /**< SCIP data structure */
    516 )
    517{
    519
    520 return scip->tree->repropdepth;
    521}
    522
    523/** prints all branching decisions on variables from the root to the given node
    524 *
    525 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
    526 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
    527 *
    528 * @pre This method can be called if @p scip is in one of the following stages:
    529 * - \ref SCIP_STAGE_SOLVING
    530 */
    532 SCIP* scip, /**< SCIP data structure */
    533 SCIP_NODE* node, /**< node data */
    534 FILE* file /**< output file (or NULL for standard output) */
    535 )
    536{
    537 SCIP_VAR** branchvars; /* array of variables on which the branchings has been performed in all ancestors */
    538 SCIP_Real* branchbounds; /* array of bounds which the branchings in all ancestors set */
    539 SCIP_BOUNDTYPE* boundtypes; /* array of boundtypes which the branchings in all ancestors set */
    540 int* nodeswitches; /* marks, where in the arrays the branching decisions of the next node on the path start
    541 * branchings performed at the parent of node always start at position 0. For single variable branching,
    542 * nodeswitches[i] = i holds */
    543 int nbranchvars; /* number of variables on which branchings have been performed in all ancestors
    544 * if this is larger than the array size, arrays should be reallocated and method should be called again */
    545 int branchvarssize; /* available slots in arrays */
    546 int nnodes; /* number of nodes in the nodeswitch array */
    547 int nodeswitchsize; /* available slots in node switch array */
    548
    549 branchvarssize = SCIPnodeGetDepth(node);
    550 nodeswitchsize = branchvarssize;
    551
    552 /* memory allocation */
    553 SCIP_CALL( SCIPallocBufferArray(scip, &branchvars, branchvarssize) );
    554 SCIP_CALL( SCIPallocBufferArray(scip, &branchbounds, branchvarssize) );
    555 SCIP_CALL( SCIPallocBufferArray(scip, &boundtypes, branchvarssize) );
    556 SCIP_CALL( SCIPallocBufferArray(scip, &nodeswitches, nodeswitchsize) );
    557
    558 SCIPnodeGetAncestorBranchingPath(node, branchvars, branchbounds, boundtypes, &nbranchvars, branchvarssize, nodeswitches, &nnodes, nodeswitchsize );
    559
    560 /* if the arrays were too small, we have to reallocate them and recall SCIPnodeGetAncestorBranchingPath */
    561 if( nbranchvars > branchvarssize || nnodes > nodeswitchsize )
    562 {
    563 branchvarssize = nbranchvars;
    564 nodeswitchsize = nnodes;
    565
    566 /* memory reallocation */
    567 SCIP_CALL( SCIPreallocBufferArray(scip, &branchvars, branchvarssize) );
    568 SCIP_CALL( SCIPreallocBufferArray(scip, &branchbounds, branchvarssize) );
    569 SCIP_CALL( SCIPreallocBufferArray(scip, &boundtypes, branchvarssize) );
    570 SCIP_CALL( SCIPreallocBufferArray(scip, &nodeswitches, nodeswitchsize) );
    571
    572 SCIPnodeGetAncestorBranchingPath(node, branchvars, branchbounds, boundtypes, &nbranchvars, branchvarssize, nodeswitches, &nnodes, nodeswitchsize);
    573 assert(nbranchvars == branchvarssize);
    574 }
    575
    576 /* we only want to create output, if branchings were performed */
    577 if( nbranchvars >= 1 )
    578 {
    579 int i;
    580 int j;
    581
    582 /* print all nodes, starting from the root, which is last in the arrays */
    583 for( j = nnodes-1; j >= 0; --j)
    584 {
    585 int end;
    586 if(j == nnodes-1)
    587 end = nbranchvars;
    588 else
    589 end = nodeswitches[j+1];
    590
    591 for( i = nodeswitches[j]; i < end; ++i )
    592 {
    593 if( i > nodeswitches[j] )
    594 SCIPmessageFPrintInfo(scip->messagehdlr, file, " AND ");
    595 SCIPmessageFPrintInfo(scip->messagehdlr, file, "<%s> %s %.1f",SCIPvarGetName(branchvars[i]), boundtypes[i] == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=", branchbounds[i]);
    596 }
    597 SCIPmessageFPrintInfo(scip->messagehdlr, file, "\n");
    598 if( j > 0 )
    599 {
    600 if( nodeswitches[j]-nodeswitches[j-1] != 1 )
    601 SCIPmessageFPrintInfo(scip->messagehdlr, file, " |\n |\n");
    602 else if( boundtypes[i-1] == SCIP_BOUNDTYPE_LOWER )
    603 SCIPmessageFPrintInfo(scip->messagehdlr, file, "\\ \n \\\n");
    604 else
    605 SCIPmessageFPrintInfo(scip->messagehdlr, file, " /\n/ \n");
    606 }
    607 }
    608 }
    609
    610 /* free all local memory */
    611 SCIPfreeBufferArray(scip, &nodeswitches);
    612 SCIPfreeBufferArray(scip, &boundtypes);
    613 SCIPfreeBufferArray(scip, &branchbounds);
    614 SCIPfreeBufferArray(scip, &branchvars);
    615
    616 return SCIP_OKAY;
    617}
    618
    619/** sets whether the LP should be solved at the focus node
    620 *
    621 * @note In order to have an effect, this method needs to be called after a node is focused but before the LP is
    622 * solved.
    623 *
    624 * @pre This method can be called if @p scip is in one of the following stages:
    625 * - \ref SCIP_STAGE_SOLVING
    626 */
    628 SCIP* scip, /**< SCIP data structure */
    629 SCIP_Bool solvelp /**< should the LP be solved? */
    630 )
    631{
    633
    634 SCIPtreeSetFocusNodeLP(scip->tree, solvelp);
    635}
    636
    637/** gets number of nodes left in the tree (children + siblings + leaves)
    638 *
    639 * @return the number of nodes left in the tree (children + siblings + leaves)
    640 *
    641 * @pre This method can be called if SCIP is in one of the following stages:
    642 * - \ref SCIP_STAGE_PRESOLVED
    643 * - \ref SCIP_STAGE_SOLVING
    644 * - \ref SCIP_STAGE_SOLVED
    645 */
    647 SCIP* scip /**< SCIP data structure */
    648 )
    649{
    651
    652 return SCIPtreeGetNNodes(scip->tree);
    653}
    654
    655/** gets depth of current node, or -1 if no current node exists; in probing, the current node is the last probing node,
    656 * such that the depth includes the probing path
    657 *
    658 * @return the depth of current node, or -1 if no current node exists; in probing, the current node is the last probing node,
    659 * such that the depth includes the probing path
    660 *
    661 * @pre This method can be called if SCIP is in one of the following stages:
    662 * - \ref SCIP_STAGE_TRANSFORMED
    663 * - \ref SCIP_STAGE_INITPRESOLVE
    664 * - \ref SCIP_STAGE_PRESOLVING
    665 * - \ref SCIP_STAGE_EXITPRESOLVE
    666 * - \ref SCIP_STAGE_PRESOLVED
    667 * - \ref SCIP_STAGE_INITSOLVE
    668 * - \ref SCIP_STAGE_SOLVING
    669 * - \ref SCIP_STAGE_SOLVED
    670 * - \ref SCIP_STAGE_EXITSOLVE
    671 */
    673 SCIP* scip /**< SCIP data structure */
    674 )
    675{
    677
    678 return SCIPtreeGetCurrentDepth(scip->tree);
    679}
    680
    681/** gets depth of the focus node, or -1 if no focus node exists; the focus node is the currently processed node in the
    682 * branching tree, excluding the nodes of the probing path
    683 *
    684 * @return the depth of the focus node, or -1 if no focus node exists; the focus node is the currently processed node in the
    685 * branching tree, excluding the nodes of the probing path
    686 *
    687 * @pre This method can be called if SCIP is in one of the following stages:
    688 * - \ref SCIP_STAGE_TRANSFORMED
    689 * - \ref SCIP_STAGE_INITPRESOLVE
    690 * - \ref SCIP_STAGE_PRESOLVING
    691 * - \ref SCIP_STAGE_EXITPRESOLVE
    692 * - \ref SCIP_STAGE_PRESOLVED
    693 * - \ref SCIP_STAGE_INITSOLVE
    694 * - \ref SCIP_STAGE_SOLVING
    695 * - \ref SCIP_STAGE_SOLVED
    696 * - \ref SCIP_STAGE_EXITSOLVE
    697 */
    699 SCIP* scip /**< SCIP data structure */
    700 )
    701{
    703
    704 return SCIPtreeGetFocusDepth(scip->tree);
    705}
    706
    707/** gets current plunging depth (successive times, a child was selected as next node)
    708 *
    709 * @return the current plunging depth (successive times, a child was selected as next node)
    710 *
    711 * @pre This method can be called if SCIP is in one of the following stages:
    712 * - \ref SCIP_STAGE_PRESOLVED
    713 * - \ref SCIP_STAGE_SOLVING
    714 */
    716 SCIP* scip /**< SCIP data structure */
    717 )
    718{
    720
    721 return scip->stat->plungedepth;
    722}
    723
    724/** query if node was the last parent of a branching of the tree
    725 *
    726 * @return TRUE if node was the last parent of a branching of the tree
    727 *
    728 * @pre This method can be called if SCIP is in one of the following stages:
    729 * - \ref SCIP_STAGE_PRESOLVED
    730 * - \ref SCIP_STAGE_SOLVING
    731 * - \ref SCIP_STAGE_SOLVED
    732 */
    734 SCIP* scip, /**< SCIP data structure */
    735 SCIP_NODE* node /**< tree node, or NULL to check focus node */
    736 )
    737{
    738 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPwasNodeLastBranchParent", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) );
    739
    740 return SCIPtreeWasNodeLastBranchParent(scip->tree, node);
    741}
    methods for debugging
    #define SCIPcheckStage(scip, method, init, problem, transforming, transformed, initpresolve, presolving, exitpresolve, presolved, initsolve, solving, solved, exitsolve, freetrans, freescip)
    Definition: debug.h:364
    #define NULL
    Definition: def.h:248
    #define SCIP_Bool
    Definition: def.h:91
    #define SCIP_Real
    Definition: def.h:156
    #define TRUE
    Definition: def.h:93
    #define FALSE
    Definition: def.h:94
    #define SCIP_CALL_ABORT(x)
    Definition: def.h:334
    #define SCIP_CALL(x)
    Definition: def.h:355
    #define nnodes
    Definition: gastrans.c:74
    #define SCIPallocBufferArray(scip, ptr, num)
    Definition: scip_mem.h:124
    #define SCIPreallocBufferArray(scip, ptr, num)
    Definition: scip_mem.h:128
    #define SCIPfreeBufferArray(scip, ptr)
    Definition: scip_mem.h:136
    void SCIPnodeGetAncestorBranchingPath(SCIP_NODE *node, SCIP_VAR **branchvars, SCIP_Real *branchbounds, SCIP_BOUNDTYPE *boundtypes, int *nbranchvars, int branchvarssize, int *nodeswitches, int *nnodes, int nodeswitchsize)
    Definition: tree.c:9170
    int SCIPnodeGetDepth(SCIP_NODE *node)
    Definition: tree.c:8493
    SCIP_Real SCIPinfinity(SCIP *scip)
    SCIP_RETCODE SCIPpruneTree(SCIP *scip)
    Definition: scip_tree.c:459
    int SCIPgetEffectiveRootDepth(SCIP *scip)
    Definition: scip_tree.c:127
    int SCIPgetNSiblings(SCIP *scip)
    Definition: scip_tree.c:230
    SCIP_RETCODE SCIPrepropagateNode(SCIP *scip, SCIP_NODE *node)
    Definition: scip_tree.c:479
    SCIP_NODE * SCIPgetBestSibling(SCIP *scip)
    Definition: scip_tree.c:336
    int SCIPgetNChildren(SCIP *scip)
    Definition: scip_tree.c:188
    SCIP_RETCODE SCIPgetOpenNodesData(SCIP *scip, SCIP_NODE ***leaves, SCIP_NODE ***children, SCIP_NODE ***siblings, int *nleaves, int *nchildren, int *nsiblings)
    Definition: scip_tree.c:398
    SCIP_Bool SCIPinRepropagation(SCIP *scip)
    Definition: scip_tree.c:146
    void SCIPsetFocusnodeLP(SCIP *scip, SCIP_Bool solvelp)
    Definition: scip_tree.c:627
    SCIP_RETCODE SCIPgetChildren(SCIP *scip, SCIP_NODE ***children, int *nchildren)
    Definition: scip_tree.c:164
    int SCIPgetNNodesLeft(SCIP *scip)
    Definition: scip_tree.c:646
    int SCIPgetFocusDepth(SCIP *scip)
    Definition: scip_tree.c:698
    SCIP_NODE * SCIPgetFocusNode(SCIP *scip)
    Definition: scip_tree.c:72
    SCIP_RETCODE SCIPgetLeaves(SCIP *scip, SCIP_NODE ***leaves, int *nleaves)
    Definition: scip_tree.c:248
    SCIP_NODE * SCIPgetBestChild(SCIP *scip)
    Definition: scip_tree.c:320
    SCIP_NODE * SCIPgetPrioSibling(SCIP *scip)
    Definition: scip_tree.c:304
    int SCIPgetCutoffdepth(SCIP *scip)
    Definition: scip_tree.c:498
    SCIP_RETCODE SCIPprintNodeRootPath(SCIP *scip, SCIP_NODE *node, FILE *file)
    Definition: scip_tree.c:531
    int SCIPgetDepth(SCIP *scip)
    Definition: scip_tree.c:672
    int SCIPgetNLeaves(SCIP *scip)
    Definition: scip_tree.c:272
    SCIP_Bool SCIPwasNodeLastBranchParent(SCIP *scip, SCIP_NODE *node)
    Definition: scip_tree.c:733
    SCIP_NODE * SCIPgetBestNode(SCIP *scip)
    Definition: scip_tree.c:368
    SCIP_RETCODE SCIPgetSiblings(SCIP *scip, SCIP_NODE ***siblings, int *nsiblings)
    Definition: scip_tree.c:206
    int SCIPgetPlungeDepth(SCIP *scip)
    Definition: scip_tree.c:715
    SCIP_NODE * SCIPgetBestboundNode(SCIP *scip)
    Definition: scip_tree.c:384
    SCIP_NODE * SCIPgetPrioChild(SCIP *scip)
    Definition: scip_tree.c:288
    int SCIPgetRepropdepth(SCIP *scip)
    Definition: scip_tree.c:514
    SCIP_RETCODE SCIPcutoffNode(SCIP *scip, SCIP_NODE *node)
    Definition: scip_tree.c:436
    SCIP_NODE * SCIPgetBestLeaf(SCIP *scip)
    Definition: scip_tree.c:352
    SCIP_NODE * SCIPgetCurrentNode(SCIP *scip)
    Definition: scip_tree.c:91
    SCIP_NODE * SCIPgetRootNode(SCIP *scip)
    Definition: scip_tree.c:110
    const char * SCIPvarGetName(SCIP_VAR *var)
    Definition: var.c:23267
    memory allocation routines
    void SCIPmessageFPrintInfo(SCIP_MESSAGEHDLR *messagehdlr, FILE *file, const char *formatstr,...)
    Definition: message.c:618
    int SCIPnodepqLen(const SCIP_NODEPQ *nodepq)
    Definition: nodesel.c:628
    SCIP_NODE ** SCIPnodepqNodes(const SCIP_NODEPQ *nodepq)
    Definition: nodesel.c:618
    internal methods for node selectors and node priority queues
    public methods for message output
    public methods for branch and bound tree
    public methods for problem variables
    public methods for memory management
    public methods for numerical tolerances
    public methods for the branch-and-bound tree
    datastructures for block memory pools and memory buffers
    SCIP main data structure.
    datastructures for problem statistics
    data structures for branch and bound tree
    SCIP_NODE * SCIPtreeGetBestSibling(SCIP_TREE *tree, SCIP_SET *set)
    Definition: tree.c:8153
    SCIP_NODE * SCIPtreeGetFocusNode(SCIP_TREE *tree)
    Definition: tree.c:9387
    int SCIPtreeGetFocusDepth(SCIP_TREE *tree)
    Definition: tree.c:9404
    void SCIPnodePropagateAgain(SCIP_NODE *node, SCIP_SET *set, SCIP_STAT *stat, SCIP_TREE *tree)
    Definition: tree.c:1368
    int SCIPtreeGetNChildren(SCIP_TREE *tree)
    Definition: tree.c:9304
    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
    SCIP_NODE * SCIPtreeGetRootNode(SCIP_TREE *tree)
    Definition: tree.c:9529
    SCIP_NODE * SCIPtreeGetBestChild(SCIP_TREE *tree, SCIP_SET *set)
    Definition: tree.c:8126
    int SCIPtreeGetEffectiveRootDepth(SCIP_TREE *tree)
    Definition: tree.c:9518
    SCIP_NODE * SCIPtreeGetPrioSibling(SCIP_TREE *tree)
    Definition: tree.c:8100
    void SCIPtreeSetFocusNodeLP(SCIP_TREE *tree, SCIP_Bool solvelp)
    Definition: tree.c:9431
    int SCIPtreeGetNNodes(SCIP_TREE *tree)
    Definition: tree.c:9334
    int SCIPtreeGetNSiblings(SCIP_TREE *tree)
    Definition: tree.c:9314
    SCIP_NODE * SCIPtreeGetBestNode(SCIP_TREE *tree, SCIP_SET *set)
    Definition: tree.c:8190
    SCIP_NODE * SCIPtreeGetBestLeaf(SCIP_TREE *tree)
    Definition: tree.c:8180
    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
    int SCIPtreeGetCurrentDepth(SCIP_TREE *tree)
    Definition: tree.c:9479
    SCIP_NODE * SCIPtreeGetPrioChild(SCIP_TREE *tree)
    Definition: tree.c:8074
    SCIP_Bool SCIPtreeWasNodeLastBranchParent(SCIP_TREE *tree, SCIP_NODE *node)
    Definition: tree.c:1102
    SCIP_Bool SCIPtreeInRepropagation(SCIP_TREE *tree)
    Definition: tree.c:9452
    SCIP_NODE * SCIPtreeGetLowerboundNode(SCIP_TREE *tree, SCIP_SET *set)
    Definition: tree.c:8305
    internal methods for branch and bound tree
    @ SCIP_BOUNDTYPE_LOWER
    Definition: type_lp.h:57
    enum SCIP_BoundType SCIP_BOUNDTYPE
    Definition: type_lp.h:60
    @ SCIP_OKAY
    Definition: type_retcode.h:42
    enum SCIP_Retcode SCIP_RETCODE
    Definition: type_retcode.h:63