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