Scippy

SCIP

Solving Constraint Integer Programs

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