Scippy

    SCIP

    Solving Constraint Integer Programs

    nodesel.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 nodesel.c
    26 * @ingroup OTHER_CFILES
    27 * @brief methods for node selectors
    28 * @author Tobias Achterberg
    29 * @author Timo Berthold
    30 */
    31
    32/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
    33
    34#include <assert.h>
    35#include <string.h>
    36
    37#include "scip/def.h"
    38#include "scip/set.h"
    39#include "scip/clock.h"
    40#include "scip/stat.h"
    41#include "scip/visual.h"
    42#include "scip/paramset.h"
    43#include "scip/tree.h"
    44#include "scip/reopt.h"
    45#include "scip/lp.h"
    46#include "scip/primal.h"
    47#include "scip/scip.h"
    48#include "scip/nodesel.h"
    49#include "scip/pub_message.h"
    50#include "scip/pub_misc.h"
    51#include "scip/event.h"
    52
    53#include "scip/struct_scip.h"
    54#include "scip/struct_nodesel.h"
    55#include "scip/struct_event.h"
    56
    57/*
    58 * node priority queue methods
    59 */
    60
    61#define PQ_PARENT(q) (((q)+1)/2-1)
    62#define PQ_LEFTCHILD(p) (2*(p)+1)
    63#define PQ_RIGHTCHILD(p) (2*(p)+2)
    64
    65
    66/** node comparator for node numbers */
    67static
    68SCIP_DECL_SORTPTRCOMP(nodeCompNumber)
    69{ /*lint --e{715}*/
    70 assert(elem1 != NULL);
    71 assert(elem2 != NULL);
    72
    73 if( ((SCIP_NODE*)elem1)->number < ((SCIP_NODE*)elem2)->number )
    74 return -1;
    75 else if( ((SCIP_NODE*)elem1)->number > ((SCIP_NODE*)elem2)->number )
    76 return +1;
    77 else
    78 {
    79 /* no such two nodes should have the same node number */
    80 assert(elem1 == elem2);
    81 return 0;
    82 }
    83}
    84
    85
    86/** resizes node memory to hold at least the given number of nodes */
    87static
    89 SCIP_NODEPQ* nodepq, /**< node priority queue */
    90 SCIP_SET* set, /**< global SCIP settings */
    91 int minsize /**< minimal number of storable nodes */
    92 )
    93{
    94 assert(nodepq != NULL);
    95
    96 if( minsize <= nodepq->size )
    97 return SCIP_OKAY;
    98
    99 nodepq->size = SCIPsetCalcTreeGrowSize(set, minsize);
    100 SCIP_ALLOC( BMSreallocMemoryArray(&nodepq->slots, nodepq->size) );
    101 SCIP_ALLOC( BMSreallocMemoryArray(&nodepq->bfsposs, nodepq->size) );
    102 SCIP_ALLOC( BMSreallocMemoryArray(&nodepq->bfsqueue, nodepq->size) );
    103
    104 return SCIP_OKAY;
    105}
    106
    107/** creates node priority queue */
    109 SCIP_NODEPQ** nodepq, /**< pointer to a node priority queue */
    110 SCIP_SET* set, /**< global SCIP settings */
    111 SCIP_NODESEL* nodesel /**< node selector to use for sorting the nodes in the queue */
    112 )
    113{ /*lint --e{715}*/
    114 assert(nodepq != NULL);
    115 assert(set != NULL);
    116
    117 SCIP_ALLOC( BMSallocMemory(nodepq) );
    118 (*nodepq)->nodesel = nodesel;
    119 (*nodepq)->slots = NULL;
    120 (*nodepq)->bfsposs = NULL;
    121 (*nodepq)->bfsqueue = NULL;
    122 (*nodepq)->len = 0;
    123 (*nodepq)->size = 0;
    124 (*nodepq)->lowerboundsum = 0.0;
    125
    126 return SCIP_OKAY;
    127}
    128
    129/** frees node priority queue, but not the data nodes themselves */
    131 SCIP_NODEPQ** nodepq /**< pointer to a node priority queue */
    132 )
    133{
    134 assert(nodepq != NULL);
    135 assert(*nodepq != NULL);
    136
    137 BMSfreeMemoryArrayNull(&(*nodepq)->slots);
    138 BMSfreeMemoryArrayNull(&(*nodepq)->bfsposs);
    139 BMSfreeMemoryArrayNull(&(*nodepq)->bfsqueue);
    140 BMSfreeMemory(nodepq);
    141}
    142
    143/** frees node priority queue and all nodes in the queue */
    145 SCIP_NODEPQ** nodepq, /**< pointer to a node priority queue */
    146 BMS_BLKMEM* blkmem, /**< block memory buffers */
    147 SCIP_SET* set, /**< global SCIP settings */
    148 SCIP_STAT* stat, /**< problem statistics */
    149 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
    150 SCIP_EVENTFILTER* eventfilter, /**< global event filter */
    151 SCIP_TREE* tree, /**< branch and bound tree */
    152 SCIP_LP* lp /**< current LP data */
    153 )
    154{
    155 assert(nodepq != NULL);
    156 assert(*nodepq != NULL);
    157
    158 /* free the nodes of the queue */
    159 SCIP_CALL( SCIPnodepqClear(*nodepq, blkmem, set, stat, eventqueue, eventfilter, tree, lp) );
    160
    161 /* free the queue data structure */
    162 SCIPnodepqDestroy(nodepq);
    163
    164 return SCIP_OKAY;
    165}
    166
    167/** deletes all nodes in the node priority queue */
    169 SCIP_NODEPQ* nodepq, /**< node priority queue */
    170 BMS_BLKMEM* blkmem, /**< block memory buffers */
    171 SCIP_SET* set, /**< global SCIP settings */
    172 SCIP_STAT* stat, /**< problem statistics */
    173 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
    174 SCIP_EVENTFILTER* eventfilter, /**< global event filter */
    175 SCIP_TREE* tree, /**< branch and bound tree */
    176 SCIP_LP* lp /**< current LP data */
    177 )
    178{
    179 int i;
    180
    181 assert(nodepq != NULL);
    182
    183 if( nodepq->len > 0 )
    184 {
    185 /* sort the sorts downwards after their number to increase speed when freeing in debug mode */
    186 /* @todo: if a node is freed, the parent will also be freed, if no children are left; maybe we want to free all
    187 * nodes in the order of decreasing node numbers
    188 */
    189 SCIPsortDownPtr((void**)nodepq->slots, nodeCompNumber, nodepq->len);
    190
    191 /* free the nodes of the queue */
    192 for( i = 0; i < nodepq->len; ++i )
    193 {
    194 assert(nodepq->slots[i] != NULL);
    195 assert(SCIPnodeGetType(nodepq->slots[i]) == SCIP_NODETYPE_LEAF);
    196
    197 SCIP_CALL( SCIPnodeFree(&nodepq->slots[i], blkmem, set, stat, eventqueue, eventfilter, tree, lp) );
    198 }
    199 }
    200
    201 /* reset data */
    202 nodepq->len = 0;
    203 nodepq->lowerboundsum = 0.0;
    204
    205 return SCIP_OKAY;
    206}
    207
    208/** returns the node selector associated with the given node priority queue */
    210 SCIP_NODEPQ* nodepq /**< node priority queue */
    211 )
    212{
    213 assert(nodepq != NULL);
    214
    215 return nodepq->nodesel;
    216}
    217
    218/** sets the node selector used for sorting the nodes in the queue, and resorts the queue if necessary */
    220 SCIP_NODEPQ** nodepq, /**< pointer to a node priority queue */
    221 SCIP_SET* set, /**< global SCIP settings */
    222 SCIP_NODESEL* nodesel /**< node selector to use for sorting the nodes in the queue */
    223 )
    224{
    225 SCIP_NODEPQ* newnodepq;
    226 SCIP_RETCODE retcode;
    227 int i;
    228
    229 assert(nodepq != NULL);
    230 assert(*nodepq != NULL);
    231 assert((*nodepq)->len >= 0);
    232 assert(nodesel != NULL);
    233 assert(nodesel->nodeselcomp != NULL);
    234
    235 if( (*nodepq)->nodesel == nodesel )
    236 return SCIP_OKAY;
    237
    238 /* create new node priority queue */
    239 SCIP_CALL( SCIPnodepqCreate(&newnodepq, set, nodesel) );
    240
    241 /* resize the new node priority queue to be able to store all nodes */
    242 retcode = nodepqResize(newnodepq, set, (*nodepq)->len);
    243
    244 /* insert all nodes in the new node priority queue */
    245 for( i = 0; i < (*nodepq)->len && retcode == SCIP_OKAY; ++i )
    246 {
    247 retcode = SCIPnodepqInsert(newnodepq, set, (*nodepq)->slots[i]);
    248 }
    249
    250 if( retcode != SCIP_OKAY )
    251 {
    252 SCIPnodepqDestroy(&newnodepq);
    253
    254 return retcode;
    255 }
    256
    257 /* destroy the old node priority queue without freeing the nodes */
    258 SCIPnodepqDestroy(nodepq);
    259
    260 /* use the new node priority queue */
    261 *nodepq = newnodepq;
    262
    263 return SCIP_OKAY;
    264}
    265
    266/** compares two nodes; returns -1/0/+1 if node1 better/equal/worse than node2 */
    268 SCIP_NODEPQ* nodepq, /**< node priority queue */
    269 SCIP_SET* set, /**< global SCIP settings */
    270 SCIP_NODE* node1, /**< first node to compare */
    271 SCIP_NODE* node2 /**< second node to compare */
    272 )
    273{
    274 assert(nodepq != NULL);
    275 assert(nodepq->nodesel != NULL);
    276 assert(nodepq->nodesel->nodeselcomp != NULL);
    277 assert(set != NULL);
    278
    279 return SCIPnodeselCompare(nodepq->nodesel, set, node1, node2);
    280}
    281
    282/** inserts node into node priority queue */
    284 SCIP_NODEPQ* nodepq, /**< node priority queue */
    285 SCIP_SET* set, /**< global SCIP settings */
    286 SCIP_NODE* node /**< node to be inserted */
    287 )
    288{
    289 SCIP_NODESEL* nodesel;
    290 SCIP_NODE** slots;
    291 int* bfsposs;
    292 int* bfsqueue;
    293 int pos;
    294 int bfspos;
    295
    296 assert(nodepq != NULL);
    297 assert(nodepq->len >= 0);
    298 assert(set != NULL);
    299 assert(node != NULL);
    300
    301 nodesel = nodepq->nodesel;
    302 assert(nodesel != NULL);
    303 assert(nodesel->nodeselcomp != NULL);
    304
    305 SCIP_CALL( nodepqResize(nodepq, set, nodepq->len+1) );
    306 slots = nodepq->slots;
    307 bfsposs = nodepq->bfsposs;
    308 bfsqueue = nodepq->bfsqueue;
    309
    310 /* insert node as leaf in the tree, move it towards the root as long it is better than its parent */
    311 nodepq->len++;
    312 nodepq->lowerboundsum += SCIPnodeGetLowerbound(node);
    313 pos = nodepq->len-1;
    314 while( pos > 0 && nodesel->nodeselcomp(set->scip, nodesel, node, slots[PQ_PARENT(pos)]) < 0 )
    315 {
    316 slots[pos] = slots[PQ_PARENT(pos)];
    317 bfsposs[pos] = bfsposs[PQ_PARENT(pos)];
    318 bfsqueue[bfsposs[pos]] = pos;
    319 pos = PQ_PARENT(pos);
    320 }
    321 slots[pos] = node;
    322
    323 /* insert the final position into the bfs index queue */
    324 bfspos = nodepq->len-1;
    325 if( set->exact_enable )
    326 {
    327 SCIP_RATIONAL* lowerbound = SCIPnodeGetLowerboundExact(node);
    328 while( bfspos > 0 && SCIPrationalIsLT(lowerbound, SCIPnodeGetLowerboundExact(slots[bfsqueue[PQ_PARENT(bfspos)]])) )
    329 {
    330 bfsqueue[bfspos] = bfsqueue[PQ_PARENT(bfspos)];
    331 bfsposs[bfsqueue[bfspos]] = bfspos;
    332 bfspos = PQ_PARENT(bfspos);
    333 }
    334
    335 SCIPrationalDebugMessage("inserted node %p[%q] at pos %d and bfspos %d of node queue\n", (void*)node, lowerbound, pos, bfspos);
    336 }
    337 else
    338 {
    339 SCIP_Real lowerbound = SCIPnodeGetLowerbound(node);
    340 while( bfspos > 0 && lowerbound < SCIPnodeGetLowerbound(slots[bfsqueue[PQ_PARENT(bfspos)]]) )
    341 {
    342 bfsqueue[bfspos] = bfsqueue[PQ_PARENT(bfspos)];
    343 bfsposs[bfsqueue[bfspos]] = bfspos;
    344 bfspos = PQ_PARENT(bfspos);
    345 }
    346
    347 SCIPsetDebugMsg(set, "inserted node %p[%g] at pos %d and bfspos %d of node queue\n", (void*)node, lowerbound, pos, bfspos);
    348 }
    349 bfsqueue[bfspos] = pos;
    350 bfsposs[pos] = bfspos;
    351
    352 return SCIP_OKAY;
    353}
    354
    355/** deletes node at given position from the node priority queue; returns TRUE, if the parent fell down to the
    356 * free position
    357 */
    358static
    360 SCIP_NODEPQ* nodepq, /**< node priority queue */
    361 SCIP_SET* set, /**< global SCIP settings */
    362 int rempos /**< queue position of node to remove */
    363 )
    364{
    365 SCIP_NODESEL* nodesel;
    366 SCIP_NODE** slots;
    367 int* bfsposs;
    368 int* bfsqueue;
    369 SCIP_NODE* lastnode;
    370 int lastbfspos;
    371 int lastbfsqueueidx;
    372 int freepos;
    373 int freebfspos;
    374 SCIP_Bool parentfelldown;
    375 SCIP_Bool bfsparentfelldown;
    376
    377 assert(nodepq != NULL);
    378 assert(nodepq->len > 0);
    379 assert(set != NULL);
    380 assert(0 <= rempos && rempos < nodepq->len);
    381
    382 nodesel = nodepq->nodesel;
    383 assert(nodesel != NULL);
    384 assert(nodesel->nodeselcomp != NULL);
    385
    386 slots = nodepq->slots;
    387 bfsposs = nodepq->bfsposs;
    388 bfsqueue = nodepq->bfsqueue;
    389
    390 nodepq->lowerboundsum -= SCIPnodeGetLowerbound(slots[rempos]);
    391 freepos = rempos;
    392 freebfspos = bfsposs[rempos];
    393 assert(0 <= freebfspos && freebfspos < nodepq->len);
    394
    395 SCIPsetDebugMsg(set, "delete node %p[%g] at pos %d and bfspos %d of node queue\n",
    396 (void*)slots[freepos], SCIPnodeGetLowerbound(slots[freepos]), freepos, freebfspos);
    397
    398 /* remove node of the tree and get a free slot,
    399 * if the removed node was the last node of the queue
    400 * - do nothing
    401 * if the last node of the queue is better than the parent of the removed node:
    402 * - move the parent to the free slot, until the last node can be placed in the free slot
    403 * if the last node of the queue is not better than the parent of the free slot:
    404 * - move the better child to the free slot until the last node can be placed in the free slot
    405 */
    406 nodepq->len--;
    407
    408 /* process the slots queue ordered by the node selection comparator */
    409 lastnode = slots[nodepq->len];
    410 lastbfspos = bfsposs[nodepq->len];
    411 parentfelldown = FALSE;
    412 if( freepos < nodepq->len )
    413 {
    414 int parentpos;
    415
    416 /* try to move parents downwards to insert last node */
    417 parentpos = PQ_PARENT(freepos);
    418 while( freepos > 0 && nodesel->nodeselcomp(set->scip, nodesel, lastnode, slots[parentpos]) < 0 )
    419 {
    420 slots[freepos] = slots[parentpos];
    421 bfsposs[freepos] = bfsposs[parentpos];
    422 bfsqueue[bfsposs[freepos]] = freepos;
    423 freepos = parentpos;
    424 parentpos = PQ_PARENT(freepos);
    425 parentfelldown = TRUE;
    426 }
    427 if( !parentfelldown )
    428 {
    429 /* downward moving of parents was not successful -> move children upwards */
    430 while( freepos <= PQ_PARENT(nodepq->len-1) ) /* as long as free slot has children... */
    431 {
    432 int childpos;
    433 int brotherpos;
    434
    435 /* select the better child of free slot */
    436 childpos = PQ_LEFTCHILD(freepos);
    437 assert(childpos < nodepq->len);
    438 brotherpos = PQ_RIGHTCHILD(freepos);
    439 if( brotherpos < nodepq->len
    440 && nodesel->nodeselcomp(set->scip, nodesel, slots[brotherpos], slots[childpos]) < 0 )
    441 childpos = brotherpos;
    442
    443 /* exit search loop if better child is not better than last node */
    444 if( nodesel->nodeselcomp(set->scip, nodesel, lastnode, slots[childpos]) <= 0 )
    445 break;
    446
    447 /* move better child upwards, free slot is now the better child's slot */
    448 slots[freepos] = slots[childpos];
    449 bfsposs[freepos] = bfsposs[childpos];
    450 bfsqueue[bfsposs[freepos]] = freepos;
    451 freepos = childpos;
    452 }
    453 }
    454 assert(0 <= freepos && freepos < nodepq->len);
    455 assert(!parentfelldown || PQ_LEFTCHILD(freepos) < nodepq->len);
    456 slots[freepos] = lastnode;
    457 bfsposs[freepos] = lastbfspos;
    458 bfsqueue[lastbfspos] = freepos;
    459 }
    460
    461 /* process the bfs queue ordered by the lower bound */
    462 lastbfsqueueidx = bfsqueue[nodepq->len];
    463 bfsparentfelldown = FALSE;
    464 if( freebfspos < nodepq->len )
    465 {
    466 int parentpos;
    467
    468 /* try to move parents downwards to insert last queue index */
    469 parentpos = PQ_PARENT(freebfspos);
    470 if( set->exact_enable )
    471 {
    472 SCIP_RATIONAL* lastlowerbound = SCIPnodeGetLowerboundExact(slots[lastbfsqueueidx]);
    473 while( freebfspos > 0 && SCIPrationalIsLT(lastlowerbound, SCIPnodeGetLowerboundExact(slots[bfsqueue[parentpos]])) )
    474 {
    475 bfsqueue[freebfspos] = bfsqueue[parentpos];
    476 bfsposs[bfsqueue[freebfspos]] = freebfspos;
    477 freebfspos = parentpos;
    478 parentpos = PQ_PARENT(freebfspos);
    479 bfsparentfelldown = TRUE;
    480 }
    481 if( !bfsparentfelldown )
    482 {
    483 /* downward moving of parents was not successful -> move children upwards */
    484 while( freebfspos <= PQ_PARENT(nodepq->len-1) ) /* as long as free slot has children... */
    485 {
    486 int childpos;
    487 int brotherpos;
    488
    489 /* select the better child of free slot */
    490 childpos = PQ_LEFTCHILD(freebfspos);
    491 assert(childpos < nodepq->len);
    492 brotherpos = PQ_RIGHTCHILD(freebfspos);
    493 if( brotherpos < nodepq->len
    494 && SCIPrationalIsLT(SCIPnodeGetLowerboundExact(slots[bfsqueue[brotherpos]]), SCIPnodeGetLowerboundExact(slots[bfsqueue[childpos]])) )
    495 childpos = brotherpos;
    496
    497 /* exit search loop if better child is not better than last node */
    498 if( SCIPrationalIsLE(lastlowerbound, SCIPnodeGetLowerboundExact(slots[bfsqueue[childpos]])) )
    499 break;
    500
    501 /* move better child upwards, free slot is now the better child's slot */
    502 bfsqueue[freebfspos] = bfsqueue[childpos];
    503 bfsposs[bfsqueue[freebfspos]] = freebfspos;
    504 freebfspos = childpos;
    505 }
    506 }
    507 }
    508 else
    509 {
    510 SCIP_Real lastlowerbound = SCIPnodeGetLowerbound(slots[lastbfsqueueidx]);
    511 while( freebfspos > 0 && lastlowerbound < SCIPnodeGetLowerbound(slots[bfsqueue[parentpos]]) )
    512 {
    513 bfsqueue[freebfspos] = bfsqueue[parentpos];
    514 bfsposs[bfsqueue[freebfspos]] = freebfspos;
    515 freebfspos = parentpos;
    516 parentpos = PQ_PARENT(freebfspos);
    517 bfsparentfelldown = TRUE;
    518 }
    519 if( !bfsparentfelldown )
    520 {
    521 /* downward moving of parents was not successful -> move children upwards */
    522 while( freebfspos <= PQ_PARENT(nodepq->len-1) ) /* as long as free slot has children... */
    523 {
    524 int childpos;
    525 int brotherpos;
    526
    527 /* select the better child of free slot */
    528 childpos = PQ_LEFTCHILD(freebfspos);
    529 assert(childpos < nodepq->len);
    530 brotherpos = PQ_RIGHTCHILD(freebfspos);
    531 if( brotherpos < nodepq->len
    532 && SCIPnodeGetLowerbound(slots[bfsqueue[brotherpos]]) < SCIPnodeGetLowerbound(slots[bfsqueue[childpos]]) )
    533 childpos = brotherpos;
    534
    535 /* exit search loop if better child is not better than last node */
    536 if( lastlowerbound <= SCIPnodeGetLowerbound(slots[bfsqueue[childpos]]) )
    537 break;
    538
    539 /* move better child upwards, free slot is now the better child's slot */
    540 bfsqueue[freebfspos] = bfsqueue[childpos];
    541 bfsposs[bfsqueue[freebfspos]] = freebfspos;
    542 freebfspos = childpos;
    543 }
    544 }
    545 }
    546 assert(0 <= freebfspos && freebfspos < nodepq->len);
    547 assert(!bfsparentfelldown || PQ_LEFTCHILD(freebfspos) < nodepq->len);
    548 bfsqueue[freebfspos] = lastbfsqueueidx;
    549 bfsposs[lastbfsqueueidx] = freebfspos;
    550 }
    551
    552 return parentfelldown;
    553}
    554
    555/** returns the position of given node in the priority queue, or -1 if not existing */
    556static
    558 SCIP_NODEPQ* nodepq, /**< node priority queue */
    559 SCIP_SET* set, /**< global SCIP settings */
    560 SCIP_NODE* node /**< node to find */
    561 )
    562{
    563 int pos;
    564
    565 assert(nodepq != NULL);
    566 assert(nodepq->len >= 0);
    567 assert(set != NULL);
    568 assert(node != NULL);
    569
    570 /* search the node in the queue */
    571 for( pos = 0; pos < nodepq->len && node != nodepq->slots[pos]; ++pos )
    572 {}
    573
    574 if( pos == nodepq->len )
    575 pos = -1;
    576
    577 return pos;
    578}
    579
    580/** removes node from the node priority queue */
    582 SCIP_NODEPQ* nodepq, /**< node priority queue */
    583 SCIP_SET* set, /**< global SCIP settings */
    584 SCIP_NODE* node /**< node to remove */
    585 )
    586{
    587 int pos;
    588
    589 pos = nodepqFindNode(nodepq, set, node);
    590 if( pos == -1 )
    591 {
    592 SCIPerrorMessage("node doesn't exist in node priority queue\n");
    593 return SCIP_INVALIDDATA;
    594 }
    595
    596 (void)nodepqDelPos(nodepq, set, pos);
    597
    598 return SCIP_OKAY;
    599}
    600
    601/** returns the best node of the queue without removing it */
    603 const SCIP_NODEPQ* nodepq /**< node priority queue */
    604 )
    605{
    606 assert(nodepq != NULL);
    607 assert(nodepq->len >= 0);
    608
    609 if( nodepq->len == 0 )
    610 return NULL;
    611
    612 assert(nodepq->slots[0] != NULL);
    613
    614 return nodepq->slots[0];
    615}
    616
    617/** returns the nodes array of the queue */
    619 const SCIP_NODEPQ* nodepq /**< node priority queue */
    620 )
    621{
    622 assert(nodepq != NULL);
    623
    624 return nodepq->slots;
    625}
    626
    627/** returns the number of nodes stored in the node priority queue */
    629 const SCIP_NODEPQ* nodepq /**< node priority queue */
    630 )
    631{
    632 assert(nodepq != NULL);
    633 assert(nodepq->len >= 0);
    634
    635 return nodepq->len;
    636}
    637
    638/** gets the minimal lower bound of all nodes in the queue */
    640 SCIP_NODEPQ* nodepq, /**< node priority queue */
    641 SCIP_SET* set /**< global SCIP settings */
    642 )
    643{
    644 assert(nodepq != NULL);
    645 assert(nodepq->nodesel != NULL);
    646 assert(set != NULL);
    647
    648 if( nodepq->len > 0 )
    649 {
    650 int bfspos;
    651
    652 bfspos = nodepq->bfsqueue[0];
    653 assert(0 <= bfspos && bfspos < nodepq->len);
    654 assert(nodepq->slots[bfspos] != NULL);
    655 return SCIPnodeGetLowerbound(nodepq->slots[bfspos]);
    656 }
    657 else
    658 return SCIPsetInfinity(set);
    659}
    660
    661/** gets the minimal exact lower bound of all nodes in the queue or NULL if empty */
    663 SCIP_NODEPQ* nodepq, /**< node priority queue */
    664 SCIP_SET* set /**< global SCIP settings */
    665 )
    666{
    667 assert(nodepq != NULL);
    668 assert(nodepq->nodesel != NULL);
    669 assert(set != NULL);
    670
    671 if( nodepq->len > 0 )
    672 {
    673 int bfspos;
    674
    675 bfspos = nodepq->bfsqueue[0];
    676 assert(0 <= bfspos && bfspos < nodepq->len);
    677 assert(nodepq->slots[bfspos] != NULL);
    678 return SCIPnodeGetLowerboundExact(nodepq->slots[bfspos]);
    679 }
    680 else
    681 return NULL;
    682}
    683
    684/** gets the node with minimal lower bound of all nodes in the queue */
    686 SCIP_NODEPQ* nodepq, /**< node priority queue */
    687 SCIP_SET* set /**< global SCIP settings */
    688 )
    689{
    690 assert(nodepq != NULL);
    691 assert(nodepq->nodesel != NULL);
    692 assert(set != NULL);
    693
    694 /* the node selector's compare method sorts the minimal lower bound to the front */
    695 if( nodepq->len > 0 )
    696 {
    697 int bfspos;
    698
    699 bfspos = nodepq->bfsqueue[0];
    700 assert(0 <= bfspos && bfspos < nodepq->len);
    701 assert(nodepq->slots[bfspos] != NULL);
    702 return nodepq->slots[bfspos];
    703 }
    704 else
    705 return NULL;
    706}
    707
    708/** gets the sum of lower bounds of all nodes in the queue */
    710 SCIP_NODEPQ* nodepq /**< node priority queue */
    711 )
    712{
    713 assert(nodepq != NULL);
    714
    715 return nodepq->lowerboundsum;
    716}
    717
    718/** free all nodes from the queue that are cut off by the given upper bound */
    720 SCIP_NODEPQ* nodepq, /**< node priority queue */
    721 BMS_BLKMEM* blkmem, /**< block memory buffer */
    722 SCIP_SET* set, /**< global SCIP settings */
    723 SCIP_STAT* stat, /**< dynamic problem statistics */
    724 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
    725 SCIP_EVENTFILTER* eventfilter, /**< global event filter */
    726 SCIP_TREE* tree, /**< branch and bound tree */
    727 SCIP_REOPT* reopt, /**< reoptimization data structure */
    728 SCIP_LP* lp, /**< current LP data */
    729 SCIP_Real cutoffbound /**< cutoff bound: all nodes with lowerbound >= cutoffbound are cut off */
    730 )
    731{
    732 SCIP_NODE* node;
    733 int pos;
    734
    735 assert(nodepq != NULL);
    736 assert(set != NULL);
    737
    738 SCIPsetDebugMsg(set, "bounding node queue of length %d with cutoffbound=%g\n", nodepq->len, cutoffbound);
    739
    740 pos = nodepq->len - 1;
    741
    742 while( pos >= 0 )
    743 {
    744 assert(pos < nodepq->len);
    745 node = nodepq->slots[pos];
    746 assert(node != NULL);
    747 assert(SCIPnodeGetType(node) == SCIP_NODETYPE_LEAF);
    748
    749 /* cut off node */
    750 if( set->exact_enable ? SCIPrationalIsGEReal(SCIPnodeGetLowerboundExact(node), cutoffbound)
    751 : SCIPsetIsGE(set, SCIPnodeGetLowerbound(node), cutoffbound) )
    752 {
    753 /* because we loop from back to front, the existing children of the node must have a smaller lower bound
    754 * than the cut off value
    755 */
    756 assert(!node->active);
    757 assert(node->depth != 0 || tree->focusnode == NULL);
    758 assert(PQ_LEFTCHILD(pos) >= nodepq->len
    759 || SCIPsetIsLT(set, SCIPnodeGetLowerbound(nodepq->slots[PQ_LEFTCHILD(pos)]), cutoffbound)
    760 || (set->exact_enable && SCIPnodeGetLowerbound(nodepq->slots[PQ_LEFTCHILD(pos)]) < cutoffbound));
    761 assert(PQ_RIGHTCHILD(pos) >= nodepq->len
    762 || SCIPsetIsLT(set, SCIPnodeGetLowerbound(nodepq->slots[PQ_RIGHTCHILD(pos)]), cutoffbound)
    763 || (set->exact_enable && SCIPnodeGetLowerbound(nodepq->slots[PQ_RIGHTCHILD(pos)]) < cutoffbound));
    764
    765 SCIPsetDebugMsg(set, "cutting off leaf node in slot %d (queuelen=%d) at depth %d with lowerbound=%g\n",
    766 pos, SCIPnodepqLen(nodepq), SCIPnodeGetDepth(node), SCIPnodeGetLowerbound(node));
    767
    768 /* check if the node should be stored for reoptimization */
    769 if( set->reopt_enable )
    770 {
    772 SCIPlpGetSolstat(lp), tree->root == node, FALSE, node->lowerbound, tree->effectiverootdepth) );
    773 }
    774
    775 /* remove node from the queue
    776 * - if the slot was occupied by the parent, we have to check this slot (the parent) again; unfortunately,
    777 * we will check the node which occupied the parent's slot again, even though it cannot be cut off;
    778 * - otherwise, the slot was the last slot or it was occupied by a node with a position greater than
    779 * the current position; this node was already checked and we can decrease the position
    780 */
    781 if( !nodepqDelPos(nodepq, set, pos) )
    782 --pos;
    783
    784 node->cutoff = TRUE;
    785 if( set->exact_enable )
    789
    790 if( node->depth == 0 )
    792
    793 if( set->exact_enable )
    794 {
    795 SCIP_RATIONAL* lowerboundexact = SCIPtreeGetLowerboundExact(tree, set);
    796
    797 assert(SCIPrationalIsGEReal(lowerboundexact, SCIPtreeGetLowerbound(tree, set)));
    798
    799 /* exact lower bound improved */
    800 if( SCIPrationalIsLT(stat->lastlowerboundexact, lowerboundexact) )
    801 {
    802 /* throw improvement event if upper bound not already exceeded */
    803 if( SCIPrationalIsLT(stat->lastlowerboundexact, set->scip->primal->upperboundexact) )
    804 {
    805 SCIP_EVENT event;
    806
    808 SCIP_CALL( SCIPeventProcess(&event, set, NULL, NULL, NULL, eventfilter) );
    809 }
    810
    811 /* update exact last lower bound */
    812 SCIPrationalSetRational(stat->lastlowerboundexact, lowerboundexact);
    813 }
    814 }
    815
    816 SCIP_Real lowerbound = SCIPtreeGetLowerbound(tree, set);
    817
    818 assert(lowerbound <= SCIPsetInfinity(set));
    819
    820 /* lower bound improved */
    821 if( stat->lastlowerbound < lowerbound )
    822 {
    823 /* throw improvement event if not already done exactly */
    824 if( !set->exact_enable && stat->lastlowerbound < set->scip->primal->upperbound )
    825 {
    826 SCIP_EVENT event;
    827
    829 SCIP_CALL( SCIPeventProcess(&event, set, NULL, NULL, NULL, eventfilter) );
    830 }
    831
    832 /* update primal-dual integrals */
    833 if( set->misc_calcintegral )
    834 {
    835 SCIPstatUpdatePrimalDualIntegrals(stat, set, set->scip->transprob, set->scip->origprob, SCIPsetInfinity(set), lowerbound);
    836 assert(stat->lastlowerbound == lowerbound); /*lint !e777*/
    837 }
    838 else
    839 stat->lastlowerbound = lowerbound;
    840 }
    841
    842 SCIPvisualCutoffNode(stat->visual, set, stat, node, TRUE);
    843
    844 /* free node memory */
    845 SCIP_CALL( SCIPnodeFree(&node, blkmem, set, stat, eventqueue, eventfilter, tree, lp) );
    846 }
    847 else
    848 --pos;
    849 }
    850
    851 SCIPsetDebugMsg(set, " -> bounded node queue has length %d\n", nodepq->len);
    852
    853 return SCIP_OKAY;
    854}
    855
    856
    857/*
    858 * node selector methods
    859 */
    860
    861/** method to call, when the standard mode priority of a node selector was changed */
    862static
    863SCIP_DECL_PARAMCHGD(paramChgdNodeselStdPriority)
    864{ /*lint --e{715}*/
    865 SCIP_PARAMDATA* paramdata;
    866
    867 paramdata = SCIPparamGetData(param);
    868 assert(paramdata != NULL);
    869
    870 /* use SCIPsetNodeselStdPriority() to mark the nodesels unsorted */
    871 SCIP_CALL( SCIPsetNodeselStdPriority(scip, (SCIP_NODESEL*)paramdata, SCIPparamGetInt(param)) ); /*lint !e740*/
    872
    873 return SCIP_OKAY;
    874}
    875
    876/** method to call, when the memory saving mode priority of a node selector was changed */
    877static
    878SCIP_DECL_PARAMCHGD(paramChgdNodeselMemsavePriority)
    879{ /*lint --e{715}*/
    880 SCIP_PARAMDATA* paramdata;
    881
    882 paramdata = SCIPparamGetData(param);
    883 assert(paramdata != NULL);
    884
    885 /* use SCIPsetNodeselMemsavePriority() to mark the nodesels unsorted */
    886 SCIP_CALL( SCIPsetNodeselMemsavePriority(scip, (SCIP_NODESEL*)paramdata, SCIPparamGetInt(param)) ); /*lint !e740*/
    887
    888 return SCIP_OKAY;
    889}
    890
    891/** copies the given node selector to a new scip */
    893 SCIP_NODESEL* nodesel, /**< node selector */
    894 SCIP_SET* set /**< SCIP_SET of SCIP to copy to */
    895 )
    896{
    897 assert(nodesel != NULL);
    898 assert(set != NULL);
    899 assert(set->scip != NULL);
    900
    901 if( nodesel->nodeselcopy != NULL )
    902 {
    903 SCIPsetDebugMsg(set, "including node selector %s in subscip %p\n", SCIPnodeselGetName(nodesel), (void*)set->scip);
    904 SCIP_CALL( nodesel->nodeselcopy(set->scip, nodesel) );
    905 }
    906 return SCIP_OKAY;
    907}
    908
    909/** internal method for creating a node selector */
    910static
    912 SCIP_NODESEL** nodesel, /**< pointer to store node selector */
    913 SCIP_SET* set, /**< global SCIP settings */
    914 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
    915 BMS_BLKMEM* blkmem, /**< block memory for parameter settings */
    916 const char* name, /**< name of node selector */
    917 const char* desc, /**< description of node selector */
    918 int stdpriority, /**< priority of the node selector in standard mode */
    919 int memsavepriority, /**< priority of the node selector in memory saving mode */
    920 SCIP_DECL_NODESELCOPY ((*nodeselcopy)), /**< copy method of node selector or NULL if you don't want to copy your plugin into sub-SCIPs */
    921 SCIP_DECL_NODESELFREE ((*nodeselfree)), /**< destructor of node selector */
    922 SCIP_DECL_NODESELINIT ((*nodeselinit)), /**< initialize node selector */
    923 SCIP_DECL_NODESELEXIT ((*nodeselexit)), /**< deinitialize node selector */
    924 SCIP_DECL_NODESELINITSOL((*nodeselinitsol)),/**< solving process initialization method of node selector */
    925 SCIP_DECL_NODESELEXITSOL((*nodeselexitsol)),/**< solving process deinitialization method of node selector */
    926 SCIP_DECL_NODESELSELECT((*nodeselselect)),/**< node selection method */
    927 SCIP_DECL_NODESELCOMP ((*nodeselcomp)), /**< node comparison method */
    928 SCIP_NODESELDATA* nodeseldata /**< node selector data */
    929 )
    930{
    932 char paramdesc[SCIP_MAXSTRLEN];
    933
    934 assert(nodesel != NULL);
    935 assert(name != NULL);
    936 assert(desc != NULL);
    937 assert(nodeselselect != NULL);
    938 assert(nodeselcomp != NULL);
    939
    940 SCIP_ALLOC( BMSallocMemory(nodesel) );
    941 BMSclearMemory(*nodesel);
    942
    943 SCIP_ALLOC( BMSduplicateMemoryArray(&(*nodesel)->name, name, strlen(name)+1) );
    944 SCIP_ALLOC( BMSduplicateMemoryArray(&(*nodesel)->desc, desc, strlen(desc)+1) );
    945 (*nodesel)->stdpriority = stdpriority;
    946 (*nodesel)->memsavepriority = memsavepriority;
    947 (*nodesel)->nodeselcopy = nodeselcopy;
    948 (*nodesel)->nodeselfree = nodeselfree;
    949 (*nodesel)->nodeselinit = nodeselinit;
    950 (*nodesel)->nodeselexit = nodeselexit;
    951 (*nodesel)->nodeselinitsol = nodeselinitsol;
    952 (*nodesel)->nodeselexitsol = nodeselexitsol;
    953 (*nodesel)->nodeselselect = nodeselselect;
    954 (*nodesel)->nodeselcomp = nodeselcomp;
    955 (*nodesel)->nodeseldata = nodeseldata;
    956 (*nodesel)->initialized = FALSE;
    957 /* create clocks */
    958 SCIP_CALL( SCIPclockCreate(&(*nodesel)->setuptime, SCIP_CLOCKTYPE_DEFAULT) );
    959 SCIP_CALL( SCIPclockCreate(&(*nodesel)->nodeseltime, SCIP_CLOCKTYPE_DEFAULT) );
    960
    961 /* add parameters */
    962 (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "nodeselection/%s/stdpriority", name);
    963 (void) SCIPsnprintf(paramdesc, SCIP_MAXSTRLEN, "priority of node selection rule <%s> in standard mode", name);
    964 SCIP_CALL( SCIPsetAddIntParam(set, messagehdlr, blkmem, paramname, paramdesc,
    965 &(*nodesel)->stdpriority, FALSE, stdpriority, INT_MIN/4, INT_MAX/2,
    966 paramChgdNodeselStdPriority, (SCIP_PARAMDATA*)(*nodesel)) ); /*lint !e740*/
    967
    968 (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "nodeselection/%s/memsavepriority", name);
    969 (void) SCIPsnprintf(paramdesc, SCIP_MAXSTRLEN, "priority of node selection rule <%s> in memory saving mode", name);
    970 SCIP_CALL( SCIPsetAddIntParam(set, messagehdlr, blkmem, paramname, paramdesc,
    971 &(*nodesel)->memsavepriority, TRUE, memsavepriority, INT_MIN/4, INT_MAX/4,
    972 paramChgdNodeselMemsavePriority, (SCIP_PARAMDATA*)(*nodesel)) ); /*lint !e740*/
    973
    974 return SCIP_OKAY;
    975}
    976
    977/** creates a node selector */
    979 SCIP_NODESEL** nodesel, /**< pointer to store node selector */
    980 SCIP_SET* set, /**< global SCIP settings */
    981 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
    982 BMS_BLKMEM* blkmem, /**< block memory for parameter settings */
    983 const char* name, /**< name of node selector */
    984 const char* desc, /**< description of node selector */
    985 int stdpriority, /**< priority of the node selector in standard mode */
    986 int memsavepriority, /**< priority of the node selector in memory saving mode */
    987 SCIP_DECL_NODESELCOPY ((*nodeselcopy)), /**< copy method of node selector or NULL if you don't want to copy your plugin into sub-SCIPs */
    988 SCIP_DECL_NODESELFREE ((*nodeselfree)), /**< destructor of node selector */
    989 SCIP_DECL_NODESELINIT ((*nodeselinit)), /**< initialize node selector */
    990 SCIP_DECL_NODESELEXIT ((*nodeselexit)), /**< deinitialize node selector */
    991 SCIP_DECL_NODESELINITSOL((*nodeselinitsol)),/**< solving process initialization method of node selector */
    992 SCIP_DECL_NODESELEXITSOL((*nodeselexitsol)),/**< solving process deinitialization method of node selector */
    993 SCIP_DECL_NODESELSELECT((*nodeselselect)),/**< node selection method */
    994 SCIP_DECL_NODESELCOMP ((*nodeselcomp)), /**< node comparison method */
    995 SCIP_NODESELDATA* nodeseldata /**< node selector data */
    996 )
    997{
    998 assert(nodesel != NULL);
    999 assert(name != NULL);
    1000 assert(desc != NULL);
    1001 assert(nodeselselect != NULL);
    1002 assert(nodeselcomp != NULL);
    1003
    1004 SCIP_CALL_FINALLY( doNodeselCreate(nodesel, set, messagehdlr, blkmem, name, desc, stdpriority, memsavepriority,
    1005 nodeselcopy, nodeselfree, nodeselinit, nodeselexit, nodeselinitsol, nodeselexitsol, nodeselselect, nodeselcomp,
    1006 nodeseldata), (void) SCIPnodeselFree(nodesel, set) );
    1007
    1008 return SCIP_OKAY;
    1009}
    1010
    1011/** frees memory of node selector */
    1013 SCIP_NODESEL** nodesel, /**< pointer to node selector data structure */
    1014 SCIP_SET* set /**< global SCIP settings */
    1015 )
    1016{
    1017 assert(nodesel != NULL);
    1018 if( *nodesel == NULL )
    1019 return SCIP_OKAY;
    1020 assert(!(*nodesel)->initialized);
    1021 assert(set != NULL);
    1022
    1023 /* call destructor of node selector */
    1024 if( (*nodesel)->nodeselfree != NULL )
    1025 {
    1026 SCIP_CALL( (*nodesel)->nodeselfree(set->scip, *nodesel) );
    1027 }
    1028
    1029 /* free clocks */
    1030 SCIPclockFree(&(*nodesel)->nodeseltime);
    1031 SCIPclockFree(&(*nodesel)->setuptime);
    1032
    1033 BMSfreeMemoryArrayNull(&(*nodesel)->name);
    1034 BMSfreeMemoryArrayNull(&(*nodesel)->desc);
    1035 BMSfreeMemory(nodesel);
    1036
    1037 return SCIP_OKAY;
    1038}
    1039
    1040/** initializes node selector */
    1042 SCIP_NODESEL* nodesel, /**< node selector */
    1043 SCIP_SET* set /**< global SCIP settings */
    1044 )
    1045{
    1046 assert(nodesel != NULL);
    1047 assert(set != NULL);
    1048
    1049 if( nodesel->initialized )
    1050 {
    1051 SCIPerrorMessage("node selector <%s> already initialized", nodesel->name);
    1052 return SCIP_INVALIDCALL;
    1053 }
    1054
    1055 if( set->misc_resetstat )
    1056 {
    1057 SCIPclockReset(nodesel->setuptime);
    1058 SCIPclockReset(nodesel->nodeseltime);
    1059 }
    1060
    1061 if( nodesel->nodeselinit != NULL )
    1062 {
    1063 /* start timing */
    1064 SCIPclockStart(nodesel->setuptime, set);
    1065
    1066 SCIP_CALL( nodesel->nodeselinit(set->scip, nodesel) );
    1067
    1068 /* stop timing */
    1069 SCIPclockStop(nodesel->setuptime, set);
    1070 }
    1071 nodesel->initialized = TRUE;
    1072
    1073 return SCIP_OKAY;
    1074}
    1075
    1076/** deinitializes node selector */
    1078 SCIP_NODESEL* nodesel, /**< node selector */
    1079 SCIP_SET* set /**< global SCIP settings */
    1080 )
    1081{
    1082 assert(nodesel != NULL);
    1083 assert(set != NULL);
    1084
    1085 if( !nodesel->initialized )
    1086 {
    1087 SCIPerrorMessage("node selector <%s> not initialized", nodesel->name);
    1088 return SCIP_INVALIDCALL;
    1089 }
    1090
    1091 if( nodesel->nodeselexit != NULL )
    1092 {
    1093 /* start timing */
    1094 SCIPclockStart(nodesel->setuptime, set);
    1095
    1096 SCIP_CALL( nodesel->nodeselexit(set->scip, nodesel) );
    1097
    1098 /* stop timing */
    1099 SCIPclockStop(nodesel->setuptime, set);
    1100 }
    1101 nodesel->initialized = FALSE;
    1102
    1103 return SCIP_OKAY;
    1104}
    1105
    1106/** informs node selector that the branch and bound process is being started */
    1108 SCIP_NODESEL* nodesel, /**< node selector */
    1109 SCIP_SET* set /**< global SCIP settings */
    1110 )
    1111{
    1112 assert(nodesel != NULL);
    1113 assert(set != NULL);
    1114
    1115 /* call solving process initialization method of node selector */
    1116 if( nodesel->nodeselinitsol != NULL )
    1117 {
    1118 /* start timing */
    1119 SCIPclockStart(nodesel->setuptime, set);
    1120
    1121 SCIP_CALL( nodesel->nodeselinitsol(set->scip, nodesel) );
    1122
    1123 /* stop timing */
    1124 SCIPclockStop(nodesel->setuptime, set);
    1125 }
    1126
    1127 return SCIP_OKAY;
    1128}
    1129
    1130/** informs node selector that the branch and bound process data is being freed */
    1132 SCIP_NODESEL* nodesel, /**< node selector */
    1133 SCIP_SET* set /**< global SCIP settings */
    1134 )
    1135{
    1136 assert(nodesel != NULL);
    1137 assert(set != NULL);
    1138
    1139 /* call solving process deinitialization method of node selector */
    1140 if( nodesel->nodeselexitsol != NULL )
    1141 {
    1142 /* start timing */
    1143 SCIPclockStart(nodesel->setuptime, set);
    1144
    1145 SCIP_CALL( nodesel->nodeselexitsol(set->scip, nodesel) );
    1146
    1147 /* stop timing */
    1148 SCIPclockStop(nodesel->setuptime, set);
    1149 }
    1150
    1151 return SCIP_OKAY;
    1152}
    1153
    1154/** select next node to be processed */
    1156 SCIP_NODESEL* nodesel, /**< node selector */
    1157 SCIP_SET* set, /**< global SCIP settings */
    1158 SCIP_NODE** selnode /**< pointer to store node to be processed next */
    1159 )
    1160{
    1161 assert(nodesel != NULL);
    1162 assert(nodesel->nodeselselect != NULL);
    1163 assert(set != NULL);
    1164 assert(selnode != NULL);
    1165
    1166 /* start timing */
    1167 SCIPclockStart(nodesel->nodeseltime, set);
    1168
    1169 SCIP_CALL( nodesel->nodeselselect(set->scip, nodesel, selnode) );
    1170
    1171 /* stop timing */
    1172 SCIPclockStop(nodesel->nodeseltime, set);
    1173
    1174 return SCIP_OKAY;
    1175}
    1176
    1177/** compares two nodes; returns -1/0/+1 if node1 better/equal/worse than node2 */
    1179 SCIP_NODESEL* nodesel, /**< node selector */
    1180 SCIP_SET* set, /**< global SCIP settings */
    1181 SCIP_NODE* node1, /**< first node to compare */
    1182 SCIP_NODE* node2 /**< second node to compare */
    1183 )
    1184{
    1185 assert(nodesel != NULL);
    1186 assert(nodesel->nodeselcomp != NULL);
    1187 assert(set != NULL);
    1188 assert(node1 != NULL);
    1189 assert(node2 != NULL);
    1190
    1191 return nodesel->nodeselcomp(set->scip, nodesel, node1, node2);
    1192}
    1193
    1194/** gets name of node selector */
    1196 SCIP_NODESEL* nodesel /**< node selector */
    1197 )
    1198{
    1199 assert(nodesel != NULL);
    1200
    1201 return nodesel->name;
    1202}
    1203
    1204/** gets description of node selector */
    1206 SCIP_NODESEL* nodesel /**< node selector */
    1207 )
    1208{
    1209 assert(nodesel != NULL);
    1210
    1211 return nodesel->desc;
    1212}
    1213
    1214/** gets priority of node selector in standard mode */
    1216 SCIP_NODESEL* nodesel /**< node selector */
    1217 )
    1218{
    1219 assert(nodesel != NULL);
    1220
    1221 return nodesel->stdpriority;
    1222}
    1223
    1224/** gets priority of node selector in standard mode */
    1226 SCIP_NODESEL* nodesel, /**< node selector */
    1227 SCIP_SET* set, /**< global SCIP settings */
    1228 int priority /**< new priority of the node selector */
    1229 )
    1230{
    1231 assert(nodesel != NULL);
    1232 assert(set != NULL);
    1233
    1234 nodesel->stdpriority = priority;
    1235 set->nodesel = NULL;
    1236}
    1237
    1238/** gets priority of node selector in memory saving mode */
    1240 SCIP_NODESEL* nodesel /**< node selector */
    1241 )
    1242{
    1243 assert(nodesel != NULL);
    1244
    1245 return nodesel->memsavepriority;
    1246}
    1247
    1248/** sets priority of node selector in memory saving mode */
    1250 SCIP_NODESEL* nodesel, /**< node selector */
    1251 SCIP_SET* set, /**< global SCIP settings */
    1252 int priority /**< new priority of the node selector */
    1253 )
    1254{
    1255 assert(nodesel != NULL);
    1256 assert(set != NULL);
    1257
    1258 nodesel->memsavepriority = priority;
    1259 set->nodesel = NULL;
    1260}
    1261
    1262/** gets user data of node selector */
    1264 SCIP_NODESEL* nodesel /**< node selector */
    1265 )
    1266{
    1267 assert(nodesel != NULL);
    1268
    1269 return nodesel->nodeseldata;
    1270}
    1271
    1272/** sets user data of node selector; user has to free old data in advance! */
    1274 SCIP_NODESEL* nodesel, /**< node selector */
    1275 SCIP_NODESELDATA* nodeseldata /**< new node selector user data */
    1276 )
    1277{
    1278 assert(nodesel != NULL);
    1279
    1280 nodesel->nodeseldata = nodeseldata;
    1281}
    1282
    1283/* new callback/method setter methods */
    1284
    1285/** sets copy method of node selector */
    1287 SCIP_NODESEL* nodesel, /**< node selector */
    1288 SCIP_DECL_NODESELCOPY ((*nodeselcopy)) /**< copy method of node selector or NULL if you don't want to copy your plugin into sub-SCIPs */
    1289 )
    1290{
    1291 assert(nodesel != NULL);
    1292
    1293 nodesel->nodeselcopy = nodeselcopy;
    1294}
    1295
    1296/** sets destructor method of node selector */
    1298 SCIP_NODESEL* nodesel, /**< node selector */
    1299 SCIP_DECL_NODESELFREE ((*nodeselfree)) /**< destructor of node selector */
    1300 )
    1301{
    1302 assert(nodesel != NULL);
    1303
    1304 nodesel->nodeselfree = nodeselfree;
    1305}
    1306
    1307/** sets initialization method of node selector */
    1309 SCIP_NODESEL* nodesel, /**< node selector */
    1310 SCIP_DECL_NODESELINIT ((*nodeselinit)) /**< initialize node selector */
    1311 )
    1312{
    1313 assert(nodesel != NULL);
    1314
    1315 nodesel->nodeselinit = nodeselinit;
    1316}
    1317
    1318/** sets deinitialization method of node selector */
    1320 SCIP_NODESEL* nodesel, /**< node selector */
    1321 SCIP_DECL_NODESELEXIT ((*nodeselexit)) /**< deinitialize node selector */
    1322 )
    1323{
    1324 assert(nodesel != NULL);
    1325
    1326 nodesel->nodeselexit = nodeselexit;
    1327}
    1328
    1329/** sets solving process initialization method of node selector */
    1331 SCIP_NODESEL* nodesel, /**< node selector */
    1332 SCIP_DECL_NODESELINITSOL ((*nodeselinitsol))/**< solving process initialization method of node selector */
    1333 )
    1334{
    1335 assert(nodesel != NULL);
    1336
    1337 nodesel->nodeselinitsol = nodeselinitsol;
    1338}
    1339
    1340/** sets solving process deinitialization method of node selector */
    1342 SCIP_NODESEL* nodesel, /**< node selector */
    1343 SCIP_DECL_NODESELEXITSOL ((*nodeselexitsol))/**< solving process deinitialization method of node selector */
    1344 )
    1345{
    1346 assert(nodesel != NULL);
    1347
    1348 nodesel->nodeselexitsol = nodeselexitsol;
    1349}
    1350
    1351/** is node selector initialized? */
    1353 SCIP_NODESEL* nodesel /**< node selector */
    1354 )
    1355{
    1356 assert(nodesel != NULL);
    1357
    1358 return nodesel->initialized;
    1359}
    1360
    1361/** enables or disables all clocks of \p nodesel, depending on the value of the flag */
    1363 SCIP_NODESEL* nodesel, /**< the node selector for which all clocks should be enabled or disabled */
    1364 SCIP_Bool enable /**< should the clocks of the node selector be enabled? */
    1365 )
    1366{
    1367 assert(nodesel != NULL);
    1368
    1369 SCIPclockEnableOrDisable(nodesel->setuptime, enable);
    1370 SCIPclockEnableOrDisable(nodesel->nodeseltime, enable);
    1371}
    1372
    1373/** gets time in seconds used in this node selector for setting up for next stages */
    1375 SCIP_NODESEL* nodesel /**< node selector */
    1376 )
    1377{
    1378 assert(nodesel != NULL);
    1379
    1380 return SCIPclockGetTime(nodesel->setuptime);
    1381}
    1382
    1383/** gets time in seconds used in this node selector */
    1385 SCIP_NODESEL* nodesel /**< node selector */
    1386 )
    1387{
    1388 assert(nodesel != NULL);
    1389
    1390 return SCIPclockGetTime(nodesel->nodeseltime);
    1391}
    static long * number
    void SCIPclockStop(SCIP_CLOCK *clck, SCIP_SET *set)
    Definition: clock.c:360
    void SCIPclockEnableOrDisable(SCIP_CLOCK *clck, SCIP_Bool enable)
    Definition: clock.c:260
    void SCIPclockStart(SCIP_CLOCK *clck, SCIP_SET *set)
    Definition: clock.c:290
    SCIP_Real SCIPclockGetTime(SCIP_CLOCK *clck)
    Definition: clock.c:438
    void SCIPclockReset(SCIP_CLOCK *clck)
    Definition: clock.c:209
    void SCIPclockFree(SCIP_CLOCK **clck)
    Definition: clock.c:185
    SCIP_RETCODE SCIPclockCreate(SCIP_CLOCK **clck, SCIP_CLOCKTYPE clocktype)
    Definition: clock.c:170
    internal methods for clocks and timing issues
    common defines and data types used in all packages of SCIP
    #define NULL
    Definition: def.h:248
    #define SCIP_MAXSTRLEN
    Definition: def.h:269
    #define SCIP_Bool
    Definition: def.h:91
    #define SCIP_ALLOC(x)
    Definition: def.h:366
    #define SCIP_Real
    Definition: def.h:156
    #define TRUE
    Definition: def.h:93
    #define FALSE
    Definition: def.h:94
    #define SCIP_CALL(x)
    Definition: def.h:355
    #define SCIP_CALL_FINALLY(x, y)
    Definition: def.h:397
    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
    SCIP_NODETYPE SCIPnodeGetType(SCIP_NODE *node)
    Definition: tree.c:8473
    SCIP_Real SCIPnodeGetLowerbound(SCIP_NODE *node)
    Definition: tree.c:8503
    SCIP_RATIONAL * SCIPnodeGetLowerboundExact(SCIP_NODE *node)
    Definition: tree.c:8513
    int SCIPnodeGetDepth(SCIP_NODE *node)
    Definition: tree.c:8493
    const char * SCIPnodeselGetDesc(SCIP_NODESEL *nodesel)
    Definition: nodesel.c:1205
    SCIP_RETCODE SCIPsetNodeselStdPriority(SCIP *scip, SCIP_NODESEL *nodesel, int priority)
    Definition: scip_nodesel.c:277
    void SCIPnodeselSetData(SCIP_NODESEL *nodesel, SCIP_NODESELDATA *nodeseldata)
    Definition: nodesel.c:1273
    SCIP_Bool SCIPnodeselIsInitialized(SCIP_NODESEL *nodesel)
    Definition: nodesel.c:1352
    SCIP_NODESELDATA * SCIPnodeselGetData(SCIP_NODESEL *nodesel)
    Definition: nodesel.c:1263
    int SCIPnodeselGetMemsavePriority(SCIP_NODESEL *nodesel)
    Definition: nodesel.c:1239
    int SCIPnodeselGetStdPriority(SCIP_NODESEL *nodesel)
    Definition: nodesel.c:1215
    SCIP_Real SCIPnodeselGetSetupTime(SCIP_NODESEL *nodesel)
    Definition: nodesel.c:1374
    SCIP_Real SCIPnodeselGetTime(SCIP_NODESEL *nodesel)
    Definition: nodesel.c:1384
    const char * SCIPnodeselGetName(SCIP_NODESEL *nodesel)
    Definition: nodesel.c:1195
    SCIP_RETCODE SCIPsetNodeselMemsavePriority(SCIP *scip, SCIP_NODESEL *nodesel, int priority)
    Definition: scip_nodesel.c:292
    void SCIPrationalSetInfinity(SCIP_RATIONAL *res)
    Definition: rational.cpp:618
    #define SCIPrationalDebugMessage
    Definition: rational.h:641
    SCIP_Bool SCIPrationalIsLT(SCIP_RATIONAL *rat1, SCIP_RATIONAL *rat2)
    Definition: rational.cpp:1503
    void SCIPrationalSetRational(SCIP_RATIONAL *res, SCIP_RATIONAL *src)
    Definition: rational.cpp:569
    SCIP_Bool SCIPrationalIsGEReal(SCIP_RATIONAL *rat, SCIP_Real real)
    Definition: rational.cpp:1606
    SCIP_Bool SCIPrationalIsLE(SCIP_RATIONAL *rat1, SCIP_RATIONAL *rat2)
    Definition: rational.cpp:1521
    void SCIPsortDownPtr(void **ptrarray, SCIP_DECL_SORTPTRCOMP((*ptrcomp)), int len)
    int SCIPsnprintf(char *t, int len, const char *s,...)
    Definition: misc.c:10827
    SCIP_LPSOLSTAT SCIPlpGetSolstat(SCIP_LP *lp)
    Definition: lp.c:13420
    internal methods for LP management
    static const char * paramname[]
    Definition: lpi_msk.c:5172
    #define BMSfreeMemory(ptr)
    Definition: memory.h:145
    #define BMSreallocMemoryArray(ptr, num)
    Definition: memory.h:127
    #define BMSduplicateMemoryArray(ptr, source, num)
    Definition: memory.h:143
    #define BMSclearMemory(ptr)
    Definition: memory.h:129
    struct BMS_BlkMem BMS_BLKMEM
    Definition: memory.h:437
    #define BMSfreeMemoryArrayNull(ptr)
    Definition: memory.h:148
    #define BMSallocMemory(ptr)
    Definition: memory.h:118
    SCIP_Real SCIPnodepqGetLowerbound(SCIP_NODEPQ *nodepq, SCIP_SET *set)
    Definition: nodesel.c:639
    static SCIP_DECL_SORTPTRCOMP(nodeCompNumber)
    Definition: nodesel.c:68
    void SCIPnodeselSetFree(SCIP_NODESEL *nodesel, SCIP_DECL_NODESELFREE((*nodeselfree)))
    Definition: nodesel.c:1297
    int SCIPnodepqLen(const SCIP_NODEPQ *nodepq)
    Definition: nodesel.c:628
    void SCIPnodepqDestroy(SCIP_NODEPQ **nodepq)
    Definition: nodesel.c:130
    SCIP_RETCODE SCIPnodepqRemove(SCIP_NODEPQ *nodepq, SCIP_SET *set, SCIP_NODE *node)
    Definition: nodesel.c:581
    #define PQ_RIGHTCHILD(p)
    Definition: nodesel.c:63
    SCIP_RETCODE SCIPnodeselExit(SCIP_NODESEL *nodesel, SCIP_SET *set)
    Definition: nodesel.c:1077
    void SCIPnodeselEnableOrDisableClocks(SCIP_NODESEL *nodesel, SCIP_Bool enable)
    Definition: nodesel.c:1362
    void SCIPnodeselSetInitsol(SCIP_NODESEL *nodesel, SCIP_DECL_NODESELINITSOL((*nodeselinitsol)))
    Definition: nodesel.c:1330
    int SCIPnodeselCompare(SCIP_NODESEL *nodesel, SCIP_SET *set, SCIP_NODE *node1, SCIP_NODE *node2)
    Definition: nodesel.c:1178
    SCIP_RETCODE SCIPnodeselCreate(SCIP_NODESEL **nodesel, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, BMS_BLKMEM *blkmem, const char *name, const char *desc, int stdpriority, int memsavepriority, SCIP_DECL_NODESELCOPY((*nodeselcopy)), SCIP_DECL_NODESELFREE((*nodeselfree)), SCIP_DECL_NODESELINIT((*nodeselinit)), SCIP_DECL_NODESELEXIT((*nodeselexit)), SCIP_DECL_NODESELINITSOL((*nodeselinitsol)), SCIP_DECL_NODESELEXITSOL((*nodeselexitsol)), SCIP_DECL_NODESELSELECT((*nodeselselect)), SCIP_DECL_NODESELCOMP((*nodeselcomp)), SCIP_NODESELDATA *nodeseldata)
    Definition: nodesel.c:978
    SCIP_RETCODE SCIPnodeselFree(SCIP_NODESEL **nodesel, SCIP_SET *set)
    Definition: nodesel.c:1012
    static int nodepqFindNode(SCIP_NODEPQ *nodepq, SCIP_SET *set, SCIP_NODE *node)
    Definition: nodesel.c:557
    SCIP_RETCODE SCIPnodeselCopyInclude(SCIP_NODESEL *nodesel, SCIP_SET *set)
    Definition: nodesel.c:892
    SCIP_RATIONAL * SCIPnodepqGetLowerboundExact(SCIP_NODEPQ *nodepq, SCIP_SET *set)
    Definition: nodesel.c:662
    SCIP_RETCODE SCIPnodepqSetNodesel(SCIP_NODEPQ **nodepq, SCIP_SET *set, SCIP_NODESEL *nodesel)
    Definition: nodesel.c:219
    static SCIP_RETCODE nodepqResize(SCIP_NODEPQ *nodepq, SCIP_SET *set, int minsize)
    Definition: nodesel.c:88
    void SCIPnodeselSetCopy(SCIP_NODESEL *nodesel, SCIP_DECL_NODESELCOPY((*nodeselcopy)))
    Definition: nodesel.c:1286
    SCIP_RETCODE SCIPnodeselExitsol(SCIP_NODESEL *nodesel, SCIP_SET *set)
    Definition: nodesel.c:1131
    SCIP_RETCODE SCIPnodepqFree(SCIP_NODEPQ **nodepq, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_TREE *tree, SCIP_LP *lp)
    Definition: nodesel.c:144
    static SCIP_Bool nodepqDelPos(SCIP_NODEPQ *nodepq, SCIP_SET *set, int rempos)
    Definition: nodesel.c:359
    SCIP_RETCODE SCIPnodeselSelect(SCIP_NODESEL *nodesel, SCIP_SET *set, SCIP_NODE **selnode)
    Definition: nodesel.c:1155
    void SCIPnodeselSetStdPriority(SCIP_NODESEL *nodesel, SCIP_SET *set, int priority)
    Definition: nodesel.c:1225
    void SCIPnodeselSetExitsol(SCIP_NODESEL *nodesel, SCIP_DECL_NODESELEXITSOL((*nodeselexitsol)))
    Definition: nodesel.c:1341
    SCIP_NODESEL * SCIPnodepqGetNodesel(SCIP_NODEPQ *nodepq)
    Definition: nodesel.c:209
    #define PQ_PARENT(q)
    Definition: nodesel.c:61
    void SCIPnodeselSetInit(SCIP_NODESEL *nodesel, SCIP_DECL_NODESELINIT((*nodeselinit)))
    Definition: nodesel.c:1308
    SCIP_RETCODE SCIPnodepqInsert(SCIP_NODEPQ *nodepq, SCIP_SET *set, SCIP_NODE *node)
    Definition: nodesel.c:283
    SCIP_NODE * SCIPnodepqFirst(const SCIP_NODEPQ *nodepq)
    Definition: nodesel.c:602
    SCIP_RETCODE SCIPnodepqBound(SCIP_NODEPQ *nodepq, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_TREE *tree, SCIP_REOPT *reopt, SCIP_LP *lp, SCIP_Real cutoffbound)
    Definition: nodesel.c:719
    int SCIPnodepqCompare(SCIP_NODEPQ *nodepq, SCIP_SET *set, SCIP_NODE *node1, SCIP_NODE *node2)
    Definition: nodesel.c:267
    SCIP_RETCODE SCIPnodepqCreate(SCIP_NODEPQ **nodepq, SCIP_SET *set, SCIP_NODESEL *nodesel)
    Definition: nodesel.c:108
    static SCIP_RETCODE doNodeselCreate(SCIP_NODESEL **nodesel, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, BMS_BLKMEM *blkmem, const char *name, const char *desc, int stdpriority, int memsavepriority, SCIP_DECL_NODESELCOPY((*nodeselcopy)), SCIP_DECL_NODESELFREE((*nodeselfree)), SCIP_DECL_NODESELINIT((*nodeselinit)), SCIP_DECL_NODESELEXIT((*nodeselexit)), SCIP_DECL_NODESELINITSOL((*nodeselinitsol)), SCIP_DECL_NODESELEXITSOL((*nodeselexitsol)), SCIP_DECL_NODESELSELECT((*nodeselselect)), SCIP_DECL_NODESELCOMP((*nodeselcomp)), SCIP_NODESELDATA *nodeseldata)
    Definition: nodesel.c:911
    SCIP_Real SCIPnodepqGetLowerboundSum(SCIP_NODEPQ *nodepq)
    Definition: nodesel.c:709
    SCIP_RETCODE SCIPnodeselInitsol(SCIP_NODESEL *nodesel, SCIP_SET *set)
    Definition: nodesel.c:1107
    void SCIPnodeselSetExit(SCIP_NODESEL *nodesel, SCIP_DECL_NODESELEXIT((*nodeselexit)))
    Definition: nodesel.c:1319
    #define PQ_LEFTCHILD(p)
    Definition: nodesel.c:62
    SCIP_NODE ** SCIPnodepqNodes(const SCIP_NODEPQ *nodepq)
    Definition: nodesel.c:618
    SCIP_NODE * SCIPnodepqGetLowerboundNode(SCIP_NODEPQ *nodepq, SCIP_SET *set)
    Definition: nodesel.c:685
    SCIP_RETCODE SCIPnodeselInit(SCIP_NODESEL *nodesel, SCIP_SET *set)
    Definition: nodesel.c:1041
    static SCIP_DECL_PARAMCHGD(paramChgdNodeselStdPriority)
    Definition: nodesel.c:863
    SCIP_RETCODE SCIPnodepqClear(SCIP_NODEPQ *nodepq, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_TREE *tree, SCIP_LP *lp)
    Definition: nodesel.c:168
    void SCIPnodeselSetMemsavePriority(SCIP_NODESEL *nodesel, SCIP_SET *set, int priority)
    Definition: nodesel.c:1249
    internal methods for node selectors and node priority queues
    SCIP_PARAMDATA * SCIPparamGetData(SCIP_PARAM *param)
    Definition: paramset.c:678
    int SCIPparamGetInt(SCIP_PARAM *param)
    Definition: paramset.c:733
    internal methods for handling parameter settings
    internal methods for collecting primal CIP solutions and primal informations
    public methods for message output
    #define SCIPerrorMessage
    Definition: pub_message.h:64
    public data structures and miscellaneous methods
    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
    data structures and methods for collecting reoptimization information
    SCIP callable library.
    SCIP_RETCODE SCIPsetAddIntParam(SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, BMS_BLKMEM *blkmem, const char *name, const char *desc, int *valueptr, SCIP_Bool isadvanced, int defaultvalue, int minvalue, int maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
    Definition: set.c:3229
    int SCIPsetCalcTreeGrowSize(SCIP_SET *set, int num)
    Definition: set.c:6089
    SCIP_Bool SCIPsetIsGE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
    Definition: set.c:6617
    SCIP_Real SCIPsetInfinity(SCIP_SET *set)
    Definition: set.c:6380
    SCIP_Bool SCIPsetIsLT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
    Definition: set.c:6557
    internal methods for global SCIP settings
    #define SCIPsetDebugMsg
    Definition: set.h:1811
    void SCIPstatUpdatePrimalDualIntegrals(SCIP_STAT *stat, SCIP_SET *set, SCIP_PROB *transprob, SCIP_PROB *origprob, SCIP_Real upperbound, SCIP_Real lowerbound)
    Definition: stat.c:513
    internal methods for problem statistics
    SCIP_NODE ** slots
    SCIP_Real lowerboundsum
    SCIP_NODESEL * nodesel
    unsigned int cutoff
    Definition: struct_tree.h:166
    SCIP_Real lowerbound
    Definition: struct_tree.h:144
    SCIP_RATIONAL * lowerboundexact
    Definition: struct_tree.h:145
    SCIP_Real estimate
    Definition: struct_tree.h:146
    unsigned int depth
    Definition: struct_tree.h:161
    unsigned int active
    Definition: struct_tree.h:165
    SCIP_Bool initialized
    SCIP_CLOCK * setuptime
    SCIP_NODESELDATA * nodeseldata
    SCIP_CLOCK * nodeseltime
    SCIP_Real rootlowerbound
    Definition: struct_stat.h:133
    SCIP_RATIONAL * lastlowerboundexact
    Definition: struct_stat.h:156
    SCIP_Real lastlowerbound
    Definition: struct_stat.h:155
    SCIP_VISUAL * visual
    Definition: struct_stat.h:198
    SCIP_NODE * root
    Definition: struct_tree.h:188
    SCIP_NODE * focusnode
    Definition: struct_tree.h:193
    int effectiverootdepth
    Definition: struct_tree.h:231
    datastructures for managing events
    data structures for node selectors and node priority queues
    SCIP main data structure.
    Definition: heur_padm.c:135
    SCIP_RATIONAL * SCIPtreeGetLowerboundExact(SCIP_TREE *tree, SCIP_SET *set)
    Definition: tree.c:8265
    SCIP_RETCODE SCIPnodeFree(SCIP_NODE **node, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_TREE *tree, SCIP_LP *lp)
    Definition: tree.c:1115
    SCIP_Real SCIPtreeGetLowerbound(SCIP_TREE *tree, SCIP_SET *set)
    Definition: tree.c:8224
    internal methods for branch and bound tree
    @ SCIP_CLOCKTYPE_DEFAULT
    Definition: type_clock.h:43
    #define SCIP_EVENTTYPE_NODEINFEASIBLE
    Definition: type_event.h:95
    #define SCIP_EVENTTYPE_DUALBOUNDIMPROVED
    Definition: type_event.h:98
    #define SCIP_DECL_NODESELEXIT(x)
    Definition: type_nodesel.h:86
    #define SCIP_DECL_NODESELCOMP(x)
    Definition: type_nodesel.h:140
    #define SCIP_DECL_NODESELINITSOL(x)
    Definition: type_nodesel.h:97
    #define SCIP_DECL_NODESELCOPY(x)
    Definition: type_nodesel.h:61
    #define SCIP_DECL_NODESELEXITSOL(x)
    Definition: type_nodesel.h:108
    #define SCIP_DECL_NODESELINIT(x)
    Definition: type_nodesel.h:78
    #define SCIP_DECL_NODESELSELECT(x)
    Definition: type_nodesel.h:123
    #define SCIP_DECL_NODESELFREE(x)
    Definition: type_nodesel.h:70
    struct SCIP_NodeselData SCIP_NODESELDATA
    Definition: type_nodesel.h:52
    struct SCIP_ParamData SCIP_PARAMDATA
    Definition: type_paramset.h:87
    @ SCIP_INVALIDDATA
    Definition: type_retcode.h:52
    @ SCIP_OKAY
    Definition: type_retcode.h:42
    @ SCIP_INVALIDCALL
    Definition: type_retcode.h:51
    enum SCIP_Retcode SCIP_RETCODE
    Definition: type_retcode.h:63
    @ SCIP_NODETYPE_LEAF
    Definition: type_tree.h:45
    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)