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-2024 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;
701
702 if( node->depth == 0 )
704
705 /* update primal-dual integrals */
706 if( set->misc_calcintegral )
707 {
708 SCIP_Real lowerbound = SCIPtreeGetLowerbound(tree, set);
709
710 assert(lowerbound <= SCIPsetInfinity(set));
711
712 /* updating the primal integral is only necessary if lower bound has increased since last evaluation */
713 if( lowerbound > stat->lastlowerbound )
714 SCIPstatUpdatePrimalDualIntegrals(stat, set, set->scip->transprob, set->scip->origprob, SCIPsetInfinity(set), lowerbound);
715 }
716
717 SCIPvisualCutoffNode(stat->visual, set, stat, node, TRUE);
718
719 /* free node memory */
720 SCIP_CALL( SCIPnodeFree(&node, blkmem, set, stat, eventfilter, eventqueue, tree, lp) );
721 }
722 else
723 --pos;
724 }
725
726 SCIPsetDebugMsg(set, " -> bounded node queue has length %d\n", nodepq->len);
727
728 return SCIP_OKAY;
729}
730
731
732/*
733 * node selector methods
734 */
735
736/** method to call, when the standard mode priority of a node selector was changed */
737static
738SCIP_DECL_PARAMCHGD(paramChgdNodeselStdPriority)
739{ /*lint --e{715}*/
740 SCIP_PARAMDATA* paramdata;
741
742 paramdata = SCIPparamGetData(param);
743 assert(paramdata != NULL);
744
745 /* use SCIPsetNodeselStdPriority() to mark the nodesels unsorted */
746 SCIP_CALL( SCIPsetNodeselStdPriority(scip, (SCIP_NODESEL*)paramdata, SCIPparamGetInt(param)) ); /*lint !e740*/
747
748 return SCIP_OKAY;
749}
750
751/** method to call, when the memory saving mode priority of a node selector was changed */
752static
753SCIP_DECL_PARAMCHGD(paramChgdNodeselMemsavePriority)
754{ /*lint --e{715}*/
755 SCIP_PARAMDATA* paramdata;
756
757 paramdata = SCIPparamGetData(param);
758 assert(paramdata != NULL);
759
760 /* use SCIPsetNodeselMemsavePriority() to mark the nodesels unsorted */
761 SCIP_CALL( SCIPsetNodeselMemsavePriority(scip, (SCIP_NODESEL*)paramdata, SCIPparamGetInt(param)) ); /*lint !e740*/
762
763 return SCIP_OKAY;
764}
765
766/** copies the given node selector to a new scip */
768 SCIP_NODESEL* nodesel, /**< node selector */
769 SCIP_SET* set /**< SCIP_SET of SCIP to copy to */
770 )
771{
772 assert(nodesel != NULL);
773 assert(set != NULL);
774 assert(set->scip != NULL);
775
776 if( nodesel->nodeselcopy != NULL )
777 {
778 SCIPsetDebugMsg(set, "including node selector %s in subscip %p\n", SCIPnodeselGetName(nodesel), (void*)set->scip);
779 SCIP_CALL( nodesel->nodeselcopy(set->scip, nodesel) );
780 }
781 return SCIP_OKAY;
782}
783
784/** internal method for creating a node selector */
785static
787 SCIP_NODESEL** nodesel, /**< pointer to store node selector */
788 SCIP_SET* set, /**< global SCIP settings */
789 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
790 BMS_BLKMEM* blkmem, /**< block memory for parameter settings */
791 const char* name, /**< name of node selector */
792 const char* desc, /**< description of node selector */
793 int stdpriority, /**< priority of the node selector in standard mode */
794 int memsavepriority, /**< priority of the node selector in memory saving mode */
795 SCIP_DECL_NODESELCOPY ((*nodeselcopy)), /**< copy method of node selector or NULL if you don't want to copy your plugin into sub-SCIPs */
796 SCIP_DECL_NODESELFREE ((*nodeselfree)), /**< destructor of node selector */
797 SCIP_DECL_NODESELINIT ((*nodeselinit)), /**< initialize node selector */
798 SCIP_DECL_NODESELEXIT ((*nodeselexit)), /**< deinitialize node selector */
799 SCIP_DECL_NODESELINITSOL((*nodeselinitsol)),/**< solving process initialization method of node selector */
800 SCIP_DECL_NODESELEXITSOL((*nodeselexitsol)),/**< solving process deinitialization method of node selector */
801 SCIP_DECL_NODESELSELECT((*nodeselselect)),/**< node selection method */
802 SCIP_DECL_NODESELCOMP ((*nodeselcomp)), /**< node comparison method */
803 SCIP_NODESELDATA* nodeseldata /**< node selector data */
804 )
805{
807 char paramdesc[SCIP_MAXSTRLEN];
808
809 assert(nodesel != NULL);
810 assert(name != NULL);
811 assert(desc != NULL);
812 assert(nodeselselect != NULL);
813 assert(nodeselcomp != NULL);
814
815 SCIP_ALLOC( BMSallocMemory(nodesel) );
816 BMSclearMemory(*nodesel);
817
818 SCIP_ALLOC( BMSduplicateMemoryArray(&(*nodesel)->name, name, strlen(name)+1) );
819 SCIP_ALLOC( BMSduplicateMemoryArray(&(*nodesel)->desc, desc, strlen(desc)+1) );
820 (*nodesel)->stdpriority = stdpriority;
821 (*nodesel)->memsavepriority = memsavepriority;
822 (*nodesel)->nodeselcopy = nodeselcopy;
823 (*nodesel)->nodeselfree = nodeselfree;
824 (*nodesel)->nodeselinit = nodeselinit;
825 (*nodesel)->nodeselexit = nodeselexit;
826 (*nodesel)->nodeselinitsol = nodeselinitsol;
827 (*nodesel)->nodeselexitsol = nodeselexitsol;
828 (*nodesel)->nodeselselect = nodeselselect;
829 (*nodesel)->nodeselcomp = nodeselcomp;
830 (*nodesel)->nodeseldata = nodeseldata;
831 (*nodesel)->initialized = FALSE;
832 /* create clocks */
833 SCIP_CALL( SCIPclockCreate(&(*nodesel)->setuptime, SCIP_CLOCKTYPE_DEFAULT) );
834 SCIP_CALL( SCIPclockCreate(&(*nodesel)->nodeseltime, SCIP_CLOCKTYPE_DEFAULT) );
835
836 /* add parameters */
837 (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "nodeselection/%s/stdpriority", name);
838 (void) SCIPsnprintf(paramdesc, SCIP_MAXSTRLEN, "priority of node selection rule <%s> in standard mode", name);
839 SCIP_CALL( SCIPsetAddIntParam(set, messagehdlr, blkmem, paramname, paramdesc,
840 &(*nodesel)->stdpriority, FALSE, stdpriority, INT_MIN/4, INT_MAX/2,
841 paramChgdNodeselStdPriority, (SCIP_PARAMDATA*)(*nodesel)) ); /*lint !e740*/
842
843 (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "nodeselection/%s/memsavepriority", name);
844 (void) SCIPsnprintf(paramdesc, SCIP_MAXSTRLEN, "priority of node selection rule <%s> in memory saving mode", name);
845 SCIP_CALL( SCIPsetAddIntParam(set, messagehdlr, blkmem, paramname, paramdesc,
846 &(*nodesel)->memsavepriority, TRUE, memsavepriority, INT_MIN/4, INT_MAX/4,
847 paramChgdNodeselMemsavePriority, (SCIP_PARAMDATA*)(*nodesel)) ); /*lint !e740*/
848
849 return SCIP_OKAY;
850}
851
852/** creates a node selector */
854 SCIP_NODESEL** nodesel, /**< pointer to store node selector */
855 SCIP_SET* set, /**< global SCIP settings */
856 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
857 BMS_BLKMEM* blkmem, /**< block memory for parameter settings */
858 const char* name, /**< name of node selector */
859 const char* desc, /**< description of node selector */
860 int stdpriority, /**< priority of the node selector in standard mode */
861 int memsavepriority, /**< priority of the node selector in memory saving mode */
862 SCIP_DECL_NODESELCOPY ((*nodeselcopy)), /**< copy method of node selector or NULL if you don't want to copy your plugin into sub-SCIPs */
863 SCIP_DECL_NODESELFREE ((*nodeselfree)), /**< destructor of node selector */
864 SCIP_DECL_NODESELINIT ((*nodeselinit)), /**< initialize node selector */
865 SCIP_DECL_NODESELEXIT ((*nodeselexit)), /**< deinitialize node selector */
866 SCIP_DECL_NODESELINITSOL((*nodeselinitsol)),/**< solving process initialization method of node selector */
867 SCIP_DECL_NODESELEXITSOL((*nodeselexitsol)),/**< solving process deinitialization method of node selector */
868 SCIP_DECL_NODESELSELECT((*nodeselselect)),/**< node selection method */
869 SCIP_DECL_NODESELCOMP ((*nodeselcomp)), /**< node comparison method */
870 SCIP_NODESELDATA* nodeseldata /**< node selector data */
871 )
872{
873 assert(nodesel != NULL);
874 assert(name != NULL);
875 assert(desc != NULL);
876 assert(nodeselselect != NULL);
877 assert(nodeselcomp != NULL);
878
879 SCIP_CALL_FINALLY( doNodeselCreate(nodesel, set, messagehdlr, blkmem, name, desc, stdpriority, memsavepriority,
880 nodeselcopy, nodeselfree, nodeselinit, nodeselexit, nodeselinitsol, nodeselexitsol, nodeselselect, nodeselcomp,
881 nodeseldata), (void) SCIPnodeselFree(nodesel, set) );
882
883 return SCIP_OKAY;
884}
885
886/** frees memory of node selector */
888 SCIP_NODESEL** nodesel, /**< pointer to node selector data structure */
889 SCIP_SET* set /**< global SCIP settings */
890 )
891{
892 assert(nodesel != NULL);
893 if( *nodesel == NULL )
894 return SCIP_OKAY;
895 assert(!(*nodesel)->initialized);
896 assert(set != NULL);
897
898 /* call destructor of node selector */
899 if( (*nodesel)->nodeselfree != NULL )
900 {
901 SCIP_CALL( (*nodesel)->nodeselfree(set->scip, *nodesel) );
902 }
903
904 /* free clocks */
905 SCIPclockFree(&(*nodesel)->nodeseltime);
906 SCIPclockFree(&(*nodesel)->setuptime);
907
908 BMSfreeMemoryArrayNull(&(*nodesel)->name);
909 BMSfreeMemoryArrayNull(&(*nodesel)->desc);
910 BMSfreeMemory(nodesel);
911
912 return SCIP_OKAY;
913}
914
915/** initializes node selector */
917 SCIP_NODESEL* nodesel, /**< node selector */
918 SCIP_SET* set /**< global SCIP settings */
919 )
920{
921 assert(nodesel != NULL);
922 assert(set != NULL);
923
924 if( nodesel->initialized )
925 {
926 SCIPerrorMessage("node selector <%s> already initialized", nodesel->name);
927 return SCIP_INVALIDCALL;
928 }
929
930 if( set->misc_resetstat )
931 {
932 SCIPclockReset(nodesel->setuptime);
933 SCIPclockReset(nodesel->nodeseltime);
934 }
935
936 if( nodesel->nodeselinit != NULL )
937 {
938 /* start timing */
939 SCIPclockStart(nodesel->setuptime, set);
940
941 SCIP_CALL( nodesel->nodeselinit(set->scip, nodesel) );
942
943 /* stop timing */
944 SCIPclockStop(nodesel->setuptime, set);
945 }
946 nodesel->initialized = TRUE;
947
948 return SCIP_OKAY;
949}
950
951/** deinitializes node selector */
953 SCIP_NODESEL* nodesel, /**< node selector */
954 SCIP_SET* set /**< global SCIP settings */
955 )
956{
957 assert(nodesel != NULL);
958 assert(set != NULL);
959
960 if( !nodesel->initialized )
961 {
962 SCIPerrorMessage("node selector <%s> not initialized", nodesel->name);
963 return SCIP_INVALIDCALL;
964 }
965
966 if( nodesel->nodeselexit != NULL )
967 {
968 /* start timing */
969 SCIPclockStart(nodesel->setuptime, set);
970
971 SCIP_CALL( nodesel->nodeselexit(set->scip, nodesel) );
972
973 /* stop timing */
974 SCIPclockStop(nodesel->setuptime, set);
975 }
976 nodesel->initialized = FALSE;
977
978 return SCIP_OKAY;
979}
980
981/** informs node selector that the branch and bound process is being started */
983 SCIP_NODESEL* nodesel, /**< node selector */
984 SCIP_SET* set /**< global SCIP settings */
985 )
986{
987 assert(nodesel != NULL);
988 assert(set != NULL);
989
990 /* call solving process initialization method of node selector */
991 if( nodesel->nodeselinitsol != NULL )
992 {
993 /* start timing */
994 SCIPclockStart(nodesel->setuptime, set);
995
996 SCIP_CALL( nodesel->nodeselinitsol(set->scip, nodesel) );
997
998 /* stop timing */
999 SCIPclockStop(nodesel->setuptime, set);
1000 }
1001
1002 return SCIP_OKAY;
1003}
1004
1005/** informs node selector that the branch and bound process data is being freed */
1007 SCIP_NODESEL* nodesel, /**< node selector */
1008 SCIP_SET* set /**< global SCIP settings */
1009 )
1010{
1011 assert(nodesel != NULL);
1012 assert(set != NULL);
1013
1014 /* call solving process deinitialization method of node selector */
1015 if( nodesel->nodeselexitsol != NULL )
1016 {
1017 /* start timing */
1018 SCIPclockStart(nodesel->setuptime, set);
1019
1020 SCIP_CALL( nodesel->nodeselexitsol(set->scip, nodesel) );
1021
1022 /* stop timing */
1023 SCIPclockStop(nodesel->setuptime, set);
1024 }
1025
1026 return SCIP_OKAY;
1027}
1028
1029/** select next node to be processed */
1031 SCIP_NODESEL* nodesel, /**< node selector */
1032 SCIP_SET* set, /**< global SCIP settings */
1033 SCIP_NODE** selnode /**< pointer to store node to be processed next */
1034 )
1035{
1036 assert(nodesel != NULL);
1037 assert(nodesel->nodeselselect != NULL);
1038 assert(set != NULL);
1039 assert(selnode != NULL);
1040
1041 /* start timing */
1042 SCIPclockStart(nodesel->nodeseltime, set);
1043
1044 SCIP_CALL( nodesel->nodeselselect(set->scip, nodesel, selnode) );
1045
1046 /* stop timing */
1047 SCIPclockStop(nodesel->nodeseltime, set);
1048
1049 return SCIP_OKAY;
1050}
1051
1052/** compares two nodes; returns -1/0/+1 if node1 better/equal/worse than node2 */
1054 SCIP_NODESEL* nodesel, /**< node selector */
1055 SCIP_SET* set, /**< global SCIP settings */
1056 SCIP_NODE* node1, /**< first node to compare */
1057 SCIP_NODE* node2 /**< second node to compare */
1058 )
1059{
1060 assert(nodesel != NULL);
1061 assert(nodesel->nodeselcomp != NULL);
1062 assert(set != NULL);
1063 assert(node1 != NULL);
1064 assert(node2 != NULL);
1065
1066 return nodesel->nodeselcomp(set->scip, nodesel, node1, node2);
1067}
1068
1069/** gets name of node selector */
1071 SCIP_NODESEL* nodesel /**< node selector */
1072 )
1073{
1074 assert(nodesel != NULL);
1075
1076 return nodesel->name;
1077}
1078
1079/** gets description of node selector */
1081 SCIP_NODESEL* nodesel /**< node selector */
1082 )
1083{
1084 assert(nodesel != NULL);
1085
1086 return nodesel->desc;
1087}
1088
1089/** gets priority of node selector in standard mode */
1091 SCIP_NODESEL* nodesel /**< node selector */
1092 )
1093{
1094 assert(nodesel != NULL);
1095
1096 return nodesel->stdpriority;
1097}
1098
1099/** gets priority of node selector in standard mode */
1101 SCIP_NODESEL* nodesel, /**< node selector */
1102 SCIP_SET* set, /**< global SCIP settings */
1103 int priority /**< new priority of the node selector */
1104 )
1105{
1106 assert(nodesel != NULL);
1107 assert(set != NULL);
1108
1109 nodesel->stdpriority = priority;
1110 set->nodesel = NULL;
1111}
1112
1113/** gets priority of node selector in memory saving mode */
1115 SCIP_NODESEL* nodesel /**< node selector */
1116 )
1117{
1118 assert(nodesel != NULL);
1119
1120 return nodesel->memsavepriority;
1121}
1122
1123/** sets priority of node selector in memory saving mode */
1125 SCIP_NODESEL* nodesel, /**< node selector */
1126 SCIP_SET* set, /**< global SCIP settings */
1127 int priority /**< new priority of the node selector */
1128 )
1129{
1130 assert(nodesel != NULL);
1131 assert(set != NULL);
1132
1133 nodesel->memsavepriority = priority;
1134 set->nodesel = NULL;
1135}
1136
1137/** gets user data of node selector */
1139 SCIP_NODESEL* nodesel /**< node selector */
1140 )
1141{
1142 assert(nodesel != NULL);
1143
1144 return nodesel->nodeseldata;
1145}
1146
1147/** sets user data of node selector; user has to free old data in advance! */
1149 SCIP_NODESEL* nodesel, /**< node selector */
1150 SCIP_NODESELDATA* nodeseldata /**< new node selector user data */
1151 )
1152{
1153 assert(nodesel != NULL);
1154
1155 nodesel->nodeseldata = nodeseldata;
1156}
1157
1158/* new callback/method setter methods */
1159
1160/** sets copy method of node selector */
1162 SCIP_NODESEL* nodesel, /**< node selector */
1163 SCIP_DECL_NODESELCOPY ((*nodeselcopy)) /**< copy method of node selector or NULL if you don't want to copy your plugin into sub-SCIPs */
1164 )
1165{
1166 assert(nodesel != NULL);
1167
1168 nodesel->nodeselcopy = nodeselcopy;
1169}
1170
1171/** sets destructor method of node selector */
1173 SCIP_NODESEL* nodesel, /**< node selector */
1174 SCIP_DECL_NODESELFREE ((*nodeselfree)) /**< destructor of node selector */
1175 )
1176{
1177 assert(nodesel != NULL);
1178
1179 nodesel->nodeselfree = nodeselfree;
1180}
1181
1182/** sets initialization method of node selector */
1184 SCIP_NODESEL* nodesel, /**< node selector */
1185 SCIP_DECL_NODESELINIT ((*nodeselinit)) /**< initialize node selector */
1186 )
1187{
1188 assert(nodesel != NULL);
1189
1190 nodesel->nodeselinit = nodeselinit;
1191}
1192
1193/** sets deinitialization method of node selector */
1195 SCIP_NODESEL* nodesel, /**< node selector */
1196 SCIP_DECL_NODESELEXIT ((*nodeselexit)) /**< deinitialize node selector */
1197 )
1198{
1199 assert(nodesel != NULL);
1200
1201 nodesel->nodeselexit = nodeselexit;
1202}
1203
1204/** sets solving process initialization method of node selector */
1206 SCIP_NODESEL* nodesel, /**< node selector */
1207 SCIP_DECL_NODESELINITSOL ((*nodeselinitsol))/**< solving process initialization method of node selector */
1208 )
1209{
1210 assert(nodesel != NULL);
1211
1212 nodesel->nodeselinitsol = nodeselinitsol;
1213}
1214
1215/** sets solving process deinitialization method of node selector */
1217 SCIP_NODESEL* nodesel, /**< node selector */
1218 SCIP_DECL_NODESELEXITSOL ((*nodeselexitsol))/**< solving process deinitialization method of node selector */
1219 )
1220{
1221 assert(nodesel != NULL);
1222
1223 nodesel->nodeselexitsol = nodeselexitsol;
1224}
1225
1226/** is node selector initialized? */
1228 SCIP_NODESEL* nodesel /**< node selector */
1229 )
1230{
1231 assert(nodesel != NULL);
1232
1233 return nodesel->initialized;
1234}
1235
1236/** enables or disables all clocks of \p nodesel, depending on the value of the flag */
1238 SCIP_NODESEL* nodesel, /**< the node selector for which all clocks should be enabled or disabled */
1239 SCIP_Bool enable /**< should the clocks of the node selector be enabled? */
1240 )
1241{
1242 assert(nodesel != NULL);
1243
1244 SCIPclockEnableOrDisable(nodesel->setuptime, enable);
1245 SCIPclockEnableOrDisable(nodesel->nodeseltime, enable);
1246}
1247
1248/** gets time in seconds used in this node selector for setting up for next stages */
1250 SCIP_NODESEL* nodesel /**< node selector */
1251 )
1252{
1253 assert(nodesel != NULL);
1254
1255 return SCIPclockGetTime(nodesel->setuptime);
1256}
1257
1258/** gets time in seconds used in this node selector */
1260 SCIP_NODESEL* nodesel /**< node selector */
1261 )
1262{
1263 assert(nodesel != NULL);
1264
1265 return SCIPclockGetTime(nodesel->nodeseltime);
1266}
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:7500
SCIP_Real SCIPnodeGetLowerbound(SCIP_NODE *node)
Definition: tree.c:7530
int SCIPnodeGetDepth(SCIP_NODE *node)
Definition: tree.c:7520
const char * SCIPnodeselGetDesc(SCIP_NODESEL *nodesel)
Definition: nodesel.c:1080
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:1148
SCIP_Bool SCIPnodeselIsInitialized(SCIP_NODESEL *nodesel)
Definition: nodesel.c:1227
SCIP_NODESELDATA * SCIPnodeselGetData(SCIP_NODESEL *nodesel)
Definition: nodesel.c:1138
int SCIPnodeselGetMemsavePriority(SCIP_NODESEL *nodesel)
Definition: nodesel.c:1114
int SCIPnodeselGetStdPriority(SCIP_NODESEL *nodesel)
Definition: nodesel.c:1090
SCIP_Real SCIPnodeselGetSetupTime(SCIP_NODESEL *nodesel)
Definition: nodesel.c:1249
SCIP_Real SCIPnodeselGetTime(SCIP_NODESEL *nodesel)
Definition: nodesel.c:1259
const char * SCIPnodeselGetName(SCIP_NODESEL *nodesel)
Definition: nodesel.c:1070
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:1172
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:952
void SCIPnodeselEnableOrDisableClocks(SCIP_NODESEL *nodesel, SCIP_Bool enable)
Definition: nodesel.c:1237
void SCIPnodeselSetInitsol(SCIP_NODESEL *nodesel, SCIP_DECL_NODESELINITSOL((*nodeselinitsol)))
Definition: nodesel.c:1205
int SCIPnodeselCompare(SCIP_NODESEL *nodesel, SCIP_SET *set, SCIP_NODE *node1, SCIP_NODE *node2)
Definition: nodesel.c:1053
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:853
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:887
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:767
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:1161
SCIP_RETCODE SCIPnodeselExitsol(SCIP_NODESEL *nodesel, SCIP_SET *set)
Definition: nodesel.c:1006
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:1030
void SCIPnodeselSetStdPriority(SCIP_NODESEL *nodesel, SCIP_SET *set, int priority)
Definition: nodesel.c:1100
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:1216
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:1183
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:786
SCIP_Real SCIPnodepqGetLowerboundSum(SCIP_NODEPQ *nodepq)
Definition: nodesel.c:629
SCIP_RETCODE SCIPnodeselInitsol(SCIP_NODESEL *nodesel, SCIP_SET *set)
Definition: nodesel.c:982
void SCIPnodeselSetExit(SCIP_NODESEL *nodesel, SCIP_DECL_NODESELEXIT((*nodeselexit)))
Definition: nodesel.c:1194
#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:916
static SCIP_DECL_PARAMCHGD(paramChgdNodeselStdPriority)
Definition: nodesel.c:738
void SCIPnodeselSetMemsavePriority(SCIP_NODESEL *nodesel, SCIP_SET *set, int priority)
Definition: nodesel.c:1124
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
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:7323
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)