1    	/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2    	/*                                                                           */
3    	/*                  This file is part of the program and library             */
4    	/*         SCIP --- Solving Constraint Integer Programs                      */
5    	/*                                                                           */
6    	/*  Copyright (c) 2002-2023 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   tree.c
26   	 * @ingroup OTHER_CFILES
27   	 * @brief  methods for branch and bound tree
28   	 * @author Tobias Achterberg
29   	 * @author Timo Berthold
30   	 * @author Gerald Gamrath
31   	 */
32   	
33   	/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
34   	
35   	#include <assert.h>
36   	
37   	#include "scip/def.h"
38   	#include "scip/set.h"
39   	#include "scip/stat.h"
40   	#include "scip/clock.h"
41   	#include "scip/visual.h"
42   	#include "scip/event.h"
43   	#include "scip/lp.h"
44   	#include "scip/relax.h"
45   	#include "scip/var.h"
46   	#include "scip/implics.h"
47   	#include "scip/primal.h"
48   	#include "scip/tree.h"
49   	#include "scip/reopt.h"
50   	#include "scip/conflictstore.h"
51   	#include "scip/solve.h"
52   	#include "scip/cons.h"
53   	#include "scip/nodesel.h"
54   	#include "scip/prop.h"
55   	#include "scip/debug.h"
56   	#include "scip/prob.h"
57   	#include "scip/scip.h"
58   	#include "scip/struct_event.h"
59   	#include "scip/pub_message.h"
60   	#include "scip/struct_branch.h"
61   	#include "lpi/lpi.h"
62   	
63   	
64   	#define MAXREPROPMARK       511  /**< maximal subtree repropagation marker; must correspond to node data structure */
65   	
66   	
67   	/*
68   	 * dynamic memory arrays
69   	 */
70   	
71   	/** resizes children arrays to be able to store at least num nodes */
72   	static
73   	SCIP_RETCODE treeEnsureChildrenMem(
74   	   SCIP_TREE*            tree,               /**< branch and bound tree */
75   	   SCIP_SET*             set,                /**< global SCIP settings */
76   	   int                   num                 /**< minimal number of node slots in array */
77   	   )
78   	{
79   	   assert(tree != NULL);
80   	   assert(set != NULL);
81   	
82   	   if( num > tree->childrensize )
83   	   {
84   	      int newsize;
85   	
86   	      newsize = SCIPsetCalcMemGrowSize(set, num);
87   	      SCIP_ALLOC( BMSreallocMemoryArray(&tree->children, newsize) );
88   	      SCIP_ALLOC( BMSreallocMemoryArray(&tree->childrenprio, newsize) );
89   	      tree->childrensize = newsize;
90   	   }
91   	   assert(num <= tree->childrensize);
92   	
93   	   return SCIP_OKAY;
94   	}
95   	
96   	/** resizes path array to be able to store at least num nodes */
97   	static
98   	SCIP_RETCODE treeEnsurePathMem(
99   	   SCIP_TREE*            tree,               /**< branch and bound tree */
100  	   SCIP_SET*             set,                /**< global SCIP settings */
101  	   int                   num                 /**< minimal number of node slots in path */
102  	   )
103  	{
104  	   assert(tree != NULL);
105  	   assert(set != NULL);
106  	
107  	   if( num > tree->pathsize )
108  	   {
109  	      int newsize;
110  	
111  	      newsize = SCIPsetCalcPathGrowSize(set, num);
112  	      SCIP_ALLOC( BMSreallocMemoryArray(&tree->path, newsize) );
113  	      SCIP_ALLOC( BMSreallocMemoryArray(&tree->pathnlpcols, newsize) );
114  	      SCIP_ALLOC( BMSreallocMemoryArray(&tree->pathnlprows, newsize) );
115  	      tree->pathsize = newsize;
116  	   }
117  	   assert(num <= tree->pathsize);
118  	
119  	   return SCIP_OKAY;
120  	}
121  	
122  	/** resizes pendingbdchgs array to be able to store at least num nodes */
123  	static
124  	SCIP_RETCODE treeEnsurePendingbdchgsMem(
125  	   SCIP_TREE*            tree,               /**< branch and bound tree */
126  	   SCIP_SET*             set,                /**< global SCIP settings */
127  	   int                   num                 /**< minimal number of node slots in path */
128  	   )
129  	{
130  	   assert(tree != NULL);
131  	   assert(set != NULL);
132  	
133  	   if( num > tree->pendingbdchgssize )
134  	   {
135  	      int newsize;
136  	
137  	      newsize = SCIPsetCalcMemGrowSize(set, num);
138  	      SCIP_ALLOC( BMSreallocMemoryArray(&tree->pendingbdchgs, newsize) );
139  	      tree->pendingbdchgssize = newsize;
140  	   }
141  	   assert(num <= tree->pendingbdchgssize);
142  	
143  	   return SCIP_OKAY;
144  	}
145  	
146  	
147  	
148  	
149  	/*
150  	 * Node methods
151  	 */
152  	
153  	/** node comparator for best lower bound */
154  	SCIP_DECL_SORTPTRCOMP(SCIPnodeCompLowerbound)
155  	{  /*lint --e{715}*/
156  	   assert(elem1 != NULL);
157  	   assert(elem2 != NULL);
158  	
159  	   if( ((SCIP_NODE*)elem1)->lowerbound < ((SCIP_NODE*)elem2)->lowerbound )
160  	      return -1;
161  	   else if( ((SCIP_NODE*)elem1)->lowerbound > ((SCIP_NODE*)elem2)->lowerbound )
162  	      return +1;
163  	   else
164  	      return 0;
165  	}
166  	
167  	/** increases the reference counter of the LP state in the fork */
168  	static
169  	void forkCaptureLPIState(
170  	   SCIP_FORK*            fork,               /**< fork data */
171  	   int                   nuses               /**< number to add to the usage counter */
172  	   )
173  	{
174  	   assert(fork != NULL);
175  	   assert(fork->nlpistateref >= 0);
176  	   assert(nuses > 0);
177  	
178  	   fork->nlpistateref += nuses;
179  	   SCIPdebugMessage("captured LPI state of fork %p %d times -> new nlpistateref=%d\n", (void*)fork, nuses, fork->nlpistateref);
180  	}
181  	
182  	/** decreases the reference counter of the LP state in the fork */
183  	static
184  	SCIP_RETCODE forkReleaseLPIState(
185  	   SCIP_FORK*            fork,               /**< fork data */
186  	   BMS_BLKMEM*           blkmem,             /**< block memory buffers */
187  	   SCIP_LP*              lp                  /**< current LP data */
188  	   )
189  	{
190  	   assert(fork != NULL);
191  	   assert(fork->nlpistateref > 0);
192  	   assert(blkmem != NULL);
193  	   assert(lp != NULL);
194  	
195  	   fork->nlpistateref--;
196  	   if( fork->nlpistateref == 0 )
197  	   {
198  	      SCIP_CALL( SCIPlpFreeState(lp, blkmem, &(fork->lpistate)) );
199  	   }
200  	
201  	   SCIPdebugMessage("released LPI state of fork %p -> new nlpistateref=%d\n", (void*)fork, fork->nlpistateref);
202  	
203  	   return SCIP_OKAY;
204  	}
205  	
206  	/** increases the reference counter of the LP state in the subroot */
207  	static
208  	void subrootCaptureLPIState(
209  	   SCIP_SUBROOT*         subroot,            /**< subroot data */
210  	   int                   nuses               /**< number to add to the usage counter */
211  	   )
212  	{
213  	   assert(subroot != NULL);
214  	   assert(subroot->nlpistateref >= 0);
215  	   assert(nuses > 0);
216  	
217  	   subroot->nlpistateref += nuses;
218  	   SCIPdebugMessage("captured LPI state of subroot %p %d times -> new nlpistateref=%d\n", 
219  	      (void*)subroot, nuses, subroot->nlpistateref);
220  	}
221  	
222  	/** decreases the reference counter of the LP state in the subroot */
223  	static
224  	SCIP_RETCODE subrootReleaseLPIState(
225  	   SCIP_SUBROOT*         subroot,            /**< subroot data */
226  	   BMS_BLKMEM*           blkmem,             /**< block memory buffers */
227  	   SCIP_LP*              lp                  /**< current LP data */
228  	   )
229  	{
230  	   assert(subroot != NULL);
231  	   assert(subroot->nlpistateref > 0);
232  	   assert(blkmem != NULL);
233  	   assert(lp != NULL);
234  	
235  	   subroot->nlpistateref--;
236  	   if( subroot->nlpistateref == 0 )
237  	   {
238  	      SCIP_CALL( SCIPlpFreeState(lp, blkmem, &(subroot->lpistate)) );
239  	   }
240  	
241  	   SCIPdebugMessage("released LPI state of subroot %p -> new nlpistateref=%d\n", (void*)subroot, subroot->nlpistateref);
242  	
243  	   return SCIP_OKAY;
244  	}
245  	
246  	/** increases the reference counter of the LP state in the fork or subroot node */
247  	SCIP_RETCODE SCIPnodeCaptureLPIState(
248  	   SCIP_NODE*            node,               /**< fork/subroot node */
249  	   int                   nuses               /**< number to add to the usage counter */
250  	   )
251  	{
252  	   assert(node != NULL);
253  	
254  	   SCIPdebugMessage("capture %d times LPI state of node #%" SCIP_LONGINT_FORMAT " at depth %d (current: %d)\n",
255  	      nuses, SCIPnodeGetNumber(node), SCIPnodeGetDepth(node),
256  	      SCIPnodeGetType(node) == SCIP_NODETYPE_FORK ? node->data.fork->nlpistateref : node->data.subroot->nlpistateref);
257  	
258  	   switch( SCIPnodeGetType(node) )
259  	   {  
260  	   case SCIP_NODETYPE_FORK:
261  	      forkCaptureLPIState(node->data.fork, nuses);
262  	      break;
263  	   case SCIP_NODETYPE_SUBROOT:
264  	      subrootCaptureLPIState(node->data.subroot, nuses);
265  	      break;
266  	   default:
267  	      SCIPerrorMessage("node for capturing the LPI state is neither fork nor subroot\n");
268  	      SCIPABORT();
269  	      return SCIP_INVALIDDATA;  /*lint !e527*/
270  	   }  /*lint !e788*/
271  	   return SCIP_OKAY;
272  	}
273  	
274  	/** decreases the reference counter of the LP state in the fork or subroot node */
275  	SCIP_RETCODE SCIPnodeReleaseLPIState(
276  	   SCIP_NODE*            node,               /**< fork/subroot node */
277  	   BMS_BLKMEM*           blkmem,             /**< block memory buffers */
278  	   SCIP_LP*              lp                  /**< current LP data */
279  	   )
280  	{
281  	   assert(node != NULL);
282  	
283  	   SCIPdebugMessage("release LPI state of node #%" SCIP_LONGINT_FORMAT " at depth %d (current: %d)\n",
284  	      SCIPnodeGetNumber(node), SCIPnodeGetDepth(node),
285  	      SCIPnodeGetType(node) == SCIP_NODETYPE_FORK ? node->data.fork->nlpistateref : node->data.subroot->nlpistateref);
286  	   switch( SCIPnodeGetType(node) )
287  	   {  
288  	   case SCIP_NODETYPE_FORK:
289  	      return forkReleaseLPIState(node->data.fork, blkmem, lp);
290  	   case SCIP_NODETYPE_SUBROOT:
291  	      return subrootReleaseLPIState(node->data.subroot, blkmem, lp);
292  	   default:
293  	      SCIPerrorMessage("node for releasing the LPI state is neither fork nor subroot\n");
294  	      return SCIP_INVALIDDATA;
295  	   }  /*lint !e788*/
296  	}
297  	
298  	/** creates probingnode data without LP information */
299  	static
300  	SCIP_RETCODE probingnodeCreate(
301  	   SCIP_PROBINGNODE**    probingnode,        /**< pointer to probingnode data */
302  	   BMS_BLKMEM*           blkmem,             /**< block memory */
303  	   SCIP_LP*              lp                  /**< current LP data */
304  	   )
305  	{
306  	   assert(probingnode != NULL);
307  	
308  	   SCIP_ALLOC( BMSallocBlockMemory(blkmem, probingnode) );
309  	
310  	   (*probingnode)->lpistate = NULL;
311  	   (*probingnode)->lpinorms = NULL;
312  	   (*probingnode)->ninitialcols = SCIPlpGetNCols(lp);
313  	   (*probingnode)->ninitialrows = SCIPlpGetNRows(lp);
314  	   (*probingnode)->ncols = (*probingnode)->ninitialcols;
315  	   (*probingnode)->nrows = (*probingnode)->ninitialrows;
316  	   (*probingnode)->origobjvars = NULL;
317  	   (*probingnode)->origobjvals = NULL;
318  	   (*probingnode)->nchgdobjs = 0;
319  	
320  	   SCIPdebugMessage("created probingnode information (%d cols, %d rows)\n", (*probingnode)->ncols, (*probingnode)->nrows);
321  	
322  	   return SCIP_OKAY;
323  	}
324  	
325  	/** updates LP information in probingnode data */
326  	static
327  	SCIP_RETCODE probingnodeUpdate(
328  	   SCIP_PROBINGNODE*     probingnode,        /**< probingnode data */
329  	   BMS_BLKMEM*           blkmem,             /**< block memory */
330  	   SCIP_TREE*            tree,               /**< branch and bound tree */
331  	   SCIP_LP*              lp                  /**< current LP data */
332  	   )
333  	{
334  	   SCIP_Bool storenorms = FALSE;
335  	
336  	   assert(probingnode != NULL);
337  	   assert(SCIPtreeIsPathComplete(tree));
338  	   assert(lp != NULL);
339  	
340  	   /* free old LP state */
341  	   if( probingnode->lpistate != NULL )
342  	   {
343  	      SCIP_CALL( SCIPlpFreeState(lp, blkmem, &probingnode->lpistate) );
344  	   }
345  	
346  	   /* free old LP norms */
347  	   if( probingnode->lpinorms != NULL )
348  	   {
349  	      SCIP_CALL( SCIPlpFreeNorms(lp, blkmem, &probingnode->lpinorms) );
350  	      probingnode->lpinorms = NULL;
351  	      storenorms = TRUE;
352  	   }
353  	
354  	   /* get current LP state */
355  	   if( lp->flushed && lp->solved )
356  	   {
357  	      SCIP_CALL( SCIPlpGetState(lp, blkmem, &probingnode->lpistate) );
358  	
359  	      /* if LP norms were stored at this node before, store the new ones */
360  	      if( storenorms )
361  	      {
362  	         SCIP_CALL( SCIPlpGetNorms(lp, blkmem, &probingnode->lpinorms) );
363  	      }
364  	      probingnode->lpwasprimfeas = lp->primalfeasible;
365  	      probingnode->lpwasprimchecked = lp->primalchecked;
366  	      probingnode->lpwasdualfeas = lp->dualfeasible;
367  	      probingnode->lpwasdualchecked = lp->dualchecked;
368  	   }
369  	   else
370  	      probingnode->lpistate = NULL;
371  	
372  	   probingnode->ncols = SCIPlpGetNCols(lp);
373  	   probingnode->nrows = SCIPlpGetNRows(lp);
374  	
375  	   SCIPdebugMessage("updated probingnode information (%d cols, %d rows)\n", probingnode->ncols, probingnode->nrows);
376  	
377  	   return SCIP_OKAY;
378  	}
379  	
380  	/** frees probingnode data */
381  	static
382  	SCIP_RETCODE probingnodeFree(
383  	   SCIP_PROBINGNODE**    probingnode,        /**< probingnode data */
384  	   BMS_BLKMEM*           blkmem,             /**< block memory */
385  	   SCIP_LP*              lp                  /**< current LP data */
386  	   )
387  	{
388  	   assert(probingnode != NULL);
389  	   assert(*probingnode != NULL);
390  	
391  	   /* free the associated LP state */
392  	   if( (*probingnode)->lpistate != NULL )
393  	   {
394  	      SCIP_CALL( SCIPlpFreeState(lp, blkmem, &(*probingnode)->lpistate) );
395  	   }
396  	   /* free the associated LP norms */
397  	   if( (*probingnode)->lpinorms != NULL )
398  	   {
399  	      SCIP_CALL( SCIPlpFreeNorms(lp, blkmem, &(*probingnode)->lpinorms) );
400  	   }
401  	
402  	   /* free objective information */
403  	   if( (*probingnode)->nchgdobjs > 0 )
404  	   {
405  	      assert((*probingnode)->origobjvars != NULL);
406  	      assert((*probingnode)->origobjvals != NULL);
407  	
408  	      BMSfreeMemoryArray(&(*probingnode)->origobjvars);
409  	      BMSfreeMemoryArray(&(*probingnode)->origobjvals);
410  	   }
411  	
412  	   BMSfreeBlockMemory(blkmem, probingnode);
413  	
414  	   return SCIP_OKAY;
415  	}
416  	
417  	/** initializes junction data */
418  	static
419  	SCIP_RETCODE junctionInit(
420  	   SCIP_JUNCTION*        junction,           /**< pointer to junction data */
421  	   SCIP_TREE*            tree                /**< branch and bound tree */
422  	   )
423  	{
424  	   assert(junction != NULL);
425  	   assert(tree != NULL);
426  	   assert(tree->nchildren > 0);
427  	   assert(SCIPtreeIsPathComplete(tree));
428  	   assert(tree->focusnode != NULL);
429  	
430  	   junction->nchildren = tree->nchildren;
431  	
432  	   /* increase the LPI state usage counter of the current LP fork */
433  	   if( tree->focuslpstatefork != NULL )
434  	   {
435  	      SCIP_CALL( SCIPnodeCaptureLPIState(tree->focuslpstatefork, tree->nchildren) );
436  	   }
437  	
438  	   return SCIP_OKAY;
439  	}
440  	
441  	/** creates pseudofork data */
442  	static
443  	SCIP_RETCODE pseudoforkCreate(
444  	   SCIP_PSEUDOFORK**     pseudofork,         /**< pointer to pseudofork data */
445  	   BMS_BLKMEM*           blkmem,             /**< block memory */
446  	   SCIP_TREE*            tree,               /**< branch and bound tree */
447  	   SCIP_LP*              lp                  /**< current LP data */
448  	   )
449  	{
450  	   assert(pseudofork != NULL);
451  	   assert(blkmem != NULL);
452  	   assert(tree != NULL);
453  	   assert(tree->nchildren > 0);
454  	   assert(SCIPtreeIsPathComplete(tree));
455  	   assert(tree->focusnode != NULL);
456  	
457  	   SCIP_ALLOC( BMSallocBlockMemory(blkmem, pseudofork) );
458  	
459  	   (*pseudofork)->addedcols = NULL;
460  	   (*pseudofork)->addedrows = NULL;
461  	   (*pseudofork)->naddedcols = SCIPlpGetNNewcols(lp);
462  	   (*pseudofork)->naddedrows = SCIPlpGetNNewrows(lp);
463  	   (*pseudofork)->nchildren = tree->nchildren;
464  	
465  	   SCIPdebugMessage("creating pseudofork information with %d children (%d new cols, %d new rows)\n",
466  	      (*pseudofork)->nchildren, (*pseudofork)->naddedcols, (*pseudofork)->naddedrows);
467  	
468  	   if( (*pseudofork)->naddedcols > 0 )
469  	   {
470  	      /* copy the newly created columns to the pseudofork's col array */
471  	      SCIP_ALLOC( BMSduplicateBlockMemoryArray(blkmem, &(*pseudofork)->addedcols, SCIPlpGetNewcols(lp), (*pseudofork)->naddedcols) ); /*lint !e666*/
472  	   }
473  	   if( (*pseudofork)->naddedrows > 0 )
474  	   {
475  	      int i;
476  	
477  	      /* copy the newly created rows to the pseudofork's row array */
478  	      SCIP_ALLOC( BMSduplicateBlockMemoryArray(blkmem, &(*pseudofork)->addedrows, SCIPlpGetNewrows(lp), (*pseudofork)->naddedrows) ); /*lint !e666*/
479  	
480  	      /* capture the added rows */
481  	      for( i = 0; i < (*pseudofork)->naddedrows; ++i )
482  	         SCIProwCapture((*pseudofork)->addedrows[i]);
483  	   }
484  	
485  	   /* increase the LPI state usage counter of the current LP fork */
486  	   if( tree->focuslpstatefork != NULL )
487  	   {
488  	      SCIP_CALL( SCIPnodeCaptureLPIState(tree->focuslpstatefork, tree->nchildren) );
489  	   }
490  	
491  	   return SCIP_OKAY;
492  	}
493  	
494  	/** frees pseudofork data */
495  	static
496  	SCIP_RETCODE pseudoforkFree(
497  	   SCIP_PSEUDOFORK**     pseudofork,         /**< pseudofork data */
498  	   BMS_BLKMEM*           blkmem,             /**< block memory */
499  	   SCIP_SET*             set,                /**< global SCIP settings */
500  	   SCIP_LP*              lp                  /**< current LP data */
501  	   )
502  	{
503  	   int i;
504  	
505  	   assert(pseudofork != NULL);
506  	   assert(*pseudofork != NULL);
507  	   assert((*pseudofork)->nchildren == 0);
508  	   assert(blkmem != NULL);
509  	   assert(set != NULL);
510  	
511  	   /* release the added rows */
512  	   for( i = 0; i < (*pseudofork)->naddedrows; ++i )
513  	   {
514  	      SCIP_CALL( SCIProwRelease(&(*pseudofork)->addedrows[i], blkmem, set, lp) );
515  	   }
516  	
517  	   BMSfreeBlockMemoryArrayNull(blkmem, &(*pseudofork)->addedcols, (*pseudofork)->naddedcols);
518  	   BMSfreeBlockMemoryArrayNull(blkmem, &(*pseudofork)->addedrows, (*pseudofork)->naddedrows);
519  	   BMSfreeBlockMemory(blkmem, pseudofork);
520  	
521  	   return SCIP_OKAY;
522  	}
523  	
524  	/** creates fork data */
525  	static
526  	SCIP_RETCODE forkCreate(
527  	   SCIP_FORK**           fork,               /**< pointer to fork data */
528  	   BMS_BLKMEM*           blkmem,             /**< block memory */
529  	   SCIP_SET*             set,                /**< global SCIP settings */
530  	   SCIP_PROB*            prob,               /**< transformed problem after presolve */
531  	   SCIP_TREE*            tree,               /**< branch and bound tree */
532  	   SCIP_LP*              lp                  /**< current LP data */
533  	   )
534  	{
535  	   assert(fork != NULL);
536  	   assert(blkmem != NULL);
537  	   assert(tree != NULL);
538  	   assert(tree->nchildren > 0);
539  	   assert(tree->nchildren < (1 << 30));
540  	   assert(SCIPtreeIsPathComplete(tree));
541  	   assert(tree->focusnode != NULL);
542  	   assert(lp != NULL);
543  	   assert(lp->flushed);
544  	   assert(lp->solved);
545  	   assert(SCIPlpGetSolstat(lp) == SCIP_LPSOLSTAT_OPTIMAL);
546  	
547  	   SCIP_ALLOC( BMSallocBlockMemory(blkmem, fork) );
548  	
549  	   SCIP_CALL( SCIPlpGetState(lp, blkmem, &((*fork)->lpistate)) );
550  	   (*fork)->lpwasprimfeas = lp->primalfeasible;
551  	   (*fork)->lpwasprimchecked = lp->primalchecked;
552  	   (*fork)->lpwasdualfeas = lp->dualfeasible;
553  	   (*fork)->lpwasdualchecked = lp->dualchecked;
554  	   (*fork)->lpobjval = SCIPlpGetObjval(lp, set, prob);
555  	   (*fork)->nlpistateref = 0;
556  	   (*fork)->addedcols = NULL;
557  	   (*fork)->addedrows = NULL;
558  	   (*fork)->naddedcols = SCIPlpGetNNewcols(lp);
559  	   (*fork)->naddedrows = SCIPlpGetNNewrows(lp);
560  	   (*fork)->nchildren = (unsigned int) tree->nchildren;
561  	
562  	   SCIPsetDebugMsg(set, "creating fork information with %u children (%d new cols, %d new rows)\n", (*fork)->nchildren, (*fork)->naddedcols, (*fork)->naddedrows);
563  	
564  	   if( (*fork)->naddedcols > 0 )
565  	   {
566  	      /* copy the newly created columns to the fork's col array */
567  	      SCIP_ALLOC( BMSduplicateBlockMemoryArray(blkmem, &(*fork)->addedcols, SCIPlpGetNewcols(lp), (*fork)->naddedcols) ); /*lint !e666*/
568  	   }
569  	   if( (*fork)->naddedrows > 0 )
570  	   {
571  	      int i;
572  	
573  	      /* copy the newly created rows to the fork's row array */
574  	      SCIP_ALLOC( BMSduplicateBlockMemoryArray(blkmem, &(*fork)->addedrows, SCIPlpGetNewrows(lp), (*fork)->naddedrows) ); /*lint !e666*/
575  	
576  	      /* capture the added rows */
577  	      for( i = 0; i < (*fork)->naddedrows; ++i )
578  	         SCIProwCapture((*fork)->addedrows[i]);
579  	   }
580  	
581  	   /* capture the LPI state for the children */
582  	   forkCaptureLPIState(*fork, tree->nchildren);
583  	
584  	   return SCIP_OKAY;
585  	}
586  	
587  	/** frees fork data */
588  	static
589  	SCIP_RETCODE forkFree(
590  	   SCIP_FORK**           fork,               /**< fork data */
591  	   BMS_BLKMEM*           blkmem,             /**< block memory */
592  	   SCIP_SET*             set,                /**< global SCIP settings */
593  	   SCIP_LP*              lp                  /**< current LP data */
594  	   )
595  	{
596  	   int i;
597  	
598  	   assert(fork != NULL);
599  	   assert(*fork != NULL);
600  	   assert((*fork)->nchildren == 0);
601  	   assert((*fork)->nlpistateref == 0);
602  	   assert((*fork)->lpistate == NULL);
603  	   assert(blkmem != NULL);
604  	   assert(set != NULL);
605  	   assert(lp != NULL);
606  	
607  	   /* release the added rows */
608  	   for( i = (*fork)->naddedrows - 1; i >= 0; --i )
609  	   {
610  	      SCIP_CALL( SCIProwRelease(&(*fork)->addedrows[i], blkmem, set, lp) );
611  	   }
612  	
613  	   BMSfreeBlockMemoryArrayNull(blkmem, &(*fork)->addedcols, (*fork)->naddedcols);
614  	   BMSfreeBlockMemoryArrayNull(blkmem, &(*fork)->addedrows, (*fork)->naddedrows);
615  	   BMSfreeBlockMemory(blkmem, fork);
616  	
617  	   return SCIP_OKAY;
618  	}
619  	
620  	#ifdef WITHSUBROOTS /** @todo test whether subroots should be created */
621  	/** creates subroot data */
622  	static
623  	SCIP_RETCODE subrootCreate(
624  	   SCIP_SUBROOT**        subroot,            /**< pointer to subroot data */
625  	   BMS_BLKMEM*           blkmem,             /**< block memory */
626  	   SCIP_SET*             set,                /**< global SCIP settings */
627  	   SCIP_PROB*            prob,               /**< transformed problem after presolve */
628  	   SCIP_TREE*            tree,               /**< branch and bound tree */
629  	   SCIP_LP*              lp                  /**< current LP data */
630  	   )
631  	{
632  	   int i;
633  	
634  	   assert(subroot != NULL);
635  	   assert(blkmem != NULL);
636  	   assert(tree != NULL);
637  	   assert(tree->nchildren > 0);
638  	   assert(SCIPtreeIsPathComplete(tree));
639  	   assert(tree->focusnode != NULL);
640  	   assert(lp != NULL);
641  	   assert(lp->flushed);
642  	   assert(lp->solved);
643  	   assert(SCIPlpGetSolstat(lp) == SCIP_LPSOLSTAT_OPTIMAL);
644  	
645  	   SCIP_ALLOC( BMSallocBlockMemory(blkmem, subroot) );
646  	   (*subroot)->lpobjval = SCIPlpGetObjval(lp, set, prob);
647  	   (*subroot)->nlpistateref = 0;
648  	   (*subroot)->ncols = SCIPlpGetNCols(lp);
649  	   (*subroot)->nrows = SCIPlpGetNRows(lp);
650  	   (*subroot)->nchildren = (unsigned int) tree->nchildren;
651  	   SCIP_CALL( SCIPlpGetState(lp, blkmem, &((*subroot)->lpistate)) );
652  	   (*subroot)->lpwasprimfeas = lp->primalfeasible;
653  	   (*subroot)->lpwasprimchecked = lp->primalchecked;
654  	   (*subroot)->lpwasdualfeas = lp->dualfeasible;
655  	   (*subroot)->lpwasdualchecked = lp->dualchecked;
656  	
657  	   if( (*subroot)->ncols != 0 )
658  	   {
659  	      SCIP_ALLOC( BMSduplicateBlockMemoryArray(blkmem, &(*subroot)->cols, SCIPlpGetCols(lp), (*subroot)->ncols) );
660  	   }
661  	   else
662  	      (*subroot)->cols = NULL;
663  	   if( (*subroot)->nrows != 0 )
664  	   {
665  	      SCIP_ALLOC( BMSduplicateBlockMemoryArray(blkmem, &(*subroot)->rows, SCIPlpGetRows(lp), (*subroot)->nrows) );
666  	   }
667  	   else
668  	      (*subroot)->rows = NULL;
669  	
670  	   /* capture the rows of the subroot */
671  	   for( i = 0; i < (*subroot)->nrows; ++i )
672  	      SCIProwCapture((*subroot)->rows[i]);
673  	
674  	   /* capture the LPI state for the children */
675  	   subrootCaptureLPIState(*subroot, tree->nchildren);
676  	
677  	   return SCIP_OKAY;
678  	}
679  	#endif
680  	
681  	/** frees subroot */
682  	static
683  	SCIP_RETCODE subrootFree(
684  	   SCIP_SUBROOT**        subroot,            /**< subroot data */
685  	   BMS_BLKMEM*           blkmem,             /**< block memory */
686  	   SCIP_SET*             set,                /**< global SCIP settings */
687  	   SCIP_LP*              lp                  /**< current LP data */
688  	   )
689  	{
690  	   int i;
691  	
692  	   assert(subroot != NULL);
693  	   assert(*subroot != NULL);
694  	   assert((*subroot)->nchildren == 0);
695  	   assert((*subroot)->nlpistateref == 0);
696  	   assert((*subroot)->lpistate == NULL);
697  	   assert(blkmem != NULL);
698  	   assert(set != NULL);
699  	   assert(lp != NULL);
700  	
701  	   /* release the rows of the subroot */
702  	   for( i = 0; i < (*subroot)->nrows; ++i )
703  	   {
704  	      SCIP_CALL( SCIProwRelease(&(*subroot)->rows[i], blkmem, set, lp) );
705  	   }
706  	
707  	   BMSfreeBlockMemoryArrayNull(blkmem, &(*subroot)->cols, (*subroot)->ncols);
708  	   BMSfreeBlockMemoryArrayNull(blkmem, &(*subroot)->rows, (*subroot)->nrows);
709  	   BMSfreeBlockMemory(blkmem, subroot);
710  	
711  	   return SCIP_OKAY;
712  	}
713  	
714  	/** removes given sibling node from the siblings array */
715  	static
716  	void treeRemoveSibling(
717  	   SCIP_TREE*            tree,               /**< branch and bound tree */
718  	   SCIP_NODE*            sibling             /**< sibling node to remove */
719  	   )
720  	{
721  	   int delpos;
722  	
723  	   assert(tree != NULL);
724  	   assert(sibling != NULL);
725  	   assert(SCIPnodeGetType(sibling) == SCIP_NODETYPE_SIBLING);
726  	   assert(sibling->data.sibling.arraypos >= 0 && sibling->data.sibling.arraypos < tree->nsiblings);
727  	   assert(tree->siblings[sibling->data.sibling.arraypos] == sibling);
728  	   assert(SCIPnodeGetType(tree->siblings[tree->nsiblings-1]) == SCIP_NODETYPE_SIBLING);
729  	
730  	   delpos = sibling->data.sibling.arraypos;
731  	
732  	   /* move last sibling in array to position of removed sibling */
733  	   tree->siblings[delpos] = tree->siblings[tree->nsiblings-1];
734  	   tree->siblingsprio[delpos] = tree->siblingsprio[tree->nsiblings-1];
735  	   tree->siblings[delpos]->data.sibling.arraypos = delpos;
736  	   sibling->data.sibling.arraypos = -1;
737  	   tree->nsiblings--;
738  	}
739  	
740  	/** adds given child node to children array of focus node */
741  	static
742  	SCIP_RETCODE treeAddChild(
743  	   SCIP_TREE*            tree,               /**< branch and bound tree */
744  	   SCIP_SET*             set,                /**< global SCIP settings */
745  	   SCIP_NODE*            child,              /**< child node to add */
746  	   SCIP_Real             nodeselprio         /**< node selection priority of child node */
747  	   )
748  	{
749  	   assert(tree != NULL);
750  	   assert(child != NULL);
751  	   assert(SCIPnodeGetType(child) == SCIP_NODETYPE_CHILD);
752  	   assert(child->data.child.arraypos == -1);
753  	
754  	   SCIP_CALL( treeEnsureChildrenMem(tree, set, tree->nchildren+1) );
755  	   tree->children[tree->nchildren] = child;
756  	   tree->childrenprio[tree->nchildren] = nodeselprio;
757  	   child->data.child.arraypos = tree->nchildren;
758  	   tree->nchildren++;
759  	
760  	   return SCIP_OKAY;
761  	}
762  	
763  	/** removes given child node from the children array */
764  	static
765  	void treeRemoveChild(
766  	   SCIP_TREE*            tree,               /**< branch and bound tree */
767  	   SCIP_NODE*            child               /**< child node to remove */
768  	   )
769  	{
770  	   int delpos;
771  	
772  	   assert(tree != NULL);
773  	   assert(child != NULL);
774  	   assert(SCIPnodeGetType(child) == SCIP_NODETYPE_CHILD);
775  	   assert(child->data.child.arraypos >= 0 && child->data.child.arraypos < tree->nchildren);
776  	   assert(tree->children[child->data.child.arraypos] == child);
777  	   assert(SCIPnodeGetType(tree->children[tree->nchildren-1]) == SCIP_NODETYPE_CHILD);
778  	
779  	   delpos = child->data.child.arraypos;
780  	
781  	   /* move last child in array to position of removed child */
782  	   tree->children[delpos] = tree->children[tree->nchildren-1];
783  	   tree->childrenprio[delpos] = tree->childrenprio[tree->nchildren-1];
784  	   tree->children[delpos]->data.child.arraypos = delpos;
785  	   child->data.child.arraypos = -1;
786  	   tree->nchildren--;
787  	}
788  	
789  	/** makes node a child of the given parent node, which must be the focus node; if the child is a probing node,
790  	 *  the parent node can also be a refocused node or a probing node
791  	 */
792  	static
793  	SCIP_RETCODE nodeAssignParent(
794  	   SCIP_NODE*            node,               /**< child node */
795  	   BMS_BLKMEM*           blkmem,             /**< block memory buffers */
796  	   SCIP_SET*             set,                /**< global SCIP settings */
797  	   SCIP_TREE*            tree,               /**< branch and bound tree */
798  	   SCIP_NODE*            parent,             /**< parent (= focus) node (or NULL, if node is root) */
799  	   SCIP_Real             nodeselprio         /**< node selection priority of child node */
800  	   )
801  	{
802  	   assert(node != NULL);
803  	   assert(node->parent == NULL);
804  	   assert(SCIPnodeGetType(node) == SCIP_NODETYPE_CHILD || SCIPnodeGetType(node) == SCIP_NODETYPE_PROBINGNODE);
805  	   assert(node->conssetchg == NULL);
806  	   assert(node->domchg == NULL);
807  	   assert(SCIPsetIsInfinity(set, -node->lowerbound)); /* node was just created */
808  	   assert(blkmem != NULL);
809  	   assert(set != NULL);
810  	   assert(tree != NULL);
811  	   assert(SCIPtreeIsPathComplete(tree));
812  	   assert(tree->pathlen == 0 || tree->path[tree->pathlen-1] == parent);
813  	   assert(parent == tree->focusnode || SCIPnodeGetType(parent) == SCIP_NODETYPE_PROBINGNODE);
814  	   assert(parent == NULL || SCIPnodeGetType(parent) == SCIP_NODETYPE_FOCUSNODE
815  	      || (SCIPnodeGetType(node) == SCIP_NODETYPE_PROBINGNODE
816  	         && (SCIPnodeGetType(parent) == SCIP_NODETYPE_REFOCUSNODE
817  	            || SCIPnodeGetType(parent) == SCIP_NODETYPE_PROBINGNODE)));
818  	
819  	   /* link node to parent */
820  	   node->parent = parent;
821  	   if( parent != NULL )
822  	   {
823  	      assert(parent->lowerbound <= parent->estimate);
824  	      node->lowerbound = parent->lowerbound;
825  	      node->estimate = parent->estimate;
826  	      node->depth = parent->depth+1; /*lint !e732*/
827  	      if( parent->depth >= SCIP_MAXTREEDEPTH )
828  	      {
829  	         SCIPerrorMessage("maximal depth level exceeded\n");
830  	         return SCIP_MAXDEPTHLEVEL;
831  	      }
832  	   }
833  	   SCIPsetDebugMsg(set, "assigning parent #%" SCIP_LONGINT_FORMAT " to node #%" SCIP_LONGINT_FORMAT " at depth %d\n",
834  	      parent != NULL ? SCIPnodeGetNumber(parent) : -1, SCIPnodeGetNumber(node), SCIPnodeGetDepth(node));
835  	
836  	   /* register node in the childlist of the focus (the parent) node */
837  	   if( SCIPnodeGetType(node) == SCIP_NODETYPE_CHILD )
838  	   {
839  	      assert(parent == NULL || SCIPnodeGetType(parent) == SCIP_NODETYPE_FOCUSNODE);
840  	      SCIP_CALL( treeAddChild(tree, set, node, nodeselprio) );
841  	   }
842  	
843  	   return SCIP_OKAY;
844  	}
845  	
846  	/** decreases number of children of the parent, frees it if no children are left */
847  	static
848  	SCIP_RETCODE nodeReleaseParent(
849  	   SCIP_NODE*            node,               /**< child node */
850  	   BMS_BLKMEM*           blkmem,             /**< block memory buffer */
851  	   SCIP_SET*             set,                /**< global SCIP settings */
852  	   SCIP_STAT*            stat,               /**< problem statistics */
853  	   SCIP_EVENTFILTER*     eventfilter,        /**< event filter for global (not variable dependent) events */
854  	   SCIP_EVENTQUEUE*      eventqueue,         /**< event queue */
855  	   SCIP_TREE*            tree,               /**< branch and bound tree */
856  	   SCIP_LP*              lp                  /**< current LP data */
857  	   )
858  	{
859  	   SCIP_NODE* parent;
860  	
861  	   assert(node != NULL);
862  	   assert(blkmem != NULL);
863  	   assert(tree != NULL);
864  	
865  	   SCIPsetDebugMsg(set, "releasing parent-child relationship of node #%" SCIP_LONGINT_FORMAT " at depth %d of type %d with parent #%" SCIP_LONGINT_FORMAT " of type %d\n",
866  	      SCIPnodeGetNumber(node), SCIPnodeGetDepth(node), SCIPnodeGetType(node),
867  	      node->parent != NULL ? SCIPnodeGetNumber(node->parent) : -1,
868  	      node->parent != NULL ? (int)SCIPnodeGetType(node->parent) : -1);
869  	   parent = node->parent;
870  	   if( parent != NULL )
871  	   {
872  	      SCIP_Bool freeParent;
873  	      SCIP_Bool singleChild;
874  	
875  	      freeParent = FALSE;
876  	      singleChild = FALSE;
877  	      switch( SCIPnodeGetType(parent) )
878  	      {
879  	      case SCIP_NODETYPE_FOCUSNODE:
880  	         assert(parent->active);
881  	         assert(SCIPnodeGetType(node) == SCIP_NODETYPE_CHILD || SCIPnodeGetType(node) == SCIP_NODETYPE_PROBINGNODE
882  	            || SCIPnodeGetType(node) == SCIP_NODETYPE_LEAF);
883  	         if( SCIPnodeGetType(node) == SCIP_NODETYPE_CHILD )
884  	            treeRemoveChild(tree, node);
885  	         /* don't kill the focus node at this point => freeParent = FALSE */
886  	         break;
887  	      case SCIP_NODETYPE_PROBINGNODE:
888  	         assert(SCIPtreeProbing(tree));
889  	         /* probing nodes have to be freed individually => freeParent = FALSE */
890  	         break;
891  	      case SCIP_NODETYPE_SIBLING:
892  	         SCIPerrorMessage("sibling cannot be a parent node\n");
893  	         return SCIP_INVALIDDATA;
894  	      case SCIP_NODETYPE_CHILD:
895  	         SCIPerrorMessage("child cannot be a parent node\n");
896  	         return SCIP_INVALIDDATA;
897  	      case SCIP_NODETYPE_LEAF:
898  	         SCIPerrorMessage("leaf cannot be a parent node\n");
899  	         return SCIP_INVALIDDATA;
900  	      case SCIP_NODETYPE_DEADEND:
901  	         SCIPerrorMessage("dead-end cannot be a parent node\n");
902  	         return SCIP_INVALIDDATA;
903  	      case SCIP_NODETYPE_JUNCTION:
904  	         assert(parent->data.junction.nchildren > 0);
905  	         parent->data.junction.nchildren--;
906  	         freeParent = (parent->data.junction.nchildren == 0); /* free parent if it has no more children */
907  	         singleChild = (parent->data.junction.nchildren == 1);
908  	         break;
909  	      case SCIP_NODETYPE_PSEUDOFORK:
910  	         assert(parent->data.pseudofork != NULL);
911  	         assert(parent->data.pseudofork->nchildren > 0);
912  	         parent->data.pseudofork->nchildren--;
913  	         freeParent = (parent->data.pseudofork->nchildren == 0); /* free parent if it has no more children */
914  	         singleChild = (parent->data.pseudofork->nchildren == 1);
915  	         break;
916  	      case SCIP_NODETYPE_FORK:
917  	         assert(parent->data.fork != NULL);
918  	         assert(parent->data.fork->nchildren > 0);
919  	         parent->data.fork->nchildren--;
920  	         freeParent = (parent->data.fork->nchildren == 0); /* free parent if it has no more children */
921  	         singleChild = (parent->data.fork->nchildren == 1);
922  	         break;
923  	      case SCIP_NODETYPE_SUBROOT:
924  	         assert(parent->data.subroot != NULL);
925  	         assert(parent->data.subroot->nchildren > 0);
926  	         parent->data.subroot->nchildren--;
927  	         freeParent = (parent->data.subroot->nchildren == 0); /* free parent if it has no more children */
928  	         singleChild = (parent->data.subroot->nchildren == 1);
929  	         break;
930  	      case SCIP_NODETYPE_REFOCUSNODE:
931  	         /* the only possible child a refocused node can have in its refocus state is the probing root node;
932  	          * we don't want to free the refocused node, because we first have to convert it back to its original
933  	          * type (where it possibly has children) => freeParent = FALSE
934  	          */
935  	         assert(SCIPnodeGetType(node) == SCIP_NODETYPE_PROBINGNODE);
936  	         assert(!SCIPtreeProbing(tree));
937  	         break;
938  	      default:
939  	         SCIPerrorMessage("unknown node type %d\n", SCIPnodeGetType(parent));
940  	         return SCIP_INVALIDDATA;
941  	      }
942  	
943  	      /* free parent, if it is not on the current active path */
944  	      if( freeParent && !parent->active )
945  	      {
946  	         SCIP_CALL( SCIPnodeFree(&node->parent, blkmem, set, stat, eventfilter, eventqueue, tree, lp) );
947  	      }
948  	
949  	      /* update the effective root depth
950  	       * in reoptimization we must not increase the effective root depth
951  	       */
952  	      assert(tree->effectiverootdepth >= 0);
953  	      if( singleChild && SCIPnodeGetDepth(parent) == tree->effectiverootdepth && !set->reopt_enable )
954  	      {
955  	         tree->effectiverootdepth++;
956  	         SCIPsetDebugMsg(set, "unlinked node #%" SCIP_LONGINT_FORMAT " in depth %d -> new effective root depth: %d\n",
957  	            SCIPnodeGetNumber(node), SCIPnodeGetDepth(node), tree->effectiverootdepth);
958  	      }
959  	   }
960  	
961  	   return SCIP_OKAY;
962  	}
963  	
964  	/** creates a node data structure */
965  	static
966  	SCIP_RETCODE nodeCreate(
967  	   SCIP_NODE**           node,               /**< pointer to node data structure */
968  	   BMS_BLKMEM*           blkmem,             /**< block memory */
969  	   SCIP_SET*             set                 /**< global SCIP settings */
970  	   )
971  	{
972  	   assert(node != NULL);
973  	
974  	   SCIP_ALLOC( BMSallocBlockMemory(blkmem, node) );
975  	   (*node)->parent = NULL;
976  	   (*node)->conssetchg = NULL;
977  	   (*node)->domchg = NULL;
978  	   (*node)->number = 0;
979  	   (*node)->lowerbound = -SCIPsetInfinity(set);
980  	   (*node)->estimate = -SCIPsetInfinity(set);
981  	   (*node)->reoptid = 0;
982  	   (*node)->reopttype = (unsigned int) SCIP_REOPTTYPE_NONE;
983  	   (*node)->depth = 0;
984  	   (*node)->active = FALSE;
985  	   (*node)->cutoff = FALSE;
986  	   (*node)->reprop = FALSE;
987  	   (*node)->repropsubtreemark = 0;
988  	
989  	   return SCIP_OKAY;
990  	}
991  	
992  	/** creates a child node of the focus node */
993  	SCIP_RETCODE SCIPnodeCreateChild(
994  	   SCIP_NODE**           node,               /**< pointer to node data structure */
995  	   BMS_BLKMEM*           blkmem,             /**< block memory */
996  	   SCIP_SET*             set,                /**< global SCIP settings */
997  	   SCIP_STAT*            stat,               /**< problem statistics */
998  	   SCIP_TREE*            tree,               /**< branch and bound tree */
999  	   SCIP_Real             nodeselprio,        /**< node selection priority of new node */
1000 	   SCIP_Real             estimate            /**< estimate for (transformed) objective value of best feasible solution in subtree */
1001 	   )
1002 	{
1003 	   assert(node != NULL);
1004 	   assert(blkmem != NULL);
1005 	   assert(set != NULL);
1006 	   assert(stat != NULL);
1007 	   assert(tree != NULL);
1008 	   assert(SCIPtreeIsPathComplete(tree));
1009 	   assert(tree->pathlen == 0 || tree->path != NULL);
1010 	   assert((tree->pathlen == 0) == (tree->focusnode == NULL));
1011 	   assert(tree->focusnode == NULL || tree->focusnode == tree->path[tree->pathlen-1]);
1012 	   assert(tree->focusnode == NULL || SCIPnodeGetType(tree->focusnode) == SCIP_NODETYPE_FOCUSNODE);
1013 	
1014 	   stat->ncreatednodes++;
1015 	   stat->ncreatednodesrun++;
1016 	
1017 	   /* create the node data structure */
1018 	   SCIP_CALL( nodeCreate(node, blkmem, set) );
1019 	   (*node)->number = stat->ncreatednodesrun;
1020 	
1021 	   /* mark node to be a child node */
1022 	   (*node)->nodetype = SCIP_NODETYPE_CHILD; /*lint !e641*/
1023 	   (*node)->data.child.arraypos = -1;
1024 	
1025 	   /* make focus node the parent of the new child */
1026 	   SCIP_CALL( nodeAssignParent(*node, blkmem, set, tree, tree->focusnode, nodeselprio) );
1027 	
1028 	   /* update the estimate of the child */
1029 	   SCIPnodeSetEstimate(*node, set, estimate);
1030 	
1031 	   tree->lastbranchparentid = tree->focusnode == NULL ? -1L : SCIPnodeGetNumber(tree->focusnode);
1032 	
1033 	   /* output node creation to visualization file */
1034 	   SCIP_CALL( SCIPvisualNewChild(stat->visual, set, stat, *node) );
1035 	
1036 	   SCIPsetDebugMsg(set, "created child node #%" SCIP_LONGINT_FORMAT " at depth %u (prio: %g)\n", SCIPnodeGetNumber(*node), (*node)->depth, nodeselprio);
1037 	
1038 	   return SCIP_OKAY;
1039 	}
1040 	
1041 	/** query if focus node was already branched on */
1042 	SCIP_Bool SCIPtreeWasNodeLastBranchParent(
1043 	   SCIP_TREE*            tree,               /**< branch and bound tree */
1044 	   SCIP_NODE*            node                /**< tree node, or NULL to check focus node */
1045 	   )
1046 	{
1047 	   node = node == NULL ? tree->focusnode : node;
1048 	   if( node != NULL && node->number == tree->lastbranchparentid )
1049 	      return TRUE;
1050 	
1051 	   return FALSE;
1052 	}
1053 	
1054 	/** frees node */
1055 	SCIP_RETCODE SCIPnodeFree(
1056 	   SCIP_NODE**           node,               /**< node data */
1057 	   BMS_BLKMEM*           blkmem,             /**< block memory buffer */
1058 	   SCIP_SET*             set,                /**< global SCIP settings */
1059 	   SCIP_STAT*            stat,               /**< problem statistics */
1060 	   SCIP_EVENTFILTER*     eventfilter,        /**< event filter for global (not variable dependent) events */
1061 	   SCIP_EVENTQUEUE*      eventqueue,         /**< event queue */
1062 	   SCIP_TREE*            tree,               /**< branch and bound tree */
1063 	   SCIP_LP*              lp                  /**< current LP data */
1064 	   )
1065 	{
1066 	   SCIP_Bool isroot;
1067 	
1068 	   assert(node != NULL);
1069 	   assert(*node != NULL);
1070 	   assert(!(*node)->active);
1071 	   assert(blkmem != NULL);
1072 	   assert(tree != NULL);
1073 	
1074 	   SCIPsetDebugMsg(set, "free node #%" SCIP_LONGINT_FORMAT " at depth %d of type %d\n", SCIPnodeGetNumber(*node), SCIPnodeGetDepth(*node), SCIPnodeGetType(*node));
1075 	
1076 	   /* check lower bound w.r.t. debugging solution */
1077 	   SCIP_CALL( SCIPdebugCheckGlobalLowerbound(blkmem, set) );
1078 	
1079 	   if( SCIPnodeGetType(*node) != SCIP_NODETYPE_PROBINGNODE )
1080 	   {
1081 	      SCIP_EVENT event;
1082 	
1083 	      /* trigger a node deletion event */
1084 	      SCIP_CALL( SCIPeventChgType(&event, SCIP_EVENTTYPE_NODEDELETE) );
1085 	      SCIP_CALL( SCIPeventChgNode(&event, *node) );
1086 	      SCIP_CALL( SCIPeventProcess(&event, set, NULL, NULL, NULL, eventfilter) );
1087 	   }
1088 	
1089 	   /* inform solution debugger, that the node has been freed */
1090 	   SCIP_CALL( SCIPdebugRemoveNode(blkmem, set, *node) );
1091 	
1092 	   /* check, if the node to be freed is the root node */
1093 	   isroot = (SCIPnodeGetDepth(*node) == 0);
1094 	
1095 	   /* free nodetype specific data, and release no longer needed LPI states */
1096 	   switch( SCIPnodeGetType(*node) )
1097 	   {
1098 	   case SCIP_NODETYPE_FOCUSNODE:
1099 	      assert(tree->focusnode == *node);
1100 	      assert(!SCIPtreeProbing(tree));
1101 	      SCIPerrorMessage("cannot free focus node - has to be converted into a dead end first\n");
1102 	      return SCIP_INVALIDDATA;
1103 	   case SCIP_NODETYPE_PROBINGNODE:
1104 	      assert(SCIPtreeProbing(tree));
1105 	      assert(SCIPnodeGetDepth(tree->probingroot) <= SCIPnodeGetDepth(*node));
1106 	      assert(SCIPnodeGetDepth(*node) > 0);
1107 	      SCIP_CALL( probingnodeFree(&((*node)->data.probingnode), blkmem, lp) );
1108 	      break;
1109 	   case SCIP_NODETYPE_SIBLING:
1110 	      assert((*node)->data.sibling.arraypos >= 0);
1111 	      assert((*node)->data.sibling.arraypos < tree->nsiblings);
1112 	      assert(tree->siblings[(*node)->data.sibling.arraypos] == *node);
1113 	      if( tree->focuslpstatefork != NULL )
1114 	      {
1115 	         assert(SCIPnodeGetType(tree->focuslpstatefork) == SCIP_NODETYPE_FORK
1116 	            || SCIPnodeGetType(tree->focuslpstatefork) == SCIP_NODETYPE_SUBROOT);
1117 	         SCIP_CALL( SCIPnodeReleaseLPIState(tree->focuslpstatefork, blkmem, lp) );
1118 	      }
1119 	      treeRemoveSibling(tree, *node);
1120 	      break;
1121 	   case SCIP_NODETYPE_CHILD:
1122 	      assert((*node)->data.child.arraypos >= 0);
1123 	      assert((*node)->data.child.arraypos < tree->nchildren);
1124 	      assert(tree->children[(*node)->data.child.arraypos] == *node);
1125 	      /* The children capture the LPI state at the moment, where the focus node is
1126 	       * converted into a junction, pseudofork, fork, or subroot, and a new node is focused.
1127 	       * At the same time, they become siblings or leaves, such that freeing a child
1128 	       * of the focus node doesn't require to release the LPI state;
1129 	       * we don't need to call treeRemoveChild(), because this is done in nodeReleaseParent()
1130 	       */
1131 	      break;
1132 	   case SCIP_NODETYPE_LEAF:
1133 	      if( (*node)->data.leaf.lpstatefork != NULL )
1134 	      {
1135 	         SCIP_CALL( SCIPnodeReleaseLPIState((*node)->data.leaf.lpstatefork, blkmem, lp) );
1136 	      }
1137 	      break;
1138 	   case SCIP_NODETYPE_DEADEND:
1139 	   case SCIP_NODETYPE_JUNCTION:
1140 	      break;
1141 	   case SCIP_NODETYPE_PSEUDOFORK:
1142 	      SCIP_CALL( pseudoforkFree(&((*node)->data.pseudofork), blkmem, set, lp) );
1143 	      break;
1144 	   case SCIP_NODETYPE_FORK:
1145 	
1146 	      /* release special root LPI state capture which is used to keep the root LPI state over the whole solving
1147 	       * process
1148 	       */
1149 	      if( isroot )
1150 	      {
1151 	         SCIP_CALL( SCIPnodeReleaseLPIState(*node, blkmem, lp) );
1152 	      }
1153 	      SCIP_CALL( forkFree(&((*node)->data.fork), blkmem, set, lp) );
1154 	      break;
1155 	   case SCIP_NODETYPE_SUBROOT:
1156 	      SCIP_CALL( subrootFree(&((*node)->data.subroot), blkmem, set, lp) );
1157 	      break;
1158 	   case SCIP_NODETYPE_REFOCUSNODE:
1159 	      SCIPerrorMessage("cannot free node as long it is refocused\n");
1160 	      return SCIP_INVALIDDATA;
1161 	   default:
1162 	      SCIPerrorMessage("unknown node type %d\n", SCIPnodeGetType(*node));
1163 	      return SCIP_INVALIDDATA;
1164 	   }
1165 	
1166 	   /* free common data */
1167 	   SCIP_CALL( SCIPconssetchgFree(&(*node)->conssetchg, blkmem, set) );
1168 	   SCIP_CALL( SCIPdomchgFree(&(*node)->domchg, blkmem, set, eventqueue, lp) );
1169 	   SCIP_CALL( nodeReleaseParent(*node, blkmem, set, stat, eventfilter, eventqueue, tree, lp) );
1170 	
1171 	   /* check, if the node is the current probing root */
1172 	   if( *node == tree->probingroot )
1173 	   {
1174 	      assert(SCIPnodeGetType(*node) == SCIP_NODETYPE_PROBINGNODE);
1175 	      tree->probingroot = NULL;
1176 	   }
1177 	
1178 	   BMSfreeBlockMemory(blkmem, node);
1179 	
1180 	   /* delete the tree's root node pointer, if the freed node was the root */
1181 	   if( isroot )
1182 	      tree->root = NULL;
1183 	
1184 	   return SCIP_OKAY;
1185 	}
1186 	
1187 	/** cuts off node and whole sub tree from branch and bound tree */
1188 	SCIP_RETCODE SCIPnodeCutoff(
1189 	   SCIP_NODE*            node,               /**< node that should be cut off */
1190 	   SCIP_SET*             set,                /**< global SCIP settings */
1191 	   SCIP_STAT*            stat,               /**< problem statistics */
1192 	   SCIP_TREE*            tree,               /**< branch and bound tree */
1193 	   SCIP_PROB*            transprob,          /**< transformed problem after presolve */
1194 	   SCIP_PROB*            origprob,           /**< original problem */
1195 	   SCIP_REOPT*           reopt,              /**< reoptimization data structure */
1196 	   SCIP_LP*              lp,                 /**< current LP */
1197 	   BMS_BLKMEM*           blkmem              /**< block memory */
1198 	   )
1199 	{
1200 	   SCIP_Real oldbound;
1201 	
1202 	   assert(node != NULL);
1203 	   assert(set != NULL);
1204 	   assert(stat != NULL);
1205 	   assert(tree != NULL);
1206 	
1207 	   if( set->reopt_enable )
1208 	   {
1209 	      assert(reopt != NULL);
1210 	      /* check if the node should be stored for reoptimization */
1211 	      SCIP_CALL( SCIPreoptCheckCutoff(reopt, set, blkmem, node, SCIP_EVENTTYPE_NODEINFEASIBLE, lp, SCIPlpGetSolstat(lp),
1212 	            tree->root == node, tree->focusnode == node, node->lowerbound, tree->effectiverootdepth) );
1213 	   }
1214 	
1215 	   oldbound = node->lowerbound;
1216 	   node->cutoff = TRUE;
1217 	   node->lowerbound = SCIPsetInfinity(set);
1218 	   node->estimate = SCIPsetInfinity(set);
1219 	   if( node->active )
1220 	      tree->cutoffdepth = MIN(tree->cutoffdepth, (int)node->depth);
1221 	
1222 	   /* update primal integral */
1223 	   if( node->depth == 0 )
1224 	   {
1225 	      stat->rootlowerbound = SCIPsetInfinity(set);
1226 	      if( set->misc_calcintegral )
1227 	         SCIPstatUpdatePrimalDualIntegrals(stat, set, transprob, origprob, SCIPsetInfinity(set), SCIPsetInfinity(set));
1228 	   }
1229 	   else if( set->misc_calcintegral && SCIPsetIsEQ(set, oldbound, stat->lastlowerbound) )
1230 	   {
1231 	      SCIP_Real lowerbound;
1232 	      lowerbound = SCIPtreeGetLowerbound(tree, set);
1233 	
1234 	      /* updating the primal integral is only necessary if dual bound has increased since last evaluation */
1235 	      if( lowerbound > stat->lastlowerbound )
1236 	         SCIPstatUpdatePrimalDualIntegrals(stat, set, transprob, origprob, SCIPsetInfinity(set), SCIPsetInfinity(set));
1237 	   }
1238 	
1239 	   SCIPvisualCutoffNode(stat->visual, set, stat, node, TRUE);
1240 	
1241 	   SCIPsetDebugMsg(set, "cutting off %s node #%" SCIP_LONGINT_FORMAT " at depth %d (cutoffdepth: %d)\n",
1242 	      node->active ? "active" : "inactive", SCIPnodeGetNumber(node), SCIPnodeGetDepth(node), tree->cutoffdepth);
1243 	
1244 	   return SCIP_OKAY;
1245 	}
1246 	
1247 	/** marks node, that propagation should be applied again the next time, a node of its subtree is focused */
1248 	void SCIPnodePropagateAgain(
1249 	   SCIP_NODE*            node,               /**< node that should be propagated again */
1250 	   SCIP_SET*             set,                /**< global SCIP settings */
1251 	   SCIP_STAT*            stat,               /**< problem statistics */
1252 	   SCIP_TREE*            tree                /**< branch and bound tree */
1253 	   )
1254 	{
1255 	   assert(node != NULL);
1256 	   assert(set != NULL);
1257 	   assert(stat != NULL);
1258 	   assert(tree != NULL);
1259 	
1260 	   if( !node->reprop )
1261 	   {
1262 	      node->reprop = TRUE;
1263 	      if( node->active )
1264 	         tree->repropdepth = MIN(tree->repropdepth, (int)node->depth);
1265 	
1266 	      SCIPvisualMarkedRepropagateNode(stat->visual, stat, node);
1267 	
1268 	      SCIPsetDebugMsg(set, "marked %s node #%" SCIP_LONGINT_FORMAT " at depth %d to be propagated again (repropdepth: %d)\n",
1269 	         node->active ? "active" : "inactive", SCIPnodeGetNumber(node), SCIPnodeGetDepth(node), tree->repropdepth);
1270 	   }
1271 	}
1272 	
1273 	/** marks node, that it is completely propagated in the current repropagation subtree level */
1274 	void SCIPnodeMarkPropagated(
1275 	   SCIP_NODE*            node,               /**< node that should be marked to be propagated */
1276 	   SCIP_TREE*            tree                /**< branch and bound tree */
1277 	   )
1278 	{
1279 	   assert(node != NULL);
1280 	   assert(tree != NULL);
1281 	
1282 	   if( node->parent != NULL )
1283 	      node->repropsubtreemark = node->parent->repropsubtreemark; /*lint !e732*/
1284 	   node->reprop = FALSE;
1285 	
1286 	   /* if the node was the highest repropagation node in the path, update the repropdepth in the tree data */
1287 	   if( node->active && node->depth == tree->repropdepth )
1288 	   {
1289 	      do
1290 	      {
1291 	         assert(tree->repropdepth < tree->pathlen);
1292 	         assert(tree->path[tree->repropdepth]->active);
1293 	         assert(!tree->path[tree->repropdepth]->reprop);
1294 	         tree->repropdepth++;
1295 	      }
1296 	      while( tree->repropdepth < tree->pathlen && !tree->path[tree->repropdepth]->reprop );
1297 	      if( tree->repropdepth == tree->pathlen )
1298 	         tree->repropdepth = INT_MAX;
1299 	   }
1300 	}
1301 	
1302 	/** moves the subtree repropagation counter to the next value */
1303 	static
1304 	void treeNextRepropsubtreecount(
1305 	   SCIP_TREE*            tree                /**< branch and bound tree */
1306 	   )
1307 	{
1308 	   assert(tree != NULL);
1309 	
1310 	   tree->repropsubtreecount++;
1311 	   tree->repropsubtreecount %= (MAXREPROPMARK+1);
1312 	}
1313 	
1314 	/** applies propagation on the node, that was marked to be propagated again */
1315 	static
1316 	SCIP_RETCODE nodeRepropagate(
1317 	   SCIP_NODE*            node,               /**< node to apply propagation on */
1318 	   BMS_BLKMEM*           blkmem,             /**< block memory buffers */
1319 	   SCIP_SET*             set,                /**< global SCIP settings */
1320 	   SCIP_STAT*            stat,               /**< dynamic problem statistics */
1321 	   SCIP_PROB*            transprob,          /**< transformed problem */
1322 	   SCIP_PROB*            origprob,           /**< original problem */
1323 	   SCIP_PRIMAL*          primal,             /**< primal data */
1324 	   SCIP_TREE*            tree,               /**< branch and bound tree */
1325 	   SCIP_REOPT*           reopt,              /**< reoptimization data structure */
1326 	   SCIP_LP*              lp,                 /**< current LP data */
1327 	   SCIP_BRANCHCAND*      branchcand,         /**< branching candidate storage */
1328 	   SCIP_CONFLICT*        conflict,           /**< conflict analysis data */
1329 	   SCIP_EVENTFILTER*     eventfilter,        /**< event filter for global (not variable dependent) events */
1330 	   SCIP_EVENTQUEUE*      eventqueue,         /**< event queue */
1331 	   SCIP_CLIQUETABLE*     cliquetable,        /**< clique table data structure */
1332 	   SCIP_Bool*            cutoff              /**< pointer to store whether the node can be cut off */
1333 	   )
1334 	{
1335 	   SCIP_NODETYPE oldtype;
1336 	   SCIP_NODE* oldfocusnode;
1337 	   SCIP_NODE* oldfocuslpfork;
1338 	   SCIP_NODE* oldfocuslpstatefork;
1339 	   SCIP_NODE* oldfocussubroot;
1340 	   SCIP_Longint oldfocuslpstateforklpcount;
1341 	   int oldnchildren;
1342 	   int oldnsiblings;
1343 	   SCIP_Bool oldfocusnodehaslp;
1344 	   SCIP_Longint oldnboundchgs;
1345 	   SCIP_Bool initialreprop;
1346 	   SCIP_Bool clockisrunning;
1347 	
1348 	   assert(node != NULL);
1349 	   assert((SCIP_NODETYPE)node->nodetype == SCIP_NODETYPE_FOCUSNODE
1350 	      || (SCIP_NODETYPE)node->nodetype == SCIP_NODETYPE_JUNCTION
1351 	      || (SCIP_NODETYPE)node->nodetype == SCIP_NODETYPE_PSEUDOFORK
1352 	      || (SCIP_NODETYPE)node->nodetype == SCIP_NODETYPE_FORK
1353 	      || (SCIP_NODETYPE)node->nodetype == SCIP_NODETYPE_SUBROOT);
1354 	   assert(node->active);
1355 	   assert(node->reprop || node->repropsubtreemark != node->parent->repropsubtreemark);
1356 	   assert(stat != NULL);
1357 	   assert(tree != NULL);
1358 	   assert(SCIPeventqueueIsDelayed(eventqueue));
1359 	   assert(cutoff != NULL);
1360 	
1361 	   SCIPsetDebugMsg(set, "propagating again node #%" SCIP_LONGINT_FORMAT " at depth %d\n", SCIPnodeGetNumber(node), SCIPnodeGetDepth(node));
1362 	   initialreprop = node->reprop;
1363 	
1364 	   SCIPvisualRepropagatedNode(stat->visual, stat, node);
1365 	
1366 	   /* process the delayed events in order to flush the problem changes */
1367 	   SCIP_CALL( SCIPeventqueueProcess(eventqueue, blkmem, set, primal, lp, branchcand, eventfilter) );
1368 	
1369 	   /* stop node activation timer */
1370 	   clockisrunning = SCIPclockIsRunning(stat->nodeactivationtime);
1371 	   if( clockisrunning )
1372 	      SCIPclockStop(stat->nodeactivationtime, set);
1373 	
1374 	   /* mark the node refocused and temporarily install it as focus node */
1375 	   oldtype = (SCIP_NODETYPE)node->nodetype;
1376 	   oldfocusnode = tree->focusnode;
1377 	   oldfocuslpfork = tree->focuslpfork;
1378 	   oldfocuslpstatefork = tree->focuslpstatefork;
1379 	   oldfocussubroot = tree->focussubroot;
1380 	   oldfocuslpstateforklpcount = tree->focuslpstateforklpcount;
1381 	   oldnchildren = tree->nchildren;
1382 	   oldnsiblings = tree->nsiblings;
1383 	   oldfocusnodehaslp = tree->focusnodehaslp;
1384 	   node->nodetype = SCIP_NODETYPE_REFOCUSNODE; /*lint !e641*/
1385 	   tree->focusnode = node;
1386 	   tree->focuslpfork = NULL;
1387 	   tree->focuslpstatefork = NULL;
1388 	   tree->focussubroot = NULL;
1389 	   tree->focuslpstateforklpcount = -1;
1390 	   tree->nchildren = 0;
1391 	   tree->nsiblings = 0;
1392 	   tree->focusnodehaslp = FALSE;
1393 	
1394 	   /* propagate the domains again */
1395 	   oldnboundchgs = stat->nboundchgs;
1396 	   SCIP_CALL( SCIPpropagateDomains(blkmem, set, stat, transprob, origprob, tree, reopt, lp, branchcand,
1397 	         eventqueue, conflict, cliquetable, SCIPnodeGetDepth(node), 0, SCIP_PROPTIMING_ALWAYS, cutoff) );
1398 	   assert(!node->reprop || *cutoff);
1399 	   assert(node->parent == NULL || node->repropsubtreemark == node->parent->repropsubtreemark);
1400 	   assert((SCIP_NODETYPE)node->nodetype == SCIP_NODETYPE_REFOCUSNODE);
1401 	   assert(tree->focusnode == node);
1402 	   assert(tree->focuslpfork == NULL);
1403 	   assert(tree->focuslpstatefork == NULL);
1404 	   assert(tree->focussubroot == NULL);
1405 	   assert(tree->focuslpstateforklpcount == -1);
1406 	   assert(tree->nchildren == 0);
1407 	   assert(tree->nsiblings == 0);
1408 	   assert(tree->focusnodehaslp == FALSE);
1409 	   assert(stat->nboundchgs >= oldnboundchgs);
1410 	   stat->nreprops++;
1411 	   stat->nrepropboundchgs += stat->nboundchgs - oldnboundchgs;
1412 	   if( *cutoff )
1413 	      stat->nrepropcutoffs++;
1414 	
1415 	   SCIPsetDebugMsg(set, "repropagation %" SCIP_LONGINT_FORMAT " at depth %u changed %" SCIP_LONGINT_FORMAT " bounds (total reprop bound changes: %" SCIP_LONGINT_FORMAT "), cutoff: %u\n",
1416 	      stat->nreprops, node->depth, stat->nboundchgs - oldnboundchgs, stat->nrepropboundchgs, *cutoff);
1417 	
1418 	   /* if a propagation marked with the reprop flag was successful, we want to repropagate the whole subtree */
1419 	   /**@todo because repropsubtree is only a bit flag, we cannot mark a whole subtree a second time for
1420 	    *       repropagation; use a (small) part of the node's bits to be able to store larger numbers,
1421 	    *       and update tree->repropsubtreelevel with this number
1422 	    */
1423 	   if( initialreprop && !(*cutoff) && stat->nboundchgs > oldnboundchgs )
1424 	   {
1425 	      treeNextRepropsubtreecount(tree);
1426 	      node->repropsubtreemark = tree->repropsubtreecount; /*lint !e732*/
1427 	      SCIPsetDebugMsg(set, "initial repropagation at depth %u changed %" SCIP_LONGINT_FORMAT " bounds -> repropagating subtree (new mark: %d)\n",
1428 	         node->depth, stat->nboundchgs - oldnboundchgs, tree->repropsubtreecount);
1429 	      assert((int)(node->repropsubtreemark) == tree->repropsubtreecount); /* bitfield must be large enough */
1430 	   }
1431 	
1432 	   /* reset the node's type and reinstall the old focus node */
1433 	   node->nodetype = oldtype; /*lint !e641*/
1434 	   tree->focusnode = oldfocusnode;
1435 	   tree->focuslpfork = oldfocuslpfork;
1436 	   tree->focuslpstatefork = oldfocuslpstatefork;
1437 	   tree->focussubroot = oldfocussubroot;
1438 	   tree->focuslpstateforklpcount = oldfocuslpstateforklpcount;
1439 	   tree->nchildren = oldnchildren;
1440 	   tree->nsiblings = oldnsiblings;
1441 	   tree->focusnodehaslp = oldfocusnodehaslp;
1442 	
1443 	   /* make the domain change data static again to save memory */
1444 	   if( (SCIP_NODETYPE)node->nodetype != SCIP_NODETYPE_FOCUSNODE )
1445 	   {
1446 	      SCIP_CALL( SCIPdomchgMakeStatic(&node->domchg, blkmem, set, eventqueue, lp) );
1447 	   }
1448 	
1449 	   /* start node activation timer again */
1450 	   if( clockisrunning )
1451 	      SCIPclockStart(stat->nodeactivationtime, set);
1452 	
1453 	   /* delay events in path switching */
1454 	   SCIP_CALL( SCIPeventqueueDelay(eventqueue) );
1455 	
1456 	   /* mark the node to be cut off if a cutoff was detected */
1457 	   if( *cutoff )
1458 	   {
1459 	      SCIP_CALL( SCIPnodeCutoff(node, set, stat, tree, transprob, origprob, reopt, lp, blkmem) );
1460 	   }
1461 	
1462 	   return SCIP_OKAY;
1463 	}
1464 	
1465 	/** informs node, that it is now on the active path and applies any domain and constraint set changes */
1466 	static
1467 	SCIP_RETCODE nodeActivate(
1468 	   SCIP_NODE*            node,               /**< node to activate */
1469 	   BMS_BLKMEM*           blkmem,             /**< block memory buffers */
1470 	   SCIP_SET*             set,                /**< global SCIP settings */
1471 	   SCIP_STAT*            stat,               /**< problem statistics */
1472 	   SCIP_PROB*            transprob,          /**< transformed problem */
1473 	   SCIP_PROB*            origprob,           /**< original problem */
1474 	   SCIP_PRIMAL*          primal,             /**< primal data */
1475 	   SCIP_TREE*            tree,               /**< branch and bound tree */
1476 	   SCIP_REOPT*           reopt,              /**< reotimization data structure */
1477 	   SCIP_LP*              lp,                 /**< current LP data */
1478 	   SCIP_BRANCHCAND*      branchcand,         /**< branching candidate storage */
1479 	   SCIP_CONFLICT*        conflict,           /**< conflict analysis data */
1480 	   SCIP_EVENTFILTER*     eventfilter,        /**< event filter for global (not variable dependent) events */
1481 	   SCIP_EVENTQUEUE*      eventqueue,         /**< event queue */
1482 	   SCIP_CLIQUETABLE*     cliquetable,        /**< clique table data structure */
1483 	   SCIP_Bool*            cutoff              /**< pointer to store whether the node can be cut off */
1484 	   )
1485 	{
1486 	   assert(node != NULL);
1487 	   assert(!node->active);
1488 	   assert(stat != NULL);
1489 	   assert(tree != NULL);
1490 	   assert(!SCIPtreeProbing(tree));
1491 	   assert(cutoff != NULL);
1492 	
1493 	   SCIPsetDebugMsg(set, "activate node #%" SCIP_LONGINT_FORMAT " at depth %d of type %d (reprop subtree mark: %u)\n",
1494 	      SCIPnodeGetNumber(node), SCIPnodeGetDepth(node), SCIPnodeGetType(node), node->repropsubtreemark);
1495 	
1496 	   /* apply domain and constraint set changes */
1497 	   SCIP_CALL( SCIPconssetchgApply(node->conssetchg, blkmem, set, stat, (int) node->depth,
1498 	         (SCIPnodeGetType(node) == SCIP_NODETYPE_FOCUSNODE)) );
1499 	   SCIP_CALL( SCIPdomchgApply(node->domchg, blkmem, set, stat, lp, branchcand, eventqueue, (int) node->depth, cutoff) );
1500 	
1501 	   /* mark node active */
1502 	   node->active = TRUE;
1503 	   stat->nactivatednodes++;
1504 	
1505 	   /* check if the domain change produced a cutoff */
1506 	   if( *cutoff )
1507 	   {
1508 	      /* try to repropagate the node to see, if the propagation also leads to a conflict and a conflict constraint
1509 	       * could be generated; if propagation conflict analysis is turned off, repropagating the node makes no
1510 	       * sense, since it is already cut off
1511 	       */
1512 	      node->reprop = set->conf_enable && set->conf_useprop;
1513 	
1514 	      /* mark the node to be cut off */
1515 	      SCIP_CALL( SCIPnodeCutoff(node, set, stat, tree, transprob, origprob, reopt, lp, blkmem) );
1516 	   }
1517 	
1518 	   /* propagate node again, if the reprop flag is set; in the new focus node, no repropagation is necessary, because
1519 	    * the focus node is propagated anyways
1520 	    */
1521 	   if( SCIPnodeGetType(node) != SCIP_NODETYPE_FOCUSNODE
1522 	      && (node->reprop || (node->parent != NULL && node->repropsubtreemark != node->parent->repropsubtreemark)) )
1523 	   {
1524 	      SCIP_Bool propcutoff;
1525 	
1526 	      SCIP_CALL( nodeRepropagate(node, blkmem, set, stat, transprob, origprob, primal, tree, reopt, lp, branchcand, conflict,
1527 	            eventfilter, eventqueue, cliquetable, &propcutoff) );
1528 	      *cutoff = *cutoff || propcutoff;
1529 	   }
1530 	
1531 	   return SCIP_OKAY;
1532 	}
1533 	
1534 	/** informs node, that it is no longer on the active path and undoes any domain and constraint set changes */
1535 	static
1536 	SCIP_RETCODE nodeDeactivate(
1537 	   SCIP_NODE*            node,               /**< node to deactivate */
1538 	   BMS_BLKMEM*           blkmem,             /**< block memory buffers */
1539 	   SCIP_SET*             set,                /**< global SCIP settings */
1540 	   SCIP_STAT*            stat,               /**< problem statistics */
1541 	   SCIP_TREE*            tree,               /**< branch and bound tree */
1542 	   SCIP_LP*              lp,                 /**< current LP data */
1543 	   SCIP_BRANCHCAND*      branchcand,         /**< branching candidate storage */
1544 	   SCIP_EVENTFILTER*     eventfilter,        /**< event filter for global (not variable dependent) events */
1545 	   SCIP_EVENTQUEUE*      eventqueue          /**< event queue */
1546 	   )
1547 	{
1548 	   SCIP_Bool freeNode;
1549 	
1550 	   assert(node != NULL);
1551 	   assert(node->active);
1552 	   assert(tree != NULL);
1553 	   assert(SCIPnodeGetType(node) != SCIP_NODETYPE_FOCUSNODE);
1554 	
1555 	   SCIPsetDebugMsg(set, "deactivate node #%" SCIP_LONGINT_FORMAT " at depth %d of type %d (reprop subtree mark: %u)\n",
1556 	      SCIPnodeGetNumber(node), SCIPnodeGetDepth(node), SCIPnodeGetType(node), node->repropsubtreemark);
1557 	
1558 	   /* undo domain and constraint set changes */
1559 	   SCIP_CALL( SCIPdomchgUndo(node->domchg, blkmem, set, stat, lp, branchcand, eventqueue) );
1560 	   SCIP_CALL( SCIPconssetchgUndo(node->conssetchg, blkmem, set, stat) );
1561 	
1562 	   /* mark node inactive */
1563 	   node->active = FALSE;
1564 	
1565 	   /* count number of deactivated nodes (ignoring probing switches) */
1566 	   if( !SCIPtreeProbing(tree) )
1567 	      stat->ndeactivatednodes++;
1568 	
1569 	   /* free node if it is a dead-end node, i.e., has no children */
1570 	   switch( SCIPnodeGetType(node) )   
1571 	   {
1572 	   case SCIP_NODETYPE_FOCUSNODE:
1573 	   case SCIP_NODETYPE_PROBINGNODE:
1574 	   case SCIP_NODETYPE_SIBLING:
1575 	   case SCIP_NODETYPE_CHILD:
1576 	   case SCIP_NODETYPE_LEAF:
1577 	   case SCIP_NODETYPE_DEADEND:
1578 	   case SCIP_NODETYPE_REFOCUSNODE:
1579 	      freeNode = FALSE;
1580 	      break;
1581 	   case SCIP_NODETYPE_JUNCTION:
1582 	      freeNode = (node->data.junction.nchildren == 0); 
1583 	      break;
1584 	   case SCIP_NODETYPE_PSEUDOFORK:
1585 	      freeNode = (node->data.pseudofork->nchildren == 0); 
1586 	      break;
1587 	   case SCIP_NODETYPE_FORK:
1588 	      freeNode = (node->data.fork->nchildren == 0); 
1589 	      break;
1590 	   case SCIP_NODETYPE_SUBROOT:
1591 	      freeNode = (node->data.subroot->nchildren == 0); 
1592 	      break;
1593 	   default:
1594 	      SCIPerrorMessage("unknown node type %d\n", SCIPnodeGetType(node));
1595 	      return SCIP_INVALIDDATA;
1596 	   }
1597 	   if( freeNode ) 
1598 	   {
1599 	      SCIP_CALL( SCIPnodeFree(&node, blkmem, set, stat, eventfilter, eventqueue, tree, lp) );
1600 	   }
1601 	
1602 	   return SCIP_OKAY;
1603 	}
1604 	
1605 	/** adds constraint locally to the node and captures it; activates constraint, if node is active;
1606 	 *  if a local constraint is added to the root node, it is automatically upgraded into a global constraint
1607 	 */
1608 	SCIP_RETCODE SCIPnodeAddCons(
1609 	   SCIP_NODE*            node,               /**< node to add constraint to */
1610 	   BMS_BLKMEM*           blkmem,             /**< block memory */
1611 	   SCIP_SET*             set,                /**< global SCIP settings */
1612 	   SCIP_STAT*            stat,               /**< problem statistics */
1613 	   SCIP_TREE*            tree,               /**< branch and bound tree */
1614 	   SCIP_CONS*            cons                /**< constraint to add */
1615 	   )
1616 	{
1617 	   assert(node != NULL);
1618 	   assert(cons != NULL);
1619 	   assert(cons->validdepth <= SCIPnodeGetDepth(node));
1620 	   assert(tree != NULL);
1621 	   assert(tree->effectiverootdepth >= 0);
1622 	   assert(tree->root != NULL);
1623 	   assert(SCIPconsIsGlobal(cons) || SCIPnodeGetDepth(node) > tree->effectiverootdepth);
1624 	
1625 	#ifndef NDEBUG
1626 	   /* check if we add this constraint to the same scip, where we create the constraint */
1627 	   if( cons->scip != set->scip )
1628 	   {
1629 	      SCIPerrorMessage("try to add a constraint of another scip instance\n");
1630 	      return SCIP_INVALIDDATA;
1631 	   }
1632 	#endif
1633 	
1634 	   /* add constraint addition to the node's constraint set change data, and activate constraint if node is active */
1635 	   SCIP_CALL( SCIPconssetchgAddAddedCons(&node->conssetchg, blkmem, set, stat, cons, (int) node->depth,
1636 	         (SCIPnodeGetType(node) == SCIP_NODETYPE_FOCUSNODE), node->active) );
1637 	   assert(node->conssetchg != NULL);
1638 	   assert(node->conssetchg->addedconss != NULL);
1639 	   assert(!node->active || SCIPconsIsActive(cons));
1640 	
1641 	   /* if the constraint is added to an active node which is not a probing node, increment the corresponding counter */
1642 	   if( node->active && SCIPnodeGetType(node) != SCIP_NODETYPE_PROBINGNODE )
1643 	      stat->nactiveconssadded++;
1644 	
1645 	   return SCIP_OKAY;
1646 	}
1647 	
1648 	/** locally deletes constraint at the given node by disabling its separation, enforcing, and propagation capabilities
1649 	 *  at the node; captures constraint; disables constraint, if node is active
1650 	 */
1651 	SCIP_RETCODE SCIPnodeDelCons(
1652 	   SCIP_NODE*            node,               /**< node to add constraint to */
1653 	   BMS_BLKMEM*           blkmem,             /**< block memory */
1654 	   SCIP_SET*             set,                /**< global SCIP settings */
1655 	   SCIP_STAT*            stat,               /**< problem statistics */
1656 	   SCIP_TREE*            tree,               /**< branch and bound tree */
1657 	   SCIP_CONS*            cons                /**< constraint to locally delete */
1658 	   )
1659 	{
1660 	   assert(node != NULL);
1661 	   assert(tree != NULL);
1662 	   assert(cons != NULL);
1663 	
1664 	   SCIPsetDebugMsg(set, "disabling constraint <%s> at node at depth %u\n", cons->name, node->depth);
1665 	
1666 	   /* add constraint disabling to the node's constraint set change data */
1667 	   SCIP_CALL( SCIPconssetchgAddDisabledCons(&node->conssetchg, blkmem, set, cons) );
1668 	   assert(node->conssetchg != NULL);
1669 	   assert(node->conssetchg->disabledconss != NULL);
1670 	
1671 	   /* disable constraint, if node is active */
1672 	   if( node->active && cons->enabled && !cons->updatedisable )
1673 	   {
1674 	      SCIP_CALL( SCIPconsDisable(cons, set, stat) );
1675 	   }
1676 	
1677 	   return SCIP_OKAY;
1678 	}
1679 	
1680 	/** returns all constraints added to a given node */
1681 	void SCIPnodeGetAddedConss(
1682 	   SCIP_NODE*            node,               /**< node */
1683 	   SCIP_CONS**           addedconss,         /**< array to store the constraints */
1684 	   int*                  naddedconss,        /**< number of added constraints */
1685 	   int                   addedconsssize      /**< size of the constraint array */
1686 	   )
1687 	{
1688 	   int cons;
1689 	
1690 	   assert(node != NULL );
1691 	   assert(node->conssetchg != NULL);
1692 	   assert(node->conssetchg->addedconss != NULL);
1693 	   assert(node->conssetchg->naddedconss >= 1);
1694 	
1695 	   *naddedconss = node->conssetchg->naddedconss;
1696 	
1697 	   /* check the size and return if the array is not large enough */
1698 	   if( addedconsssize < *naddedconss )
1699 	      return;
1700 	
1701 	   /* fill the array */
1702 	   for( cons = 0; cons < *naddedconss; cons++ )
1703 	   {
1704 	      addedconss[cons] = node->conssetchg->addedconss[cons];
1705 	   }
1706 	
1707 	   return;
1708 	}
1709 	
1710 	/** returns the number of added constraints to the given node */
1711 	int SCIPnodeGetNAddedConss(
1712 	   SCIP_NODE*            node                /**< node */
1713 	   )
1714 	{
1715 	   assert(node != NULL);
1716 	
1717 	   if( node->conssetchg == NULL )
1718 	      return 0;
1719 	   else
1720 	      return node->conssetchg->naddedconss;
1721 	}
1722 	
1723 	/** adds the given bound change to the list of pending bound changes */
1724 	static
1725 	SCIP_RETCODE treeAddPendingBdchg(
1726 	   SCIP_TREE*            tree,               /**< branch and bound tree */
1727 	   SCIP_SET*             set,                /**< global SCIP settings */
1728 	   SCIP_NODE*            node,               /**< node to add bound change to */
1729 	   SCIP_VAR*             var,                /**< variable to change the bounds for */
1730 	   SCIP_Real             newbound,           /**< new value for bound */
1731 	   SCIP_BOUNDTYPE        boundtype,          /**< type of bound: lower or upper bound */
1732 	   SCIP_CONS*            infercons,          /**< constraint that deduced the bound change, or NULL */
1733 	   SCIP_PROP*            inferprop,          /**< propagator that deduced the bound change, or NULL */
1734 	   int                   inferinfo,          /**< user information for inference to help resolving the conflict */
1735 	   SCIP_Bool             probingchange       /**< is the bound change a temporary setting due to probing? */
1736 	   )
1737 	{
1738 	   assert(tree != NULL);
1739 	
1740 	   /* make sure that enough memory is allocated for the pendingbdchgs array */
1741 	   SCIP_CALL( treeEnsurePendingbdchgsMem(tree, set, tree->npendingbdchgs+1) );
1742 	
1743 	   /* capture the variable */
1744 	   SCIPvarCapture(var);
1745 	
1746 	   /* add the bound change to the pending list */
1747 	   tree->pendingbdchgs[tree->npendingbdchgs].node = node;
1748 	   tree->pendingbdchgs[tree->npendingbdchgs].var = var;
1749 	   tree->pendingbdchgs[tree->npendingbdchgs].newbound = newbound;
1750 	   tree->pendingbdchgs[tree->npendingbdchgs].boundtype = boundtype;
1751 	   tree->pendingbdchgs[tree->npendingbdchgs].infercons = infercons;
1752 	   tree->pendingbdchgs[tree->npendingbdchgs].inferprop = inferprop;
1753 	   tree->pendingbdchgs[tree->npendingbdchgs].inferinfo = inferinfo;
1754 	   tree->pendingbdchgs[tree->npendingbdchgs].probingchange = probingchange;
1755 	   tree->npendingbdchgs++;
1756 	
1757 	   /* check global pending boundchanges against debug solution */
1758 	   if( node->depth == 0 )
1759 	   {
1760 	#ifndef NDEBUG
1761 	      SCIP_Real bound = newbound;
1762 	
1763 	      /* get bound adjusted for integrality(, this should already be done) */
1764 	      SCIPvarAdjustBd(var, set, boundtype, &bound);
1765 	
1766 	      if( boundtype == SCIP_BOUNDTYPE_LOWER )
1767 	      {
1768 		 /* check that the bound is feasible */
1769 		 if( bound > SCIPvarGetUbGlobal(var) )
1770 		 {
1771 		    /* due to numerics we only want to be feasible in feasibility tolerance */
1772 		    assert(SCIPsetIsFeasLE(set, bound, SCIPvarGetUbGlobal(var)));
1773 		    bound = SCIPvarGetUbGlobal(var);
1774 		 }
1775 	      }
1776 	      else
1777 	      {
1778 		 assert(boundtype == SCIP_BOUNDTYPE_UPPER);
1779 	
1780 		 /* check that the bound is feasible */
1781 		 if( bound < SCIPvarGetLbGlobal(var) )
1782 		 {
1783 		    /* due to numerics we only want to be feasible in feasibility tolerance */
1784 		    assert(SCIPsetIsFeasGE(set, bound, SCIPvarGetLbGlobal(var)));
1785 		    bound = SCIPvarGetLbGlobal(var);
1786 		 }
1787 	      }
1788 	      /* check that the given bound was already adjusted for integrality */
1789 	      assert(SCIPsetIsEQ(set, newbound, bound));
1790 	#endif
1791 	      if( boundtype == SCIP_BOUNDTYPE_LOWER )
1792 	      {
1793 		 /* check bound on debugging solution */
1794 		 SCIP_CALL( SCIPdebugCheckLbGlobal(set->scip, var, newbound) ); /*lint !e506 !e774*/
1795 	      }
1796 	      else
1797 	      {
1798 		 assert(boundtype == SCIP_BOUNDTYPE_UPPER);
1799 	
1800 		 /* check bound on debugging solution */
1801 		 SCIP_CALL( SCIPdebugCheckUbGlobal(set->scip, var, newbound) ); /*lint !e506 !e774*/
1802 	      }
1803 	   }
1804 	
1805 	   return SCIP_OKAY;
1806 	}
1807 	
1808 	/** adds bound change with inference information to focus node, child of focus node, or probing node;
1809 	 *  if possible, adjusts bound to integral value;
1810 	 *  at most one of infercons and inferprop may be non-NULL
1811 	 */
1812 	SCIP_RETCODE SCIPnodeAddBoundinfer(
1813 	   SCIP_NODE*            node,               /**< node to add bound change to */
1814 	   BMS_BLKMEM*           blkmem,             /**< block memory */
1815 	   SCIP_SET*             set,                /**< global SCIP settings */
1816 	   SCIP_STAT*            stat,               /**< problem statistics */
1817 	   SCIP_PROB*            transprob,          /**< transformed problem after presolve */
1818 	   SCIP_PROB*            origprob,           /**< original problem */
1819 	   SCIP_TREE*            tree,               /**< branch and bound tree */
1820 	   SCIP_REOPT*           reopt,              /**< reoptimization data structure */
1821 	   SCIP_LP*              lp,                 /**< current LP data */
1822 	   SCIP_BRANCHCAND*      branchcand,         /**< branching candidate storage */
1823 	   SCIP_EVENTQUEUE*      eventqueue,         /**< event queue */
1824 	   SCIP_CLIQUETABLE*     cliquetable,        /**< clique table data structure */
1825 	   SCIP_VAR*             var,                /**< variable to change the bounds for */
1826 	   SCIP_Real             newbound,           /**< new value for bound */
1827 	   SCIP_BOUNDTYPE        boundtype,          /**< type of bound: lower or upper bound */
1828 	   SCIP_CONS*            infercons,          /**< constraint that deduced the bound change, or NULL */
1829 	   SCIP_PROP*            inferprop,          /**< propagator that deduced the bound change, or NULL */
1830 	   int                   inferinfo,          /**< user information for inference to help resolving the conflict */
1831 	   SCIP_Bool             probingchange       /**< is the bound change a temporary setting due to probing? */
1832 	   )
1833 	{
1834 	   SCIP_VAR* infervar;
1835 	   SCIP_BOUNDTYPE inferboundtype;
1836 	   SCIP_Real oldlb;
1837 	   SCIP_Real oldub;
1838 	   SCIP_Real oldbound;
1839 	   SCIP_Bool useglobal;
1840 	
1841 	   useglobal = (int) node->depth <= tree->effectiverootdepth;
1842 	   if( useglobal )
1843 	   {
1844 	      oldlb = SCIPvarGetLbGlobal(var);
1845 	      oldub = SCIPvarGetUbGlobal(var);
1846 	   }
1847 	   else
1848 	   {
1849 	      oldlb = SCIPvarGetLbLocal(var);
1850 	      oldub = SCIPvarGetUbLocal(var);
1851 	   }
1852 	
1853 	   assert(node != NULL);
1854 	   assert((SCIP_NODETYPE)node->nodetype == SCIP_NODETYPE_FOCUSNODE
1855 	      || (SCIP_NODETYPE)node->nodetype == SCIP_NODETYPE_PROBINGNODE
1856 	      || (SCIP_NODETYPE)node->nodetype == SCIP_NODETYPE_CHILD
1857 	      || (SCIP_NODETYPE)node->nodetype == SCIP_NODETYPE_REFOCUSNODE
1858 	      || node->depth == 0);
1859 	   assert(set != NULL);
1860 	   assert(tree != NULL);
1861 	   assert(tree->effectiverootdepth >= 0);
1862 	   assert(tree->root != NULL);
1863 	   assert(var != NULL);
1864 	   assert(node->active || (infercons == NULL && inferprop == NULL));
1865 	   assert((SCIP_NODETYPE)node->nodetype == SCIP_NODETYPE_PROBINGNODE || !probingchange);
1866 	   assert((boundtype == SCIP_BOUNDTYPE_LOWER && SCIPsetIsGT(set, newbound, oldlb))
1867 	         || (boundtype == SCIP_BOUNDTYPE_LOWER && newbound > oldlb && newbound * oldlb <= 0.0)
1868 	         || (boundtype == SCIP_BOUNDTYPE_UPPER && SCIPsetIsLT(set, newbound, oldub))
1869 	         || (boundtype == SCIP_BOUNDTYPE_UPPER && newbound < oldub && newbound * oldub <= 0.0));
1870 	
1871 	   SCIPsetDebugMsg(set, "adding boundchange at node %" SCIP_LONGINT_FORMAT " at depth %u to variable <%s>: old bounds=[%g,%g], new %s bound: %g (infer%s=<%s>, inferinfo=%d)\n",
1872 	      node->number, node->depth, SCIPvarGetName(var), SCIPvarGetLbLocal(var), SCIPvarGetUbLocal(var),
1873 	      boundtype == SCIP_BOUNDTYPE_LOWER ? "lower" : "upper", newbound, infercons != NULL ? "cons" : "prop",
1874 	      infercons != NULL ? SCIPconsGetName(infercons) : (inferprop != NULL ? SCIPpropGetName(inferprop) : "-"), inferinfo);
1875 	
1876 	   /* remember variable as inference variable, and get corresponding active variable, bound and bound type */
1877 	   infervar = var;
1878 	   inferboundtype = boundtype;
1879 	
1880 	   SCIP_CALL( SCIPvarGetProbvarBound(&var, &newbound, &boundtype) );
1881 	
1882 	   if( SCIPvarGetStatus(var) == SCIP_VARSTATUS_MULTAGGR )
1883 	   {
1884 	      SCIPerrorMessage("cannot change bounds of multi-aggregated variable <%s>\n", SCIPvarGetName(var));
1885 	      SCIPABORT();
1886 	      return SCIP_INVALIDDATA; /*lint !e527*/
1887 	   }
1888 	   assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_LOOSE || SCIPvarGetStatus(var) == SCIP_VARSTATUS_COLUMN);
1889 	
1890 	   /* the variable may have changed, make sure we have the correct bounds */
1891 	   if( useglobal )
1892 	   {
1893 	      oldlb = SCIPvarGetLbGlobal(var);
1894 	      oldub = SCIPvarGetUbGlobal(var);
1895 	   }
1896 	   else
1897 	   {
1898 	      oldlb = SCIPvarGetLbLocal(var);
1899 	      oldub = SCIPvarGetUbLocal(var);
1900 	   }
1901 	   assert(SCIPsetIsLE(set, oldlb, oldub));
1902 	
1903 	   if( boundtype == SCIP_BOUNDTYPE_LOWER )
1904 	   {
1905 	      /* adjust lower bound w.r.t. to integrality */
1906 	      SCIPvarAdjustLb(var, set, &newbound);
1907 	      assert(SCIPsetIsFeasLE(set, newbound, oldub));
1908 	      oldbound = oldlb;
1909 	      newbound = MIN(newbound, oldub);
1910 	
1911 	      if ( set->stage == SCIP_STAGE_SOLVING && SCIPsetIsInfinity(set, newbound) )
1912 	      {
1913 	         SCIPerrorMessage("cannot change lower bound of variable <%s> to infinity.\n", SCIPvarGetName(var));
1914 	         SCIPABORT();
1915 	         return SCIP_INVALIDDATA; /*lint !e527*/
1916 	      }
1917 	   }
1918 	   else
1919 	   {
1920 	      assert(boundtype == SCIP_BOUNDTYPE_UPPER);
1921 	
1922 	      /* adjust the new upper bound */
1923 	      SCIPvarAdjustUb(var, set, &newbound);
1924 	      assert(SCIPsetIsFeasGE(set, newbound, oldlb));
1925 	      oldbound = oldub;
1926 	      newbound = MAX(newbound, oldlb);
1927 	
1928 	      if ( set->stage == SCIP_STAGE_SOLVING && SCIPsetIsInfinity(set, -newbound) )
1929 	      {
1930 	         SCIPerrorMessage("cannot change upper bound of variable <%s> to minus infinity.\n", SCIPvarGetName(var));
1931 	         SCIPABORT();
1932 	         return SCIP_INVALIDDATA; /*lint !e527*/
1933 	      }
1934 	   }
1935 	
1936 	   /* after switching to the active variable, the bounds might become redundant
1937 	    * if this happens, ignore the bound change
1938 	    */
1939 	   if( (boundtype == SCIP_BOUNDTYPE_LOWER && !SCIPsetIsGT(set, newbound, oldlb))
1940 	       || (boundtype == SCIP_BOUNDTYPE_UPPER && !SCIPsetIsLT(set, newbound, oldub)) )
1941 	      return SCIP_OKAY;
1942 	
1943 	   SCIPsetDebugMsg(set, " -> transformed to active variable <%s>: old bounds=[%g,%g], new %s bound: %g, obj: %g\n",
1944 	      SCIPvarGetName(var), oldlb, oldub, boundtype == SCIP_BOUNDTYPE_LOWER ? "lower" : "upper", newbound,
1945 	      SCIPvarGetObj(var));
1946 	
1947 	   /* if the bound change takes place at an active node but is conflicting with the current local bounds,
1948 	    * we cannot apply it immediately because this would introduce inconsistencies to the bound change data structures
1949 	    * in the tree and to the bound change information data in the variable;
1950 	    * instead we have to remember the bound change as a pending bound change and mark the affected nodes on the active
1951 	    * path to be infeasible
1952 	    */
1953 	   if( node->active )
1954 	   {
1955 	      int conflictingdepth;
1956 	
1957 	      conflictingdepth = SCIPvarGetConflictingBdchgDepth(var, set, boundtype, newbound);
1958 	
1959 	      if( conflictingdepth >= 0 )
1960 	      {
1961 	         /* 0 would mean the bound change conflicts with a global bound */
1962 	         assert(conflictingdepth > 0);
1963 	         assert(conflictingdepth < tree->pathlen);
1964 	
1965 	         SCIPsetDebugMsg(set, " -> bound change <%s> %s %g violates current local bounds [%g,%g] since depth %d: remember for later application\n",
1966 	            SCIPvarGetName(var), boundtype == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=", newbound,
1967 	            SCIPvarGetLbLocal(var), SCIPvarGetUbLocal(var), conflictingdepth);
1968 	
1969 	         /* remember the pending bound change */
1970 	         SCIP_CALL( treeAddPendingBdchg(tree, set, node, var, newbound, boundtype, infercons, inferprop, inferinfo, 
1971 	               probingchange) );
1972 	
1973 	         /* mark the node with the conflicting bound change to be cut off */
1974 	         SCIP_CALL( SCIPnodeCutoff(tree->path[conflictingdepth], set, stat, tree, transprob, origprob, reopt, lp, blkmem) );
1975 	
1976 	         return SCIP_OKAY;
1977 	      }
1978 	   }
1979 	
1980 	   SCIPstatIncrement(stat, set, nboundchgs);
1981 	
1982 	   /* if we are in probing mode we have to additionally count the bound changes for the probing statistic */
1983 	   if( tree->probingroot != NULL )
1984 	      SCIPstatIncrement(stat, set, nprobboundchgs);
1985 	
1986 	   /* if the node is the root node: change local and global bound immediately */
1987 	   if( SCIPnodeGetDepth(node) <= tree->effectiverootdepth )
1988 	   {
1989 	      assert(node->active || tree->focusnode == NULL );
1990 	      assert(SCIPnodeGetType(node) != SCIP_NODETYPE_PROBINGNODE);
1991 	      assert(!probingchange);
1992 	
1993 	      SCIPsetDebugMsg(set, " -> bound change in root node: perform global bound change\n");
1994 	      SCIP_CALL( SCIPvarChgBdGlobal(var, blkmem, set, stat, lp, branchcand, eventqueue, cliquetable, newbound, boundtype) );
1995 	
1996 	      if( set->stage == SCIP_STAGE_SOLVING )
1997 	      {
1998 	         /* the root should be repropagated due to the bound change */
1999 	         SCIPnodePropagateAgain(tree->root, set, stat, tree);
2000 	         SCIPsetDebugMsg(set, "marked root node to be repropagated due to global bound change <%s>:[%g,%g] -> [%g,%g] found in depth %u\n",
2001 	            SCIPvarGetName(var), oldlb, oldub, boundtype == SCIP_BOUNDTYPE_LOWER ? newbound : oldlb,
2002 	            boundtype == SCIP_BOUNDTYPE_LOWER ? oldub : newbound, node->depth);
2003 	      }
2004 	
2005 	      return SCIP_OKAY;
2006 	   }
2007 	
2008 	   /* if the node is a child, or the bound is a temporary probing bound
2009 	    *  - the bound change is a branching decision
2010 	    *  - the child's lower bound can be updated due to the changed pseudo solution
2011 	    * otherwise:
2012 	    *  - the bound change is an inference
2013 	    */
2014 	   if( SCIPnodeGetType(node) == SCIP_NODETYPE_CHILD || probingchange )
2015 	   {
2016 	      SCIP_Real newpseudoobjval;
2017 	      SCIP_Real lpsolval;
2018 	
2019 	      assert(!node->active || SCIPnodeGetType(node) == SCIP_NODETYPE_PROBINGNODE);
2020 	
2021 	      /* get the solution value of variable in last solved LP on the active path:
2022 	       *  - if the LP was solved at the current node, the LP values of the columns are valid
2023 	       *  - if the last solved LP was the one in the current lpstatefork, the LP value in the columns are still valid
2024 	       *  - otherwise, the LP values are invalid
2025 	       */
2026 	      if( SCIPtreeHasCurrentNodeLP(tree)
2027 	         || (tree->focuslpstateforklpcount == stat->lpcount && SCIPvarGetStatus(var) == SCIP_VARSTATUS_COLUMN) )
2028 	      {
2029 	         lpsolval = SCIPvarGetLPSol(var);
2030 	      }
2031 	      else
2032 	         lpsolval = SCIP_INVALID;
2033 	
2034 	      /* remember the bound change as branching decision (infervar/infercons/inferprop are not important: use NULL) */
2035 	      SCIP_CALL( SCIPdomchgAddBoundchg(&node->domchg, blkmem, set, var, newbound, boundtype, SCIP_BOUNDCHGTYPE_BRANCHING, 
2036 	            lpsolval, NULL, NULL, NULL, 0, inferboundtype) );
2037 	
2038 	      /* update the child's lower bound */
2039 	      if( set->misc_exactsolve )
2040 	         newpseudoobjval = SCIPlpGetModifiedProvedPseudoObjval(lp, set, var, oldbound, newbound, boundtype);
2041 	      else
2042 	         newpseudoobjval = SCIPlpGetModifiedPseudoObjval(lp, set, transprob, var, oldbound, newbound, boundtype);
2043 	      SCIPnodeUpdateLowerbound(node, stat, set, tree, transprob, origprob, newpseudoobjval);
2044 	   }
2045 	   else
2046 	   {
2047 	      /* check the inferred bound change on the debugging solution */
2048 	      SCIP_CALL( SCIPdebugCheckInference(blkmem, set, node, var, newbound, boundtype) ); /*lint !e506 !e774*/
2049 	
2050 	      /* remember the bound change as inference (lpsolval is not important: use 0.0) */
2051 	      SCIP_CALL( SCIPdomchgAddBoundchg(&node->domchg, blkmem, set, var, newbound, boundtype,
2052 	            infercons != NULL ? SCIP_BOUNDCHGTYPE_CONSINFER : SCIP_BOUNDCHGTYPE_PROPINFER, 
2053 	            0.0, infervar, infercons, inferprop, inferinfo, inferboundtype) );
2054 	   }
2055 	
2056 	   assert(node->domchg != NULL);
2057 	   assert(node->domchg->domchgdyn.domchgtype == SCIP_DOMCHGTYPE_DYNAMIC); /*lint !e641*/
2058 	   assert(node->domchg->domchgdyn.boundchgs != NULL);
2059 	   assert(node->domchg->domchgdyn.nboundchgs > 0);
2060 	   assert(node->domchg->domchgdyn.boundchgs[node->domchg->domchgdyn.nboundchgs-1].var == var);
2061 	   assert(node->domchg->domchgdyn.boundchgs[node->domchg->domchgdyn.nboundchgs-1].newbound == newbound); /*lint !e777*/
2062 	
2063 	   /* if node is active, apply the bound change immediately */
2064 	   if( node->active )
2065 	   {
2066 	      SCIP_Bool cutoff;
2067 	
2068 	      /**@todo if the node is active, it currently must either be the effective root (see above) or the current node;
2069 	       *       if a bound change to an intermediate active node should be added, we must make sure, the bound change
2070 	       *       information array of the variable stays sorted (new info must be sorted in instead of putting it to
2071 	       *       the end of the array), and we should identify now redundant bound changes that are applied at a
2072 	       *       later node on the active path
2073 	       */
2074 	      assert(SCIPtreeGetCurrentNode(tree) == node); 
2075 	      SCIP_CALL( SCIPboundchgApply(&node->domchg->domchgdyn.boundchgs[node->domchg->domchgdyn.nboundchgs-1],
2076 	            blkmem, set, stat, lp, branchcand, eventqueue, (int) node->depth, node->domchg->domchgdyn.nboundchgs-1, &cutoff) );
2077 	      assert(node->domchg->domchgdyn.boundchgs[node->domchg->domchgdyn.nboundchgs-1].var == var);
2078 	      assert(!cutoff);
2079 	   }
2080 	
2081 	   return SCIP_OKAY;
2082 	}
2083 	
2084 	/** adds bound change to focus node, or child of focus node, or probing node;
2085 	 *  if possible, adjusts bound to integral value
2086 	 */
2087 	SCIP_RETCODE SCIPnodeAddBoundchg(
2088 	   SCIP_NODE*            node,               /**< node to add bound change to */
2089 	   BMS_BLKMEM*           blkmem,             /**< block memory */
2090 	   SCIP_SET*             set,                /**< global SCIP settings */
2091 	   SCIP_STAT*            stat,               /**< problem statistics */
2092 	   SCIP_PROB*            transprob,          /**< transformed problem after presolve */
2093 	   SCIP_PROB*            origprob,           /**< original problem */
2094 	   SCIP_TREE*            tree,               /**< branch and bound tree */
2095 	   SCIP_REOPT*           reopt,              /**< reoptimization data structure */
2096 	   SCIP_LP*              lp,                 /**< current LP data */
2097 	   SCIP_BRANCHCAND*      branchcand,         /**< branching candidate storage */
2098 	   SCIP_EVENTQUEUE*      eventqueue,         /**< event queue */
2099 	   SCIP_CLIQUETABLE*     cliquetable,        /**< clique table data structure */
2100 	   SCIP_VAR*             var,                /**< variable to change the bounds for */
2101 	   SCIP_Real             newbound,           /**< new value for bound */
2102 	   SCIP_BOUNDTYPE        boundtype,          /**< type of bound: lower or upper bound */
2103 	   SCIP_Bool             probingchange       /**< is the bound change a temporary setting due to probing? */
2104 	   )
2105 	{
2106 	   SCIP_CALL( SCIPnodeAddBoundinfer(node, blkmem, set, stat, transprob, origprob, tree, reopt, lp, branchcand, eventqueue,
2107 	         cliquetable, var, newbound, boundtype, NULL, NULL, 0, probingchange) );
2108 	
2109 	   return SCIP_OKAY;
2110 	}
2111 	
2112 	/** adds hole with inference information to focus node, child of focus node, or probing node;
2113 	 *  if possible, adjusts bound to integral value;
2114 	 *  at most one of infercons and inferprop may be non-NULL
2115 	 */
2116 	SCIP_RETCODE SCIPnodeAddHoleinfer(
2117 	   SCIP_NODE*            node,               /**< node to add bound change to */
2118 	   BMS_BLKMEM*           blkmem,             /**< block memory */
2119 	   SCIP_SET*             set,                /**< global SCIP settings */
2120 	   SCIP_STAT*            stat,               /**< problem statistics */
2121 	   SCIP_TREE*            tree,               /**< branch and bound tree */
2122 	   SCIP_EVENTQUEUE*      eventqueue,         /**< event queue */
2123 	   SCIP_VAR*             var,                /**< variable to change the bounds for */
2124 	   SCIP_Real             left,               /**< left bound of open interval defining the hole (left,right) */
2125 	   SCIP_Real             right,              /**< right bound of open interval defining the hole (left,right) */
2126 	   SCIP_CONS*            infercons,          /**< constraint that deduced the bound change, or NULL */
2127 	   SCIP_PROP*            inferprop,          /**< propagator that deduced the bound change, or NULL */
2128 	   int                   inferinfo,          /**< user information for inference to help resolving the conflict */
2129 	   SCIP_Bool             probingchange,      /**< is the bound change a temporary setting due to probing? */
2130 	   SCIP_Bool*            added               /**< pointer to store whether the hole was added, or NULL */
2131 	   )
2132 	{
2133 	#if 0
2134 	   SCIP_VAR* infervar;
2135 	#endif
2136 	
2137 	   assert(node != NULL);
2138 	   assert((SCIP_NODETYPE)node->nodetype == SCIP_NODETYPE_FOCUSNODE
2139 	      || (SCIP_NODETYPE)node->nodetype == SCIP_NODETYPE_PROBINGNODE
2140 	      || (SCIP_NODETYPE)node->nodetype == SCIP_NODETYPE_CHILD
2141 	      || (SCIP_NODETYPE)node->nodetype == SCIP_NODETYPE_REFOCUSNODE
2142 	      || node->depth == 0);
2143 	   assert(blkmem != NULL);
2144 	   assert(set != NULL);
2145 	   assert(tree != NULL);
2146 	   assert(tree->effectiverootdepth >= 0);
2147 	   assert(tree->root != NULL);
2148 	   assert(var != NULL);
2149 	   assert(node->active || (infercons == NULL && inferprop == NULL));
2150 	   assert((SCIP_NODETYPE)node->nodetype == SCIP_NODETYPE_PROBINGNODE || !probingchange);
2151 	
2152 	   /* the interval should not be empty */
2153 	   assert(SCIPsetIsLT(set, left, right));
2154 	
2155 	#ifndef NDEBUG
2156 	   {
2157 	      SCIP_Real adjustedleft;
2158 	      SCIP_Real adjustedright;
2159 	
2160 	      adjustedleft = left;
2161 	      adjustedright = right;
2162 	
2163 	      SCIPvarAdjustUb(var, set, &adjustedleft);
2164 	      SCIPvarAdjustLb(var, set, &adjustedright);
2165 	
2166 	      assert(SCIPsetIsEQ(set, left, adjustedleft));
2167 	      assert(SCIPsetIsEQ(set, right, adjustedright));
2168 	   }
2169 	#endif
2170 	
2171 	   /* the hole should lay within the lower and upper bounds */
2172 	   assert(SCIPsetIsGE(set, left, SCIPvarGetLbLocal(var)));
2173 	   assert(SCIPsetIsLE(set, right, SCIPvarGetUbLocal(var)));
2174 	
2175 	   SCIPsetDebugMsg(set, "adding hole (%g,%g) at node at depth %u to variable <%s>: bounds=[%g,%g], (infer%s=<%s>, inferinfo=%d)\n",
2176 	      left, right, node->depth, SCIPvarGetName(var), SCIPvarGetLbLocal(var), SCIPvarGetUbLocal(var), infercons != NULL ? "cons" : "prop",
2177 	      infercons != NULL ? SCIPconsGetName(infercons) : (inferprop != NULL ? SCIPpropGetName(inferprop) : "-"), inferinfo);
2178 	
2179 	#if 0
2180 	   /* remember variable as inference variable, and get corresponding active variable, bound and bound type */
2181 	   infervar = var;
2182 	#endif
2183 	   SCIP_CALL( SCIPvarGetProbvarHole(&var, &left, &right) );
2184 	
2185 	   if( SCIPvarGetStatus(var) == SCIP_VARSTATUS_MULTAGGR )
2186 	   {
2187 	      SCIPerrorMessage("cannot change bounds of multi-aggregated variable <%s>\n", SCIPvarGetName(var));
2188 	      SCIPABORT();
2189 	      return SCIP_INVALIDDATA; /*lint !e527*/
2190 	   }
2191 	   assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_LOOSE || SCIPvarGetStatus(var) == SCIP_VARSTATUS_COLUMN);
2192 	
2193 	   SCIPsetDebugMsg(set, " -> transformed to active variable <%s>: hole (%g,%g), obj: %g\n", SCIPvarGetName(var), left, right, SCIPvarGetObj(var));
2194 	
2195 	   stat->nholechgs++;
2196 	
2197 	   /* if we are in probing mode we have to additionally count the bound changes for the probing statistic */
2198 	   if( tree->probingroot != NULL )
2199 	      stat->nprobholechgs++;
2200 	
2201 	   /* if the node is the root node: change local and global bound immediately */
2202 	   if( SCIPnodeGetDepth(node) <= tree->effectiverootdepth )
2203 	   {
2204 	      assert(node->active || tree->focusnode == NULL );
2205 	      assert(SCIPnodeGetType(node) != SCIP_NODETYPE_PROBINGNODE);
2206 	      assert(!probingchange);
2207 	
2208 	      SCIPsetDebugMsg(set, " -> hole added in root node: perform global domain change\n");
2209 	      SCIP_CALL( SCIPvarAddHoleGlobal(var, blkmem, set, stat, eventqueue, left, right, added) );
2210 	
2211 	      if( set->stage == SCIP_STAGE_SOLVING && (*added) )
2212 	      {
2213 	         /* the root should be repropagated due to the bound change */
2214 	         SCIPnodePropagateAgain(tree->root, set, stat, tree);
2215 	         SCIPsetDebugMsg(set, "marked root node to be repropagated due to global added hole <%s>: (%g,%g) found in depth %u\n",
2216 	            SCIPvarGetName(var), left, right, node->depth);
2217 	      }
2218 	
2219 	      return SCIP_OKAY;
2220 	   }
2221 	
2222 	   /**@todo add adding of local domain holes */
2223 	
2224 	   (*added) = FALSE;
2225 	   SCIPerrorMessage("WARNING: currently domain holes can only be handled globally!\n");
2226 	
2227 	   stat->nholechgs--;
2228 	
2229 	   /* if we are in probing mode we have to additionally count the bound changes for the probing statistic */
2230 	   if( tree->probingroot != NULL )
2231 	      stat->nprobholechgs--;
2232 	
2233 	   return SCIP_OKAY;
2234 	}
2235 	
2236 	/** adds hole change to focus node, or child of focus node */
2237 	SCIP_RETCODE SCIPnodeAddHolechg(
2238 	   SCIP_NODE*            node,               /**< node to add bound change to */
2239 	   BMS_BLKMEM*           blkmem,             /**< block memory */
2240 	   SCIP_SET*             set,                /**< global SCIP settings */
2241 	   SCIP_STAT*            stat,               /**< problem statistics */
2242 	   SCIP_TREE*            tree,               /**< branch and bound tree */
2243 	   SCIP_EVENTQUEUE*      eventqueue,         /**< event queue */
2244 	   SCIP_VAR*             var,                /**< variable to change the bounds for */
2245 	   SCIP_Real             left,               /**< left bound of open interval defining the hole (left,right) */
2246 	   SCIP_Real             right,              /**< right bound of open interval defining the hole (left,right) */
2247 	   SCIP_Bool             probingchange,      /**< is the bound change a temporary setting due to probing? */
2248 	   SCIP_Bool*            added               /**< pointer to store whether the hole was added, or NULL */
2249 	   )
2250 	{
2251 	   assert(node != NULL);
2252 	   assert((SCIP_NODETYPE)node->nodetype == SCIP_NODETYPE_FOCUSNODE
2253 	      || (SCIP_NODETYPE)node->nodetype == SCIP_NODETYPE_PROBINGNODE
2254 	      || (SCIP_NODETYPE)node->nodetype == SCIP_NODETYPE_CHILD);
2255 	   assert(blkmem != NULL);
2256 	
2257 	   SCIPsetDebugMsg(set, "adding hole (%g,%g) at node at depth %u of variable <%s>\n",
2258 	      left, right, node->depth, SCIPvarGetName(var));
2259 	
2260 	   SCIP_CALL( SCIPnodeAddHoleinfer(node, blkmem, set, stat, tree, eventqueue, var, left, right,
2261 	         NULL, NULL, 0, probingchange, added) );
2262 	
2263 	   /**@todo apply hole change on active nodes and issue event */
2264 	
2265 	   return SCIP_OKAY;
2266 	}
2267 	
2268 	/** applies the pending bound changes */
2269 	static
2270 	SCIP_RETCODE treeApplyPendingBdchgs(
2271 	   SCIP_TREE*            tree,               /**< branch and bound tree */
2272 	   SCIP_REOPT*           reopt,              /**< reoptimization data structure */
2273 	   BMS_BLKMEM*           blkmem,             /**< block memory */
2274 	   SCIP_SET*             set,                /**< global SCIP settings */
2275 	   SCIP_STAT*            stat,               /**< problem statistics */
2276 	   SCIP_PROB*            transprob,          /**< transformed problem after presolve */
2277 	   SCIP_PROB*            origprob,           /**< original problem */
2278 	   SCIP_LP*              lp,                 /**< current LP data */
2279 	   SCIP_BRANCHCAND*      branchcand,         /**< branching candidate storage */
2280 	   SCIP_EVENTQUEUE*      eventqueue,         /**< event queue */
2281 	   SCIP_CLIQUETABLE*     cliquetable         /**< clique table data structure */
2282 	   )
2283 	{
2284 	   SCIP_VAR* var;
2285 	   int npendingbdchgs;
2286 	   int conflictdepth;
2287 	   int i;
2288 	
2289 	   assert(tree != NULL);
2290 	
2291 	   npendingbdchgs = tree->npendingbdchgs;
2292 	   for( i = 0; i < npendingbdchgs; ++i )
2293 	   {
2294 	      var = tree->pendingbdchgs[i].var;
2295 	      assert(SCIPnodeGetDepth(tree->pendingbdchgs[i].node) < tree->cutoffdepth);
2296 	
2297 	      conflictdepth = SCIPvarGetConflictingBdchgDepth(var, set, tree->pendingbdchgs[i].boundtype,
2298 	         tree->pendingbdchgs[i].newbound);
2299 	
2300 	      /* It can happen, that a pending bound change conflicts with the global bounds, because when it was collected, it
2301 	       * just conflicted with the local bounds, but a conflicting global bound change was applied afterwards. In this
2302 	       * case, we can cut off the node where the pending bound change should be applied.
2303 	       */
2304 	      if( conflictdepth == 0 )
2305 	      {
2306 	         SCIP_CALL( SCIPnodeCutoff(tree->pendingbdchgs[i].node, set, stat, tree, transprob, origprob, reopt, lp, blkmem) );
2307 	
2308 	         if( ((int) tree->pendingbdchgs[i].node->depth) <= tree->effectiverootdepth )
2309 	            break; /* break here to clear all pending bound changes */
2310 	         else
2311 	            continue;
2312 	      }
2313 	
2314 	      assert(conflictdepth == -1);
2315 	
2316 	      SCIPsetDebugMsg(set, "applying pending bound change <%s>[%g,%g] %s %g\n", SCIPvarGetName(var),
2317 	         SCIPvarGetLbLocal(var), SCIPvarGetUbLocal(var),
2318 	         tree->pendingbdchgs[i].boundtype == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=",
2319 	         tree->pendingbdchgs[i].newbound);
2320 	
2321 	      /* ignore bounds that are now redundant (for example, multiple entries in the pendingbdchgs for the same
2322 	       * variable)
2323 	       */
2324 	      if( tree->pendingbdchgs[i].boundtype == SCIP_BOUNDTYPE_LOWER )
2325 	      {
2326 	         SCIP_Real lb;
2327 	
2328 	         lb = SCIPvarGetLbLocal(var);
2329 	         if( !SCIPsetIsGT(set, tree->pendingbdchgs[i].newbound, lb) )
2330 	            continue;
2331 	      }
2332 	      else
2333 	      {
2334 	         SCIP_Real ub;
2335 	
2336 	         assert(tree->pendingbdchgs[i].boundtype == SCIP_BOUNDTYPE_UPPER);
2337 	         ub = SCIPvarGetUbLocal(var);
2338 	         if( !SCIPsetIsLT(set, tree->pendingbdchgs[i].newbound, ub) )
2339 	            continue;
2340 	      }
2341 	
2342 	      SCIP_CALL( SCIPnodeAddBoundinfer(tree->pendingbdchgs[i].node, blkmem, set, stat, transprob, origprob, tree, reopt,
2343 	            lp, branchcand, eventqueue, cliquetable, var, tree->pendingbdchgs[i].newbound, tree->pendingbdchgs[i].boundtype,
2344 	            tree->pendingbdchgs[i].infercons, tree->pendingbdchgs[i].inferprop, tree->pendingbdchgs[i].inferinfo,
2345 	            tree->pendingbdchgs[i].probingchange) );
2346 	      assert(tree->npendingbdchgs == npendingbdchgs); /* this time, the bound change can be applied! */
2347 	   }
2348 	
2349 	   /* clear pending bound changes */
2350 	   for( i = 0; i < tree->npendingbdchgs; ++i )
2351 	   {
2352 	      var = tree->pendingbdchgs[i].var;
2353 	      assert(var != NULL);
2354 	
2355 	      /* release the variable */
2356 	      SCIP_CALL( SCIPvarRelease(&var, blkmem, set, eventqueue, lp) );
2357 	   }
2358 	
2359 	   tree->npendingbdchgs = 0;
2360 	
2361 	   return SCIP_OKAY;
2362 	}
2363 	
2364 	/** if given value is larger than the node's lower bound, sets the node's lower bound to the new value */
2365 	void SCIPnodeUpdateLowerbound(
2366 	   SCIP_NODE*            node,               /**< node to update lower bound for */
2367 	   SCIP_STAT*            stat,               /**< problem statistics */
2368 	   SCIP_SET*             set,                /**< global SCIP settings */
2369 	   SCIP_TREE*            tree,               /**< branch and bound tree */
2370 	   SCIP_PROB*            transprob,          /**< transformed problem after presolve */
2371 	   SCIP_PROB*            origprob,           /**< original problem */
2372 	   SCIP_Real             newbound            /**< new lower bound for the node (if it's larger than the old one) */
2373 	   )
2374 	{
2375 	   assert(node != NULL);
2376 	   assert(stat != NULL);
2377 	
2378 	   if( newbound > node->lowerbound )
2379 	   {
2380 	      SCIP_Real oldbound;
2381 	
2382 	      oldbound = node->lowerbound;
2383 	      node->lowerbound = newbound;
2384 	      node->estimate = MAX(node->estimate, newbound);
2385 	
2386 	      if( node->depth == 0 )
2387 	      {
2388 	         stat->rootlowerbound = newbound;
2389 	         if( set->misc_calcintegral )
2390 	            SCIPstatUpdatePrimalDualIntegrals(stat, set, transprob, origprob, SCIPsetInfinity(set), newbound);
2391 	         SCIPvisualLowerbound(stat->visual, set, stat, newbound);
2392 	      }
2393 	      else if ( SCIPnodeGetType(node) != SCIP_NODETYPE_PROBINGNODE )
2394 	      {
2395 	         SCIP_Real lowerbound;
2396 	
2397 	         lowerbound = SCIPtreeGetLowerbound(tree, set);
2398 	         assert(newbound >= lowerbound);
2399 	         SCIPvisualLowerbound(stat->visual, set, stat, lowerbound);
2400 	
2401 	         /* updating the primal integral is only necessary if dual bound has increased since last evaluation */
2402 	         if( set->misc_calcintegral && SCIPsetIsEQ(set, oldbound, stat->lastlowerbound) && lowerbound > stat->lastlowerbound )
2403 	            SCIPstatUpdatePrimalDualIntegrals(stat, set, transprob, origprob, SCIPsetInfinity(set), lowerbound);
2404 	      }
2405 	   }
2406 	}
2407 	
2408 	/** updates lower bound of node using lower bound of LP */
2409 	SCIP_RETCODE SCIPnodeUpdateLowerboundLP(
2410 	   SCIP_NODE*            node,               /**< node to set lower bound for */
2411 	   SCIP_SET*             set,                /**< global SCIP settings */
2412 	   SCIP_STAT*            stat,               /**< problem statistics */
2413 	   SCIP_TREE*            tree,               /**< branch and bound tree */
2414 	   SCIP_PROB*            transprob,          /**< transformed problem after presolve */
2415 	   SCIP_PROB*            origprob,           /**< original problem */
2416 	   SCIP_LP*              lp                  /**< LP data */
2417 	   )
2418 	{
2419 	   SCIP_Real lpobjval;
2420 	
2421 	   assert(set != NULL);
2422 	   assert(lp->flushed);
2423 	
2424 	   /* in case of iteration or time limit, the LP value may not be a valid dual bound */
2425 	   /* @todo check for dual feasibility of LP solution and use sub-optimal solution if they are dual feasible */
2426 	   if( lp->lpsolstat == SCIP_LPSOLSTAT_ITERLIMIT || lp->lpsolstat == SCIP_LPSOLSTAT_TIMELIMIT )
2427 	      return SCIP_OKAY;
2428 	
2429 	   if( set->misc_exactsolve )
2430 	   {
2431 	      SCIP_CALL( SCIPlpGetProvedLowerbound(lp, set, &lpobjval) );
2432 	   }
2433 	   else
2434 	      lpobjval = SCIPlpGetObjval(lp, set, transprob);
2435 	
2436 	   SCIPnodeUpdateLowerbound(node, stat, set, tree, transprob, origprob, lpobjval);
2437 	
2438 	   return SCIP_OKAY;
2439 	}
2440 	
2441 	
2442 	/** change the node selection priority of the given child */
2443 	void SCIPchildChgNodeselPrio(
2444 	   SCIP_TREE*            tree,               /**< branch and bound tree */
2445 	   SCIP_NODE*            child,              /**< child to update the node selection priority */
2446 	   SCIP_Real             priority            /**< node selection priority value */
2447 	   )
2448 	{
2449 	   int pos;
2450 	
2451 	   assert( SCIPnodeGetType(child) == SCIP_NODETYPE_CHILD );
2452 	
2453 	   pos = child->data.child.arraypos;
2454 	   assert( pos >= 0 );
2455 	
2456 	   tree->childrenprio[pos] = priority;
2457 	}
2458 	
2459 	
2460 	/** sets the node's estimated bound to the new value */
2461 	void SCIPnodeSetEstimate(
2462 	   SCIP_NODE*            node,               /**< node to update lower bound for */
2463 	   SCIP_SET*             set,                /**< global SCIP settings */
2464 	   SCIP_Real             newestimate         /**< new estimated bound for the node */
2465 	   )
2466 	{
2467 	   assert(node != NULL);
2468 	   assert(set != NULL);
2469 	   assert(SCIPsetIsRelGE(set, newestimate, node->lowerbound));
2470 	
2471 	   /* due to numerical reasons we need this check, see https://git.zib.de/integer/scip/issues/2866 */
2472 	   if( node->lowerbound <= newestimate )
2473 	      node->estimate = newestimate;
2474 	}
2475 	
2476 	/** propagates implications of binary fixings at the given node triggered by the implication graph and the clique table */
2477 	SCIP_RETCODE SCIPnodePropagateImplics(
2478 	   SCIP_NODE*            node,               /**< node to propagate implications on */
2479 	   BMS_BLKMEM*           blkmem,             /**< block memory */
2480 	   SCIP_SET*             set,                /**< global SCIP settings */
2481 	   SCIP_STAT*            stat,               /**< problem statistics */
2482 	   SCIP_PROB*            transprob,          /**< transformed problem after presolve */
2483 	   SCIP_PROB*            origprob,           /**< original problem */
2484 	   SCIP_TREE*            tree,               /**< branch and bound tree */
2485 	   SCIP_REOPT*           reopt,              /**< reoptimization data structure */
2486 	   SCIP_LP*              lp,                 /**< current LP data */
2487 	   SCIP_BRANCHCAND*      branchcand,         /**< branching candidate storage */
2488 	   SCIP_EVENTQUEUE*      eventqueue,         /**< event queue */
2489 	   SCIP_CLIQUETABLE*     cliquetable,        /**< clique table data structure */
2490 	   SCIP_Bool*            cutoff              /**< pointer to store whether the node can be cut off */
2491 	   )
2492 	{
2493 	   int nboundchgs;
2494 	   int i;
2495 	
2496 	   assert(node != NULL);
2497 	   assert(SCIPnodeIsActive(node));
2498 	   assert(SCIPnodeGetType(node) == SCIP_NODETYPE_FOCUSNODE
2499 	      || SCIPnodeGetType(node) == SCIP_NODETYPE_REFOCUSNODE
2500 	      || SCIPnodeGetType(node) == SCIP_NODETYPE_PROBINGNODE);
2501 	   assert(cutoff != NULL);
2502 	
2503 	   SCIPsetDebugMsg(set, "implication graph propagation of node #%" SCIP_LONGINT_FORMAT " in depth %d\n",
2504 	      SCIPnodeGetNumber(node), SCIPnodeGetDepth(node));
2505 	
2506 	   *cutoff = FALSE;
2507 	
2508 	   /* propagate all fixings of binary variables performed at this node */
2509 	   nboundchgs = SCIPdomchgGetNBoundchgs(node->domchg);
2510 	   for( i = 0; i < nboundchgs && !(*cutoff); ++i )
2511 	   {
2512 	      SCIP_BOUNDCHG* boundchg;
2513 	      SCIP_VAR* var;
2514 	
2515 	      boundchg = SCIPdomchgGetBoundchg(node->domchg, i);
2516 	
2517 	      /* ignore redundant bound changes */
2518 	      if( SCIPboundchgIsRedundant(boundchg) )
2519 	         continue;
2520 	
2521 	      var = SCIPboundchgGetVar(boundchg);
2522 	      if( SCIPvarIsBinary(var) )
2523 	      {
2524 	         SCIP_Bool varfixing;
2525 	         int nimpls;
2526 	         SCIP_VAR** implvars;
2527 	         SCIP_BOUNDTYPE* impltypes;
2528 	         SCIP_Real* implbounds;
2529 	         SCIP_CLIQUE** cliques;
2530 	         int ncliques;
2531 	         int j;
2532 	
2533 	         varfixing = (SCIPboundchgGetBoundtype(boundchg) == SCIP_BOUNDTYPE_LOWER);
2534 	         nimpls = SCIPvarGetNImpls(var, varfixing);
2535 	         implvars = SCIPvarGetImplVars(var, varfixing);
2536 	         impltypes = SCIPvarGetImplTypes(var, varfixing);
2537 	         implbounds = SCIPvarGetImplBounds(var, varfixing);
2538 	
2539 	         /* apply implications */
2540 	         for( j = 0; j < nimpls; ++j )
2541 	         {
2542 	            SCIP_Real lb;
2543 	            SCIP_Real ub;
2544 	
2545 	            /* @note should this be checked here (because SCIPnodeAddBoundinfer fails for multi-aggregated variables)
2546 	             *       or should SCIPnodeAddBoundinfer() just return for multi-aggregated variables?
2547 	             */
2548 	            if( SCIPvarGetStatus(implvars[j]) == SCIP_VARSTATUS_MULTAGGR ||
2549 	                  SCIPvarGetStatus(SCIPvarGetProbvar(implvars[j])) == SCIP_VARSTATUS_MULTAGGR )
2550 	               continue;
2551 	
2552 	            /* check for infeasibility */
2553 	            lb = SCIPvarGetLbLocal(implvars[j]);
2554 	            ub = SCIPvarGetUbLocal(implvars[j]);
2555 	            if( impltypes[j] == SCIP_BOUNDTYPE_LOWER )
2556 	            {
2557 	               if( SCIPsetIsFeasGT(set, implbounds[j], ub) )
2558 	               {
2559 	                  *cutoff = TRUE;
2560 	                  return SCIP_OKAY;
2561 	               }
2562 	               if( SCIPsetIsFeasLE(set, implbounds[j], lb) )
2563 	                  continue;
2564 	            }
2565 	            else
2566 	            {
2567 	               if( SCIPsetIsFeasLT(set, implbounds[j], lb) )
2568 	               {
2569 	                  *cutoff = TRUE;
2570 	                  return SCIP_OKAY;
2571 	               }
2572 	               if( SCIPsetIsFeasGE(set, implbounds[j], ub) )
2573 	                  continue;
2574 	            }
2575 	
2576 	            /* @note the implication might affect a fixed variable (after resolving (multi-)aggregations);
2577 	             *       normally, the implication should have been deleted in that case, but this is only possible
2578 	             *       if the implied variable has the reverse implication stored as a variable bound;
2579 	             *       due to numerics, the variable bound may not be present and so the implication is not deleted
2580 	             */
2581 	            if( SCIPvarGetStatus(SCIPvarGetProbvar(implvars[j])) == SCIP_VARSTATUS_FIXED )
2582 	               continue;
2583 	
2584 	            /* apply the implication */
2585 	            SCIP_CALL( SCIPnodeAddBoundinfer(node, blkmem, set, stat, transprob, origprob, tree, reopt, lp, branchcand,
2586 	                  eventqueue, cliquetable, implvars[j], implbounds[j], impltypes[j], NULL, NULL, 0, FALSE) );
2587 	         }
2588 	
2589 	         /* apply cliques */
2590 	         ncliques = SCIPvarGetNCliques(var, varfixing);
2591 	         cliques = SCIPvarGetCliques(var, varfixing);
2592 	         for( j = 0; j < ncliques; ++j )
2593 	         {
2594 	            SCIP_VAR** vars;
2595 	            SCIP_Bool* values;
2596 	            int nvars;
2597 	            int k;
2598 	
2599 	            nvars = SCIPcliqueGetNVars(cliques[j]);
2600 	            vars = SCIPcliqueGetVars(cliques[j]);
2601 	            values = SCIPcliqueGetValues(cliques[j]);
2602 	            for( k = 0; k < nvars; ++k )
2603 	            {
2604 	               SCIP_Real lb;
2605 	               SCIP_Real ub;
2606 	
2607 	               assert(SCIPvarIsBinary(vars[k]));
2608 	
2609 	               if( SCIPvarGetStatus(vars[k]) == SCIP_VARSTATUS_MULTAGGR ||
2610 	                     SCIPvarGetStatus(SCIPvarGetProbvar(vars[k])) == SCIP_VARSTATUS_MULTAGGR )
2611 	                  continue;
2612 	
2613 	               if( vars[k] == var && values[k] == varfixing )
2614 	                  continue;
2615 	
2616 	               /* check for infeasibility */
2617 	               lb = SCIPvarGetLbLocal(vars[k]);
2618 	               ub = SCIPvarGetUbLocal(vars[k]);
2619 	               if( values[k] == FALSE )
2620 	               {
2621 	                  if( ub < 0.5 )
2622 	                  {
2623 	                     *cutoff = TRUE;
2624 	                     return SCIP_OKAY;
2625 	                  }
2626 	                  if( lb > 0.5 )
2627 	                     continue;
2628 	               }
2629 	               else
2630 	               {
2631 	                  if( lb > 0.5 )
2632 	                  {
2633 	                     *cutoff = TRUE;
2634 	                     return SCIP_OKAY;
2635 	                  }
2636 	                  if( ub < 0.5 )
2637 	                     continue;
2638 	               }
2639 	
2640 	               if( SCIPvarGetStatus(SCIPvarGetProbvar(vars[k])) == SCIP_VARSTATUS_FIXED )
2641 	                  continue;
2642 	
2643 	               /* apply the clique implication */
2644 	               SCIP_CALL( SCIPnodeAddBoundinfer(node, blkmem, set, stat, transprob, origprob, tree, reopt, lp, branchcand,
2645 	                     eventqueue, cliquetable, vars[k], (SCIP_Real)(!values[k]), values[k] ? SCIP_BOUNDTYPE_UPPER : SCIP_BOUNDTYPE_LOWER,
2646 	                     NULL, NULL, 0, FALSE) );
2647 	            }
2648 	         }
2649 	      }
2650 	   }
2651 	
2652 	   return SCIP_OKAY;
2653 	}
2654 	
2655 	
2656 	
2657 	
2658 	/*
2659 	 * Path Switching
2660 	 */
2661 	
2662 	/** updates the LP sizes of the active path starting at the given depth */
2663 	static
2664 	SCIP_RETCODE treeUpdatePathLPSize(
2665 	   SCIP_TREE*            tree,               /**< branch and bound tree */
2666 	   int                   startdepth          /**< depth to start counting */
2667 	   )
2668 	{
2669 	   SCIP_NODE* node;
2670 	   int ncols;
2671 	   int nrows;
2672 	   int i;
2673 	
2674 	   assert(tree != NULL);
2675 	   assert(startdepth >= 0);
2676 	   assert(startdepth <= tree->pathlen);
2677 	
2678 	   if( startdepth == 0 )
2679 	   {
2680 	      ncols = 0;
2681 	      nrows = 0;
2682 	   }
2683 	   else
2684 	   {
2685 	      ncols = tree->pathnlpcols[startdepth-1];
2686 	      nrows = tree->pathnlprows[startdepth-1];
2687 	   }
2688 	
2689 	   for( i = startdepth; i < tree->pathlen; ++i )
2690 	   {
2691 	      node = tree->path[i];
2692 	      assert(node != NULL);
2693 	      assert(node->active);
2694 	      assert((int)(node->depth) == i);
2695 	
2696 	      switch( SCIPnodeGetType(node) )
2697 	      {
2698 	      case SCIP_NODETYPE_FOCUSNODE:
2699 	         assert(i == tree->pathlen-1 || SCIPtreeProbing(tree));
2700 	         break;
2701 	      case SCIP_NODETYPE_PROBINGNODE:
2702 	         assert(SCIPtreeProbing(tree));
2703 	         assert(i >= 1);
2704 	         assert(SCIPnodeGetType(tree->path[i-1]) == SCIP_NODETYPE_FOCUSNODE
2705 	            || (ncols == node->data.probingnode->ninitialcols && nrows == node->data.probingnode->ninitialrows));
2706 	         assert(ncols <= node->data.probingnode->ncols || !tree->focuslpconstructed);
2707 	         assert(nrows <= node->data.probingnode->nrows || !tree->focuslpconstructed);
2708 	         if( i < tree->pathlen-1 )
2709 	         {
2710 	            ncols = node->data.probingnode->ncols;
2711 	            nrows = node->data.probingnode->nrows;
2712 	         }
2713 	         else
2714 	         {
2715 	            /* for the current probing node, the initial LP size is stored in the path */
2716 	            ncols = node->data.probingnode->ninitialcols;
2717 	            nrows = node->data.probingnode->ninitialrows;
2718 	         }
2719 	         break;
2720 	      case SCIP_NODETYPE_SIBLING:
2721 	         SCIPerrorMessage("sibling cannot be in the active path\n");
2722 	         SCIPABORT();
2723 	         return SCIP_INVALIDDATA;  /*lint !e527*/
2724 	      case SCIP_NODETYPE_CHILD:
2725 	         SCIPerrorMessage("child cannot be in the active path\n");
2726 	         SCIPABORT();
2727 	         return SCIP_INVALIDDATA;  /*lint !e527*/
2728 	      case SCIP_NODETYPE_LEAF:
2729 	         SCIPerrorMessage("leaf cannot be in the active path\n");
2730 	         SCIPABORT();
2731 	         return SCIP_INVALIDDATA;  /*lint !e527*/
2732 	      case SCIP_NODETYPE_DEADEND:
2733 	         SCIPerrorMessage("dead-end cannot be in the active path\n");
2734 	         SCIPABORT();
2735 	         return SCIP_INVALIDDATA;  /*lint !e527*/
2736 	      case SCIP_NODETYPE_JUNCTION:
2737 	         break;
2738 	      case SCIP_NODETYPE_PSEUDOFORK:
2739 	         assert(node->data.pseudofork != NULL);
2740 	         ncols += node->data.pseudofork->naddedcols;
2741 	         nrows += node->data.pseudofork->naddedrows;
2742 	         break;
2743 	      case SCIP_NODETYPE_FORK:
2744 	         assert(node->data.fork != NULL);
2745 	         ncols += node->data.fork->naddedcols;
2746 	         nrows += node->data.fork->naddedrows;
2747 	         break;
2748 	      case SCIP_NODETYPE_SUBROOT:
2749 	         assert(node->data.subroot != NULL);
2750 	         ncols = node->data.subroot->ncols;
2751 	         nrows = node->data.subroot->nrows;
2752 	         break;
2753 	      case SCIP_NODETYPE_REFOCUSNODE:
2754 	         SCIPerrorMessage("node cannot be of type REFOCUSNODE at this point\n");
2755 	         SCIPABORT();
2756 	         return SCIP_INVALIDDATA;  /*lint !e527*/
2757 	      default:
2758 	         SCIPerrorMessage("unknown node type %d\n", SCIPnodeGetType(node));
2759 	         SCIPABORT();
2760 	         return SCIP_INVALIDDATA;  /*lint !e527*/
2761 	      }
2762 	      tree->pathnlpcols[i] = ncols;
2763 	      tree->pathnlprows[i] = nrows;
2764 	   }
2765 	   return SCIP_OKAY;
2766 	}
2767 	
2768 	/** finds the common fork node, the new LP state defining fork, and the new focus subroot, if the path is switched to
2769 	 *  the given node
2770 	 */
2771 	static
2772 	void treeFindSwitchForks(
2773 	   SCIP_TREE*            tree,               /**< branch and bound tree */
2774 	   SCIP_NODE*            node,               /**< new focus node, or NULL */
2775 	   SCIP_NODE**           commonfork,         /**< pointer to store common fork node of old and new focus node */
2776 	   SCIP_NODE**           newlpfork,          /**< pointer to store the new LP defining fork node */
2777 	   SCIP_NODE**           newlpstatefork,     /**< pointer to store the new LP state defining fork node */
2778 	   SCIP_NODE**           newsubroot,         /**< pointer to store the new subroot node */
2779 	   SCIP_Bool*            cutoff              /**< pointer to store whether the given node can be cut off and no path switching
2780 	                                              *   should be performed */
2781 	   )
2782 	{
2783 	   SCIP_NODE* fork;
2784 	   SCIP_NODE* lpfork;
2785 	   SCIP_NODE* lpstatefork;
2786 	   SCIP_NODE* subroot;
2787 	
2788 	   assert(tree != NULL);
2789 	   assert(tree->root != NULL);
2790 	   assert((tree->focusnode == NULL) == !tree->root->active);
2791 	   assert(tree->focuslpfork == NULL || tree->focusnode != NULL);
2792 	   assert(tree->focuslpfork == NULL || tree->focuslpfork->depth < tree->focusnode->depth);
2793 	   assert(tree->focuslpstatefork == NULL || tree->focuslpfork != NULL);
2794 	   assert(tree->focuslpstatefork == NULL || tree->focuslpstatefork->depth <= tree->focuslpfork->depth);
2795 	   assert(tree->focussubroot == NULL || tree->focuslpstatefork != NULL);
2796 	   assert(tree->focussubroot == NULL || tree->focussubroot->depth <= tree->focuslpstatefork->depth);
2797 	   assert(tree->cutoffdepth >= 0);
2798 	   assert(tree->cutoffdepth == INT_MAX || tree->cutoffdepth < tree->pathlen);
2799 	   assert(tree->cutoffdepth == INT_MAX || tree->path[tree->cutoffdepth]->cutoff);
2800 	   assert(tree->repropdepth >= 0);
2801 	   assert(tree->repropdepth == INT_MAX || tree->repropdepth < tree->pathlen);
2802 	   assert(tree->repropdepth == INT_MAX || tree->path[tree->repropdepth]->reprop);
2803 	   assert(commonfork != NULL);
2804 	   assert(newlpfork != NULL);
2805 	   assert(newlpstatefork != NULL);
2806 	   assert(newsubroot != NULL);
2807 	   assert(cutoff != NULL);
2808 	
2809 	   *commonfork = NULL;
2810 	   *newlpfork = NULL;
2811 	   *newlpstatefork = NULL;
2812 	   *newsubroot = NULL;
2813 	   *cutoff = FALSE;
2814 	
2815 	   /* if the new focus node is NULL, there is no common fork node, and the new LP fork, LP state fork, and subroot
2816 	    * are NULL
2817 	    */
2818 	   if( node == NULL )
2819 	   {
2820 	      tree->cutoffdepth = INT_MAX;
2821 	      tree->repropdepth = INT_MAX;
2822 	      return;
2823 	   }
2824 	
2825 	   /* check if the new node is marked to be cut off */
2826 	   if( node->cutoff )
2827 	   {
2828 	      *cutoff = TRUE;
2829 	      return;
2830 	   }
2831 	
2832 	   /* if the old focus node is NULL, there is no common fork node, and we have to search the new LP fork, LP state fork
2833 	    * and subroot
2834 	    */
2835 	   if( tree->focusnode == NULL )
2836 	   {
2837 	      assert(!tree->root->active);
2838 	      assert(tree->pathlen == 0);
2839 	      assert(tree->cutoffdepth == INT_MAX);
2840 	      assert(tree->repropdepth == INT_MAX);
2841 	
2842 	      lpfork = node;
2843 	      while( SCIPnodeGetType(lpfork) != SCIP_NODETYPE_PSEUDOFORK
2844 	         && SCIPnodeGetType(lpfork) != SCIP_NODETYPE_FORK && SCIPnodeGetType(lpfork) != SCIP_NODETYPE_SUBROOT )
2845 	      {
2846 	         lpfork = lpfork->parent;
2847 	         if( lpfork == NULL )
2848 	            return;
2849 	         if( lpfork->cutoff )
2850 	         {
2851 	            *cutoff = TRUE;
2852 	            return;
2853 	         }
2854 	      }
2855 	      *newlpfork = lpfork;
2856 	
2857 	      lpstatefork = lpfork;
2858 	      while( SCIPnodeGetType(lpstatefork) != SCIP_NODETYPE_FORK && SCIPnodeGetType(lpstatefork) != SCIP_NODETYPE_SUBROOT )
2859 	      {
2860 	         lpstatefork = lpstatefork->parent;
2861 	         if( lpstatefork == NULL )
2862 	            return;
2863 	         if( lpstatefork->cutoff )
2864 	         {
2865 	            *cutoff = TRUE;
2866 	            return;
2867 	         }
2868 	      }
2869 	      *newlpstatefork = lpstatefork;
2870 	
2871 	      subroot = lpstatefork;
2872 	      while( SCIPnodeGetType(subroot) != SCIP_NODETYPE_SUBROOT )
2873 	      {
2874 	         subroot = subroot->parent;
2875 	         if( subroot == NULL )
2876 	            return;
2877 	         if( subroot->cutoff )
2878 	         {
2879 	            *cutoff = TRUE;
2880 	            return;
2881 	         }
2882 	      }
2883 	      *newsubroot = subroot;
2884 	
2885 	      fork = subroot;
2886 	      while( fork->parent != NULL )
2887 	      {
2888 	         fork = fork->parent;
2889 	         if( fork->cutoff )
2890 	         {
2891 	            *cutoff = TRUE;
2892 	            return;
2893 	         }
2894 	      }
2895 	      return;
2896 	   }
2897 	
2898 	   /* find the common fork node, the new LP defining fork, the new LP state defining fork, and the new focus subroot */
2899 	   fork = node;
2900 	   lpfork = NULL;
2901 	   lpstatefork = NULL;
2902 	   subroot = NULL;
2903 	   assert(fork != NULL);
2904 	
2905 	   while( !fork->active )
2906 	   {
2907 	      fork = fork->parent;
2908 	      assert(fork != NULL); /* because the root is active, there must be a common fork node */
2909 	
2910 	      if( fork->cutoff )
2911 	      {
2912 	         *cutoff = TRUE;
2913 	         return;
2914 	      }
2915 	      if( lpfork == NULL
2916 	         && (SCIPnodeGetType(fork) == SCIP_NODETYPE_PSEUDOFORK
2917 	            || SCIPnodeGetType(fork) == SCIP_NODETYPE_FORK || SCIPnodeGetType(fork) == SCIP_NODETYPE_SUBROOT) )
2918 	         lpfork = fork;
2919 	      if( lpstatefork == NULL
2920 	         && (SCIPnodeGetType(fork) == SCIP_NODETYPE_FORK || SCIPnodeGetType(fork) == SCIP_NODETYPE_SUBROOT) )
2921 	         lpstatefork = fork;
2922 	      if( subroot == NULL && SCIPnodeGetType(fork) == SCIP_NODETYPE_SUBROOT )
2923 	         subroot = fork;
2924 	   }
2925 	   assert(lpfork == NULL || !lpfork->active || lpfork == fork);
2926 	   assert(lpstatefork == NULL || !lpstatefork->active || lpstatefork == fork);
2927 	   assert(subroot == NULL || !subroot->active || subroot == fork);
2928 	   SCIPdebugMessage("find switch forks: forkdepth=%u\n", fork->depth);
2929 	
2930 	   /* if the common fork node is below the current cutoff depth, the cutoff node is an ancestor of the common fork
2931 	    * and thus an ancestor of the new focus node, s.t. the new node can also be cut off
2932 	    */
2933 	   assert((int)fork->depth != tree->cutoffdepth);
2934 	   if( (int)fork->depth > tree->cutoffdepth )
2935 	   {
2936 	#ifndef NDEBUG
2937 	      while( !fork->cutoff )
2938 	      {
2939 	         fork = fork->parent;
2940 	         assert(fork != NULL);
2941 	      }
2942 	      assert((int)fork->depth >= tree->cutoffdepth);
2943 	#endif
2944 	      *cutoff = TRUE;
2945 	      return;
2946 	   }
2947 	   tree->cutoffdepth = INT_MAX;
2948 	
2949 	   /* if not already found, continue searching the LP defining fork; it cannot be deeper than the common fork */
2950 	   if( lpfork == NULL )
2951 	   {
2952 	      if( tree->focuslpfork != NULL && tree->focuslpfork->depth > fork->depth )
2953 	      {
2954 	         /* focuslpfork is not on the same active path as the new node: we have to continue searching */
2955 	         lpfork = fork;
2956 	         while( lpfork != NULL
2957 	            && SCIPnodeGetType(lpfork) != SCIP_NODETYPE_PSEUDOFORK
2958 	            && SCIPnodeGetType(lpfork) != SCIP_NODETYPE_FORK
2959 	            && SCIPnodeGetType(lpfork) != SCIP_NODETYPE_SUBROOT )
2960 	         {
2961 	            assert(lpfork->active);
2962 	            lpfork = lpfork->parent;
2963 	         }
2964 	      }
2965 	      else
2966 	      {
2967 	         /* focuslpfork is on the same active path as the new node: old and new node have the same lpfork */
2968 	         lpfork = tree->focuslpfork;
2969 	      }
2970 	      assert(lpfork == NULL || lpfork->depth <= fork->depth);
2971 	      assert(lpfork == NULL || lpfork->active);
2972 	   }
2973 	   assert(lpfork == NULL
2974 	      || SCIPnodeGetType(lpfork) == SCIP_NODETYPE_PSEUDOFORK
2975 	      || SCIPnodeGetType(lpfork) == SCIP_NODETYPE_FORK
2976 	      || SCIPnodeGetType(lpfork) == SCIP_NODETYPE_SUBROOT);
2977 	   SCIPdebugMessage("find switch forks: lpforkdepth=%d\n", lpfork == NULL ? -1 : (int)(lpfork->depth));
2978 	
2979 	   /* if not already found, continue searching the LP state defining fork; it cannot be deeper than the
2980 	    * LP defining fork and the common fork
2981 	    */
2982 	   if( lpstatefork == NULL )
2983 	   {
2984 	      if( tree->focuslpstatefork != NULL && tree->focuslpstatefork->depth > fork->depth )
2985 	      {
2986 	         /* focuslpstatefork is not on the same active path as the new node: we have to continue searching */
2987 	         if( lpfork != NULL && lpfork->depth < fork->depth )
2988 	            lpstatefork = lpfork;
2989 	         else
2990 	            lpstatefork = fork;
2991 	         while( lpstatefork != NULL
2992 	            && SCIPnodeGetType(lpstatefork) != SCIP_NODETYPE_FORK
2993 	            && SCIPnodeGetType(lpstatefork) != SCIP_NODETYPE_SUBROOT )
2994 	         {
2995 	            assert(lpstatefork->active);
2996 	            lpstatefork = lpstatefork->parent;
2997 	         }
2998 	      }
2999 	      else
3000 	      {
3001 	         /* focuslpstatefork is on the same active path as the new node: old and new node have the same lpstatefork */
3002 	         lpstatefork = tree->focuslpstatefork;
3003 	      }
3004 	      assert(lpstatefork == NULL || lpstatefork->depth <= fork->depth);
3005 	      assert(lpstatefork == NULL || lpstatefork->active);
3006 	   }
3007 	   assert(lpstatefork == NULL
3008 	      || SCIPnodeGetType(lpstatefork) == SCIP_NODETYPE_FORK
3009 	      || SCIPnodeGetType(lpstatefork) == SCIP_NODETYPE_SUBROOT);
3010 	   assert(lpstatefork == NULL || (lpfork != NULL && lpstatefork->depth <= lpfork->depth));
3011 	   SCIPdebugMessage("find switch forks: lpstateforkdepth=%d\n", lpstatefork == NULL ? -1 : (int)(lpstatefork->depth));
3012 	
3013 	   /* if not already found, continue searching the subroot; it cannot be deeper than the LP defining fork, the
3014 	    * LP state fork and the common fork
3015 	    */
3016 	   if( subroot == NULL )
3017 	   {
3018 	      if( tree->focussubroot != NULL && tree->focussubroot->depth > fork->depth )
3019 	      {
3020 	         /* focussubroot is not on the same active path as the new node: we have to continue searching */
3021 	         if( lpstatefork != NULL && lpstatefork->depth < fork->depth )
3022 	            subroot = lpstatefork;
3023 	         else if( lpfork != NULL && lpfork->depth < fork->depth )
3024 	            subroot = lpfork;
3025 	         else
3026 	            subroot = fork;
3027 	         while( subroot != NULL && SCIPnodeGetType(subroot) != SCIP_NODETYPE_SUBROOT )
3028 	         {
3029 	            assert(subroot->active);
3030 	            subroot = subroot->parent;
3031 	         }
3032 	      }
3033 	      else
3034 	         subroot = tree->focussubroot;
3035 	      assert(subroot == NULL || subroot->depth <= fork->depth);
3036 	      assert(subroot == NULL || subroot->active);
3037 	   }
3038 	   assert(subroot == NULL || SCIPnodeGetType(subroot) == SCIP_NODETYPE_SUBROOT);
3039 	   assert(subroot == NULL || (lpstatefork != NULL && subroot->depth <= lpstatefork->depth));
3040 	   SCIPdebugMessage("find switch forks: subrootdepth=%d\n", subroot == NULL ? -1 : (int)(subroot->depth));
3041 	
3042 	   /* if a node prior to the common fork should be repropagated, we select the node to be repropagated as common
3043 	    * fork in order to undo all bound changes up to this node, repropagate the node, and redo the bound changes
3044 	    * afterwards
3045 	    */
3046 	   if( (int)fork->depth > tree->repropdepth )
3047 	   {
3048 	      fork = tree->path[tree->repropdepth];
3049 	      assert(fork->active);
3050 	      assert(fork->reprop);
3051 	   }
3052 	
3053 	   *commonfork = fork;
3054 	   *newlpfork = lpfork;
3055 	   *newlpstatefork = lpstatefork;
3056 	   *newsubroot = subroot;
3057 	
3058 	#ifndef NDEBUG
3059 	   while( fork != NULL )
3060 	   {
3061 	      assert(fork->active);
3062 	      assert(!fork->cutoff);
3063 	      assert(fork->parent == NULL || !fork->parent->reprop);
3064 	      fork = fork->parent;
3065 	   }
3066 	#endif
3067 	   tree->repropdepth = INT_MAX;
3068 	}
3069 	
3070 	/** switches the active path to the new focus node, frees dead end, applies domain and constraint set changes */
3071 	static
3072 	SCIP_RETCODE treeSwitchPath(
3073 	   SCIP_TREE*            tree,               /**< branch and bound tree */
3074 	   SCIP_REOPT*           reopt,              /**< reoptimization data structure */
3075 	   BMS_BLKMEM*           blkmem,             /**< block memory buffers */
3076 	   SCIP_SET*             set,                /**< global SCIP settings */
3077 	   SCIP_STAT*            stat,               /**< problem statistics */
3078 	   SCIP_PROB*            transprob,          /**< transformed problem after presolve */
3079 	   SCIP_PROB*            origprob,           /**< original problem */
3080 	   SCIP_PRIMAL*          primal,             /**< primal data */
3081 	   SCIP_LP*              lp,                 /**< current LP data */
3082 	   SCIP_BRANCHCAND*      branchcand,         /**< branching candidate storage */
3083 	   SCIP_CONFLICT*        conflict,           /**< conflict analysis data */
3084 	   SCIP_EVENTFILTER*     eventfilter,        /**< event filter for global (not variable dependent) events */
3085 	   SCIP_EVENTQUEUE*      eventqueue,         /**< event queue */
3086 	   SCIP_CLIQUETABLE*     cliquetable,        /**< clique table data structure */
3087 	   SCIP_NODE*            fork,               /**< common fork node of old and new focus node, or NULL */
3088 	   SCIP_NODE*            focusnode,          /**< new focus node, or NULL */
3089 	   SCIP_Bool*            cutoff              /**< pointer to store whether the new focus node can be cut off */
3090 	   )
3091 	{
3092 	   int newappliedeffectiverootdepth;
3093 	   int focusnodedepth;  /* depth of the new focus node, or -1 if focusnode == NULL */
3094 	   int forkdepth;       /* depth of the common subroot/fork/pseudofork/junction node, or -1 if no common fork exists */
3095 	   int i;
3096 	   SCIP_NODE* oldfocusnode;
3097 	
3098 	   assert(tree != NULL);
3099 	   assert(fork == NULL || (fork->active && !fork->cutoff));
3100 	   assert(fork == NULL || focusnode != NULL);
3101 	   assert(focusnode == NULL || (!focusnode->active && !focusnode->cutoff));
3102 	   assert(focusnode == NULL || SCIPnodeGetType(focusnode) == SCIP_NODETYPE_FOCUSNODE);
3103 	   assert(cutoff != NULL);
3104 	
3105 	   /* set new focus node */
3106 	   oldfocusnode = tree->focusnode;
3107 	   tree->focusnode = focusnode;
3108 	
3109 	   SCIPsetDebugMsg(set, "switch path: old pathlen=%d\n", tree->pathlen);
3110 	
3111 	   /* get the nodes' depths */
3112 	   focusnodedepth = (focusnode != NULL ? (int)focusnode->depth : -1);
3113 	   forkdepth = (fork != NULL ? (int)fork->depth : -1);
3114 	   assert(forkdepth <= focusnodedepth);
3115 	   assert(forkdepth < tree->pathlen);
3116 	
3117 	   /* delay events in node deactivations to fork and node activations to parent of new focus node */
3118 	   SCIP_CALL( SCIPeventqueueDelay(eventqueue) );
3119 	
3120 	   /* undo the domain and constraint set changes of the old active path by deactivating the path's nodes */
3121 	   for( i = tree->pathlen-1; i > forkdepth; --i )
3122 	   {
3123 	      SCIP_CALL( nodeDeactivate(tree->path[i], blkmem, set, stat, tree, lp, branchcand, eventfilter, eventqueue) );
3124 	   }
3125 	   tree->pathlen = forkdepth+1;
3126 	
3127 	   /* apply the pending bound changes */
3128 	   SCIP_CALL( treeApplyPendingBdchgs(tree, reopt, blkmem, set, stat, transprob, origprob, lp, branchcand, eventqueue, cliquetable) );
3129 	
3130 	   /* create the new active path */
3131 	   SCIP_CALL( treeEnsurePathMem(tree, set, focusnodedepth+1) );
3132 	
3133 	   while( focusnode != fork )
3134 	   {
3135 	      assert(focusnode != NULL);
3136 	      assert(!focusnode->active);
3137 	      assert(!focusnode->cutoff);
3138 	      /* coverity[var_deref_op] */
3139 	      tree->path[focusnode->depth] = focusnode;
3140 	      focusnode = focusnode->parent;
3141 	   }
3142 	
3143 	   /* if the old focus node is a dead end (has no children), delete it */
3144 	   if( oldfocusnode != NULL && SCIPnodeGetType(oldfocusnode) == SCIP_NODETYPE_DEADEND )
3145 	   {
3146 	      assert(tree->appliedeffectiverootdepth <= tree->effectiverootdepth);
3147 	      SCIP_CALL( SCIPnodeFree(&oldfocusnode, blkmem, set, stat, eventfilter, eventqueue, tree, lp) );
3148 	      assert(tree->effectiverootdepth <= focusnodedepth || tree->focusnode == NULL);
3149 	   }
3150 	
3151 	   /* apply effective root shift up to the new focus node */
3152 	   *cutoff = FALSE;
3153 	   newappliedeffectiverootdepth = MIN(tree->effectiverootdepth, focusnodedepth);
3154 	
3155 	   /* promote the constraint set and bound changes up to the new effective root to be global changes */
3156 	   if( tree->appliedeffectiverootdepth < newappliedeffectiverootdepth )
3157 	   {
3158 	      SCIPsetDebugMsg(set,
3159 	                      "shift effective root from depth %d to %d: applying constraint set and bound changes to global problem\n",
3160 	                      tree->appliedeffectiverootdepth, newappliedeffectiverootdepth);
3161 	
3162 	      /* at first globalize constraint changes to update constraint handlers before changing bounds */
3163 	      for( i = tree->appliedeffectiverootdepth + 1; i <= newappliedeffectiverootdepth; ++i )
3164 	      {
3165 	         SCIPsetDebugMsg(set, " -> applying constraint set changes of depth %d\n", i);
3166 	
3167 	         SCIP_CALL( SCIPconssetchgMakeGlobal(&tree->path[i]->conssetchg, blkmem, set, stat, transprob, reopt) );
3168 	      }
3169 	
3170 	      /* at last globalize bound changes triggering delayed events processed after the path switch */
3171 	      for( i = tree->appliedeffectiverootdepth + 1; i <= newappliedeffectiverootdepth && !(*cutoff); ++i )
3172 	      {
3173 	         SCIPsetDebugMsg(set, " -> applying bound changes of depth %d\n", i);
3174 	
3175 	         SCIP_CALL( SCIPdomchgApplyGlobal(tree->path[i]->domchg, blkmem, set, stat, lp, branchcand, eventqueue, cliquetable, cutoff) );
3176 	      }
3177 	
3178 	      /* update applied effective root depth */
3179 	      tree->appliedeffectiverootdepth = newappliedeffectiverootdepth;
3180 	   }
3181 	
3182 	   /* fork might be cut off when applying the pending bound changes */
3183 	   if( fork != NULL && fork->cutoff )
3184 	      *cutoff = TRUE;
3185 	   else if( fork != NULL && fork->reprop && !(*cutoff) )
3186 	   {
3187 	     /* propagate common fork again, if the reprop flag is set */
3188 	      assert(tree->path[forkdepth] == fork);
3189 	      assert(fork->active);
3190 	      assert(!fork->cutoff);
3191 	
3192 	      SCIP_CALL( nodeRepropagate(fork, blkmem, set, stat, transprob, origprob, primal, tree, reopt, lp, branchcand, conflict,
3193 	            eventfilter, eventqueue, cliquetable, cutoff) );
3194 	   }
3195 	   assert(fork != NULL || !(*cutoff));
3196 	
3197 	   /* Apply domain and constraint set changes of the new path by activating the path's nodes;
3198 	    * on the way, domain propagation might be applied again to the path's nodes, which can result in the cutoff of
3199 	    * the node (and its subtree).
3200 	    * We only activate all nodes down to the parent of the new focus node, because the events in this process are
3201 	    * delayed, which means that multiple changes of a bound of a variable are merged (and might even be cancelled out,
3202 	    * if the bound is first relaxed when deactivating a node on the old path and then tightened to the same value
3203 	    * when activating a node on the new path).
3204 	    * This is valid for all nodes down to the parent of the new focus node, since they have already been propagated.
3205 	    * Bound change events on the new focus node, however, must not be cancelled out, since they need to be propagated
3206 	    * and thus, the event must be thrown and catched by the constraint handlers to mark constraints for propagation.
3207 	    */
3208 	   for( i = forkdepth+1; i < focusnodedepth && !(*cutoff); ++i )
3209 	   {
3210 	      assert(!tree->path[i]->cutoff);
3211 	      assert(tree->pathlen == i);
3212 	
3213 	      /* activate the node, and apply domain propagation if the reprop flag is set */
3214 	      tree->pathlen++;
3215 	      SCIP_CALL( nodeActivate(tree->path[i], blkmem, set, stat, transprob, origprob, primal, tree, reopt, lp, branchcand,
3216 	            conflict, eventfilter, eventqueue, cliquetable, cutoff) );
3217 	   }
3218 	
3219 	   /* process the delayed events */
3220 	   SCIP_CALL( SCIPeventqueueProcess(eventqueue, blkmem, set, primal, lp, branchcand, eventfilter) );
3221 	
3222 	   /* activate the new focus node; there is no need to delay these events */
3223 	   if( !(*cutoff) && (i == focusnodedepth) )
3224 	   {
3225 	      assert(!tree->path[focusnodedepth]->cutoff);
3226 	      assert(tree->pathlen == focusnodedepth);
3227 	
3228 	      /* activate the node, and apply domain propagation if the reprop flag is set */
3229 	      tree->pathlen++;
3230 	      SCIP_CALL( nodeActivate(tree->path[focusnodedepth], blkmem, set, stat, transprob, origprob, primal, tree, reopt, lp, branchcand,
3231 	            conflict, eventfilter, eventqueue, cliquetable, cutoff) );
3232 	   }
3233 	
3234 	   /* mark last node of path to be cut off, if a cutoff was found */
3235 	   if( *cutoff )
3236 	   {
3237 	      assert(tree->pathlen > 0);
3238 	      assert(tree->path[tree->pathlen-1]->active);
3239 	      SCIP_CALL( SCIPnodeCutoff(tree->path[tree->pathlen-1], set, stat, tree, transprob, origprob, reopt, lp, blkmem) );
3240 	   }
3241 	
3242 	   /* count the new LP sizes of the path */
3243 	   SCIP_CALL( treeUpdatePathLPSize(tree, forkdepth+1) );
3244 	
3245 	   SCIPsetDebugMsg(set, "switch path: new pathlen=%d\n", tree->pathlen);
3246 	
3247 	   return SCIP_OKAY;
3248 	}
3249 	
3250 	/** loads the subroot's LP data */
3251 	static
3252 	SCIP_RETCODE subrootConstructLP(
3253 	   SCIP_NODE*            subroot,            /**< subroot node to construct LP for */
3254 	   BMS_BLKMEM*           blkmem,             /**< block memory buffers */
3255 	   SCIP_SET*             set,                /**< global SCIP settings */
3256 	   SCIP_EVENTQUEUE*      eventqueue,         /**< event queue */
3257 	   SCIP_EVENTFILTER*     eventfilter,        /**< global event filter */
3258 	   SCIP_LP*              lp                  /**< current LP data */
3259 	   )
3260 	{
3261 	   SCIP_COL** cols;
3262 	   SCIP_ROW** rows;
3263 	   int ncols;
3264 	   int nrows;
3265 	   int c;
3266 	   int r;
3267 	
3268 	   assert(subroot != NULL);
3269 	   assert(SCIPnodeGetType(subroot) == SCIP_NODETYPE_SUBROOT);
3270 	   assert(subroot->data.subroot != NULL);
3271 	   assert(blkmem != NULL);
3272 	   assert(set != NULL);
3273 	   assert(lp != NULL);
3274 	
3275 	   cols = subroot->data.subroot->cols;
3276 	   rows = subroot->data.subroot->rows;
3277 	   ncols = subroot->data.subroot->ncols;
3278 	   nrows = subroot->data.subroot->nrows;
3279 	
3280 	   assert(ncols == 0 || cols != NULL);
3281 	   assert(nrows == 0 || rows != NULL);
3282 	
3283 	   for( c = 0; c < ncols; ++c )
3284 	   {
3285 	      SCIP_CALL( SCIPlpAddCol(lp, set, cols[c], (int) subroot->depth) );
3286 	   }
3287 	   for( r = 0; r < nrows; ++r )
3288 	   {
3289 	      SCIP_CALL( SCIPlpAddRow(lp, blkmem, set, eventqueue, eventfilter, rows[r], (int) subroot->depth) );
3290 	   }
3291 	
3292 	   return SCIP_OKAY;
3293 	}
3294 	
3295 	/** loads the fork's additional LP data */
3296 	static
3297 	SCIP_RETCODE forkAddLP(
3298 	   SCIP_NODE*            fork,               /**< fork node to construct additional LP for */
3299 	   BMS_BLKMEM*           blkmem,             /**< block memory buffers */
3300 	   SCIP_SET*             set,                /**< global SCIP settings */
3301 	   SCIP_EVENTQUEUE*      eventqueue,         /**< event queue */
3302 	   SCIP_EVENTFILTER*     eventfilter,        /**< global event filter */
3303 	   SCIP_LP*              lp                  /**< current LP data */
3304 	   )
3305 	{
3306 	   SCIP_COL** cols;
3307 	   SCIP_ROW** rows;
3308 	   int ncols;
3309 	   int nrows;
3310 	   int c;
3311 	   int r;
3312 	
3313 	   assert(fork != NULL);
3314 	   assert(SCIPnodeGetType(fork) == SCIP_NODETYPE_FORK);
3315 	   assert(fork->data.fork != NULL);
3316 	   assert(blkmem != NULL);
3317 	   assert(set != NULL);
3318 	   assert(lp != NULL);
3319 	
3320 	   cols = fork->data.fork->addedcols;
3321 	   rows = fork->data.fork->addedrows;
3322 	   ncols = fork->data.fork->naddedcols;
3323 	   nrows = fork->data.fork->naddedrows;
3324 	
3325 	   assert(ncols == 0 || cols != NULL);
3326 	   assert(nrows == 0 || rows != NULL);
3327 	
3328 	   for( c = 0; c < ncols; ++c )
3329 	   {
3330 	      SCIP_CALL( SCIPlpAddCol(lp, set, cols[c], (int) fork->depth) );
3331 	   }
3332 	   for( r = 0; r < nrows; ++r )
3333 	   {
3334 	      SCIP_CALL( SCIPlpAddRow(lp, blkmem, set, eventqueue, eventfilter, rows[r], (int) fork->depth) );
3335 	   }
3336 	
3337 	   return SCIP_OKAY;
3338 	}
3339 	
3340 	/** loads the pseudofork's additional LP data */
3341 	static
3342 	SCIP_RETCODE pseudoforkAddLP(
3343 	   SCIP_NODE*            pseudofork,         /**< pseudofork node to construct additional LP for */
3344 	   BMS_BLKMEM*           blkmem,             /**< block memory buffers */
3345 	   SCIP_SET*             set,                /**< global SCIP settings */
3346 	   SCIP_EVENTQUEUE*      eventqueue,         /**< event queue */
3347 	   SCIP_EVENTFILTER*     eventfilter,        /**< global event filter */
3348 	   SCIP_LP*              lp                  /**< current LP data */
3349 	   )
3350 	{
3351 	   SCIP_COL** cols;
3352 	   SCIP_ROW** rows;
3353 	   int ncols;
3354 	   int nrows;
3355 	   int c;
3356 	   int r;
3357 	
3358 	   assert(pseudofork != NULL);
3359 	   assert(SCIPnodeGetType(pseudofork) == SCIP_NODETYPE_PSEUDOFORK);
3360 	   assert(pseudofork->data.pseudofork != NULL);
3361 	   assert(blkmem != NULL);
3362 	   assert(set != NULL);
3363 	   assert(lp != NULL);
3364 	
3365 	   cols = pseudofork->data.pseudofork->addedcols;
3366 	   rows = pseudofork->data.pseudofork->addedrows;
3367 	   ncols = pseudofork->data.pseudofork->naddedcols;
3368 	   nrows = pseudofork->data.pseudofork->naddedrows;
3369 	
3370 	   assert(ncols == 0 || cols != NULL);
3371 	   assert(nrows == 0 || rows != NULL);
3372 	
3373 	   for( c = 0; c < ncols; ++c )
3374 	   {
3375 	      SCIP_CALL( SCIPlpAddCol(lp, set, cols[c], (int) pseudofork->depth) );
3376 	   }
3377 	   for( r = 0; r < nrows; ++r )
3378 	   {
3379 	      SCIP_CALL( SCIPlpAddRow(lp, blkmem, set, eventqueue, eventfilter, rows[r], (int) pseudofork->depth) );
3380 	   }
3381 	
3382 	   return SCIP_OKAY;
3383 	}
3384 	
3385 	#ifndef NDEBUG
3386 	/** checks validity of active path */
3387 	static
3388 	void treeCheckPath(
3389 	   SCIP_TREE*            tree                /**< branch and bound tree */
3390 	   )
3391 	{
3392 	   SCIP_NODE* node;
3393 	   int ncols;
3394 	   int nrows;
3395 	   int d;
3396 	
3397 	   assert(tree != NULL);
3398 	   assert(tree->path != NULL);
3399 	
3400 	   ncols = 0;
3401 	   nrows = 0;
3402 	   for( d = 0; d < tree->pathlen; ++d )
3403 	   {
3404 	      node = tree->path[d];
3405 	      assert(node != NULL);
3406 	      assert((int)(node->depth) == d);
3407 	      switch( SCIPnodeGetType(node) )
3408 	      {  
3409 	      case SCIP_NODETYPE_PROBINGNODE:
3410 	         assert(SCIPtreeProbing(tree));
3411 	         assert(d >= 1);
3412 	         assert(SCIPnodeGetType(tree->path[d-1]) == SCIP_NODETYPE_FOCUSNODE
3413 	            || (ncols == node->data.probingnode->ninitialcols && nrows == node->data.probingnode->ninitialrows));
3414 	         assert(ncols <= node->data.probingnode->ncols || !tree->focuslpconstructed);
3415 	         assert(nrows <= node->data.probingnode->nrows || !tree->focuslpconstructed);
3416 	         if( d < tree->pathlen-1 )
3417 	         {
3418 	            ncols = node->data.probingnode->ncols;
3419 	            nrows = node->data.probingnode->nrows;
3420 	         }
3421 	         else
3422 	         {
3423 	            /* for the current probing node, the initial LP size is stored in the path */
3424 	            ncols = node->data.probingnode->ninitialcols;
3425 	            nrows = node->data.probingnode->ninitialrows;
3426 	         }
3427 	         break;
3428 	      case SCIP_NODETYPE_JUNCTION:
3429 	         break;
3430 	      case SCIP_NODETYPE_PSEUDOFORK:
3431 	         ncols += node->data.pseudofork->naddedcols;
3432 	         nrows += node->data.pseudofork->naddedrows;
3433 	         break;
3434 	      case SCIP_NODETYPE_FORK:
3435 	         ncols += node->data.fork->naddedcols;
3436 	         nrows += node->data.fork->naddedrows;
3437 	         break;
3438 	      case SCIP_NODETYPE_SUBROOT:
3439 	         ncols = node->data.subroot->ncols;
3440 	         nrows = node->data.subroot->nrows;
3441 	         break;
3442 	      case SCIP_NODETYPE_FOCUSNODE:
3443 	      case SCIP_NODETYPE_REFOCUSNODE:
3444 	         assert(d == tree->pathlen-1 || SCIPtreeProbing(tree));
3445 	         break;
3446 	      default:
3447 	         SCIPerrorMessage("node at depth %d on active path has to be of type JUNCTION, PSEUDOFORK, FORK, SUBROOT, FOCUSNODE, REFOCUSNODE, or PROBINGNODE, but is %d\n",
3448 	            d, SCIPnodeGetType(node));
3449 	         SCIPABORT();
3450 	      }  /*lint !e788*/
3451 	      assert(tree->pathnlpcols[d] == ncols);
3452 	      assert(tree->pathnlprows[d] == nrows);
3453 	   }
3454 	}
3455 	#else
3456 	#define treeCheckPath(tree) /**/
3457 	#endif
3458 	
3459 	/** constructs the LP relaxation of the focus node */
3460 	SCIP_RETCODE SCIPtreeLoadLP(
3461 	   SCIP_TREE*            tree,               /**< branch and bound tree */
3462 	   BMS_BLKMEM*           blkmem,             /**< block memory buffers */
3463 	   SCIP_SET*             set,                /**< global SCIP settings */
3464 	   SCIP_EVENTQUEUE*      eventqueue,         /**< event queue */
3465 	   SCIP_EVENTFILTER*     eventfilter,        /**< global event filter */
3466 	   SCIP_LP*              lp,                 /**< current LP data */
3467 	   SCIP_Bool*            initroot            /**< pointer to store whether the root LP relaxation has to be initialized */
3468 	   )
3469 	{
3470 	   SCIP_NODE* lpfork;
3471 	   int lpforkdepth;
3472 	   int d;
3473 	
3474 	   assert(tree != NULL);
3475 	   assert(!tree->focuslpconstructed);
3476 	   assert(tree->path != NULL);
3477 	   assert(tree->pathlen > 0);
3478 	   assert(tree->focusnode != NULL);
3479 	   assert(SCIPnodeGetType(tree->focusnode) == SCIP_NODETYPE_FOCUSNODE);
3480 	   assert(SCIPnodeGetDepth(tree->focusnode) == tree->pathlen-1);
3481 	   assert(!SCIPtreeProbing(tree));
3482 	   assert(tree->focusnode == tree->path[tree->pathlen-1]);
3483 	   assert(blkmem != NULL);
3484 	   assert(set != NULL);
3485 	   assert(lp != NULL);
3486 	   assert(initroot != NULL);
3487 	
3488 	   SCIPsetDebugMsg(set, "load LP for current fork node #%" SCIP_LONGINT_FORMAT " at depth %d\n",
3489 	      tree->focuslpfork == NULL ? -1 : SCIPnodeGetNumber(tree->focuslpfork),
3490 	      tree->focuslpfork == NULL ? -1 : SCIPnodeGetDepth(tree->focuslpfork));
3491 	   SCIPsetDebugMsg(set, "-> old LP has %d cols and %d rows\n", SCIPlpGetNCols(lp), SCIPlpGetNRows(lp));
3492 	   SCIPsetDebugMsg(set, "-> correct LP has %d cols and %d rows\n",
3493 	      tree->correctlpdepth >= 0 ? tree->pathnlpcols[tree->correctlpdepth] : 0,
3494 	      tree->correctlpdepth >= 0 ? tree->pathnlprows[tree->correctlpdepth] : 0);
3495 	   SCIPsetDebugMsg(set, "-> old correctlpdepth: %d\n", tree->correctlpdepth);
3496 	
3497 	   treeCheckPath(tree);
3498 	
3499 	   lpfork = tree->focuslpfork;
3500 	
3501 	   /* find out the lpfork's depth (or -1, if lpfork is NULL) */
3502 	   if( lpfork == NULL )
3503 	   {
3504 	      assert(tree->correctlpdepth == -1 || tree->pathnlpcols[tree->correctlpdepth] == 0);
3505 	      assert(tree->correctlpdepth == -1 || tree->pathnlprows[tree->correctlpdepth] == 0);
3506 	      assert(tree->focuslpstatefork == NULL);
3507 	      assert(tree->focussubroot == NULL);
3508 	      lpforkdepth = -1;
3509 	   }
3510 	   else
3511 	   {
3512 	      assert(SCIPnodeGetType(lpfork) == SCIP_NODETYPE_PSEUDOFORK
3513 	         || SCIPnodeGetType(lpfork) == SCIP_NODETYPE_FORK || SCIPnodeGetType(lpfork) == SCIP_NODETYPE_SUBROOT);
3514 	      assert(lpfork->active);
3515 	      assert(tree->path[lpfork->depth] == lpfork);
3516 	      lpforkdepth = (int) lpfork->depth;
3517 	   }
3518 	   assert(lpforkdepth < tree->pathlen-1); /* lpfork must not be the last (the focus) node of the active path */
3519 	
3520 	   /* find out, if we are in the same subtree */
3521 	   if( tree->correctlpdepth >= 0 )
3522 	   {
3523 	      /* same subtree: shrink LP to the deepest node with correct LP */
3524 	      assert(lpforkdepth == -1 || tree->pathnlpcols[tree->correctlpdepth] <= tree->pathnlpcols[lpforkdepth]);
3525 	      assert(lpforkdepth == -1 || tree->pathnlprows[tree->correctlpdepth] <= tree->pathnlprows[lpforkdepth]);
3526 	      assert(lpforkdepth >= 0 || tree->pathnlpcols[tree->correctlpdepth] == 0);
3527 	      assert(lpforkdepth >= 0 || tree->pathnlprows[tree->correctlpdepth] == 0);
3528 	      SCIP_CALL( SCIPlpShrinkCols(lp, set, tree->pathnlpcols[tree->correctlpdepth]) );
3529 	      SCIP_CALL( SCIPlpShrinkRows(lp, blkmem, set, eventqueue, eventfilter, tree->pathnlprows[tree->correctlpdepth]) );
3530 	   }
3531 	   else
3532 	   {
3533 	      /* other subtree: fill LP with the subroot LP data */
3534 	      SCIP_CALL( SCIPlpClear(lp, blkmem, set, eventqueue, eventfilter) );
3535 	      if( tree->focussubroot != NULL )
3536 	      {
3537 	         SCIP_CALL( subrootConstructLP(tree->focussubroot, blkmem, set, eventqueue, eventfilter, lp) );
3538 	         tree->correctlpdepth = (int) tree->focussubroot->depth;
3539 	      }
3540 	   }
3541 	
3542 	   assert(lpforkdepth < tree->pathlen);
3543 	
3544 	   /* add the missing columns and rows */
3545 	   for( d = tree->correctlpdepth+1; d <= lpforkdepth; ++d )
3546 	   {
3547 	      SCIP_NODE* pathnode;
3548 	
3549 	      pathnode = tree->path[d];
3550 	      assert(pathnode != NULL);
3551 	      assert((int)(pathnode->depth) == d);
3552 	      assert(SCIPnodeGetType(pathnode) == SCIP_NODETYPE_JUNCTION
3553 	         || SCIPnodeGetType(pathnode) == SCIP_NODETYPE_PSEUDOFORK
3554 	         || SCIPnodeGetType(pathnode) == SCIP_NODETYPE_FORK);
3555 	      if( SCIPnodeGetType(pathnode) == SCIP_NODETYPE_FORK )
3556 	      {
3557 	         SCIP_CALL( forkAddLP(pathnode, blkmem, set, eventqueue, eventfilter, lp) );
3558 	      }
3559 	      else if( SCIPnodeGetType(pathnode) == SCIP_NODETYPE_PSEUDOFORK )
3560 	      {
3561 	         SCIP_CALL( pseudoforkAddLP(pathnode, blkmem, set, eventqueue, eventfilter, lp) );
3562 	      }
3563 	   }
3564 	   tree->correctlpdepth = MAX(tree->correctlpdepth, lpforkdepth);
3565 	   assert(lpforkdepth == -1 || tree->pathnlpcols[tree->correctlpdepth] == tree->pathnlpcols[lpforkdepth]);
3566 	   assert(lpforkdepth == -1 || tree->pathnlprows[tree->correctlpdepth] == tree->pathnlprows[lpforkdepth]);
3567 	   assert(lpforkdepth == -1 || SCIPlpGetNCols(lp) == tree->pathnlpcols[lpforkdepth]);
3568 	   assert(lpforkdepth == -1 || SCIPlpGetNRows(lp) == tree->pathnlprows[lpforkdepth]);
3569 	   assert(lpforkdepth >= 0 || SCIPlpGetNCols(lp) == 0);
3570 	   assert(lpforkdepth >= 0 || SCIPlpGetNRows(lp) == 0);
3571 	
3572 	   /* mark the LP's size, such that we know which rows and columns were added in the new node */
3573 	   SCIPlpMarkSize(lp);
3574 	
3575 	   SCIPsetDebugMsg(set, "-> new correctlpdepth: %d\n", tree->correctlpdepth);
3576 	   SCIPsetDebugMsg(set, "-> new LP has %d cols and %d rows\n", SCIPlpGetNCols(lp), SCIPlpGetNRows(lp));
3577 	
3578 	   /* if the correct LP depth is still -1, the root LP relaxation has to be initialized */
3579 	   *initroot = (tree->correctlpdepth == -1);
3580 	
3581 	   /* mark the LP of the focus node constructed */
3582 	   tree->focuslpconstructed = TRUE;
3583 	
3584 	   return SCIP_OKAY;
3585 	}
3586 	
3587 	/** loads LP state for fork/subroot of the focus node */
3588 	SCIP_RETCODE SCIPtreeLoadLPState(
3589 	   SCIP_TREE*            tree,               /**< branch and bound tree */
3590 	   BMS_BLKMEM*           blkmem,             /**< block memory buffers */
3591 	   SCIP_SET*             set,                /**< global SCIP settings */
3592 	   SCIP_PROB*            prob,               /**< problem data */
3593 	   SCIP_STAT*            stat,               /**< dynamic problem statistics */
3594 	   SCIP_EVENTQUEUE*      eventqueue,         /**< event queue */
3595 	   SCIP_LP*              lp                  /**< current LP data */
3596 	   )
3597 	{
3598 	   SCIP_NODE* lpstatefork;
3599 	   SCIP_Bool updatefeas;
3600 	   SCIP_Bool checkbdchgs;
3601 	   int lpstateforkdepth;
3602 	   int d;
3603 	
3604 	   assert(tree != NULL);
3605 	   assert(tree->focuslpconstructed);
3606 	   assert(tree->path != NULL);
3607 	   assert(tree->pathlen > 0);
3608 	   assert(tree->focusnode != NULL);
3609 	   assert(tree->correctlpdepth < tree->pathlen);
3610 	   assert(SCIPnodeGetType(tree->focusnode) == SCIP_NODETYPE_FOCUSNODE);
3611 	   assert(SCIPnodeGetDepth(tree->focusnode) == tree->pathlen-1);
3612 	   assert(!SCIPtreeProbing(tree));
3613 	   assert(tree->focusnode == tree->path[tree->pathlen-1]);
3614 	   assert(blkmem != NULL);
3615 	   assert(set != NULL);
3616 	   assert(lp != NULL);
3617 	
3618 	   SCIPsetDebugMsg(set, "load LP state for current fork node #%" SCIP_LONGINT_FORMAT " at depth %d\n",
3619 	      tree->focuslpstatefork == NULL ? -1 : SCIPnodeGetNumber(tree->focuslpstatefork),
3620 	      tree->focuslpstatefork == NULL ? -1 : SCIPnodeGetDepth(tree->focuslpstatefork));
3621 	
3622 	   lpstatefork = tree->focuslpstatefork;
3623 	
3624 	   /* if there is no LP state defining fork, nothing can be done */
3625 	   if( lpstatefork == NULL )
3626 	      return SCIP_OKAY;
3627 	
3628 	   /* get the lpstatefork's depth */
3629 	   assert(SCIPnodeGetType(lpstatefork) == SCIP_NODETYPE_FORK || SCIPnodeGetType(lpstatefork) == SCIP_NODETYPE_SUBROOT);
3630 	   assert(lpstatefork->active);
3631 	   assert(tree->path[lpstatefork->depth] == lpstatefork);
3632 	   lpstateforkdepth = (int) lpstatefork->depth;
3633 	   assert(lpstateforkdepth < tree->pathlen-1); /* lpstatefork must not be the last (the focus) node of the active path */
3634 	   assert(lpstateforkdepth <= tree->correctlpdepth); /* LP must have been constructed at least up to the fork depth */
3635 	   assert(tree->pathnlpcols[tree->correctlpdepth] >= tree->pathnlpcols[lpstateforkdepth]); /* LP can only grow */
3636 	   assert(tree->pathnlprows[tree->correctlpdepth] >= tree->pathnlprows[lpstateforkdepth]); /* LP can only grow */
3637 	
3638 	   /* load LP state */
3639 	   if( tree->focuslpstateforklpcount != stat->lpcount )
3640 	   {
3641 	      if( SCIPnodeGetType(lpstatefork) == SCIP_NODETYPE_FORK )
3642 	      {
3643 	         assert(lpstatefork->data.fork != NULL);
3644 	         SCIP_CALL( SCIPlpSetState(lp, blkmem, set, prob, eventqueue, lpstatefork->data.fork->lpistate,
3645 	               lpstatefork->data.fork->lpwasprimfeas, lpstatefork->data.fork->lpwasprimchecked,
3646 	               lpstatefork->data.fork->lpwasdualfeas, lpstatefork->data.fork->lpwasdualchecked) );
3647 	      }
3648 	      else
3649 	      {
3650 	         assert(SCIPnodeGetType(lpstatefork) == SCIP_NODETYPE_SUBROOT);
3651 	         assert(lpstatefork->data.subroot != NULL);
3652 	         SCIP_CALL( SCIPlpSetState(lp, blkmem, set, prob, eventqueue, lpstatefork->data.subroot->lpistate,
3653 	               lpstatefork->data.subroot->lpwasprimfeas, lpstatefork->data.subroot->lpwasprimchecked,
3654 	               lpstatefork->data.subroot->lpwasdualfeas, lpstatefork->data.subroot->lpwasdualchecked) );
3655 	      }
3656 	      updatefeas = !lp->solved || !lp->solisbasic;
3657 	      checkbdchgs = TRUE;
3658 	   }
3659 	   else
3660 	   {
3661 	      updatefeas = TRUE;
3662 	
3663 	      /* we do not need to check the bounds, since primalfeasible is updated anyway when flushing the LP */
3664 	      checkbdchgs = FALSE;
3665 	   }
3666 	
3667 	   if( updatefeas )
3668 	   {
3669 	      /* check whether the size of the LP increased (destroying primal/dual feasibility) */
3670 	      lp->primalfeasible = lp->primalfeasible
3671 	         && (tree->pathnlprows[tree->correctlpdepth] == tree->pathnlprows[lpstateforkdepth]);
3672 	      lp->primalchecked = lp->primalchecked
3673 	         && (tree->pathnlprows[tree->correctlpdepth] == tree->pathnlprows[lpstateforkdepth]);
3674 	      lp->dualfeasible = lp->dualfeasible
3675 	         && (tree->pathnlpcols[tree->correctlpdepth] == tree->pathnlpcols[lpstateforkdepth]);
3676 	      lp->dualchecked = lp->dualchecked
3677 	         && (tree->pathnlpcols[tree->correctlpdepth] == tree->pathnlpcols[lpstateforkdepth]);
3678 	
3679 	      /* check the path from LP fork to focus node for domain changes (destroying primal feasibility of LP basis) */
3680 	      if( checkbdchgs )
3681 	      {
3682 	         for( d = lpstateforkdepth; d < (int)(tree->focusnode->depth) && lp->primalfeasible; ++d )
3683 	         {
3684 	            assert(d < tree->pathlen);
3685 	            lp->primalfeasible = (tree->path[d]->domchg == NULL || tree->path[d]->domchg->domchgbound.nboundchgs == 0);
3686 	            lp->primalchecked = lp->primalfeasible;
3687 	         }
3688 	      }
3689 	   }
3690 	
3691 	   SCIPsetDebugMsg(set, "-> primalfeasible=%u, dualfeasible=%u\n", lp->primalfeasible, lp->dualfeasible);
3692 	
3693 	   return SCIP_OKAY;
3694 	}
3695 	
3696 	
3697 	
3698 	
3699 	/*
3700 	 * Node Conversion
3701 	 */
3702 	
3703 	/** converts node into LEAF and moves it into the array of the node queue
3704 	 *  if node's lower bound is greater or equal than the given upper bound, the node is deleted;
3705 	 *  otherwise, it is moved to the node queue; anyways, the given pointer is NULL after the call
3706 	 */
3707 	static
3708 	SCIP_RETCODE nodeToLeaf(
3709 	   SCIP_NODE**           node,               /**< pointer to child or sibling node to convert */
3710 	   BMS_BLKMEM*           blkmem,             /**< block memory buffers */
3711 	   SCIP_SET*             set,                /**< global SCIP settings */
3712 	   SCIP_STAT*            stat,               /**< dynamic problem statistics */
3713 	   SCIP_EVENTFILTER*     eventfilter,        /**< event filter for global (not variable dependent) events */
3714 	   SCIP_EVENTQUEUE*      eventqueue,         /**< event queue */
3715 	   SCIP_TREE*            tree,               /**< branch and bound tree */
3716 	   SCIP_REOPT*           reopt,              /**< reoptimization data structure */
3717 	   SCIP_LP*              lp,                 /**< current LP data */
3718 	   SCIP_NODE*            lpstatefork,        /**< LP state defining fork of the node */
3719 	   SCIP_Real             cutoffbound         /**< cutoff bound: all nodes with lowerbound >= cutoffbound are cut off */
3720 	   )
3721 	{
3722 	   assert(SCIPnodeGetType(*node) == SCIP_NODETYPE_SIBLING || SCIPnodeGetType(*node) == SCIP_NODETYPE_CHILD
3723 	      || SCIPnodeGetType(*node) == SCIP_NODETYPE_FOCUSNODE);
3724 	   assert(stat != NULL);
3725 	   assert(lpstatefork == NULL || lpstatefork->depth < (*node)->depth);
3726 	   assert(lpstatefork == NULL || lpstatefork->active || SCIPsetIsGE(set, (*node)->lowerbound, cutoffbound));
3727 	   assert(lpstatefork == NULL
3728 	      || SCIPnodeGetType(lpstatefork) == SCIP_NODETYPE_FORK
3729 	      || SCIPnodeGetType(lpstatefork) == SCIP_NODETYPE_SUBROOT);
3730 	
3731 	   /* convert node into leaf */
3732 	   SCIPsetDebugMsg(set, "convert node #%" SCIP_LONGINT_FORMAT " at depth %d to leaf with lpstatefork #%" SCIP_LONGINT_FORMAT " at depth %d\n",
3733 	      SCIPnodeGetNumber(*node), SCIPnodeGetDepth(*node),
3734 	      lpstatefork == NULL ? -1 : SCIPnodeGetNumber(lpstatefork),
3735 	      lpstatefork == NULL ? -1 : SCIPnodeGetDepth(lpstatefork));
3736 	   (*node)->nodetype = SCIP_NODETYPE_LEAF; /*lint !e641*/
3737 	   (*node)->data.leaf.lpstatefork = lpstatefork;
3738 	
3739 	#ifndef NDEBUG
3740 	   /* check, if the LP state fork is the first node with LP state information on the path back to the root */
3741 	   if( !SCIPsetIsInfinity(set, -cutoffbound) ) /* if the node was cut off in SCIPnodeFocus(), the lpstatefork is invalid */
3742 	   {
3743 	      SCIP_NODE* pathnode;
3744 	      pathnode = (*node)->parent;
3745 	      while( pathnode != NULL && pathnode != lpstatefork )
3746 	      {
3747 	         assert(SCIPnodeGetType(pathnode) == SCIP_NODETYPE_JUNCTION
3748 	            || SCIPnodeGetType(pathnode) == SCIP_NODETYPE_PSEUDOFORK);
3749 	         pathnode = pathnode->parent;
3750 	      }
3751 	      assert(pathnode == lpstatefork);
3752 	   }
3753 	#endif
3754 	
3755 	   /* if node is good enough to keep, put it on the node queue */
3756 	   if( SCIPsetIsLT(set, (*node)->lowerbound, cutoffbound) )
3757 	   {
3758 	      /* insert leaf in node queue */
3759 	      SCIP_CALL( SCIPnodepqInsert(tree->leaves, set, *node) );
3760 	
3761 	      /* make the domain change data static to save memory */
3762 	      SCIP_CALL( SCIPdomchgMakeStatic(&(*node)->domchg, blkmem, set, eventqueue, lp) );
3763 	
3764 	      /* node is now member of the node queue: delete the pointer to forbid further access */
3765 	      *node = NULL;
3766 	   }
3767 	   else
3768 	   {
3769 	      if( set->reopt_enable )
3770 	      {
3771 	         assert(reopt != NULL);
3772 	         /* check if the node should be stored for reoptimization */
3773 	         SCIP_CALL( SCIPreoptCheckCutoff(reopt, set, blkmem, *node, SCIP_EVENTTYPE_NODEINFEASIBLE, lp, SCIPlpGetSolstat(lp),
3774 	               tree->root == *node, tree->focusnode == *node, (*node)->lowerbound, tree->effectiverootdepth) );
3775 	      }
3776 	
3777 	      /* delete node due to bound cut off */
3778 	      SCIPvisualCutoffNode(stat->visual, set, stat, *node, FALSE);
3779 	      SCIP_CALL( SCIPnodeFree(node, blkmem, set, stat, eventfilter, eventqueue, tree, lp) );
3780 	   }
3781 	   assert(*node == NULL);
3782 	
3783 	   return SCIP_OKAY;
3784 	}
3785 	
3786 	/** removes variables from the problem, that are marked to be deletable, and were created at the focusnode;
3787 	 *  only removes variables that were created at the focusnode, unless inlp is TRUE (e.g., when the node is cut off, anyway)
3788 	 */
3789 	static
3790 	SCIP_RETCODE focusnodeCleanupVars(
3791 	   BMS_BLKMEM*           blkmem,             /**< block memory buffers */
3792 	   SCIP_SET*             set,                /**< global SCIP settings */
3793 	   SCIP_STAT*            stat,               /**< dynamic problem statistics */
3794 	   SCIP_EVENTQUEUE*      eventqueue,         /**< event queue */
3795 	   SCIP_PROB*            transprob,          /**< transformed problem after presolve */
3796 	   SCIP_PROB*            origprob,           /**< original problem */
3797 	   SCIP_TREE*            tree,               /**< branch and bound tree */
3798 	   SCIP_REOPT*           reopt,              /**< reoptimization data structure */
3799 	   SCIP_LP*              lp,                 /**< current LP data */
3800 	   SCIP_BRANCHCAND*      branchcand,         /**< branching candidate storage */
3801 	   SCIP_CLIQUETABLE*     cliquetable,        /**< clique table data structure */
3802 	   SCIP_Bool             inlp                /**< should variables in the LP be deleted, too?*/
3803 	   )
3804 	{
3805 	   SCIP_VAR* var;
3806 	   int i;
3807 	   int ndelvars;
3808 	   SCIP_Bool needdel;
3809 	   SCIP_Bool deleted;
3810 	
3811 	   assert(blkmem != NULL);
3812 	   assert(set != NULL);
3813 	   assert(stat != NULL);
3814 	   assert(tree != NULL);
3815 	   assert(!SCIPtreeProbing(tree));
3816 	   assert(tree->focusnode != NULL);
3817 	   assert(SCIPnodeGetType(tree->focusnode) == SCIP_NODETYPE_FOCUSNODE);
3818 	   assert(lp != NULL);
3819 	
3820 	   /* check the settings, whether variables should be deleted */
3821 	   needdel = (tree->focusnode == tree->root ? set->price_delvarsroot : set->price_delvars);
3822 	
3823 	   if( !needdel )
3824 	      return SCIP_OKAY;
3825 	
3826 	   ndelvars = 0;
3827 	
3828 	   /* also delete variables currently in the LP, thus remove all new variables from the LP, first */
3829 	   if( inlp )
3830 	   {
3831 	      /* remove all additions to the LP at this node */
3832 	      SCIP_CALL( SCIPlpShrinkCols(lp, set, SCIPlpGetNCols(lp) - SCIPlpGetNNewcols(lp)) );
3833 	
3834 	      SCIP_CALL( SCIPlpFlush(lp, blkmem, set, transprob, eventqueue) );
3835 	   }
3836 	
3837 	   /* mark variables as deleted */
3838 	   for( i = 0; i < transprob->nvars; i++ )
3839 	   {
3840 	      var = transprob->vars[i];
3841 	      assert(var != NULL);
3842 	
3843 	      /* check whether variable is deletable */
3844 	      if( SCIPvarIsDeletable(var) )
3845 	      {
3846 	         if( !SCIPvarIsInLP(var) )
3847 	         {
3848 	            /* fix the variable to 0, first */
3849 	            assert(!SCIPsetIsFeasPositive(set, SCIPvarGetLbGlobal(var)));
3850 	            assert(!SCIPsetIsFeasNegative(set, SCIPvarGetUbGlobal(var)));
3851 	
3852 	            if( !SCIPsetIsFeasZero(set, SCIPvarGetLbGlobal(var)) )
3853 	            {
3854 	               SCIP_CALL( SCIPnodeAddBoundchg(tree->root, blkmem, set, stat, transprob, origprob,
3855 	                     tree, reopt, lp, branchcand, eventqueue, cliquetable, var, 0.0, SCIP_BOUNDTYPE_LOWER, FALSE) );
3856 	            }
3857 	            if( !SCIPsetIsFeasZero(set, SCIPvarGetUbGlobal(var)) )
3858 	            {
3859 	               SCIP_CALL( SCIPnodeAddBoundchg(tree->root, blkmem, set, stat, transprob, origprob,
3860 	                     tree, reopt, lp, branchcand, eventqueue, cliquetable, var, 0.0, SCIP_BOUNDTYPE_UPPER, FALSE) );
3861 	            }
3862 	
3863 	            SCIP_CALL( SCIPprobDelVar(transprob, blkmem, set, eventqueue, var, &deleted) );
3864 	
3865 	            if( deleted )
3866 	               ndelvars++;
3867 	         }
3868 	         else
3869 	         {
3870 	            /* mark variable to be non-deletable, because it will be contained in the basis information
3871 	             * at this node and must not be deleted from now on
3872 	             */
3873 	            SCIPvarMarkNotDeletable(var);
3874 	         }
3875 	      }
3876 	   }
3877 	
3878 	   SCIPsetDebugMsg(set, "delvars at node %" SCIP_LONGINT_FORMAT ", deleted %d vars\n", stat->nnodes, ndelvars);
3879 	
3880 	   if( ndelvars > 0 )
3881 	   {
3882 	      /* perform the variable deletions from the problem */
3883 	      SCIP_CALL( SCIPprobPerformVarDeletions(transprob, blkmem, set, stat, eventqueue, cliquetable, lp, branchcand) );
3884 	   }
3885 	
3886 	   return SCIP_OKAY;
3887 	}
3888 	
3889 	/** converts the focus node into a dead-end node */
3890 	static
3891 	SCIP_RETCODE focusnodeToDeadend(
3892 	   BMS_BLKMEM*           blkmem,             /**< block memory buffers */
3893 	   SCIP_SET*             set,                /**< global SCIP settings */
3894 	   SCIP_STAT*            stat,               /**< dynamic problem statistics */
3895 	   SCIP_EVENTQUEUE*      eventqueue,         /**< event queue */
3896 	   SCIP_PROB*            transprob,          /**< transformed problem after presolve */
3897 	   SCIP_PROB*            origprob,           /**< original problem */
3898 	   SCIP_TREE*            tree,               /**< branch and bound tree */
3899 	   SCIP_REOPT*           reopt,              /**< reoptimization data structure */
3900 	   SCIP_LP*              lp,                 /**< current LP data */
3901 	   SCIP_BRANCHCAND*      branchcand,         /**< branching candidate storage */
3902 	   SCIP_CLIQUETABLE*     cliquetable         /**< clique table data structure */
3903 	   )
3904 	{
3905 	   assert(blkmem != NULL);
3906 	   assert(tree != NULL);
3907 	   assert(!SCIPtreeProbing(tree));
3908 	   assert(tree->focusnode != NULL);
3909 	   assert(SCIPnodeGetType(tree->focusnode) == SCIP_NODETYPE_FOCUSNODE);
3910 	   assert(tree->nchildren == 0);
3911 	
3912 	   SCIPsetDebugMsg(set, "focusnode #%" SCIP_LONGINT_FORMAT " to dead-end at depth %d\n",
3913 	      SCIPnodeGetNumber(tree->focusnode), SCIPnodeGetDepth(tree->focusnode));
3914 	
3915 	   /* remove variables from the problem that are marked as deletable and were created at this node */
3916 	   SCIP_CALL( focusnodeCleanupVars(blkmem, set, stat, eventqueue, transprob, origprob, tree, reopt, lp, branchcand, cliquetable, TRUE) );
3917 	
3918 	   tree->focusnode->nodetype = SCIP_NODETYPE_DEADEND; /*lint !e641*/
3919 	
3920 	   /* release LPI state */
3921 	   if( tree->focuslpstatefork != NULL )
3922 	   {
3923 	      SCIP_CALL( SCIPnodeReleaseLPIState(tree->focuslpstatefork, blkmem, lp) );
3924 	   }
3925 	
3926 	   return SCIP_OKAY;
3927 	}
3928 	
3929 	/** converts the focus node into a leaf node (if it was postponed) */
3930 	static
3931 	SCIP_RETCODE focusnodeToLeaf(
3932 	   BMS_BLKMEM*           blkmem,             /**< block memory buffers */
3933 	   SCIP_SET*             set,                /**< global SCIP settings */
3934 	   SCIP_STAT*            stat,               /**< dynamic problem statistics */
3935 	   SCIP_EVENTFILTER*     eventfilter,        /**< event filter for global (not variable dependent) events */
3936 	   SCIP_EVENTQUEUE*      eventqueue,         /**< event queue */
3937 	   SCIP_TREE*            tree,               /**< branch and bound tree */
3938 	   SCIP_REOPT*           reopt,              /**< reoptimization data structure */
3939 	   SCIP_LP*              lp,                 /**< current LP data */
3940 	   SCIP_NODE*            lpstatefork,        /**< LP state defining fork of the node */
3941 	   SCIP_Real             cutoffbound         /**< cutoff bound: all nodes with lowerbound >= cutoffbound are cut off */
3942 	
3943 	   )
3944 	{
3945 	   assert(tree != NULL);
3946 	   assert(!SCIPtreeProbing(tree));
3947 	   assert(tree->focusnode != NULL);
3948 	   assert(tree->focusnode->active);
3949 	   assert(SCIPnodeGetType(tree->focusnode) == SCIP_NODETYPE_FOCUSNODE);
3950 	
3951 	   SCIPsetDebugMsg(set, "focusnode #%" SCIP_LONGINT_FORMAT " to leaf at depth %d\n",
3952 	      SCIPnodeGetNumber(tree->focusnode), SCIPnodeGetDepth(tree->focusnode));
3953 	
3954 	   SCIP_CALL( nodeToLeaf(&tree->focusnode, blkmem, set, stat, eventfilter, eventqueue, tree, reopt, lp, lpstatefork, cutoffbound));
3955 	
3956 	   return SCIP_OKAY;
3957 	}
3958 	
3959 	/** converts the focus node into a junction node */
3960 	static
3961 	SCIP_RETCODE focusnodeToJunction(
3962 	   BMS_BLKMEM*           blkmem,             /**< block memory buffers */
3963 	   SCIP_SET*             set,                /**< global SCIP settings */
3964 	   SCIP_EVENTQUEUE*      eventqueue,         /**< event queue */
3965 	   SCIP_TREE*            tree,               /**< branch and bound tree */
3966 	   SCIP_LP*              lp                  /**< current LP data */
3967 	   )
3968 	{
3969 	   assert(tree != NULL);
3970 	   assert(!SCIPtreeProbing(tree));
3971 	   assert(tree->focusnode != NULL);
3972 	   assert(tree->focusnode->active); /* otherwise, no children could be created at the focus node */
3973 	   assert(SCIPnodeGetType(tree->focusnode) == SCIP_NODETYPE_FOCUSNODE);
3974 	   assert(SCIPlpGetNNewcols(lp) == 0);
3975 	
3976 	   SCIPsetDebugMsg(set, "focusnode #%" SCIP_LONGINT_FORMAT " to junction at depth %d\n",
3977 	      SCIPnodeGetNumber(tree->focusnode), SCIPnodeGetDepth(tree->focusnode));
3978 	
3979 	   /* convert node into junction */
3980 	   tree->focusnode->nodetype = SCIP_NODETYPE_JUNCTION; /*lint !e641*/
3981 	
3982 	   SCIP_CALL( junctionInit(&tree->focusnode->data.junction, tree) );
3983 	
3984 	   /* release LPI state */
3985 	   if( tree->focuslpstatefork != NULL )
3986 	   {
3987 	      SCIP_CALL( SCIPnodeReleaseLPIState(tree->focuslpstatefork, blkmem, lp) );
3988 	   }
3989 	
3990 	   /* make the domain change data static to save memory */
3991 	   SCIP_CALL( SCIPdomchgMakeStatic(&tree->focusnode->domchg, blkmem, set, eventqueue, lp) );
3992 	
3993 	   return SCIP_OKAY;
3994 	}
3995 	
3996 	/** converts the focus node into a pseudofork node */
3997 	static
3998 	SCIP_RETCODE focusnodeToPseudofork(
3999 	   BMS_BLKMEM*           blkmem,             /**< block memory buffers */
4000 	   SCIP_SET*             set,                /**< global SCIP settings */
4001 	   SCIP_STAT*            stat,               /**< dynamic problem statistics */
4002 	   SCIP_EVENTQUEUE*      eventqueue,         /**< event queue */
4003 	   SCIP_PROB*            transprob,          /**< transformed problem after presolve */
4004 	   SCIP_PROB*            origprob,           /**< original problem */
4005 	   SCIP_TREE*            tree,               /**< branch and bound tree */
4006 	   SCIP_REOPT*           reopt,              /**< reoptimization data structure */
4007 	   SCIP_LP*              lp,                 /**< current LP data */
4008 	   SCIP_BRANCHCAND*      branchcand,         /**< branching candidate storage */
4009 	   SCIP_CLIQUETABLE*     cliquetable         /**< clique table data structure */
4010 	   )
4011 	{
4012 	   SCIP_PSEUDOFORK* pseudofork;
4013 	
4014 	   assert(blkmem != NULL);
4015 	   assert(tree != NULL);
4016 	   assert(!SCIPtreeProbing(tree));
4017 	   assert(tree->focusnode != NULL);
4018 	   assert(tree->focusnode->active); /* otherwise, no children could be created at the focus node */
4019 	   assert(SCIPnodeGetType(tree->focusnode) == SCIP_NODETYPE_FOCUSNODE);
4020 	   assert(tree->nchildren > 0);
4021 	   assert(lp != NULL);
4022 	
4023 	   SCIPsetDebugMsg(set, "focusnode #%" SCIP_LONGINT_FORMAT " to pseudofork at depth %d\n",
4024 	      SCIPnodeGetNumber(tree->focusnode), SCIPnodeGetDepth(tree->focusnode));
4025 	
4026 	   /* remove variables from the problem that are marked as deletable and were created at this node */
4027 	   SCIP_CALL( focusnodeCleanupVars(blkmem, set, stat, eventqueue, transprob, origprob, tree, reopt, lp, branchcand, cliquetable, FALSE) );
4028 	
4029 	   /* create pseudofork data */
4030 	   SCIP_CALL( pseudoforkCreate(&pseudofork, blkmem, tree, lp) );
4031 	
4032 	   tree->focusnode->nodetype = SCIP_NODETYPE_PSEUDOFORK; /*lint !e641*/
4033 	   tree->focusnode->data.pseudofork = pseudofork;
4034 	
4035 	   /* release LPI state */
4036 	   if( tree->focuslpstatefork != NULL )
4037 	   {
4038 	      SCIP_CALL( SCIPnodeReleaseLPIState(tree->focuslpstatefork, blkmem, lp) );
4039 	   }
4040 	
4041 	   /* make the domain change data static to save memory */
4042 	   SCIP_CALL( SCIPdomchgMakeStatic(&tree->focusnode->domchg, blkmem, set, eventqueue, lp) );
4043 	
4044 	   return SCIP_OKAY;
4045 	}
4046 	
4047 	/** converts the focus node into a fork node */
4048 	static
4049 	SCIP_RETCODE focusnodeToFork(
4050 	   BMS_BLKMEM*           blkmem,             /**< block memory buffers */
4051 	   SCIP_SET*             set,                /**< global SCIP settings */
4052 	   SCIP_MESSAGEHDLR*     messagehdlr,        /**< message handler */
4053 	   SCIP_STAT*            stat,               /**< dynamic problem statistics */
4054 	   SCIP_EVENTQUEUE*      eventqueue,         /**< event queue */
4055 	   SCIP_EVENTFILTER*     eventfilter,        /**< global event filter */
4056 	   SCIP_PROB*            transprob,          /**< transformed problem after presolve */
4057 	   SCIP_PROB*            origprob,           /**< original problem */
4058 	   SCIP_TREE*            tree,               /**< branch and bound tree */
4059 	   SCIP_REOPT*           reopt,              /**< reoptimization data structure */
4060 	   SCIP_LP*              lp,                 /**< current LP data */
4061 	   SCIP_BRANCHCAND*      branchcand,         /**< branching candidate storage */
4062 	   SCIP_CLIQUETABLE*     cliquetable         /**< clique table data structure */
4063 	   )
4064 	{
4065 	   SCIP_FORK* fork;
4066 	   SCIP_Bool lperror;
4067 	
4068 	   assert(blkmem != NULL);
4069 	   assert(tree != NULL);
4070 	   assert(!SCIPtreeProbing(tree));
4071 	   assert(tree->focusnode != NULL);
4072 	   assert(tree->focusnode->active); /* otherwise, no children could be created at the focus node */
4073 	   assert(SCIPnodeGetType(tree->focusnode) == SCIP_NODETYPE_FOCUSNODE);
4074 	   assert(tree->nchildren > 0);
4075 	   assert(lp != NULL);
4076 	   assert(lp->flushed);
4077 	   assert(lp->solved || lp->resolvelperror);
4078 	
4079 	   SCIPsetDebugMsg(set, "focusnode #%" SCIP_LONGINT_FORMAT " to fork at depth %d\n",
4080 	      SCIPnodeGetNumber(tree->focusnode), SCIPnodeGetDepth(tree->focusnode));
4081 	
4082 	   /* usually, the LP should be solved to optimality; otherwise, numerical troubles occured,
4083 	    * and we have to forget about the LP and transform the node into a junction (see below)
4084 	    */
4085 	   lperror = FALSE;
4086 	   if( !lp->resolvelperror && SCIPlpGetSolstat(lp) == SCIP_LPSOLSTAT_OPTIMAL )
4087 	   {
4088 	      /* clean up newly created part of LP to keep only necessary columns and rows */
4089 	      SCIP_CALL( SCIPlpCleanupNew(lp, blkmem, set, stat, eventqueue, eventfilter, (tree->focusnode->depth == 0)) );
4090 	
4091 	      /* resolve LP after cleaning up */
4092 	      SCIPsetDebugMsg(set, "resolving LP after cleanup\n");
4093 	      SCIP_CALL( SCIPlpSolveAndEval(lp, set, messagehdlr, blkmem, stat, eventqueue, eventfilter, transprob, -1LL, FALSE, FALSE, TRUE, &lperror) );
4094 	   }
4095 	   assert(lp->flushed);
4096 	   assert(lp->solved || lperror || lp->resolvelperror);
4097 	
4098 	   /* There are two reasons, that the (reduced) LP is not solved to optimality:
4099 	    *  - The primal heuristics (called after the current node's LP was solved) found a new 
4100 	    *    solution, that is better than the current node's lower bound.
4101 	    *    (But in this case, all children should be cut off and the node should be converted
4102 	    *    into a dead-end instead of a fork.)
4103 	    *  - Something numerically weird happened after cleaning up or after resolving a diving or probing LP.
4104 	    * The only thing we can do, is to completely forget about the LP and treat the node as
4105 	    * if it was only a pseudo-solution node. Therefore we have to remove all additional
4106 	    * columns and rows from the LP and convert the node into a junction.
4107 	    * However, the node's lower bound is kept, thus automatically throwing away nodes that
4108 	    * were cut off due to a primal solution.
4109 	    */
4110 	   if( lperror || lp->resolvelperror || SCIPlpGetSolstat(lp) != SCIP_LPSOLSTAT_OPTIMAL )
4111 	   {
4112 	      SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
4113 	         "(node %" SCIP_LONGINT_FORMAT ") numerical troubles: LP %" SCIP_LONGINT_FORMAT " not optimal -- convert node into junction instead of fork\n",
4114 	         stat->nnodes, stat->nlps);
4115 	
4116 	      /* remove all additions to the LP at this node */
4117 	      SCIP_CALL( SCIPlpShrinkCols(lp, set, SCIPlpGetNCols(lp) - SCIPlpGetNNewcols(lp)) );
4118 	      SCIP_CALL( SCIPlpShrinkRows(lp, blkmem, set, eventqueue, eventfilter, SCIPlpGetNRows(lp) - SCIPlpGetNNewrows(lp)) );
4119 	
4120 	      /* convert node into a junction */
4121 	      SCIP_CALL( focusnodeToJunction(blkmem, set, eventqueue, tree, lp) );
4122 	
4123 	      return SCIP_OKAY;
4124 	   }
4125 	   assert(lp->flushed);
4126 	   assert(lp->solved);
4127 	   assert(SCIPlpGetSolstat(lp) == SCIP_LPSOLSTAT_OPTIMAL);
4128 	
4129 	   /* remove variables from the problem that are marked as deletable, were created at this node and are not contained in the LP */
4130 	   SCIP_CALL( focusnodeCleanupVars(blkmem, set, stat, eventqueue, transprob, origprob, tree, reopt, lp, branchcand, cliquetable, FALSE) );
4131 	
4132 	   assert(lp->flushed);
4133 	   assert(lp->solved);
4134 	
4135 	   /* create fork data */
4136 	   SCIP_CALL( forkCreate(&fork, blkmem, set, transprob, tree, lp) );
4137 	
4138 	   tree->focusnode->nodetype = SCIP_NODETYPE_FORK; /*lint !e641*/
4139 	   tree->focusnode->data.fork = fork;
4140 	
4141 	   /* capture the LPI state of the root node to ensure that the LPI state of the root stays for the whole solving
4142 	    * process
4143 	    */
4144 	   if( tree->focusnode == tree->root )
4145 	      forkCaptureLPIState(fork, 1);
4146 	
4147 	   /* release LPI state */
4148 	   if( tree->focuslpstatefork != NULL )
4149 	   {
4150 	      SCIP_CALL( SCIPnodeReleaseLPIState(tree->focuslpstatefork, blkmem, lp) );
4151 	   }
4152 	
4153 	   /* make the domain change data static to save memory */
4154 	   SCIP_CALL( SCIPdomchgMakeStatic(&tree->focusnode->domchg, blkmem, set, eventqueue, lp) );
4155 	
4156 	   return SCIP_OKAY;
4157 	}
4158 	
4159 	#ifdef WITHSUBROOTS  /** @todo test whether subroots should be created */
4160 	/** converts the focus node into a subroot node */
4161 	static
4162 	SCIP_RETCODE focusnodeToSubroot(
4163 	   BMS_BLKMEM*           blkmem,             /**< block memory buffers */
4164 	   SCIP_SET*             set,                /**< global SCIP settings */
4165 	   SCIP_MESSAGEHDLR*     messagehdlr,        /**< message handler */
4166 	   SCIP_STAT*            stat,               /**< dynamic problem statistics */
4167 	   SCIP_EVENTQUEUE*      eventqueue,         /**< event queue */
4168 	   SCIP_EVENTFILTER*     eventfilter,        /**< global event filter */
4169 	   SCIP_PROB*            transprob,          /**< transformed problem after presolve */
4170 	   SCIP_PROB*            origprob,           /**< original problem */
4171 	   SCIP_TREE*            tree,               /**< branch and bound tree */
4172 	   SCIP_LP*              lp,                 /**< current LP data */
4173 	   SCIP_BRANCHCAND*      branchcand,         /**< branching candidate storage */
4174 	   SCIP_CLIQUETABLE*     cliquetable         /**< clique table data structure */
4175 	   )
4176 	{
4177 	   SCIP_SUBROOT* subroot;
4178 	   SCIP_Bool lperror;
4179 	
4180 	   assert(blkmem != NULL);
4181 	   assert(tree != NULL);
4182 	   assert(!SCIPtreeProbing(tree));
4183 	   assert(tree->focusnode != NULL);
4184 	   assert(SCIPnodeGetType(tree->focusnode) == SCIP_NODETYPE_FOCUSNODE);
4185 	   assert(tree->focusnode->active); /* otherwise, no children could be created at the focus node */
4186 	   assert(tree->nchildren > 0);
4187 	   assert(lp != NULL);
4188 	   assert(lp->flushed);
4189 	   assert(lp->solved);
4190 	
4191 	   SCIPsetDebugMsg(set, "focusnode #%" SCIP_LONGINT_FORMAT " to subroot at depth %d\n",
4192 	      SCIPnodeGetNumber(tree->focusnode), SCIPnodeGetDepth(tree->focusnode));
4193 	
4194 	   /* usually, the LP should be solved to optimality; otherwise, numerical troubles occured,
4195 	    * and we have to forget about the LP and transform the node into a junction (see below)
4196 	    */
4197 	   lperror = FALSE;
4198 	   if( SCIPlpGetSolstat(lp) == SCIP_LPSOLSTAT_OPTIMAL )
4199 	   {
4200 	      /* clean up whole LP to keep only necessary columns and rows */
4201 	#ifdef SCIP_DISABLED_CODE
4202 	      if( tree->focusnode->depth == 0 )
4203 	      {
4204 	         SCIP_CALL( SCIPlpCleanupAll(lp, blkmem, set, stat, eventqueue, eventfilter, (tree->focusnode->depth == 0)) );
4205 	      }
4206 	      else
4207 	#endif
4208 	      {
4209 	         SCIP_CALL( SCIPlpRemoveAllObsoletes(lp, blkmem, set, stat, eventqueue, eventfilter) );
4210 	      }
4211 	
4212 	      /* resolve LP after cleaning up */
4213 	      SCIPsetDebugMsg(set, "resolving LP after cleanup\n");
4214 	      SCIP_CALL( SCIPlpSolveAndEval(lp, set, messagehdlr, blkmem, stat, eventqueue, eventfilter, transprob, -1LL, FALSE, FALSE, TRUE, &lperror) );
4215 	   }
4216 	   assert(lp->flushed);
4217 	   assert(lp->solved || lperror);
4218 	
4219 	   /* There are two reasons, that the (reduced) LP is not solved to optimality:
4220 	    *  - The primal heuristics (called after the current node's LP was solved) found a new
4221 	    *    solution, that is better than the current node's lower bound.
4222 	    *    (But in this case, all children should be cut off and the node should be converted
4223 	    *    into a dead-end instead of a subroot.)
4224 	    *  - Something numerically weird happened after cleaning up.
4225 	    * The only thing we can do, is to completely forget about the LP and treat the node as
4226 	    * if it was only a pseudo-solution node. Therefore we have to remove all additional
4227 	    * columns and rows from the LP and convert the node into a junction.
4228 	    * However, the node's lower bound is kept, thus automatically throwing away nodes that
4229 	    * were cut off due to a primal solution.
4230 	    */
4231 	   if( lperror || SCIPlpGetSolstat(lp) != SCIP_LPSOLSTAT_OPTIMAL )
4232 	   {
4233 	      SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
4234 	         "(node %" SCIP_LONGINT_FORMAT ") numerical troubles: LP %" SCIP_LONGINT_FORMAT " not optimal -- convert node into junction instead of subroot\n",
4235 	         stat->nnodes, stat->nlps);
4236 	
4237 	      /* remove all additions to the LP at this node */
4238 	      SCIP_CALL( SCIPlpShrinkCols(lp, set, SCIPlpGetNCols(lp) - SCIPlpGetNNewcols(lp)) );
4239 	      SCIP_CALL( SCIPlpShrinkRows(lp, blkmem, set, eventqueue, eventfilter, SCIPlpGetNRows(lp) - SCIPlpGetNNewrows(lp)) );
4240 	
4241 	      /* convert node into a junction */
4242 	      SCIP_CALL( focusnodeToJunction(blkmem, set, eventqueue, tree, lp) );
4243 	
4244 	      return SCIP_OKAY;
4245 	   }
4246 	   assert(lp->flushed);
4247 	   assert(lp->solved);
4248 	   assert(SCIPlpGetSolstat(lp) == SCIP_LPSOLSTAT_OPTIMAL);
4249 	
4250 	   /* remove variables from the problem that are marked as deletable, were created at this node and are not contained in the LP */
4251 	   SCIP_CALL( focusnodeCleanupVars(blkmem, set, stat, eventqueue, transprob, origprob, tree, lp, branchcand, cliquetable, FALSE) );
4252 	
4253 	   assert(lp->flushed);
4254 	   assert(lp->solved);
4255 	
4256 	   /* create subroot data */
4257 	   SCIP_CALL( subrootCreate(&subroot, blkmem, set, transprob, tree, lp) );
4258 	
4259 	   tree->focusnode->nodetype = SCIP_NODETYPE_SUBROOT; /*lint !e641*/
4260 	   tree->focusnode->data.subroot = subroot;
4261 	
4262 	   /* update the LP column and row counter for the converted node */
4263 	   SCIP_CALL( treeUpdatePathLPSize(tree, tree->focusnode->depth) );
4264 	
4265 	   /* release LPI state */
4266 	   if( tree->focuslpstatefork != NULL )
4267 	   {
4268 	      SCIP_CALL( SCIPnodeReleaseLPIState(tree->focuslpstatefork, blkmem, lp) );
4269 	   }
4270 	
4271 	   /* make the domain change data static to save memory */
4272 	   SCIP_CALL( SCIPdomchgMakeStatic(&tree->focusnode->domchg, blkmem, set, eventqueue, lp) );
4273 	
4274 	   return SCIP_OKAY;
4275 	}
4276 	#endif
4277 	
4278 	/** puts all nodes in the array on the node queue and makes them LEAFs */
4279 	static
4280 	SCIP_RETCODE treeNodesToQueue(
4281 	   SCIP_TREE*            tree,               /**< branch and bound tree */
4282 	   SCIP_REOPT*           reopt,              /**< reoptimization data structure */
4283 	   BMS_BLKMEM*           blkmem,             /**< block memory buffers */
4284 	   SCIP_SET*             set,                /**< global SCIP settings */
4285 	   SCIP_STAT*            stat,               /**< dynamic problem statistics */
4286 	   SCIP_EVENTFILTER*     eventfilter,        /**< event filter for global (not variable dependent) events */
4287 	   SCIP_EVENTQUEUE*      eventqueue,         /**< event queue */
4288 	   SCIP_LP*              lp,                 /**< current LP data */
4289 	   SCIP_NODE**           nodes,              /**< array of nodes to put on the queue */
4290 	   int*                  nnodes,             /**< pointer to number of nodes in the array */
4291 	   SCIP_NODE*            lpstatefork,        /**< LP state defining fork of the nodes */
4292 	   SCIP_Real             cutoffbound         /**< cutoff bound: all nodes with lowerbound >= cutoffbound are cut off */
4293 	   )
4294 	{
4295 	   int i;
4296 	
4297 	   assert(tree != NULL);
4298 	   assert(set != NULL);
4299 	   assert(nnodes != NULL);
4300 	   assert(*nnodes == 0 || nodes != NULL);
4301 	
4302 	   for( i = *nnodes; --i >= 0; )
4303 	   {
4304 	      /* convert node to LEAF and put it into leaves queue, or delete it if it's lower bound exceeds the cutoff bound */
4305 	      SCIP_CALL( nodeToLeaf(&nodes[i], blkmem, set, stat, eventfilter, eventqueue, tree, reopt, lp, lpstatefork, cutoffbound) );
4306 	      assert(nodes[i] == NULL);
4307 	      --(*nnodes);
4308 	   }
4309 	
4310 	   return SCIP_OKAY;
4311 	}
4312 	
4313 	/** converts children into siblings, clears children array */
4314 	static
4315 	void treeChildrenToSiblings(
4316 	   SCIP_TREE*            tree                /**< branch and bound tree */
4317 	   )
4318 	{
4319 	   SCIP_NODE** tmpnodes;
4320 	   SCIP_Real* tmpprios;
4321 	   int tmpnodessize;
4322 	   int i;
4323 	
4324 	   assert(tree != NULL);
4325 	   assert(tree->nsiblings == 0);
4326 	
4327 	   tmpnodes = tree->siblings;
4328 	   tmpprios = tree->siblingsprio;
4329 	   tmpnodessize = tree->siblingssize;
4330 	
4331 	   tree->siblings = tree->children;
4332 	   tree->siblingsprio = tree->childrenprio;
4333 	   tree->nsiblings = tree->nchildren;
4334 	   tree->siblingssize = tree->childrensize;
4335 	
4336 	   tree->children = tmpnodes;
4337 	   tree->childrenprio = tmpprios;
4338 	   tree->nchildren = 0;
4339 	   tree->childrensize = tmpnodessize;
4340 	
4341 	   for( i = 0; i < tree->nsiblings; ++i )
4342 	   {
4343 	      assert(SCIPnodeGetType(tree->siblings[i]) == SCIP_NODETYPE_CHILD);
4344 	      tree->siblings[i]->nodetype = SCIP_NODETYPE_SIBLING; /*lint !e641*/
4345 	
4346 	      /* because CHILD and SIBLING structs contain the same data in the same order, we do not have to copy it */
4347 	      assert(&(tree->siblings[i]->data.sibling.arraypos) == &(tree->siblings[i]->data.child.arraypos));
4348 	   }
4349 	}
4350 	
4351 	/** installs a child, a sibling, or a leaf node as the new focus node */
4352 	SCIP_RETCODE SCIPnodeFocus(
4353 	   SCIP_NODE**           node,               /**< pointer to node to focus (or NULL to remove focus); the node
4354 	                                              *   is freed, if it was cut off due to a cut off subtree */
4355 	   BMS_BLKMEM*           blkmem,             /**< block memory buffers */
4356 	   SCIP_SET*             set,                /**< global SCIP settings */
4357 	   SCIP_MESSAGEHDLR*     messagehdlr,        /**< message handler */
4358 	   SCIP_STAT*            stat,               /**< problem statistics */
4359 	   SCIP_PROB*            transprob,          /**< transformed problem */
4360 	   SCIP_PROB*            origprob,           /**< original problem */
4361 	   SCIP_PRIMAL*          primal,             /**< primal data */
4362 	   SCIP_TREE*            tree,               /**< branch and bound tree */
4363 	   SCIP_REOPT*           reopt,              /**< reoptimization data structure */
4364 	   SCIP_LP*              lp,                 /**< current LP data */
4365 	   SCIP_BRANCHCAND*      branchcand,         /**< branching candidate storage */
4366 	   SCIP_CONFLICT*        conflict,           /**< conflict analysis data */
4367 	   SCIP_CONFLICTSTORE*   conflictstore,      /**< conflict store */
4368 	   SCIP_EVENTFILTER*     eventfilter,        /**< event filter for global (not variable dependent) events */
4369 	   SCIP_EVENTQUEUE*      eventqueue,         /**< event queue */
4370 	   SCIP_CLIQUETABLE*     cliquetable,        /**< clique table data structure */
4371 	   SCIP_Bool*            cutoff,             /**< pointer to store whether the given node can be cut off */
4372 	   SCIP_Bool             postponed,          /**< was the current focus node postponed? */
4373 	   SCIP_Bool             exitsolve           /**< are we in exitsolve stage, so we only need to loose the children */
4374 	   )
4375 	{  /*lint --e{715}*/
4376 	   SCIP_NODE* fork;
4377 	   SCIP_NODE* lpfork;
4378 	   SCIP_NODE* lpstatefork;
4379 	   SCIP_NODE* subroot;
4380 	   SCIP_NODE* childrenlpstatefork;
4381 	   int oldcutoffdepth;
4382 	
4383 	   assert(node != NULL);
4384 	   assert(*node == NULL
4385 	      || SCIPnodeGetType(*node) == SCIP_NODETYPE_SIBLING
4386 	      || SCIPnodeGetType(*node) == SCIP_NODETYPE_CHILD
4387 	      || SCIPnodeGetType(*node) == SCIP_NODETYPE_LEAF);
4388 	   assert(*node == NULL || !(*node)->active);
4389 	   assert(stat != NULL);
4390 	   assert(tree != NULL);
4391 	   assert(!SCIPtreeProbing(tree));
4392 	   assert(lp != NULL);
4393 	   assert(conflictstore != NULL);
4394 	   assert(cutoff != NULL);
4395 	
4396 	   /* check global lower bound w.r.t. debugging solution */
4397 	   SCIP_CALL( SCIPdebugCheckGlobalLowerbound(blkmem, set) );
4398 	
4399 	   /* check local lower bound w.r.t. debugging solution */
4400 	   SCIP_CALL( SCIPdebugCheckLocalLowerbound(blkmem, set, *node) );
4401 	
4402 	   SCIPsetDebugMsg(set, "focusing node #%" SCIP_LONGINT_FORMAT " of type %d in depth %d\n",
4403 	      *node != NULL ? SCIPnodeGetNumber(*node) : -1, *node != NULL ? (int)SCIPnodeGetType(*node) : 0,
4404 	      *node != NULL ? SCIPnodeGetDepth(*node) : -1);
4405 	
4406 	   /* remember old cutoff depth in order to know, whether the children and siblings can be deleted */
4407 	   oldcutoffdepth = tree->cutoffdepth;
4408 	
4409 	   /* find the common fork node, the new LP defining fork, and the new focus subroot,
4410 	    * thereby checking, if the new node can be cut off
4411 	    */
4412 	   treeFindSwitchForks(tree, *node, &fork, &lpfork, &lpstatefork, &subroot, cutoff);
4413 	   SCIPsetDebugMsg(set, "focus node: focusnodedepth=%ld, forkdepth=%ld, lpforkdepth=%ld, lpstateforkdepth=%ld, subrootdepth=%ld, cutoff=%u\n",
4414 	      *node != NULL ? (long)((*node)->depth) : -1, fork != NULL ? (long)(fork->depth) : -1, /*lint !e705 */
4415 	      lpfork != NULL ? (long)(lpfork->depth) : -1, lpstatefork != NULL ? (long)(lpstatefork->depth) : -1, /*lint !e705 */
4416 	      subroot != NULL ? (long)(subroot->depth) : -1, *cutoff); /*lint !e705 */
4417 	
4418 	   /* free the new node, if it is located in a cut off subtree */
4419 	   if( *cutoff )
4420 	   {
4421 	      assert(*node != NULL);
4422 	      assert(tree->cutoffdepth == oldcutoffdepth);
4423 	      if( SCIPnodeGetType(*node) == SCIP_NODETYPE_LEAF )
4424 	      {
4425 	         SCIP_CALL( SCIPnodepqRemove(tree->leaves, set, *node) );
4426 	      }
4427 	      SCIPvisualCutoffNode(stat->visual, set, stat, *node, FALSE);
4428 	
4429 	      if( set->reopt_enable )
4430 	      {
4431 	         assert(reopt != NULL);
4432 	         /* check if the node should be stored for reoptimization */
4433 	         SCIP_CALL( SCIPreoptCheckCutoff(reopt, set, blkmem, *node, SCIP_EVENTTYPE_NODEINFEASIBLE, lp, SCIPlpGetSolstat(lp),
4434 	               tree->root == (*node), tree->focusnode == (*node), (*node)->lowerbound, tree->effectiverootdepth) );
4435 	      }
4436 	
4437 	      SCIP_CALL( SCIPnodeFree(node, blkmem, set, stat, eventfilter, eventqueue, tree, lp) );
4438 	
4439 	      return SCIP_OKAY;
4440 	   }
4441 	
4442 	   assert(tree->cutoffdepth == INT_MAX);
4443 	   assert(fork == NULL || fork->active);
4444 	   assert(lpstatefork == NULL || lpfork != NULL);
4445 	   assert(subroot == NULL || lpstatefork != NULL);
4446 	
4447 	   /* remember the depth of the common fork node for LP updates */
4448 	   SCIPsetDebugMsg(set, "focus node: old correctlpdepth=%d\n", tree->correctlpdepth);
4449 	   if( subroot == tree->focussubroot && fork != NULL && lpfork != NULL )
4450 	   {
4451 	      /* we are in the same subtree with valid LP fork: the LP is correct at most upto the common fork depth */
4452 	      assert(subroot == NULL || subroot->active);
4453 	      tree->correctlpdepth = MIN(tree->correctlpdepth, (int)fork->depth);
4454 	   }
4455 	   else
4456 	   {
4457 	      /* we are in a different subtree, or no valid LP fork exists: the LP is completely incorrect */
4458 	      assert(subroot == NULL || !subroot->active
4459 	         || (tree->focussubroot != NULL && tree->focussubroot->depth > subroot->depth));
4460 	      tree->correctlpdepth = -1;
4461 	   }
4462 	
4463 	   /* if the LP state fork changed, the lpcount information for the new LP state fork is unknown */
4464 	   if( lpstatefork != tree->focuslpstatefork )
4465 	      tree->focuslpstateforklpcount = -1;
4466 	
4467 	   /* in exitsolve we only need to take care of open children
4468 	    *
4469 	    * @note because we might do a 'newstart' and converted cuts to constraints might have rendered the LP in the current
4470 	    *       focusnode unsolved the latter code would have resolved the LP unnecessarily
4471 	    */
4472 	   if( exitsolve && tree->nchildren > 0 )
4473 	   {
4474 	      SCIPsetDebugMsg(set, " -> deleting the %d children (in exitsolve) of the old focus node\n", tree->nchildren);
4475 	      SCIP_CALL( treeNodesToQueue(tree, reopt, blkmem, set, stat, eventfilter, eventqueue, lp, tree->children, &tree->nchildren, NULL, -SCIPsetInfinity(set)) );
4476 	      assert(tree->nchildren == 0);
4477 	   }
4478 	
4479 	   /* if the old focus node was cut off, we can delete its children;
4480 	    * if the old focus node's parent was cut off, we can also delete the focus node's siblings
4481 	    */
4482 	   /* coverity[var_compare_op] */
4483 	   if( tree->focusnode != NULL && oldcutoffdepth <= (int)tree->focusnode->depth )
4484 	   {
4485 	      SCIPsetDebugMsg(set, "path to old focus node of depth %u was cut off at depth %d\n", tree->focusnode->depth, oldcutoffdepth);
4486 	
4487 	      /* delete the focus node's children by converting them to leaves with a cutoffbound of -SCIPsetInfinity(set);
4488 	       * we cannot delete them directly, because in SCIPnodeFree(), the children array is changed, which is the
4489 	       * same array we would have to iterate over here;
4490 	       * the children don't have an LP fork, because the old focus node is not yet converted into a fork or subroot
4491 	       */
4492 	      SCIPsetDebugMsg(set, " -> deleting the %d children of the old focus node\n", tree->nchildren);
4493 	      SCIP_CALL( treeNodesToQueue(tree, reopt, blkmem, set, stat, eventfilter, eventqueue, lp, tree->children, &tree->nchildren, NULL, -SCIPsetInfinity(set)) );
4494 	      assert(tree->nchildren == 0);
4495 	
4496 	      if( oldcutoffdepth < (int)tree->focusnode->depth )
4497 	      {
4498 	         /* delete the focus node's siblings by converting them to leaves with a cutoffbound of -SCIPsetInfinity(set);
4499 	          * we cannot delete them directly, because in SCIPnodeFree(), the siblings array is changed, which is the
4500 	          * same array we would have to iterate over here;
4501 	          * the siblings have the same LP state fork as the old focus node
4502 	          */
4503 	         SCIPsetDebugMsg(set, " -> deleting the %d siblings of the old focus node\n", tree->nsiblings);
4504 	         SCIP_CALL( treeNodesToQueue(tree, reopt, blkmem, set, stat, eventfilter, eventqueue, lp, tree->siblings, &tree->nsiblings, tree->focuslpstatefork,
4505 	               -SCIPsetInfinity(set)) );
4506 	         assert(tree->nsiblings == 0);
4507 	      }
4508 	   }
4509 	
4510 	   /* convert the old focus node into a fork or subroot node, if it has children;
4511 	    * otherwise, convert it into a dead-end, which will be freed later in treeSwitchPath();
4512 	    * if the node was postponed, make it a leaf.
4513 	    */
4514 	   childrenlpstatefork = tree->focuslpstatefork;
4515 	
4516 	   assert(!postponed || *node == NULL);
4517 	   assert(!postponed || tree->focusnode != NULL);
4518 	
4519 	   if( postponed )
4520 	   {
4521 	      assert(tree->nchildren == 0);
4522 	      assert(*node == NULL);
4523 	
4524 	      /* if the node is infeasible, convert it into a deadend; otherwise, put it into the LEAF queue */
4525 	      if( SCIPsetIsGE(set, tree->focusnode->lowerbound, primal->cutoffbound) )
4526 	      {
4527 	         /* in case the LP was not constructed (due to the parameter settings for example) we have the finally remember the
4528 	          * old size of the LP (if it was constructed in an earlier node) before we change the current node into a deadend
4529 	          */
4530 	         if( !tree->focuslpconstructed )
4531 	            SCIPlpMarkSize(lp);
4532 	
4533 	         /* convert old focus node into deadend */
4534 	         SCIP_CALL( focusnodeToDeadend(blkmem, set, stat, eventqueue, transprob, origprob, tree, reopt, lp, branchcand,
4535 	               cliquetable) );
4536 	      }
4537 	      else
4538 	      {
4539 	         SCIP_CALL( focusnodeToLeaf(blkmem, set, stat, eventfilter, eventqueue, tree, reopt, lp, tree->focuslpstatefork,
4540 	               SCIPsetInfinity(set)) );
4541 	      }
4542 	   }
4543 	   else if( tree->nchildren > 0 )
4544 	   {
4545 	      SCIP_Bool selectedchild;
4546 	
4547 	      assert(tree->focusnode != NULL);
4548 	      assert(SCIPnodeGetType(tree->focusnode) == SCIP_NODETYPE_FOCUSNODE);
4549 	      assert(oldcutoffdepth == INT_MAX);
4550 	
4551 	      /* check whether the next focus node is a child of the old focus node */
4552 	      selectedchild = (*node != NULL && SCIPnodeGetType(*node) == SCIP_NODETYPE_CHILD);
4553 	
4554 	      if( tree->focusnodehaslp && lp->isrelax )
4555 	      {
4556 	         assert(tree->focuslpconstructed);
4557 	
4558 	#ifdef WITHSUBROOTS  /** @todo test whether subroots should be created, decide: old focus node becomes fork or subroot */
4559 	         if( tree->focusnode->depth > 0 && tree->focusnode->depth % 25 == 0 )
4560 	         {
4561 	            /* convert old focus node into a subroot node */
4562 	            SCIP_CALL( focusnodeToSubroot(blkmem, set, messagehdlr, stat, eventqueue, eventfilter, transprob, origprob, tree, lp, branchcand) );
4563 	            if( *node != NULL && SCIPnodeGetType(*node) == SCIP_NODETYPE_CHILD
4564 	               && SCIPnodeGetType(tree->focusnode) == SCIP_NODETYPE_SUBROOT )
4565 	               subroot = tree->focusnode;
4566 	         }
4567 	         else
4568 	#endif
4569 	         {
4570 	            /* convert old focus node into a fork node */
4571 	            SCIP_CALL( focusnodeToFork(blkmem, set, messagehdlr, stat, eventqueue, eventfilter, transprob, origprob, tree,
4572 	                  reopt, lp, branchcand, cliquetable) );
4573 	         }
4574 	
4575 	         /* check, if the conversion into a subroot or fork was successful */
4576 	         if( SCIPnodeGetType(tree->focusnode) == SCIP_NODETYPE_FORK
4577 	            || SCIPnodeGetType(tree->focusnode) == SCIP_NODETYPE_SUBROOT )
4578 	         {
4579 	            childrenlpstatefork = tree->focusnode;
4580 	
4581 	            /* if a child of the old focus node was selected as new focus node, the old node becomes the new focus
4582 	             * LP fork and LP state fork
4583 	             */
4584 	            if( selectedchild )
4585 	            {
4586 	               lpfork = tree->focusnode;
4587 	               tree->correctlpdepth = (int) tree->focusnode->depth;
4588 	               lpstatefork = tree->focusnode;
4589 	               tree->focuslpstateforklpcount = stat->lpcount;
4590 	            }
4591 	         }
4592 	
4593 	         /* update the path's LP size */
4594 	         tree->pathnlpcols[tree->focusnode->depth] = SCIPlpGetNCols(lp);
4595 	         tree->pathnlprows[tree->focusnode->depth] = SCIPlpGetNRows(lp);
4596 	      }
4597 	      else if( tree->focuslpconstructed && (SCIPlpGetNNewcols(lp) > 0 || SCIPlpGetNNewrows(lp) > 0) )
4598 	      {
4599 	         /* convert old focus node into pseudofork */
4600 	         SCIP_CALL( focusnodeToPseudofork(blkmem, set, stat, eventqueue, transprob, origprob, tree, reopt, lp,
4601 	               branchcand, cliquetable) );
4602 	         assert(SCIPnodeGetType(tree->focusnode) == SCIP_NODETYPE_PSEUDOFORK);
4603 	
4604 	         /* update the path's LP size */
4605 	         tree->pathnlpcols[tree->focusnode->depth] = SCIPlpGetNCols(lp);
4606 	         tree->pathnlprows[tree->focusnode->depth] = SCIPlpGetNRows(lp);
4607 	
4608 	         /* if a child of the old focus node was selected as new focus node, the old node becomes the new focus LP fork */
4609 	         if( selectedchild )
4610 	         {
4611 	            lpfork = tree->focusnode;
4612 	            tree->correctlpdepth = (int) tree->focusnode->depth;
4613 	         }
4614 	      }
4615 	      else
4616 	      {
4617 	         /* in case the LP was not constructed (due to the parameter settings for example) we have the finally remember the
4618 	          * old size of the LP (if it was constructed in an earlier node) before we change the current node into a junction
4619 	          */
4620 	         SCIPlpMarkSize(lp);
4621 	
4622 	         /* convert old focus node into junction */
4623 	         SCIP_CALL( focusnodeToJunction(blkmem, set, eventqueue, tree, lp) );
4624 	      }
4625 	   }
4626 	   else if( tree->focusnode != NULL )
4627 	   {
4628 	      /* in case the LP was not constructed (due to the parameter settings for example) we have the finally remember the
4629 	       * old size of the LP (if it was constructed in an earlier node) before we change the current node into a deadend
4630 	       */
4631 	      if( !tree->focuslpconstructed )
4632 	         SCIPlpMarkSize(lp);
4633 	
4634 	      /* convert old focus node into deadend */
4635 	      SCIP_CALL( focusnodeToDeadend(blkmem, set, stat, eventqueue, transprob, origprob, tree, reopt, lp, branchcand, cliquetable) );
4636 	   }
4637 	   assert(subroot == NULL || SCIPnodeGetType(subroot) == SCIP_NODETYPE_SUBROOT);
4638 	   assert(lpstatefork == NULL
4639 	      || SCIPnodeGetType(lpstatefork) == SCIP_NODETYPE_SUBROOT
4640 	      || SCIPnodeGetType(lpstatefork) == SCIP_NODETYPE_FORK);
4641 	   assert(childrenlpstatefork == NULL
4642 	      || SCIPnodeGetType(childrenlpstatefork) == SCIP_NODETYPE_SUBROOT
4643 	      || SCIPnodeGetType(childrenlpstatefork) == SCIP_NODETYPE_FORK);
4644 	   assert(lpfork == NULL
4645 	      || SCIPnodeGetType(lpfork) == SCIP_NODETYPE_SUBROOT
4646 	      || SCIPnodeGetType(lpfork) == SCIP_NODETYPE_FORK
4647 	      || SCIPnodeGetType(lpfork) == SCIP_NODETYPE_PSEUDOFORK);
4648 	   SCIPsetDebugMsg(set, "focus node: new correctlpdepth=%d\n", tree->correctlpdepth);
4649 	
4650 	   /* set up the new lists of siblings and children */
4651 	   if( *node == NULL )
4652 	   {
4653 	      /* move siblings to the queue, make them LEAFs */
4654 	      SCIP_CALL( treeNodesToQueue(tree, reopt, blkmem, set, stat, eventfilter, eventqueue, lp, tree->siblings, &tree->nsiblings, tree->focuslpstatefork,
4655 	            primal->cutoffbound) );
4656 	
4657 	      /* move children to the queue, make them LEAFs */
4658 	      SCIP_CALL( treeNodesToQueue(tree, reopt, blkmem, set, stat, eventfilter, eventqueue, lp, tree->children, &tree->nchildren, childrenlpstatefork,
4659 	            primal->cutoffbound) );
4660 	   }
4661 	   else
4662 	   {
4663 	      SCIP_NODE* bestleaf;
4664 	
4665 	      switch( SCIPnodeGetType(*node) )
4666 	      {  
4667 	      case SCIP_NODETYPE_SIBLING:
4668 	         /* reset plunging depth, if the selected node is better than all leaves */
4669 	         bestleaf = SCIPtreeGetBestLeaf(tree);
4670 	         if( bestleaf == NULL || SCIPnodepqCompare(tree->leaves, set, *node, bestleaf) <= 0 )
4671 	            stat->plungedepth = 0;
4672 	
4673 	         /* move children to the queue, make them LEAFs */
4674 	         SCIP_CALL( treeNodesToQueue(tree, reopt, blkmem, set, stat, eventfilter, eventqueue, lp, tree->children, &tree->nchildren, childrenlpstatefork,
4675 	               primal->cutoffbound) );
4676 	
4677 	         /* remove selected sibling from the siblings array */
4678 	         treeRemoveSibling(tree, *node);
4679 	
4680 	         SCIPsetDebugMsg(set, "selected sibling node, lowerbound=%g, plungedepth=%d\n", (*node)->lowerbound, stat->plungedepth);
4681 	         break;
4682 	
4683 	      case SCIP_NODETYPE_CHILD:
4684 	         /* reset plunging depth, if the selected node is better than all leaves; otherwise, increase plunging depth */
4685 	         bestleaf = SCIPtreeGetBestLeaf(tree);
4686 	         if( bestleaf == NULL || SCIPnodepqCompare(tree->leaves, set, *node, bestleaf) <= 0 )
4687 	            stat->plungedepth = 0;
4688 	         else
4689 	            stat->plungedepth++;
4690 	
4691 	         /* move siblings to the queue, make them LEAFs */
4692 	         SCIP_CALL( treeNodesToQueue(tree, reopt, blkmem, set, stat, eventfilter, eventqueue, lp, tree->siblings, &tree->nsiblings, tree->focuslpstatefork,
4693 	               primal->cutoffbound) );
4694 	
4695 	         /* remove selected child from the children array */      
4696 	         treeRemoveChild(tree, *node);
4697 	
4698 	         /* move remaining children to the siblings array, make them SIBLINGs */
4699 	         treeChildrenToSiblings(tree);
4700 	
4701 	         SCIPsetDebugMsg(set, "selected child node, lowerbound=%g, plungedepth=%d\n", (*node)->lowerbound, stat->plungedepth);
4702 	         break;
4703 	
4704 	      case SCIP_NODETYPE_LEAF:
4705 	         /* move siblings to the queue, make them LEAFs */
4706 	         SCIP_CALL( treeNodesToQueue(tree, reopt, blkmem, set, stat, eventfilter, eventqueue, lp, tree->siblings, &tree->nsiblings, tree->focuslpstatefork,
4707 	               primal->cutoffbound) );
4708 	
4709 	         /* encounter an early backtrack if there is a child which does not exceed given reference bound */
4710 	         if( !SCIPsetIsInfinity(set, stat->referencebound) )
4711 	         {
4712 	            int c;
4713 	
4714 	            /* loop over children and stop if we find a child with a lower bound below given reference bound */
4715 	            for( c = 0; c < tree->nchildren; ++c )
4716 	            {
4717 	               if( SCIPsetIsLT(set, SCIPnodeGetLowerbound(tree->children[c]), stat->referencebound) )
4718 	               {
4719 	                  ++stat->nearlybacktracks;
4720 	                  break;
4721 	               }
4722 	            }
4723 	         }
4724 	         /* move children to the queue, make them LEAFs */
4725 	         SCIP_CALL( treeNodesToQueue(tree, reopt, blkmem, set, stat, eventfilter, eventqueue, lp, tree->children, &tree->nchildren, childrenlpstatefork,
4726 	               primal->cutoffbound) );
4727 	
4728 	         /* remove node from the queue */
4729 	         SCIP_CALL( SCIPnodepqRemove(tree->leaves, set, *node) );
4730 	
4731 	         stat->plungedepth = 0;
4732 	         if( SCIPnodeGetDepth(*node) > 0 )
4733 	            stat->nbacktracks++;
4734 	         SCIPsetDebugMsg(set, "selected leaf node, lowerbound=%g, plungedepth=%d\n", (*node)->lowerbound, stat->plungedepth);
4735 	         break;
4736 	
4737 	      default:
4738 	         SCIPerrorMessage("selected node is neither sibling, child, nor leaf (nodetype=%d)\n", SCIPnodeGetType(*node));
4739 	         return SCIP_INVALIDDATA;
4740 	      }  /*lint !e788*/
4741 	
4742 	      /* convert node into the focus node */
4743 	      (*node)->nodetype = SCIP_NODETYPE_FOCUSNODE; /*lint !e641*/
4744 	   }
4745 	   assert(tree->nchildren == 0);
4746 	
4747 	   /* set LP fork, LP state fork, and subroot */
4748 	   assert(subroot == NULL || (lpstatefork != NULL && subroot->depth <= lpstatefork->depth));
4749 	   assert(lpstatefork == NULL || (lpfork != NULL && lpstatefork->depth <= lpfork->depth));
4750 	   assert(lpfork == NULL || (*node != NULL && lpfork->depth < (*node)->depth));
4751 	   tree->focuslpfork = lpfork;
4752 	   tree->focuslpstatefork = lpstatefork;
4753 	   tree->focussubroot = subroot;
4754 	   tree->focuslpconstructed = FALSE;
4755 	   lp->resolvelperror = FALSE;
4756 	
4757 	   /* track the path from the old focus node to the new node, free dead end, set new focus node, and perform domain and constraint set changes */
4758 	   SCIP_CALL( treeSwitchPath(tree, reopt, blkmem, set, stat, transprob, origprob, primal, lp, branchcand, conflict,
4759 	         eventfilter, eventqueue, cliquetable, fork, *node, cutoff) );
4760 	   assert(tree->focusnode == *node);
4761 	   assert(tree->pathlen >= 0);
4762 	   assert(*node != NULL || tree->pathlen == 0);
4763 	   assert(*node == NULL || tree->pathlen-1 <= (int)(*node)->depth);
4764 	   assert(*cutoff || SCIPtreeIsPathComplete(tree));
4765 	
4766 	   return SCIP_OKAY;
4767 	}
4768 	
4769 	
4770 	
4771 	
4772 	/*
4773 	 * Tree methods
4774 	 */
4775 	
4776 	/** creates an initialized tree data structure */
4777 	SCIP_RETCODE SCIPtreeCreate(
4778 	   SCIP_TREE**           tree,               /**< pointer to tree data structure */
4779 	   BMS_BLKMEM*           blkmem,             /**< block memory buffers */
4780 	   SCIP_SET*             set,                /**< global SCIP settings */
4781 	   SCIP_NODESEL*         nodesel             /**< node selector to use for sorting leaves in the priority queue */
4782 	   )
4783 	{
4784 	   int p;
4785 	
4786 	   assert(tree != NULL);
4787 	   assert(blkmem != NULL);
4788 	
4789 	   SCIP_ALLOC( BMSallocMemory(tree) );
4790 	
4791 	   (*tree)->root = NULL;
4792 	
4793 	   SCIP_CALL( SCIPnodepqCreate(&(*tree)->leaves, set, nodesel) );
4794 	
4795 	   /* allocate one slot for the prioritized and the unprioritized bound change */
4796 	   for( p = 0; p <= 1; ++p )
4797 	   {
4798 	      SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*tree)->divebdchgdirs[p], 1) ); /*lint !e866*/
4799 	      SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*tree)->divebdchgvars[p], 1) ); /*lint !e866*/
4800 	      SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*tree)->divebdchgvals[p], 1) ); /*lint !e866*/
4801 	      (*tree)->ndivebdchanges[p] = 0;
4802 	      (*tree)->divebdchgsize[p] = 1;
4803 	   }
4804 	
4805 	   (*tree)->path = NULL;
4806 	   (*tree)->focusnode = NULL;
4807 	   (*tree)->focuslpfork = NULL;
4808 	   (*tree)->focuslpstatefork = NULL;
4809 	   (*tree)->focussubroot = NULL;
4810 	   (*tree)->children = NULL;
4811 	   (*tree)->siblings = NULL;
4812 	   (*tree)->probingroot = NULL;
4813 	   (*tree)->childrenprio = NULL;
4814 	   (*tree)->siblingsprio = NULL;
4815 	   (*tree)->pathnlpcols = NULL;
4816 	   (*tree)->pathnlprows = NULL;
4817 	   (*tree)->probinglpistate = NULL;
4818 	   (*tree)->probinglpinorms = NULL;
4819 	   (*tree)->pendingbdchgs = NULL;
4820 	   (*tree)->probdiverelaxsol = NULL;
4821 	   (*tree)->nprobdiverelaxsol = 0;
4822 	   (*tree)->pendingbdchgssize = 0;
4823 	   (*tree)->npendingbdchgs = 0;
4824 	   (*tree)->focuslpstateforklpcount = -1;
4825 	   (*tree)->childrensize = 0;
4826 	   (*tree)->nchildren = 0;
4827 	   (*tree)->siblingssize = 0;
4828 	   (*tree)->nsiblings = 0;
4829 	   (*tree)->pathlen = 0;
4830 	   (*tree)->pathsize = 0;
4831 	   (*tree)->effectiverootdepth = 0;
4832 	   (*tree)->appliedeffectiverootdepth = 0;
4833 	   (*tree)->lastbranchparentid = -1L;
4834 	   (*tree)->correctlpdepth = -1;
4835 	   (*tree)->cutoffdepth = INT_MAX;
4836 	   (*tree)->repropdepth = INT_MAX;
4837 	   (*tree)->repropsubtreecount = 0;
4838 	   (*tree)->focusnodehaslp = FALSE;
4839 	   (*tree)->probingnodehaslp = FALSE;
4840 	   (*tree)->focuslpconstructed = FALSE;
4841 	   (*tree)->cutoffdelayed = FALSE;
4842 	   (*tree)->probinglpwasflushed = FALSE;
4843 	   (*tree)->probinglpwassolved = FALSE;
4844 	   (*tree)->probingloadlpistate = FALSE;
4845 	   (*tree)->probinglpwasrelax = FALSE;
4846 	   (*tree)->probingsolvedlp = FALSE;
4847 	   (*tree)->forcinglpmessage = FALSE;
4848 	   (*tree)->sbprobing = FALSE;
4849 	   (*tree)->probinglpwasprimfeas = TRUE;
4850 	   (*tree)->probinglpwasdualfeas = TRUE;
4851 	   (*tree)->probdiverelaxstored = FALSE;
4852 	   (*tree)->probdiverelaxincludeslp = FALSE;
4853 	
4854 	   return SCIP_OKAY;
4855 	}
4856 	
4857 	/** frees tree data structure */
4858 	SCIP_RETCODE SCIPtreeFree(
4859 	   SCIP_TREE**           tree,               /**< pointer to tree data structure */
4860 	   BMS_BLKMEM*           blkmem,             /**< block memory buffers */
4861 	   SCIP_SET*             set,                /**< global SCIP settings */
4862 	   SCIP_STAT*            stat,               /**< problem statistics */
4863 	   SCIP_EVENTFILTER*     eventfilter,        /**< event filter for global (not variable dependent) events */
4864 	   SCIP_EVENTQUEUE*      eventqueue,         /**< event queue */
4865 	   SCIP_LP*              lp                  /**< current LP data */
4866 	   )
4867 	{
4868 	   int p;
4869 	
4870 	   assert(tree != NULL);
4871 	   assert(*tree != NULL);
4872 	   assert((*tree)->nchildren == 0);
4873 	   assert((*tree)->nsiblings == 0);
4874 	   assert((*tree)->focusnode == NULL);
4875 	   assert(!SCIPtreeProbing(*tree));
4876 	
4877 	   SCIPsetDebugMsg(set, "free tree\n");
4878 	
4879 	   /* free node queue */
4880 	   SCIP_CALL( SCIPnodepqFree(&(*tree)->leaves, blkmem, set, stat, eventfilter, eventqueue, *tree, lp) );
4881 	
4882 	   /* free diving bound change storage */
4883 	   for( p = 0; p <= 1; ++p )
4884 	   {
4885 	      BMSfreeBlockMemoryArray(blkmem, &(*tree)->divebdchgdirs[p], (*tree)->divebdchgsize[p]); /*lint !e866*/
4886 	      BMSfreeBlockMemoryArray(blkmem, &(*tree)->divebdchgvals[p], (*tree)->divebdchgsize[p]); /*lint !e866*/
4887 	      BMSfreeBlockMemoryArray(blkmem, &(*tree)->divebdchgvars[p], (*tree)->divebdchgsize[p]); /*lint !e866*/
4888 	   }
4889 	
4890 	   /* free pointer arrays */
4891 	   BMSfreeMemoryArrayNull(&(*tree)->path);
4892 	   BMSfreeMemoryArrayNull(&(*tree)->children);
4893 	   BMSfreeMemoryArrayNull(&(*tree)->siblings);
4894 	   BMSfreeMemoryArrayNull(&(*tree)->childrenprio);
4895 	   BMSfreeMemoryArrayNull(&(*tree)->siblingsprio);
4896 	   BMSfreeMemoryArrayNull(&(*tree)->pathnlpcols);
4897 	   BMSfreeMemoryArrayNull(&(*tree)->pathnlprows);
4898 	   BMSfreeMemoryArrayNull(&(*tree)->probdiverelaxsol);
4899 	   BMSfreeMemoryArrayNull(&(*tree)->pendingbdchgs);
4900 	
4901 	   BMSfreeMemory(tree);
4902 	
4903 	   return SCIP_OKAY;
4904 	}
4905 	
4906 	/** clears and resets tree data structure and deletes all nodes */
4907 	SCIP_RETCODE SCIPtreeClear(
4908 	   SCIP_TREE*            tree,               /**< tree data structure */
4909 	   BMS_BLKMEM*           blkmem,             /**< block memory buffers */
4910 	   SCIP_SET*             set,                /**< global SCIP settings */
4911 	   SCIP_STAT*            stat,               /**< problem statistics */
4912 	   SCIP_EVENTFILTER*     eventfilter,        /**< event filter for global (not variable dependent) events */
4913 	   SCIP_EVENTQUEUE*      eventqueue,         /**< event queue */
4914 	   SCIP_LP*              lp                  /**< current LP data */
4915 	   )
4916 	{
4917 	   int v;
4918 	
4919 	   assert(tree != NULL);
4920 	   assert(tree->nchildren == 0);
4921 	   assert(tree->nsiblings == 0);
4922 	   assert(tree->focusnode == NULL);
4923 	   assert(!SCIPtreeProbing(tree));
4924 	
4925 	   SCIPsetDebugMsg(set, "clearing tree\n");
4926 	
4927 	   /* clear node queue */
4928 	   SCIP_CALL( SCIPnodepqClear(tree->leaves, blkmem, set, stat, eventfilter, eventqueue, tree, lp) );
4929 	   assert(tree->root == NULL);
4930 	
4931 	   /* we have to remove the captures of the variables within the pending bound change data structure */
4932 	   for( v = tree->npendingbdchgs-1; v >= 0; --v )
4933 	   {
4934 	      SCIP_VAR* var;
4935 	
4936 	      var = tree->pendingbdchgs[v].var;
4937 	      assert(var != NULL);
4938 	
4939 	      /* release the variable */
4940 	      SCIP_CALL( SCIPvarRelease(&var, blkmem, set, eventqueue, lp) );
4941 	   }
4942 	
4943 	   /* mark working arrays to be empty and reset data */
4944 	   tree->focuslpstateforklpcount = -1;
4945 	   tree->nchildren = 0;
4946 	   tree->nsiblings = 0;
4947 	   tree->pathlen = 0;
4948 	   tree->effectiverootdepth = 0;
4949 	   tree->appliedeffectiverootdepth = 0;
4950 	   tree->correctlpdepth = -1;
4951 	   tree->cutoffdepth = INT_MAX;
4952 	   tree->repropdepth = INT_MAX;
4953 	   tree->repropsubtreecount = 0;
4954 	   tree->npendingbdchgs = 0;
4955 	   tree->focusnodehaslp = FALSE;
4956 	   tree->probingnodehaslp = FALSE;
4957 	   tree->cutoffdelayed = FALSE;
4958 	   tree->probinglpwasflushed = FALSE;
4959 	   tree->probinglpwassolved = FALSE;
4960 	   tree->probingloadlpistate = FALSE;
4961 	   tree->probinglpwasrelax = FALSE;
4962 	   tree->probingsolvedlp = FALSE;
4963 	
4964 	   return SCIP_OKAY;
4965 	}
4966 	
4967 	/** creates the root node of the tree and puts it into the leaves queue */
4968 	SCIP_RETCODE SCIPtreeCreateRoot(
4969 	   SCIP_TREE*            tree,               /**< tree data structure */
4970 	   SCIP_REOPT*           reopt,              /**< reoptimization data structure */
4971 	   BMS_BLKMEM*           blkmem,             /**< block memory buffers */
4972 	   SCIP_SET*             set,                /**< global SCIP settings */
4973 	   SCIP_STAT*            stat,               /**< problem statistics */
4974 	   SCIP_EVENTFILTER*     eventfilter,        /**< event filter for global (not variable dependent) events */
4975 	   SCIP_EVENTQUEUE*      eventqueue,         /**< event queue */
4976 	   SCIP_LP*              lp                  /**< current LP data */
4977 	   )
4978 	{
4979 	   assert(tree != NULL);
4980 	   assert(tree->nchildren == 0);
4981 	   assert(tree->nsiblings == 0);
4982 	   assert(tree->root == NULL);
4983 	   assert(tree->focusnode == NULL);
4984 	   assert(!SCIPtreeProbing(tree));
4985 	
4986 	   /* create root node */
4987 	   SCIP_CALL( SCIPnodeCreateChild(&tree->root, blkmem, set, stat, tree, 0.0, -SCIPsetInfinity(set)) );
4988 	   assert(tree->nchildren == 1);
4989 	
4990 	#ifndef NDEBUG
4991 	   /* check, if the sizes in the data structures match the maximal numbers defined here */
4992 	   tree->root->depth = SCIP_MAXTREEDEPTH + 1;
4993 	   tree->root->repropsubtreemark = MAXREPROPMARK;
4994 	   assert(tree->root->depth - 1 == SCIP_MAXTREEDEPTH); /*lint !e650*/
4995 	   assert(tree->root->repropsubtreemark == MAXREPROPMARK);
4996 	   tree->root->depth++;             /* this should produce an overflow and reset the value to 0 */
4997 	   tree->root->repropsubtreemark++; /* this should produce an overflow and reset the value to 0 */
4998 	   assert(tree->root->depth == 0);
4999 	   assert((SCIP_NODETYPE)tree->root->nodetype == SCIP_NODETYPE_CHILD);
5000 	   assert(!tree->root->active);
5001 	   assert(!tree->root->cutoff);
5002 	   assert(!tree->root->reprop);
5003 	   assert(tree->root->repropsubtreemark == 0);
5004 	#endif
5005 	
5006 	   /* move root to the queue, convert it to LEAF */
5007 	   SCIP_CALL( treeNodesToQueue(tree, reopt, blkmem, set, stat, eventfilter, eventqueue, lp, tree->children, &tree->nchildren, NULL,
5008 	         SCIPsetInfinity(set)) );
5009 	
5010 	   return SCIP_OKAY;
5011 	}
5012 	
5013 	/** creates a temporary presolving root node of the tree and installs it as focus node */
5014 	SCIP_RETCODE SCIPtreeCreatePresolvingRoot(
5015 	   SCIP_TREE*            tree,               /**< tree data structure */
5016 	   SCIP_REOPT*           reopt,              /**< reoptimization data structure */
5017 	   BMS_BLKMEM*           blkmem,             /**< block memory buffers */
5018 	   SCIP_SET*             set,                /**< global SCIP settings */
5019 	   SCIP_MESSAGEHDLR*     messagehdlr,        /**< message handler */
5020 	   SCIP_STAT*            stat,               /**< problem statistics */
5021 	   SCIP_PROB*            transprob,          /**< transformed problem */
5022 	   SCIP_PROB*            origprob,           /**< original problem */
5023 	   SCIP_PRIMAL*          primal,             /**< primal data */
5024 	   SCIP_LP*              lp,                 /**< current LP data */
5025 	   SCIP_BRANCHCAND*      branchcand,         /**< branching candidate storage */
5026 	   SCIP_CONFLICT*        conflict,           /**< conflict analysis data */
5027 	   SCIP_CONFLICTSTORE*   conflictstore,      /**< conflict store */
5028 	   SCIP_EVENTFILTER*     eventfilter,        /**< event filter for global (not variable dependent) events */
5029 	   SCIP_EVENTQUEUE*      eventqueue,         /**< event queue */
5030 	   SCIP_CLIQUETABLE*     cliquetable         /**< clique table data structure */
5031 	   )
5032 	{
5033 	   SCIP_Bool cutoff;
5034 	
5035 	   assert(tree != NULL);
5036 	   assert(tree->nchildren == 0);
5037 	   assert(tree->nsiblings == 0);
5038 	   assert(tree->root == NULL);
5039 	   assert(tree->focusnode == NULL);
5040 	   assert(!SCIPtreeProbing(tree));
5041 	
5042 	   /* create temporary presolving root node */
5043 	   SCIP_CALL( SCIPtreeCreateRoot(tree, reopt, blkmem, set, stat, eventfilter, eventqueue, lp) );
5044 	   assert(tree->root != NULL);
5045 	
5046 	   /* install the temporary root node as focus node */
5047 	   SCIP_CALL( SCIPnodeFocus(&tree->root, blkmem, set, messagehdlr, stat, transprob, origprob, primal, tree, reopt, lp, branchcand,
5048 	         conflict, conflictstore, eventfilter, eventqueue, cliquetable, &cutoff, FALSE, FALSE) );
5049 	   assert(!cutoff);
5050 	
5051 	   return SCIP_OKAY;
5052 	}
5053 	
5054 	/** frees the temporary presolving root and resets tree data structure */
5055 	SCIP_RETCODE SCIPtreeFreePresolvingRoot(
5056 	   SCIP_TREE*            tree,               /**< tree data structure */
5057 	   SCIP_REOPT*           reopt,              /**< reoptimization data structure */
5058 	   BMS_BLKMEM*           blkmem,             /**< block memory buffers */
5059 	   SCIP_SET*             set,                /**< global SCIP settings */
5060 	   SCIP_MESSAGEHDLR*     messagehdlr,        /**< message handler */
5061 	   SCIP_STAT*            stat,               /**< problem statistics */
5062 	   SCIP_PROB*            transprob,          /**< transformed problem */
5063 	   SCIP_PROB*            origprob,           /**< original problem */
5064 	   SCIP_PRIMAL*          primal,             /**< primal data */
5065 	   SCIP_LP*              lp,                 /**< current LP data */
5066 	   SCIP_BRANCHCAND*      branchcand,         /**< branching candidate storage */
5067 	   SCIP_CONFLICT*        conflict,           /**< conflict analysis data */
5068 	   SCIP_CONFLICTSTORE*   conflictstore,      /**< conflict store */
5069 	   SCIP_EVENTFILTER*     eventfilter,        /**< event filter for global (not variable dependent) events */
5070 	   SCIP_EVENTQUEUE*      eventqueue,         /**< event queue */
5071 	   SCIP_CLIQUETABLE*     cliquetable         /**< clique table data structure */
5072 	   )
5073 	{
5074 	   SCIP_NODE* node;
5075 	   SCIP_Bool cutoff;
5076 	
5077 	   assert(tree != NULL);
5078 	   assert(tree->root != NULL);
5079 	   assert(tree->focusnode == tree->root);
5080 	   assert(tree->pathlen == 1);
5081 	
5082 	   /* unfocus the temporary root node */
5083 	   node = NULL;
5084 	   SCIP_CALL( SCIPnodeFocus(&node, blkmem, set, messagehdlr, stat, transprob, origprob, primal, tree, reopt, lp, branchcand,
5085 	         conflict, conflictstore, eventfilter, eventqueue, cliquetable, &cutoff, FALSE, FALSE) );
5086 	   assert(!cutoff);
5087 	   assert(tree->root == NULL);
5088 	   assert(tree->focusnode == NULL);
5089 	   assert(tree->pathlen == 0);
5090 	
5091 	   /* reset tree data structure */
5092 	   SCIP_CALL( SCIPtreeClear(tree, blkmem, set, stat, eventfilter, eventqueue, lp) );
5093 	
5094 	   return SCIP_OKAY;
5095 	}
5096 	
5097 	/** returns the node selector associated with the given node priority queue */
5098 	SCIP_NODESEL* SCIPtreeGetNodesel(
5099 	   SCIP_TREE*            tree                /**< branch and bound tree */
5100 	   )
5101 	{
5102 	   assert(tree != NULL);
5103 	
5104 	   return SCIPnodepqGetNodesel(tree->leaves);
5105 	}
5106 	
5107 	/** sets the node selector used for sorting the nodes in the priority queue, and resorts the queue if necessary */
5108 	SCIP_RETCODE SCIPtreeSetNodesel(
5109 	   SCIP_TREE*            tree,               /**< branch and bound tree */
5110 	   SCIP_SET*             set,                /**< global SCIP settings */
5111 	   SCIP_MESSAGEHDLR*     messagehdlr,        /**< message handler */
5112 	   SCIP_STAT*            stat,               /**< problem statistics */
5113 	   SCIP_NODESEL*         nodesel             /**< node selector to use for sorting the nodes in the queue */
5114 	   )
5115 	{
5116 	   assert(tree != NULL);
5117 	   assert(stat != NULL);
5118 	
5119 	   if( SCIPnodepqGetNodesel(tree->leaves) != nodesel )
5120 	   {
5121 	      /* change the node selector used in the priority queue and resort the queue */
5122 	      SCIP_CALL( SCIPnodepqSetNodesel(&tree->leaves, set, nodesel) );
5123 	
5124 	      /* issue message */
5125 	      if( stat->nnodes > 0 )
5126 	      {
5127 	         SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
5128 	            "(node %" SCIP_LONGINT_FORMAT ") switching to node selector <%s>\n", stat->nnodes, SCIPnodeselGetName(nodesel));
5129 	      }
5130 	   }
5131 	
5132 	   return SCIP_OKAY;
5133 	}
5134 	
5135 	/** cuts off nodes with lower bound not better than given cutoff bound */
5136 	SCIP_RETCODE SCIPtreeCutoff(
5137 	   SCIP_TREE*            tree,               /**< branch and bound tree */
5138 	   SCIP_REOPT*           reopt,              /**< reoptimization data structure */
5139 	   BMS_BLKMEM*           blkmem,             /**< block memory */
5140 	   SCIP_SET*             set,                /**< global SCIP settings */
5141 	   SCIP_STAT*            stat,               /**< dynamic problem statistics */
5142 	   SCIP_EVENTFILTER*     eventfilter,        /**< event filter for global (not variable dependent) events */
5143 	   SCIP_EVENTQUEUE*      eventqueue,         /**< event queue */
5144 	   SCIP_LP*              lp,                 /**< current LP data */
5145 	   SCIP_Real             cutoffbound         /**< cutoff bound: all nodes with lowerbound >= cutoffbound are cut off */
5146 	   )
5147 	{
5148 	   SCIP_NODE* node;
5149 	   int i;
5150 	
5151 	   assert(tree != NULL);
5152 	   assert(stat != NULL);
5153 	   assert(lp != NULL);
5154 	
5155 	   /* if we are in diving mode, it is not allowed to cut off nodes, because this can lead to deleting LP rows which
5156 	    * would modify the currently unavailable (due to diving modifications) SCIP_LP
5157 	    *  -> the cutoff must be delayed and executed after the diving ends
5158 	    */
5159 	   if( SCIPlpDiving(lp) )
5160 	   {
5161 	      tree->cutoffdelayed = TRUE;
5162 	      return SCIP_OKAY;
5163 	   }
5164 	
5165 	   tree->cutoffdelayed = FALSE;
5166 	
5167 	   /* cut off leaf nodes in the queue */
5168 	   SCIP_CALL( SCIPnodepqBound(tree->leaves, blkmem, set, stat, eventfilter, eventqueue, tree, reopt, lp, cutoffbound) );
5169 	
5170 	   /* cut off siblings: we have to loop backwards, because a removal leads to moving the last node in empty slot */
5171 	   for( i = tree->nsiblings-1; i >= 0; --i )
5172 	   {
5173 	      node = tree->siblings[i];
5174 	      if( SCIPsetIsInfinity(set, node->lowerbound) || SCIPsetIsGE(set, node->lowerbound, cutoffbound) )
5175 	      {
5176 	         SCIPsetDebugMsg(set, "cut off sibling #%" SCIP_LONGINT_FORMAT " at depth %d with lowerbound=%g at position %d\n",
5177 	            SCIPnodeGetNumber(node), SCIPnodeGetDepth(node), node->lowerbound, i);
5178 	
5179 	         if( set->reopt_enable )
5180 	         {
5181 	            assert(reopt != NULL);
5182 	            /* check if the node should be stored for reoptimization */
5183 	            SCIP_CALL( SCIPreoptCheckCutoff(reopt, set, blkmem, node, SCIP_EVENTTYPE_NODEINFEASIBLE, lp, SCIPlpGetSolstat(lp),
5184 	                  tree->root == node, tree->focusnode == node, node->lowerbound, tree->effectiverootdepth) );
5185 	         }
5186 	
5187 	         SCIPvisualCutoffNode(stat->visual, set, stat, node, FALSE);
5188 	
5189 	         SCIP_CALL( SCIPnodeFree(&node, blkmem, set, stat, eventfilter, eventqueue, tree, lp) );
5190 	      }
5191 	   }
5192 	
5193 	   /* cut off children: we have to loop backwards, because a removal leads to moving the last node in empty slot */
5194 	   for( i = tree->nchildren-1; i >= 0; --i )
5195 	   {
5196 	      node = tree->children[i];
5197 	      if( SCIPsetIsInfinity(set, node->lowerbound) || SCIPsetIsGE(set, node->lowerbound, cutoffbound) )
5198 	      {
5199 	         SCIPsetDebugMsg(set, "cut off child #%" SCIP_LONGINT_FORMAT " at depth %d with lowerbound=%g at position %d\n",
5200 	            SCIPnodeGetNumber(node), SCIPnodeGetDepth(node), node->lowerbound, i);
5201 	
5202 	         if( set->reopt_enable )
5203 	         {
5204 	            assert(reopt != NULL);
5205 	            /* check if the node should be stored for reoptimization */
5206 	            SCIP_CALL( SCIPreoptCheckCutoff(reopt, set, blkmem, node, SCIP_EVENTTYPE_NODEINFEASIBLE, lp, SCIPlpGetSolstat(lp),
5207 	                  tree->root == node, tree->focusnode == node, node->lowerbound, tree->effectiverootdepth) );
5208 	         }
5209 	
5210 	         SCIPvisualCutoffNode(stat->visual, set, stat, node, FALSE);
5211 	
5212 	         SCIP_CALL( SCIPnodeFree(&node, blkmem, set, stat, eventfilter, eventqueue, tree, lp) );
5213 	      }
5214 	   }
5215 	
5216 	   return SCIP_OKAY;
5217 	}
5218 	
5219 	/** calculates the node selection priority for moving the given variable's LP value to the given target value;
5220 	 *  this node selection priority can be given to the SCIPcreateChild() call
5221 	 */
5222 	SCIP_Real SCIPtreeCalcNodeselPriority(
5223 	   SCIP_TREE*            tree,               /**< branch and bound tree */
5224 	   SCIP_SET*             set,                /**< global SCIP settings */
5225 	   SCIP_STAT*            stat,               /**< dynamic problem statistics */
5226 	   SCIP_VAR*             var,                /**< variable, of which the branching factor should be applied, or NULL */
5227 	   SCIP_BRANCHDIR        branchdir,          /**< type of branching that was performed: upwards, downwards, or fixed 
5228 	                                              * fixed should only be used, when both bounds changed 
5229 	                                              */
5230 	   SCIP_Real             targetvalue         /**< new value of the variable in the child node */
5231 	   )
5232 	{
5233 	   SCIP_Real prio;
5234 	   SCIP_Real varsol;
5235 	   SCIP_Real varrootsol;
5236 	   SCIP_Real downinfs;
5237 	   SCIP_Real upinfs;
5238 	   SCIP_Bool isroot;
5239 	   SCIP_Bool haslp;
5240 	
5241 	   assert(set != NULL);
5242 	
5243 	   /* extract necessary information */
5244 	   isroot = (SCIPtreeGetCurrentDepth(tree) == 0);
5245 	   haslp = SCIPtreeHasFocusNodeLP(tree);
5246 	   varsol = SCIPvarGetSol(var, haslp);
5247 	   varrootsol = SCIPvarGetRootSol(var);
5248 	   downinfs = SCIPvarGetAvgInferences(var, stat, SCIP_BRANCHDIR_DOWNWARDS);
5249 	   upinfs = SCIPvarGetAvgInferences(var, stat, SCIP_BRANCHDIR_UPWARDS);
5250 	
5251 	   switch( branchdir )
5252 	   {
5253 	   case SCIP_BRANCHDIR_DOWNWARDS:
5254 	      switch( SCIPvarGetBranchDirection(var) )
5255 	      {
5256 	      case SCIP_BRANCHDIR_DOWNWARDS:
5257 	         prio = +1.0;
5258 	         break;
5259 	      case SCIP_BRANCHDIR_UPWARDS:
5260 	         prio = -1.0;
5261 	         break;
5262 	      case SCIP_BRANCHDIR_AUTO:
5263 	         switch( set->nodesel_childsel )
5264 	         {
5265 	         case 'd':
5266 	            prio = +1.0;
5267 	            break;
5268 	         case 'u':
5269 	            prio = -1.0;
5270 	            break;
5271 	         case 'p':
5272 	            prio = -SCIPvarGetPseudocost(var, stat, targetvalue - varsol);
5273 	            break;
5274 	         case 'i':
5275 	            prio = downinfs;
5276 	            break;
5277 	         case 'l':
5278 	            prio = targetvalue - varsol;
5279 	            break;
5280 	         case 'r':
5281 	            prio = varrootsol - varsol;
5282 	            break;
5283 	         case 'h':
5284 	            prio = downinfs + SCIPsetEpsilon(set);
5285 	            if( !isroot && haslp )
5286 	               prio *= (varrootsol - varsol + 1.0);
5287 	            break;
5288 	         default:
5289 	            SCIPerrorMessage("invalid child selection rule <%c>\n", set->nodesel_childsel);
5290 	            prio = 0.0;
5291 	            break;
5292 	         }
5293 	         break;
5294 	      default:
5295 	         SCIPerrorMessage("invalid preferred branching direction <%d> of variable <%s>\n", 
5296 	            SCIPvarGetBranchDirection(var), SCIPvarGetName(var));
5297 	         prio = 0.0;
5298 	         break;
5299 	      }
5300 	      break;
5301 	   case SCIP_BRANCHDIR_UPWARDS:
5302 	      /* the branch is directed upwards */
5303 	      switch( SCIPvarGetBranchDirection(var) )
5304 	      {
5305 	      case SCIP_BRANCHDIR_DOWNWARDS:
5306 	         prio = -1.0;
5307 	         break;
5308 	      case SCIP_BRANCHDIR_UPWARDS:
5309 	         prio = +1.0;
5310 	         break;
5311 	      case SCIP_BRANCHDIR_AUTO:
5312 	         switch( set->nodesel_childsel )
5313 	         {
5314 	         case 'd':
5315 	            prio = -1.0;
5316 	            break;
5317 	         case 'u':
5318 	            prio = +1.0;
5319 	            break;
5320 	         case 'p':
5321 	            prio = -SCIPvarGetPseudocost(var, stat, targetvalue - varsol);
5322 	            break;
5323 	         case 'i':
5324 	            prio = upinfs;
5325 	            break;
5326 	         case 'l':
5327 	            prio = varsol - targetvalue;
5328 	            break;
5329 	         case 'r':
5330 	            prio = varsol - varrootsol;
5331 	            break;
5332 	         case 'h':
5333 	            prio = upinfs  + SCIPsetEpsilon(set);
5334 	            if( !isroot && haslp )
5335 	               prio *= (varsol - varrootsol + 1.0);
5336 	            break;
5337 	         default:
5338 	            SCIPerrorMessage("invalid child selection rule <%c>\n", set->nodesel_childsel);
5339 	            prio = 0.0;
5340 	            break;
5341 	         }
5342 	         /* since choosing the upwards direction is usually superior than the downwards direction (see results of
5343 	          * Achterberg's thesis (2007)), we break ties towards upwards branching
5344 	          */
5345 	         prio += SCIPsetEpsilon(set);
5346 	         break;
5347 	
5348 	      default:
5349 	         SCIPerrorMessage("invalid preferred branching direction <%d> of variable <%s>\n", 
5350 	            SCIPvarGetBranchDirection(var), SCIPvarGetName(var));
5351 	         prio = 0.0;
5352 	         break;
5353 	      }
5354 	      break;
5355 	   case SCIP_BRANCHDIR_FIXED:
5356 	      prio = SCIPsetInfinity(set);
5357 	      break;
5358 	   case SCIP_BRANCHDIR_AUTO:
5359 	   default:
5360 	      SCIPerrorMessage("invalid branching direction <%d> of variable <%s>\n", 
5361 	         SCIPvarGetBranchDirection(var), SCIPvarGetName(var));
5362 	      prio = 0.0;
5363 	      break;
5364 	   }
5365 	
5366 	   return prio;
5367 	}
5368 	
5369 	/** calculates an estimate for the objective of the best feasible solution contained in the subtree after applying the given 
5370 	 *  branching; this estimate can be given to the SCIPcreateChild() call
5371 	 */
5372 	SCIP_Real SCIPtreeCalcChildEstimate(
5373 	   SCIP_TREE*            tree,               /**< branch and bound tree */
5374 	   SCIP_SET*             set,                /**< global SCIP settings */
5375 	   SCIP_STAT*            stat,               /**< dynamic problem statistics */
5376 	   SCIP_VAR*             var,                /**< variable, of which the branching factor should be applied, or NULL */
5377 	   SCIP_Real             targetvalue         /**< new value of the variable in the child node */
5378 	   )
5379 	{
5380 	   SCIP_Real estimateinc;
5381 	   SCIP_Real estimate;
5382 	   SCIP_Real varsol;
5383 	
5384 	   assert(tree != NULL);
5385 	   assert(var != NULL);
5386 	
5387 	   estimate = SCIPnodeGetEstimate(tree->focusnode);
5388 	   varsol = SCIPvarGetSol(var, SCIPtreeHasFocusNodeLP(tree));
5389 	
5390 	   /* compute increase above parent node's (i.e., focus node's) estimate value */
5391 	   if( SCIPvarGetType(var) == SCIP_VARTYPE_CONTINUOUS )
5392 	      estimateinc = SCIPvarGetPseudocost(var, stat, targetvalue - varsol);
5393 	   else
5394 	   {
5395 	      SCIP_Real pscdown;
5396 	      SCIP_Real pscup;
5397 	
5398 	      /* calculate estimate based on pseudo costs:
5399 	       *   estimate = lowerbound + sum(min{f_j * pscdown_j, (1-f_j) * pscup_j})
5400 	       *            = parentestimate - min{f_b * pscdown_b, (1-f_b) * pscup_b} + (targetvalue-oldvalue)*{pscdown_b or pscup_b}
5401 	       */
5402 	      pscdown = SCIPvarGetPseudocost(var, stat, SCIPsetFeasFloor(set, varsol) - varsol);
5403 	      pscup = SCIPvarGetPseudocost(var, stat, SCIPsetFeasCeil(set, varsol) - varsol);
5404 	      estimateinc = SCIPvarGetPseudocost(var, stat, targetvalue - varsol) - MIN(pscdown, pscup);
5405 	   }
5406 	
5407 	   /* due to rounding errors estimateinc might be slightly negative; in this case return the parent node's estimate */
5408 	   if( estimateinc > 0.0 )
5409 	      estimate += estimateinc;
5410 	
5411 	   return estimate;
5412 	}
5413 	
5414 	/** branches on a variable x
5415 	 *  if x is a continuous variable, then two child nodes will be created
5416 	 *  (x <= x', x >= x')
5417 	 *  but if the bounds of x are such that their relative difference is smaller than epsilon,
5418 	 *  the variable is fixed to val (if not SCIP_INVALID) or a well chosen alternative in the current node,
5419 	 *  i.e., no children are created
5420 	 *  if x is not a continuous variable, then:
5421 	 *  if solution value x' is fractional, two child nodes will be created
5422 	 *  (x <= floor(x'), x >= ceil(x')),
5423 	 *  if solution value is integral, the x' is equal to lower or upper bound of the branching
5424 	 *  variable and the bounds of x are finite, then two child nodes will be created
5425 	 *  (x <= x", x >= x"+1 with x" = floor((lb + ub)/2)),
5426 	 *  otherwise (up to) three child nodes will be created
5427 	 *  (x <= x'-1, x == x', x >= x'+1)
5428 	 *  if solution value is equal to one of the bounds and the other bound is infinite, only two child nodes
5429 	 *  will be created (the third one would be infeasible anyway)
5430 	 */
5431 	SCIP_RETCODE SCIPtreeBranchVar(
5432 	   SCIP_TREE*            tree,               /**< branch and bound tree */
5433 	   SCIP_REOPT*           reopt,              /**< reoptimization data structure */
5434 	   BMS_BLKMEM*           blkmem,             /**< block memory */
5435 	   SCIP_SET*             set,                /**< global SCIP settings */
5436 	   SCIP_STAT*            stat,               /**< problem statistics data */
5437 	   SCIP_PROB*            transprob,          /**< transformed problem after presolve */
5438 	   SCIP_PROB*            origprob,           /**< original problem */
5439 	   SCIP_LP*              lp,                 /**< current LP data */
5440 	   SCIP_BRANCHCAND*      branchcand,         /**< branching candidate storage */
5441 	   SCIP_EVENTQUEUE*      eventqueue,         /**< event queue */
5442 	   SCIP_VAR*             var,                /**< variable to branch on */
5443 	   SCIP_Real             val,                /**< value to branch on or SCIP_INVALID for branching on current LP/pseudo solution. 
5444 	                                              *   A branching value is required for branching on continuous variables */
5445 	   SCIP_NODE**           downchild,          /**< pointer to return the left child with variable rounded down, or NULL */
5446 	   SCIP_NODE**           eqchild,            /**< pointer to return the middle child with variable fixed, or NULL */
5447 	   SCIP_NODE**           upchild             /**< pointer to return the right child with variable rounded up, or NULL */
5448 	   )
5449 	{
5450 	   SCIP_NODE* node;
5451 	   SCIP_Real priority;
5452 	   SCIP_Real estimate;
5453 	
5454 	   SCIP_Real downub;
5455 	   SCIP_Real fixval;
5456 	   SCIP_Real uplb;
5457 	   SCIP_Real lpval;
5458 	
5459 	   SCIP_Bool validval;
5460 	
5461 	   assert(tree != NULL);
5462 	   assert(set != NULL);
5463 	   assert(var != NULL);
5464 	
5465 	   /* initialize children pointer */
5466 	   if( downchild != NULL )
5467 	      *downchild = NULL;
5468 	   if( eqchild != NULL )
5469 	      *eqchild = NULL;
5470 	   if( upchild != NULL )
5471 	      *upchild = NULL;
5472 	
5473 	   /* store whether a valid value was given for branching */
5474 	   validval = (val != SCIP_INVALID);  /*lint !e777 */
5475 	
5476 	   /* get the corresponding active problem variable
5477 	    * if branching value is given, then transform it to the value of the active variable */
5478 	   if( validval )
5479 	   {
5480 	      SCIP_Real scalar;
5481 	      SCIP_Real constant;
5482 	
5483 	      scalar   = 1.0;
5484 	      constant = 0.0;
5485 	
5486 	      SCIP_CALL( SCIPvarGetProbvarSum(&var, set, &scalar, &constant) );
5487 	
5488 	      if( scalar == 0.0 )
5489 	      {
5490 	         SCIPerrorMessage("cannot branch on fixed variable <%s>\n", SCIPvarGetName(var));
5491 	         return SCIP_INVALIDDATA;
5492 	      }
5493 	
5494 	      /* we should have givenvariable = scalar * activevariable + constant */
5495 	      val = (val - constant) / scalar;
5496 	   }   
5497 	   else
5498 	      var = SCIPvarGetProbvar(var);
5499 	
5500 	   if( SCIPvarGetStatus(var) == SCIP_VARSTATUS_FIXED || SCIPvarGetStatus(var) == SCIP_VARSTATUS_MULTAGGR )
5501 	   {
5502 	      SCIPerrorMessage("cannot branch on fixed or multi-aggregated variable <%s>\n", SCIPvarGetName(var));
5503 	      SCIPABORT();
5504 	      return SCIP_INVALIDDATA; /*lint !e527*/
5505 	   }
5506 	
5507 	   /* ensure, that branching on continuous variables will only be performed when a branching point is given. */
5508 	   if( SCIPvarGetType(var) == SCIP_VARTYPE_CONTINUOUS && !validval )
5509 	   {
5510 	      SCIPerrorMessage("Cannot branch on continuous variable <%s> without a given branching value.", SCIPvarGetName(var));
5511 	      SCIPABORT();
5512 	      return SCIP_INVALIDDATA; /*lint !e527*/
5513 	   }
5514 	
5515 	   assert(SCIPvarIsActive(var));
5516 	   assert(SCIPvarGetProbindex(var) >= 0);
5517 	   assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_LOOSE || SCIPvarGetStatus(var) == SCIP_VARSTATUS_COLUMN);
5518 	   assert(SCIPvarGetType(var) == SCIP_VARTYPE_CONTINUOUS || SCIPsetIsFeasIntegral(set, SCIPvarGetLbLocal(var)));
5519 	   assert(SCIPvarGetType(var) == SCIP_VARTYPE_CONTINUOUS || SCIPsetIsFeasIntegral(set, SCIPvarGetUbLocal(var)));
5520 	   assert(SCIPsetIsLT(set, SCIPvarGetLbLocal(var), SCIPvarGetUbLocal(var)));
5521 	
5522 	   /* update the information for the focus node before creating children */
5523 	   SCIP_CALL( SCIPvisualUpdateChild(stat->visual, set, stat, tree->focusnode) );
5524 	
5525 	   /* get value of variable in current LP or pseudo solution */
5526 	   lpval = SCIPvarGetSol(var, tree->focusnodehaslp);
5527 	
5528 	   /* if there was no explicit value given for branching, branch on current LP or pseudo solution value */
5529 	   if( !validval )
5530 	   {
5531 	      val = lpval;
5532 	
5533 	      /* avoid branching on infinite values in pseudo solution */
5534 	      if( SCIPsetIsInfinity(set, -val) || SCIPsetIsInfinity(set, val) )
5535 	      {
5536 	         val = SCIPvarGetWorstBoundLocal(var);
5537 	
5538 	         /* if both bounds are infinite, choose zero as branching point */
5539 	         if( SCIPsetIsInfinity(set, -val) || SCIPsetIsInfinity(set, val) )
5540 	         {
5541 	            assert(SCIPsetIsInfinity(set, -SCIPvarGetLbLocal(var)));
5542 	            assert(SCIPsetIsInfinity(set, SCIPvarGetUbLocal(var)));         
5543 	            val = 0.0;
5544 	         }
5545 	      }
5546 	   }
5547 	
5548 	   assert(SCIPsetIsFeasGE(set, val, SCIPvarGetLbLocal(var)));
5549 	   assert(SCIPsetIsFeasLE(set, val, SCIPvarGetUbLocal(var)));
5550 	   /* see comment in SCIPbranchVarVal */
5551 	   assert(SCIPvarGetType(var) != SCIP_VARTYPE_CONTINUOUS ||
5552 	      SCIPrelDiff(SCIPvarGetUbLocal(var), SCIPvarGetLbLocal(var)) <= 2.02 * SCIPsetEpsilon(set) ||
5553 	      SCIPsetIsInfinity(set, -2.1*SCIPvarGetLbLocal(var)) || SCIPsetIsInfinity(set, 2.1*SCIPvarGetUbLocal(var)) ||
5554 	      (SCIPsetIsLT(set, 2.1*SCIPvarGetLbLocal(var), 2.1*val) && SCIPsetIsLT(set, 2.1*val, 2.1*SCIPvarGetUbLocal(var))) );
5555 	
5556 	   downub = SCIP_INVALID;
5557 	   fixval = SCIP_INVALID;
5558 	   uplb = SCIP_INVALID;
5559 	
5560 	   if( SCIPvarGetType(var) == SCIP_VARTYPE_CONTINUOUS )
5561 	   {
5562 	      if( SCIPsetIsRelEQ(set, SCIPvarGetLbLocal(var), SCIPvarGetUbLocal(var)) )
5563 	      {
5564 	         SCIPsetDebugMsg(set, "fixing continuous variable <%s> with value %g and bounds [%.15g, %.15g], priority %d (current lower bound: %g)\n",
5565 	            SCIPvarGetName(var), val, SCIPvarGetLbLocal(var), SCIPvarGetUbLocal(var), SCIPvarGetBranchPriority(var), SCIPnodeGetLowerbound(tree->focusnode));
5566 	
5567 	         /* if val is at least epsilon away from both bounds, then we change both bounds to this value
5568 	          * otherwise, we fix the variable to its worst bound
5569 	          */
5570 	         if( SCIPsetIsGT(set, val, SCIPvarGetLbLocal(var)) && SCIPsetIsLT(set, val, SCIPvarGetUbLocal(var)) )
5571 	         {
5572 	            SCIP_CALL( SCIPnodeAddBoundchg(tree->focusnode, blkmem, set, stat, transprob, origprob, tree, reopt, lp,
5573 	                  branchcand, eventqueue, NULL, var, val, SCIP_BOUNDTYPE_LOWER, FALSE) );
5574 	            SCIP_CALL( SCIPnodeAddBoundchg(tree->focusnode, blkmem, set, stat, transprob, origprob, tree, reopt, lp,
5575 	                  branchcand, eventqueue, NULL, var, val, SCIP_BOUNDTYPE_UPPER, FALSE) );
5576 	         }
5577 	         else if( SCIPvarGetObj(var) >= 0.0 )
5578 	         {
5579 	            SCIP_CALL( SCIPnodeAddBoundchg(SCIPtreeGetCurrentNode(tree), blkmem, set, stat, transprob, origprob,
5580 	                  tree, reopt, lp, branchcand, eventqueue, NULL, var, SCIPvarGetUbLocal(var), SCIP_BOUNDTYPE_LOWER, FALSE) );
5581 	         }
5582 	         else
5583 	         {
5584 	            SCIP_CALL( SCIPnodeAddBoundchg(SCIPtreeGetCurrentNode(tree), blkmem, set, stat, transprob, origprob,
5585 	                  tree, reopt, lp, branchcand, eventqueue, NULL, var, SCIPvarGetLbLocal(var), SCIP_BOUNDTYPE_UPPER, FALSE) );
5586 	         }
5587 	      }
5588 	      else if( SCIPrelDiff(SCIPvarGetUbLocal(var), SCIPvarGetLbLocal(var)) <= 2.02 * SCIPsetEpsilon(set) )
5589 	      {
5590 	         /* if the only way to branch is such that in both sides the relative domain width becomes smaller epsilon,
5591 	          * then fix the variable in both branches right away
5592 	          *
5593 	          * however, if one of the bounds is at infinity (and thus the other bound is at most 2eps away from the same infinity (in relative sense),
5594 	          * then fix the variable to the non-infinite value, as we cannot fix a variable to infinity
5595 	          */
5596 	         SCIPsetDebugMsg(set, "continuous branch on variable <%s> with bounds [%.15g, %.15g], priority %d (current lower bound: %g), node %p\n",
5597 	            SCIPvarGetName(var), SCIPvarGetLbLocal(var), SCIPvarGetUbLocal(var), SCIPvarGetBranchPriority(var), SCIPnodeGetLowerbound(tree->focusnode), (void*)tree->focusnode);
5598 	         if( SCIPsetIsInfinity(set, -SCIPvarGetLbLocal(var)) )
5599 	         {
5600 	            assert(!SCIPsetIsInfinity(set, -SCIPvarGetUbLocal(var)));
5601 	            SCIP_CALL( SCIPnodeAddBoundchg(SCIPtreeGetCurrentNode(tree), blkmem, set, stat, transprob, origprob,
5602 	                  tree, reopt, lp, branchcand, eventqueue, NULL, var, SCIPvarGetUbLocal(var), SCIP_BOUNDTYPE_LOWER, FALSE) );
5603 	         }
5604 	         else if( SCIPsetIsInfinity(set, SCIPvarGetUbLocal(var)) )
5605 	         {
5606 	            assert(!SCIPsetIsInfinity(set, SCIPvarGetLbLocal(var)));
5607 	            SCIP_CALL( SCIPnodeAddBoundchg(SCIPtreeGetCurrentNode(tree), blkmem, set, stat, transprob, origprob,
5608 	                  tree, reopt, lp, branchcand, eventqueue, NULL, var, SCIPvarGetLbLocal(var), SCIP_BOUNDTYPE_UPPER, FALSE) );
5609 	         }
5610 	         else
5611 	         {
5612 	            downub = SCIPvarGetLbLocal(var);
5613 	            uplb = SCIPvarGetUbLocal(var);
5614 	         }
5615 	      }
5616 	      else
5617 	      {
5618 	         /* in the general case, there is enough space for two branches
5619 	          * a sophisticated user should have also chosen the branching value such that it is not very close to the bounds
5620 	          * so here we only ensure that it is at least epsilon away from both bounds
5621 	          */
5622 	         SCIPsetDebugMsg(set, "continuous branch on variable <%s> with value %g, priority %d (current lower bound: %g)\n",
5623 	            SCIPvarGetName(var), val, SCIPvarGetBranchPriority(var), SCIPnodeGetLowerbound(tree->focusnode));
5624 	         downub = MIN(val, SCIPvarGetUbLocal(var) - SCIPsetEpsilon(set)); /*lint !e666*/
5625 	         uplb   = MAX(val, SCIPvarGetLbLocal(var) + SCIPsetEpsilon(set)); /*lint !e666*/
5626 	      }
5627 	   }
5628 	   else if( SCIPsetIsFeasIntegral(set, val) )
5629 	   {
5630 	      SCIP_Real lb;
5631 	      SCIP_Real ub;
5632 	
5633 	      lb = SCIPvarGetLbLocal(var);
5634 	      ub = SCIPvarGetUbLocal(var);
5635 	
5636 	      /* if there was no explicit value given for branching, the variable has a finite domain and the current LP/pseudo
5637 	       * solution is one of the bounds, we branch in the center of the domain */
5638 	      if( !validval && !SCIPsetIsInfinity(set, -lb) && !SCIPsetIsInfinity(set, ub) 
5639 	         && (SCIPsetIsFeasEQ(set, val, lb) || SCIPsetIsFeasEQ(set, val, ub)) )
5640 	      {
5641 	         SCIP_Real center;
5642 	
5643 	         /* create child nodes with x <= x", and x >= x"+1 with x" = floor((lb + ub)/2);
5644 	          * if x" is integral, make the interval smaller in the child in which the current solution x'
5645 	          * is still feasible
5646 	          */
5647 	         center = (ub + lb) / 2.0;
5648 	         if( val <= center )
5649 	         {
5650 	            downub = SCIPsetFeasFloor(set, center);
5651 	            uplb = downub + 1.0;
5652 	         }
5653 	         else
5654 	         {
5655 	            uplb = SCIPsetFeasCeil(set, center);
5656 	            downub = uplb - 1.0;
5657 	         }
5658 	      }
5659 	      else
5660 	      {
5661 	         /* create child nodes with x <= x'-1, x = x', and x >= x'+1 */
5662 	         assert(SCIPsetIsEQ(set, SCIPsetFeasCeil(set, val), SCIPsetFeasFloor(set, val)));
5663 	
5664 	         fixval = SCIPsetFeasCeil(set, val); /* get rid of numerical issues */
5665 	
5666 	         /* create child node with x <= x'-1, if this would be feasible */
5667 	         if( SCIPsetIsFeasGE(set, fixval-1.0, lb) )
5668 	            downub = fixval - 1.0;
5669 	
5670 	         /* create child node with x >= x'+1, if this would be feasible */
5671 	         if( SCIPsetIsFeasLE(set, fixval+1.0, ub) )
5672 	            uplb = fixval + 1.0;
5673 	      }
5674 	      SCIPsetDebugMsg(set, "integral branch on variable <%s> with value %g, priority %d (current lower bound: %g)\n",
5675 	         SCIPvarGetName(var), val, SCIPvarGetBranchPriority(var), SCIPnodeGetLowerbound(tree->focusnode));
5676 	   }
5677 	   else
5678 	   {
5679 	      /* create child nodes with x <= floor(x'), and x >= ceil(x') */
5680 	      downub = SCIPsetFeasFloor(set, val);
5681 	      uplb = downub + 1.0;
5682 	      assert( SCIPsetIsRelEQ(set, SCIPsetCeil(set, val), uplb) );
5683 	      SCIPsetDebugMsg(set, "fractional branch on variable <%s> with value %g, root value %g, priority %d (current lower bound: %g)\n",
5684 	         SCIPvarGetName(var), val, SCIPvarGetRootSol(var), SCIPvarGetBranchPriority(var), SCIPnodeGetLowerbound(tree->focusnode));
5685 	   }
5686 	
5687 	   /* perform the branching;
5688 	    * set the node selection priority in a way, s.t. a node is preferred whose branching goes in the same direction
5689 	    * as the deviation from the variable's root solution
5690 	    */
5691 	   if( downub != SCIP_INVALID )    /*lint !e777*/
5692 	   {
5693 	      /* create child node x <= downub */
5694 	      priority = SCIPtreeCalcNodeselPriority(tree, set, stat, var, SCIP_BRANCHDIR_DOWNWARDS, downub);
5695 	      /* if LP solution is cutoff in child, compute a new estimate
5696 	       * otherwise we cannot expect a direct change in the best solution, so we keep the estimate of the parent node */
5697 	      if( SCIPsetIsGT(set, lpval, downub) )
5698 	         estimate = SCIPtreeCalcChildEstimate(tree, set, stat, var, downub);
5699 	      else
5700 	         estimate = SCIPnodeGetEstimate(tree->focusnode);
5701 	      SCIPsetDebugMsg(set, " -> creating child: <%s> <= %g (priority: %g, estimate: %g)\n",
5702 	         SCIPvarGetName(var), downub, priority, estimate);
5703 	      SCIP_CALL( SCIPnodeCreateChild(&node, blkmem, set, stat, tree, priority, estimate) );
5704 	      SCIP_CALL( SCIPnodeAddBoundchg(node, blkmem, set, stat, transprob, origprob, tree, reopt, lp, branchcand, eventqueue,
5705 	            NULL, var, downub, SCIP_BOUNDTYPE_UPPER, FALSE) );
5706 	      /* output branching bound change to visualization file */
5707 	      SCIP_CALL( SCIPvisualUpdateChild(stat->visual, set, stat, node) );
5708 	
5709 	      if( downchild != NULL )
5710 	         *downchild = node;
5711 	   }
5712 	
5713 	   if( fixval != SCIP_INVALID )    /*lint !e777*/
5714 	   {
5715 	      /* create child node with x = fixval */
5716 	      priority = SCIPtreeCalcNodeselPriority(tree, set, stat, var, SCIP_BRANCHDIR_FIXED, fixval);
5717 	      estimate = SCIPtreeCalcChildEstimate(tree, set, stat, var, fixval);
5718 	      SCIPsetDebugMsg(set, " -> creating child: <%s> == %g (priority: %g, estimate: %g)\n",
5719 	         SCIPvarGetName(var), fixval, priority, estimate);
5720 	      SCIP_CALL( SCIPnodeCreateChild(&node, blkmem, set, stat, tree, priority, estimate) );
5721 	      if( !SCIPsetIsFeasEQ(set, SCIPvarGetLbLocal(var), fixval) )
5722 	      {
5723 	         SCIP_CALL( SCIPnodeAddBoundchg(node, blkmem, set, stat, transprob, origprob, tree, reopt, lp, branchcand, eventqueue,
5724 	               NULL, var, fixval, SCIP_BOUNDTYPE_LOWER, FALSE) );
5725 	      }
5726 	      if( !SCIPsetIsFeasEQ(set, SCIPvarGetUbLocal(var), fixval) )
5727 	      {
5728 	         SCIP_CALL( SCIPnodeAddBoundchg(node, blkmem, set, stat, transprob, origprob, tree, reopt, lp, branchcand, eventqueue,
5729 	               NULL, var, fixval, SCIP_BOUNDTYPE_UPPER, FALSE) );
5730 	      }
5731 	      /* output branching bound change to visualization file */
5732 	      SCIP_CALL( SCIPvisualUpdateChild(stat->visual, set, stat, node) );
5733 	
5734 	      if( eqchild != NULL )
5735 	         *eqchild = node;
5736 	   }
5737 	
5738 	   if( uplb != SCIP_INVALID )    /*lint !e777*/
5739 	   {
5740 	      /* create child node with x >= uplb */
5741 	      priority = SCIPtreeCalcNodeselPriority(tree, set, stat, var, SCIP_BRANCHDIR_UPWARDS, uplb);
5742 	      if( SCIPsetIsLT(set, lpval, uplb) )
5743 	         estimate = SCIPtreeCalcChildEstimate(tree, set, stat, var, uplb);
5744 	      else
5745 	         estimate = SCIPnodeGetEstimate(tree->focusnode);
5746 	      SCIPsetDebugMsg(set, " -> creating child: <%s> >= %g (priority: %g, estimate: %g)\n",
5747 	         SCIPvarGetName(var), uplb, priority, estimate);
5748 	      SCIP_CALL( SCIPnodeCreateChild(&node, blkmem, set, stat, tree, priority, estimate) );
5749 	      SCIP_CALL( SCIPnodeAddBoundchg(node, blkmem, set, stat, transprob, origprob, tree, reopt, lp, branchcand, eventqueue,
5750 	            NULL, var, uplb, SCIP_BOUNDTYPE_LOWER, FALSE) );
5751 	      /* output branching bound change to visualization file */
5752 	      SCIP_CALL( SCIPvisualUpdateChild(stat->visual, set, stat, node) );
5753 	
5754 	      if( upchild != NULL )
5755 	         *upchild = node;
5756 	   }
5757 	
5758 	   return SCIP_OKAY;
5759 	}
5760 	
5761 	/** branches a variable x using the given domain hole; two child nodes will be created (x <= left, x >= right) */
5762 	SCIP_RETCODE SCIPtreeBranchVarHole(
5763 	   SCIP_TREE*            tree,               /**< branch and bound tree */
5764 	   SCIP_REOPT*           reopt,              /**< reoptimization data structure */
5765 	   BMS_BLKMEM*           blkmem,             /**< block memory */
5766 	   SCIP_SET*             set,                /**< global SCIP settings */
5767 	   SCIP_STAT*            stat,               /**< problem statistics data */
5768 	   SCIP_PROB*            transprob,          /**< transformed problem after presolve */
5769 	   SCIP_PROB*            origprob,           /**< original problem */
5770 	   SCIP_LP*              lp,                 /**< current LP data */
5771 	   SCIP_BRANCHCAND*      branchcand,         /**< branching candidate storage */
5772 	   SCIP_EVENTQUEUE*      eventqueue,         /**< event queue */
5773 	   SCIP_VAR*             var,                /**< variable to branch on */
5774 	   SCIP_Real             left,               /**< left side of the domain hole */
5775 	   SCIP_Real             right,              /**< right side of the domain hole */
5776 	   SCIP_NODE**           downchild,          /**< pointer to return the left child with variable rounded down, or NULL */
5777 	   SCIP_NODE**           upchild             /**< pointer to return the right child with variable rounded up, or NULL */
5778 	   )
5779 	{
5780 	   SCIP_NODE* node;
5781 	   SCIP_Real priority;
5782 	   SCIP_Real estimate;
5783 	   SCIP_Real lpval;
5784 	
5785 	   assert(tree != NULL);
5786 	   assert(set != NULL);
5787 	   assert(var != NULL);
5788 	   assert(SCIPsetIsLT(set, left, SCIPvarGetUbLocal(var)));
5789 	   assert(SCIPsetIsGE(set, left, SCIPvarGetLbLocal(var)));
5790 	   assert(SCIPsetIsGT(set, right, SCIPvarGetLbLocal(var)));
5791 	   assert(SCIPsetIsLE(set, right, SCIPvarGetUbLocal(var)));
5792 	   assert(SCIPsetIsLE(set, left, right));
5793 	
5794 	   /* initialize children pointer */
5795 	   if( downchild != NULL )
5796 	      *downchild = NULL;
5797 	   if( upchild != NULL )
5798 	      *upchild = NULL;
5799 	
5800 	   /* get the corresponding active problem variable */
5801 	   SCIP_CALL( SCIPvarGetProbvarHole(&var, &left, &right) );
5802 	
5803 	   if( SCIPvarGetStatus(var) == SCIP_VARSTATUS_FIXED || SCIPvarGetStatus(var) == SCIP_VARSTATUS_MULTAGGR )
5804 	   {
5805 	      SCIPerrorMessage("cannot branch on fixed or multi-aggregated variable <%s>\n", SCIPvarGetName(var));
5806 	      SCIPABORT();
5807 	      return SCIP_INVALIDDATA; /*lint !e527*/
5808 	   }
5809 	
5810 	   assert(SCIPvarIsActive(var));
5811 	   assert(SCIPvarGetProbindex(var) >= 0);
5812 	   assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_LOOSE || SCIPvarGetStatus(var) == SCIP_VARSTATUS_COLUMN);
5813 	   assert(SCIPvarGetType(var) == SCIP_VARTYPE_CONTINUOUS || SCIPsetIsFeasIntegral(set, SCIPvarGetLbLocal(var)));
5814 	   assert(SCIPvarGetType(var) == SCIP_VARTYPE_CONTINUOUS || SCIPsetIsFeasIntegral(set, SCIPvarGetUbLocal(var)));
5815 	   assert(SCIPsetIsLT(set, SCIPvarGetLbLocal(var), SCIPvarGetUbLocal(var)));
5816 	
5817 	   assert(SCIPsetIsFeasGE(set, left, SCIPvarGetLbLocal(var)));
5818 	   assert(SCIPsetIsFeasLE(set, right, SCIPvarGetUbLocal(var)));
5819 	
5820 	   /* adjust left and right side of the domain hole if the variable is integral */
5821 	   if( SCIPvarIsIntegral(var) )
5822 	   {
5823 	      left = SCIPsetFeasFloor(set, left);
5824 	      right = SCIPsetFeasCeil(set, right);
5825 	   }
5826 	
5827 	   assert(SCIPsetIsLT(set, left, SCIPvarGetUbLocal(var)));
5828 	   assert(SCIPsetIsGE(set, left, SCIPvarGetLbLocal(var)));
5829 	   assert(SCIPsetIsGT(set, right, SCIPvarGetLbLocal(var)));
5830 	   assert(SCIPsetIsLE(set, right, SCIPvarGetUbLocal(var)));
5831 	   assert(SCIPsetIsLE(set, left, right));
5832 	
5833 	   /* get value of variable in current LP or pseudo solution */
5834 	   lpval = SCIPvarGetSol(var, tree->focusnodehaslp);
5835 	
5836 	   /* perform the branching;
5837 	    * set the node selection priority in a way, s.t. a node is preferred whose branching goes in the same direction
5838 	    * as the deviation from the variable's root solution
5839 	    */
5840 	
5841 	   /* create child node x <= left */
5842 	   priority = SCIPtreeCalcNodeselPriority(tree, set, stat, var, SCIP_BRANCHDIR_DOWNWARDS, left);
5843 	
5844 	   /* if LP solution is cutoff in child, compute a new estimate
5845 	    * otherwise we cannot expect a direct change in the best solution, so we keep the estimate of the parent node
5846 	    */
5847 	   if( SCIPsetIsGT(set, lpval, left) )
5848 	      estimate = SCIPtreeCalcChildEstimate(tree, set, stat, var, left);
5849 	   else
5850 	      estimate = SCIPnodeGetEstimate(tree->focusnode);
5851 	
5852 	   SCIPsetDebugMsg(set, " -> creating child: <%s> <= %g (priority: %g, estimate: %g)\n",
5853 	      SCIPvarGetName(var), left, priority, estimate);
5854 	
5855 	   SCIP_CALL( SCIPnodeCreateChild(&node, blkmem, set, stat, tree, priority, estimate) );
5856 	   SCIP_CALL( SCIPnodeAddBoundchg(node, blkmem, set, stat, transprob, origprob, tree, reopt, lp, branchcand, eventqueue, NULL,
5857 	         var, left, SCIP_BOUNDTYPE_UPPER, FALSE) );
5858 	   /* output branching bound change to visualization file */
5859 	   SCIP_CALL( SCIPvisualUpdateChild(stat->visual, set, stat, node) );
5860 	
5861 	   if( downchild != NULL )
5862 	      *downchild = node;
5863 	
5864 	   /* create child node with x >= right */
5865 	   priority = SCIPtreeCalcNodeselPriority(tree, set, stat, var, SCIP_BRANCHDIR_UPWARDS, right);
5866 	
5867 	   if( SCIPsetIsLT(set, lpval, right) )
5868 	      estimate = SCIPtreeCalcChildEstimate(tree, set, stat, var, right);
5869 	   else
5870 	      estimate = SCIPnodeGetEstimate(tree->focusnode);
5871 	
5872 	   SCIPsetDebugMsg(set, " -> creating child: <%s> >= %g (priority: %g, estimate: %g)\n",
5873 	      SCIPvarGetName(var), right, priority, estimate);
5874 	
5875 	   SCIP_CALL( SCIPnodeCreateChild(&node, blkmem, set, stat, tree, priority, estimate) );
5876 	   SCIP_CALL( SCIPnodeAddBoundchg(node, blkmem, set, stat, transprob, origprob, tree, reopt, lp, branchcand, eventqueue,
5877 	         NULL, var, right, SCIP_BOUNDTYPE_LOWER, FALSE) );
5878 	   /* output branching bound change to visualization file */
5879 	   SCIP_CALL( SCIPvisualUpdateChild(stat->visual, set, stat, node) );
5880 	
5881 	   if( upchild != NULL )
5882 	      *upchild = node;
5883 	
5884 	   return SCIP_OKAY;
5885 	}
5886 	
5887 	/** n-ary branching on a variable x
5888 	 * Branches on variable x such that up to n/2 children are created on each side of the usual branching value.
5889 	 * The branching value is selected as in SCIPtreeBranchVar().
5890 	 * If n is 2 or the variables local domain is too small for a branching into n pieces, SCIPtreeBranchVar() is called.
5891 	 * The parameters minwidth and widthfactor determine the domain width of the branching variable in the child nodes.
5892 	 * If n is odd, one child with domain width 'width' and having the branching value in the middle is created.
5893 	 * Otherwise, two children with domain width 'width' and being left and right of the branching value are created.
5894 	 * Next further nodes to the left and right are created, where width is multiplied by widthfactor with increasing distance from the first nodes.
5895 	 * The initial width is calculated such that n/2 nodes are created to the left and to the right of the branching value.
5896 	 * If this value is below minwidth, the initial width is set to minwidth, which may result in creating less than n nodes.
5897 	 *
5898 	 * Giving a large value for widthfactor results in creating children with small domain when close to the branching value
5899 	 * and large domain when closer to the current variable bounds. That is, setting widthfactor to a very large value and n to 3
5900 	 * results in a ternary branching where the branching variable is mostly fixed in the middle child.
5901 	 * Setting widthfactor to 1.0 results in children where the branching variable always has the same domain width
5902 	 * (except for one child if the branching value is not in the middle).
5903 	 */
5904 	SCIP_RETCODE SCIPtreeBranchVarNary(
5905 	   SCIP_TREE*            tree,               /**< branch and bound tree */
5906 	   SCIP_REOPT*           reopt,              /**< reoptimization data structure */
5907 	   BMS_BLKMEM*           blkmem,             /**< block memory */
5908 	   SCIP_SET*             set,                /**< global SCIP settings */
5909 	   SCIP_STAT*            stat,               /**< problem statistics data */
5910 	   SCIP_PROB*            transprob,          /**< transformed problem after presolve */
5911 	   SCIP_PROB*            origprob,           /**< original problem */
5912 	   SCIP_LP*              lp,                 /**< current LP data */
5913 	   SCIP_BRANCHCAND*      branchcand,         /**< branching candidate storage */
5914 	   SCIP_EVENTQUEUE*      eventqueue,         /**< event queue */
5915 	   SCIP_VAR*             var,                /**< variable to branch on */
5916 	   SCIP_Real             val,                /**< value to branch on or SCIP_INVALID for branching on current LP/pseudo solution.
5917 	                                              *   A branching value is required for branching on continuous variables */
5918 	   int                   n,                  /**< attempted number of children to be created, must be >= 2 */
5919 	   SCIP_Real             minwidth,           /**< minimal domain width in children */
5920 	   SCIP_Real             widthfactor,        /**< multiplier for children domain width with increasing distance from val, must be >= 1.0 */
5921 	   int*                  nchildren           /**< buffer to store number of created children, or NULL */
5922 	   )
5923 	{
5924 	   SCIP_NODE* node;
5925 	   SCIP_Real priority;
5926 	   SCIP_Real estimate;
5927 	   SCIP_Real lpval;
5928 	   SCIP_Real width;
5929 	   SCIP_Bool validval;
5930 	   SCIP_Real left;
5931 	   SCIP_Real right;
5932 	   SCIP_Real bnd;
5933 	   int i;
5934 	
5935 	   assert(tree != NULL);
5936 	   assert(set != NULL);
5937 	   assert(var != NULL);
5938 	   assert(n >= 2);
5939 	   assert(minwidth >= 0.0);
5940 	
5941 	   /* if binary branching is requested or we have not enough space for n children, delegate to SCIPtreeBranchVar */
5942 	   if( n == 2 ||
5943 	      2.0 * minwidth >= SCIPvarGetUbLocal(var) - SCIPvarGetLbLocal(var) ||
5944 	      SCIPrelDiff(SCIPvarGetUbLocal(SCIPvarGetProbvar(var)), SCIPvarGetLbLocal(SCIPvarGetProbvar(var))) <= n * SCIPsetEpsilon(set) )
5945 	   {
5946 	      SCIP_NODE* downchild;
5947 	      SCIP_NODE* fixchild;
5948 	      SCIP_NODE* upchild;
5949 	
5950 	      SCIP_CALL( SCIPtreeBranchVar(tree, reopt, blkmem, set, stat, transprob, origprob, lp, branchcand, eventqueue, var, val,
5951 	            &downchild, &fixchild, &upchild) );
5952 	
5953 	      if( nchildren != NULL )
5954 	         *nchildren = (downchild != NULL ? 1 : 0) + (fixchild != NULL ? 1 : 0) + (upchild != NULL ? 1 : 0);
5955 	
5956 	      return SCIP_OKAY;
5957 	   }
5958 	
5959 	   /* store whether a valid value was given for branching */
5960 	   validval = (val != SCIP_INVALID);  /*lint !e777 */
5961 	
5962 	   /* get the corresponding active problem variable
5963 	    * if branching value is given, then transform it to the value of the active variable */
5964 	   if( validval )
5965 	   {
5966 	      SCIP_Real scalar;
5967 	      SCIP_Real constant;
5968 	
5969 	      scalar   = 1.0;
5970 	      constant = 0.0;
5971 	
5972 	      SCIP_CALL( SCIPvarGetProbvarSum(&var, set, &scalar, &constant) );
5973 	
5974 	      if( scalar == 0.0 )
5975 	      {
5976 	         SCIPerrorMessage("cannot branch on fixed variable <%s>\n", SCIPvarGetName(var));
5977 	         return SCIP_INVALIDDATA;
5978 	      }
5979 	
5980 	      /* we should have givenvariable = scalar * activevariable + constant */
5981 	      val = (val - constant) / scalar;
5982 	   }
5983 	   else
5984 	      var = SCIPvarGetProbvar(var);
5985 	
5986 	   if( SCIPvarGetStatus(var) == SCIP_VARSTATUS_FIXED || SCIPvarGetStatus(var) == SCIP_VARSTATUS_MULTAGGR )
5987 	   {
5988 	      SCIPerrorMessage("cannot branch on fixed or multi-aggregated variable <%s>\n", SCIPvarGetName(var));
5989 	      SCIPABORT();
5990 	      return SCIP_INVALIDDATA; /*lint !e527*/
5991 	   }
5992 	
5993 	   /* ensure, that branching on continuous variables will only be performed when a branching point is given. */
5994 	   if( SCIPvarGetType(var) == SCIP_VARTYPE_CONTINUOUS && !validval )
5995 	   {
5996 	      SCIPerrorMessage("Cannot branch on continuous variable <%s> without a given branching value.", SCIPvarGetName(var));
5997 	      SCIPABORT();
5998 	      return SCIP_INVALIDDATA; /*lint !e527*/
5999 	   }
6000 	
6001 	   assert(SCIPvarIsActive(var));
6002 	   assert(SCIPvarGetProbindex(var) >= 0);
6003 	   assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_LOOSE || SCIPvarGetStatus(var) == SCIP_VARSTATUS_COLUMN);
6004 	   assert(SCIPvarGetType(var) == SCIP_VARTYPE_CONTINUOUS || SCIPsetIsFeasIntegral(set, SCIPvarGetLbLocal(var)));
6005 	   assert(SCIPvarGetType(var) == SCIP_VARTYPE_CONTINUOUS || SCIPsetIsFeasIntegral(set, SCIPvarGetUbLocal(var)));
6006 	   assert(SCIPsetIsLT(set, SCIPvarGetLbLocal(var), SCIPvarGetUbLocal(var)));
6007 	
6008 	   /* get value of variable in current LP or pseudo solution */
6009 	   lpval = SCIPvarGetSol(var, tree->focusnodehaslp);
6010 	
6011 	   /* if there was no explicit value given for branching, branch on current LP or pseudo solution value */
6012 	   if( !validval )
6013 	   {
6014 	      val = lpval;
6015 	
6016 	      /* avoid branching on infinite values in pseudo solution */
6017 	      if( SCIPsetIsInfinity(set, -val) || SCIPsetIsInfinity(set, val) )
6018 	      {
6019 	         val = SCIPvarGetWorstBoundLocal(var);
6020 	
6021 	         /* if both bounds are infinite, choose zero as branching point */
6022 	         if( SCIPsetIsInfinity(set, -val) || SCIPsetIsInfinity(set, val) )
6023 	         {
6024 	            assert(SCIPsetIsInfinity(set, -SCIPvarGetLbLocal(var)));
6025 	            assert(SCIPsetIsInfinity(set, SCIPvarGetUbLocal(var)));
6026 	            val = 0.0;
6027 	         }
6028 	      }
6029 	   }
6030 	
6031 	   assert(SCIPsetIsFeasGE(set, val, SCIPvarGetLbLocal(var)));
6032 	   assert(SCIPsetIsFeasLE(set, val, SCIPvarGetUbLocal(var)));
6033 	   assert(SCIPvarGetType(var) != SCIP_VARTYPE_CONTINUOUS ||
6034 	      SCIPsetIsRelEQ(set, SCIPvarGetLbLocal(var), SCIPvarGetUbLocal(var)) ||
6035 	      (SCIPsetIsLT(set, 2.1*SCIPvarGetLbLocal(var), 2.1*val) && SCIPsetIsLT(set, 2.1*val, 2.1*SCIPvarGetUbLocal(var))) );  /* see comment in SCIPbranchVarVal */
6036 	
6037 	   /* calculate minimal distance of val from bounds */
6038 	   width = SCIP_REAL_MAX;
6039 	   if( !SCIPsetIsInfinity(set, -SCIPvarGetLbLocal(var)) )
6040 	   {
6041 	      width = val - SCIPvarGetLbLocal(var);
6042 	   }
6043 	   if( !SCIPsetIsInfinity(set,  SCIPvarGetUbLocal(var)) )
6044 	   {
6045 	      width = MIN(width, SCIPvarGetUbLocal(var) - val); /*lint !e666*/
6046 	   }
6047 	   /* calculate initial domain width of child nodes
6048 	    * if we have at least one finite bound, choose width such that we have roughly the same number of nodes left and right of val
6049 	    */
6050 	   if( width == SCIP_REAL_MAX ) /*lint !e777*/
6051 	   {
6052 	      /* unbounded variable, let's create a child with a small domain */
6053 	      width = 1.0;
6054 	   }
6055 	   else if( widthfactor == 1.0 )
6056 	   {
6057 	      /* most domains get same size */
6058 	      width /= n/2; /*lint !e653*/ /* rounding is ok at this point */
6059 	   }
6060 	   else
6061 	   {
6062 	      /* width is increased by widthfactor for each child
6063 	       * if n is even, compute width such that we can create n/2 nodes with width
6064 	       * width, widthfactor*width, ..., widthfactor^(n/2)*width on each side, i.e.,
6065 	       *      sum(width * widthfactor^(i-1), i = 1..n/2) = min(ub-val, val-lb)
6066 	       *  <-> width * (widthfactor^(n/2) - 1) / (widthfactor - 1) = min(ub-val, val-lb)
6067 	       *
6068 	       * if n is odd, compute width such that we can create one middle node with width width
6069 	       * and n/2 nodes with width widthfactor*width, ..., widthfactor^(n/2)*width on each side, i.e.,
6070 	       *      width/2 + sum(width * widthfactor^i, i = 1..n/2) = min(ub-val, val-lb)
6071 	       *  <-> width * (1/2 + widthfactor * (widthfactor^(n/2) - 1) / (widthfactor - 1) = min(ub-val, val-lb)
6072 	       */
6073 	      assert(widthfactor > 1.0);
6074 	      if( n % 2 == 0 )
6075 	         width *= (widthfactor - 1.0) / (pow(widthfactor, (SCIP_Real)(n/2)) - 1.0); /*lint !e653*/
6076 	      else
6077 	         width /= 0.5 + widthfactor * (pow(widthfactor, (SCIP_Real)(n/2)) - 1.0) / (widthfactor - 1.0); /*lint !e653*/
6078 	   }
6079 	   if( SCIPvarGetType(var) != SCIP_VARTYPE_CONTINUOUS )
6080 	      minwidth = MAX(1.0, minwidth);
6081 	   if( width < minwidth )
6082 	      width = minwidth;
6083 	   assert(SCIPsetIsPositive(set, width));
6084 	
6085 	   SCIPsetDebugMsg(set, "%d-ary branching on variable <%s> [%g, %g] around %g, initial width = %g\n",
6086 	      n, SCIPvarGetName(var), SCIPvarGetLbLocal(var), SCIPvarGetUbLocal(var), val, width);
6087 	
6088 	   if( nchildren != NULL )
6089 	      *nchildren = 0;
6090 	
6091 	   /* initialize upper bound on children left of val and children right of val
6092 	    * if we are supposed to create an odd number of children, then create a child that has val in the middle of its domain */
6093 	   if( n % 2 == 1 )
6094 	   {
6095 	      left  = val - width/2.0;
6096 	      right = val + width/2.0;
6097 	      SCIPvarAdjustLb(var, set, &left);
6098 	      SCIPvarAdjustUb(var, set, &right);
6099 	
6100 	      /* create child node left <= x <= right, if left <= right */
6101 	      if( left <= right )
6102 	      {
6103 	         priority = SCIPtreeCalcNodeselPriority(tree, set, stat, var, SCIP_BRANCHDIR_FIXED, val); /* ????????????? how to compute priority for such a child? */
6104 	         /* if LP solution is cutoff in child, compute a new estimate
6105 	          * otherwise we cannot expect a direct change in the best solution, so we keep the estimate of the parent node */
6106 	         if( SCIPsetIsLT(set, lpval, left) )
6107 	            estimate = SCIPtreeCalcChildEstimate(tree, set, stat, var, left);
6108 	         else if( SCIPsetIsGT(set, lpval, right) )
6109 	            estimate = SCIPtreeCalcChildEstimate(tree, set, stat, var, right);
6110 	         else
6111 	            estimate = SCIPnodeGetEstimate(tree->focusnode);
6112 	
6113 	         SCIPsetDebugMsg(set, " -> creating middle child: %g <= <%s> <= %g (priority: %g, estimate: %g, width: %g)\n",
6114 	            left, SCIPvarGetName(var), right, priority, estimate, right - left);
6115 	
6116 	         SCIP_CALL( SCIPnodeCreateChild(&node, blkmem, set, stat, tree, priority, estimate) );
6117 	         SCIP_CALL( SCIPnodeAddBoundchg(node, blkmem, set, stat, transprob, origprob, tree, reopt, lp, branchcand,
6118 	               eventqueue, NULL, var, left , SCIP_BOUNDTYPE_LOWER, FALSE) );
6119 	         SCIP_CALL( SCIPnodeAddBoundchg(node, blkmem, set, stat, transprob, origprob, tree, reopt, lp, branchcand, eventqueue,
6120 	               NULL, var, right, SCIP_BOUNDTYPE_UPPER, FALSE) );
6121 	         /* output branching bound change to visualization file */
6122 	         SCIP_CALL( SCIPvisualUpdateChild(stat->visual, set, stat, node) );
6123 	
6124 	         if( nchildren != NULL )
6125 	            ++*nchildren;
6126 	      }
6127 	      --n;
6128 	
6129 	      if( SCIPvarGetType(var) != SCIP_VARTYPE_CONTINUOUS )
6130 	      {
6131 	         /* if it's a discrete variable, we can use left-1 and right+1 as upper and lower bounds for following nodes on the left and right, resp. */
6132 	         left  -= 1.0;
6133 	         right += 1.0;
6134 	      }
6135 	
6136 	      width *= widthfactor;
6137 	   }
6138 	   else
6139 	   {
6140 	      if( SCIPvarGetType(var) != SCIP_VARTYPE_CONTINUOUS )
6141 	      {
6142 	         left  = SCIPsetFloor(set, val);
6143 	         right = SCIPsetCeil(set, val);
6144 	         if( right - left < 0.5 )
6145 	            left -= 1.0;
6146 	      }
6147 	      else if( SCIPsetIsZero(set, val) )
6148 	      {
6149 	         left  = 0.0;
6150 	         right = 0.0;
6151 	      }
6152 	      else
6153 	      {
6154 	         left  = val;
6155 	         right = val;
6156 	      }
6157 	   }
6158 	
6159 	   assert(n % 2 == 0);
6160 	   n /= 2;
6161 	   for( i = 0; i < n; ++i )
6162 	   {
6163 	      /* create child node left - width <= x <= left, if left > lb(x) or x is discrete */
6164 	      if( SCIPsetIsRelLT(set, SCIPvarGetLbLocal(var), left) || SCIPvarGetType(var) != SCIP_VARTYPE_CONTINUOUS )
6165 	      {
6166 	         /* new lower bound should be variables lower bound, if we are in the last round or left - width is very close to lower bound
6167 	          * otherwise we take left - width
6168 	          */
6169 	         if( i == n-1 || SCIPsetIsRelEQ(set, SCIPvarGetLbLocal(var), left - width))
6170 	         {
6171 	            bnd = SCIPvarGetLbLocal(var);
6172 	         }
6173 	         else
6174 	         {
6175 	            bnd = left - width;
6176 	            SCIPvarAdjustLb(var, set, &bnd);
6177 	            bnd = MAX(SCIPvarGetLbLocal(var), bnd); /*lint !e666*/
6178 	         }
6179 	         assert(SCIPsetIsRelLT(set, bnd, left));
6180 	
6181 	         /* the nodeselection priority of nodes is decreased as more as they are away from val */
6182 	         priority = SCIPtreeCalcNodeselPriority(tree, set, stat, var, SCIP_BRANCHDIR_DOWNWARDS, bnd) / (i+1);
6183 	         /* if LP solution is cutoff in child, compute a new estimate
6184 	          * otherwise we cannot expect a direct change in the best solution, so we keep the estimate of the parent node */
6185 	         if( SCIPsetIsLT(set, lpval, bnd) )
6186 	            estimate = SCIPtreeCalcChildEstimate(tree, set, stat, var, bnd);
6187 	         else if( SCIPsetIsGT(set, lpval, left) )
6188 	            estimate = SCIPtreeCalcChildEstimate(tree, set, stat, var, left);
6189 	         else
6190 	            estimate = SCIPnodeGetEstimate(tree->focusnode);
6191 	
6192 	         SCIPsetDebugMsg(set, " -> creating left  child: %g <= <%s> <= %g (priority: %g, estimate: %g, width: %g)\n",
6193 	            bnd, SCIPvarGetName(var), left, priority, estimate, left - bnd);
6194 	
6195 	         SCIP_CALL( SCIPnodeCreateChild(&node, blkmem, set, stat, tree, priority, estimate) );
6196 	         if( SCIPsetIsGT(set, bnd, SCIPvarGetLbLocal(var)) )
6197 	         {
6198 	            SCIP_CALL( SCIPnodeAddBoundchg(node, blkmem, set, stat, transprob, origprob, tree, reopt, lp, branchcand, eventqueue,
6199 	               NULL, var, bnd, SCIP_BOUNDTYPE_LOWER, FALSE) );
6200 	         }
6201 	         SCIP_CALL( SCIPnodeAddBoundchg(node, blkmem, set, stat, transprob, origprob, tree, reopt, lp, branchcand, eventqueue,
6202 	            NULL, var, left, SCIP_BOUNDTYPE_UPPER, FALSE) );
6203 	         /* output branching bound change to visualization file */
6204 	         SCIP_CALL( SCIPvisualUpdateChild(stat->visual, set, stat, node) );
6205 	
6206 	         if( nchildren != NULL )
6207 	            ++*nchildren;
6208 	
6209 	         left = bnd;
6210 	         if( SCIPvarGetType(var) != SCIP_VARTYPE_CONTINUOUS )
6211 	            left -= 1.0;
6212 	      }
6213 	
6214 	      /* create child node right <= x <= right + width, if right < ub(x) */
6215 	      if( SCIPsetIsRelGT(set, SCIPvarGetUbLocal(var), right) || SCIPvarGetType(var) != SCIP_VARTYPE_CONTINUOUS )
6216 	      {
6217 	         /* new upper bound should be variables upper bound, if we are in the last round or right + width is very close to upper bound
6218 	          * otherwise we take right + width
6219 	          */
6220 	         if( i == n-1 || SCIPsetIsRelEQ(set, SCIPvarGetUbLocal(var), right + width))
6221 	         {
6222 	            bnd = SCIPvarGetUbLocal(var);
6223 	         }
6224 	         else
6225 	         {
6226 	            bnd = right + width;
6227 	            SCIPvarAdjustUb(var, set, &bnd);
6228 	            bnd = MIN(SCIPvarGetUbLocal(var), bnd); /*lint !e666*/
6229 	         }
6230 	         assert(SCIPsetIsRelGT(set, bnd, right));
6231 	
6232 	         /* the nodeselection priority of nodes is decreased as more as they are away from val */
6233 	         priority = SCIPtreeCalcNodeselPriority(tree, set, stat, var, SCIP_BRANCHDIR_UPWARDS, bnd) / (i+1);
6234 	         /* if LP solution is cutoff in child, compute a new estimate
6235 	          * otherwise we cannot expect a direct change in the best solution, so we keep the estimate of the parent node */
6236 	         if( SCIPsetIsLT(set, lpval, right) )
6237 	            estimate = SCIPtreeCalcChildEstimate(tree, set, stat, var, right);
6238 	         else if( SCIPsetIsGT(set, lpval, bnd) )
6239 	            estimate = SCIPtreeCalcChildEstimate(tree, set, stat, var, bnd);
6240 	         else
6241 	            estimate = SCIPnodeGetEstimate(tree->focusnode);
6242 	
6243 	         SCIPsetDebugMsg(set, " -> creating right child: %g <= <%s> <= %g (priority: %g, estimate: %g, width: %g)\n",
6244 	            right, SCIPvarGetName(var), bnd, priority, estimate, bnd - right);
6245 	
6246 	         SCIP_CALL( SCIPnodeCreateChild(&node, blkmem, set, stat, tree, priority, estimate) );
6247 	         SCIP_CALL( SCIPnodeAddBoundchg(node, blkmem, set, stat, transprob, origprob, tree, reopt, lp, branchcand, eventqueue,
6248 	            NULL, var, right, SCIP_BOUNDTYPE_LOWER, FALSE) );
6249 	         if( SCIPsetIsLT(set, bnd, SCIPvarGetUbLocal(var)) )
6250 	         {
6251 	            SCIP_CALL( SCIPnodeAddBoundchg(node, blkmem, set, stat, transprob, origprob, tree, reopt, lp, branchcand, eventqueue,
6252 	               NULL, var, bnd, SCIP_BOUNDTYPE_UPPER, FALSE) );
6253 	         }
6254 	         /* output branching bound change to visualization file */
6255 	         SCIP_CALL( SCIPvisualUpdateChild(stat->visual, set, stat, node) );
6256 	
6257 	         if( nchildren != NULL )
6258 	            ++*nchildren;
6259 	
6260 	         right = bnd;
6261 	         if( SCIPvarGetType(var) != SCIP_VARTYPE_CONTINUOUS )
6262 	            right += 1.0;
6263 	      }
6264 	
6265 	      width *= widthfactor;
6266 	   }
6267 	
6268 	   return SCIP_OKAY;
6269 	}
6270 	
6271 	/** adds a diving bound change to the tree together with the information if this is a bound change
6272 	 *  for the preferred direction or not
6273 	 */
6274 	#define ARRAYGROWTH 5
6275 	SCIP_RETCODE SCIPtreeAddDiveBoundChange(
6276 	   SCIP_TREE*            tree,               /**< branch and bound tree */
6277 	   BMS_BLKMEM*           blkmem,             /**< block memory buffers */
6278 	   SCIP_VAR*             var,                /**< variable to apply the bound change to */
6279 	   SCIP_BRANCHDIR        dir,                /**< direction of the bound change */
6280 	   SCIP_Real             value,              /**< value to adjust this variable bound to */
6281 	   SCIP_Bool             preferred           /**< is this a bound change for the preferred child? */
6282 	   )
6283 	{
6284 	   int idx = preferred ? 0 : 1;
6285 	   int pos = tree->ndivebdchanges[idx];
6286 	
6287 	   assert(pos < tree->divebdchgsize[idx]);
6288 	
6289 	   if( pos == tree->divebdchgsize[idx] - 1 )
6290 	   {
6291 	      SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &tree->divebdchgdirs[idx], tree->divebdchgsize[idx], tree->divebdchgsize[idx] + ARRAYGROWTH) ); /*lint !e866*/
6292 	      SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &tree->divebdchgvars[idx], tree->divebdchgsize[idx], tree->divebdchgsize[idx] + ARRAYGROWTH) ); /*lint !e866*/
6293 	      SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &tree->divebdchgvals[idx], tree->divebdchgsize[idx], tree->divebdchgsize[idx] + ARRAYGROWTH) ); /*lint !e866*/
6294 	      tree->divebdchgsize[idx] += ARRAYGROWTH;
6295 	   }
6296 	
6297 	   tree->divebdchgvars[idx][pos] = var;
6298 	   tree->divebdchgdirs[idx][pos] = dir;
6299 	   tree->divebdchgvals[idx][pos] = value;
6300 	
6301 	   ++tree->ndivebdchanges[idx];
6302 	
6303 	   return SCIP_OKAY;
6304 	}
6305 	
6306 	/** get the dive bound change data for the preferred or the alternative direction */
6307 	void SCIPtreeGetDiveBoundChangeData(
6308 	   SCIP_TREE*            tree,               /**< branch and bound tree */
6309 	   SCIP_VAR***           variables,          /**< pointer to store variables for the specified direction */
6310 	   SCIP_BRANCHDIR**      directions,         /**< pointer to store the branching directions */
6311 	   SCIP_Real**           values,             /**< pointer to store bound change values */
6312 	   int*                  ndivebdchgs,        /**< pointer to store the number of dive bound changes */
6313 	   SCIP_Bool             preferred           /**< should the dive bound changes for the preferred child be output? */
6314 	   )
6315 	{
6316 	   int idx = preferred ? 0 : 1;
6317 	
6318 	   assert(variables != NULL);
6319 	   assert(directions != NULL);
6320 	   assert(values != NULL);
6321 	   assert(ndivebdchgs != NULL);
6322 	
6323 	   *variables = tree->divebdchgvars[idx];
6324 	   *directions = tree->divebdchgdirs[idx];
6325 	   *values = tree->divebdchgvals[idx];
6326 	   *ndivebdchgs = tree->ndivebdchanges[idx];
6327 	}
6328 	
6329 	/** clear the tree bound change data structure */
6330 	void SCIPtreeClearDiveBoundChanges(
6331 	   SCIP_TREE*            tree                /**< branch and bound tree */
6332 	   )
6333 	{
6334 	   int p;
6335 	
6336 	   for( p = 0; p < 2; ++p )
6337 	      tree->ndivebdchanges[p] = 0;
6338 	}
6339 	
6340 	/** creates a probing child node of the current node, which must be the focus node, the current refocused node,
6341 	 *  or another probing node; if the current node is the focus or a refocused node, the created probing node is
6342 	 *  installed as probing root node
6343 	 */
6344 	static
6345 	SCIP_RETCODE treeCreateProbingNode(
6346 	   SCIP_TREE*            tree,               /**< branch and bound tree */
6347 	   BMS_BLKMEM*           blkmem,             /**< block memory */
6348 	   SCIP_SET*             set,                /**< global SCIP settings */
6349 	   SCIP_LP*              lp                  /**< current LP data */
6350 	   )
6351 	{
6352 	   SCIP_NODE* currentnode;
6353 	   SCIP_NODE* node;
6354 	   SCIP_RETCODE retcode;
6355 	
6356 	   assert(tree != NULL);
6357 	   assert(SCIPtreeIsPathComplete(tree));
6358 	   assert(tree->pathlen > 0);
6359 	   assert(blkmem != NULL);
6360 	   assert(set != NULL);
6361 	
6362 	   /* get the current node */
6363 	   currentnode = SCIPtreeGetCurrentNode(tree);
6364 	   assert(SCIPnodeGetType(currentnode) == SCIP_NODETYPE_FOCUSNODE
6365 	      || SCIPnodeGetType(currentnode) == SCIP_NODETYPE_REFOCUSNODE
6366 	      || SCIPnodeGetType(currentnode) == SCIP_NODETYPE_PROBINGNODE);
6367 	   assert((SCIPnodeGetType(currentnode) == SCIP_NODETYPE_PROBINGNODE) == SCIPtreeProbing(tree));
6368 	
6369 	   /* create the node data structure */
6370 	   SCIP_CALL( nodeCreate(&node, blkmem, set) );
6371 	   assert(node != NULL);
6372 	
6373 	   /* mark node to be a probing node */
6374 	   node->nodetype = SCIP_NODETYPE_PROBINGNODE; /*lint !e641*/
6375 	
6376 	   /* create the probingnode data */
6377 	   SCIP_CALL( probingnodeCreate(&node->data.probingnode, blkmem, lp) );
6378 	
6379 	   /* make the current node the parent of the new probing node */
6380 	   retcode = nodeAssignParent(node, blkmem, set, tree, currentnode, 0.0);
6381 	
6382 	   /* if we reached the maximal depth level we clean up the allocated memory and stop */
6383 	   if( retcode == SCIP_MAXDEPTHLEVEL )
6384 	   {
6385 	      SCIP_CALL( probingnodeFree(&(node->data.probingnode), blkmem, lp) );
6386 	      BMSfreeBlockMemory(blkmem, &node);
6387 	   }
6388 	   SCIP_CALL( retcode );
6389 	   assert(SCIPnodeGetDepth(node) == tree->pathlen);
6390 	
6391 	   /* check, if the node is the probing root node */
6392 	   if( tree->probingroot == NULL )
6393 	   {
6394 	      tree->probingroot = node;
6395 	      SCIPsetDebugMsg(set, "created probing root node #%" SCIP_LONGINT_FORMAT " at depth %d\n",
6396 	         SCIPnodeGetNumber(node), SCIPnodeGetDepth(node));
6397 	   }
6398 	   else
6399 	   {
6400 	      assert(SCIPnodeGetType(tree->probingroot) == SCIP_NODETYPE_PROBINGNODE);
6401 	      assert(SCIPnodeGetDepth(tree->probingroot) < SCIPnodeGetDepth(node));
6402 	
6403 	      SCIPsetDebugMsg(set, "created probing child node #%" SCIP_LONGINT_FORMAT " at depth %d, probing depth %d\n",
6404 	         SCIPnodeGetNumber(node), SCIPnodeGetDepth(node), SCIPnodeGetDepth(node) - SCIPnodeGetDepth(tree->probingroot));
6405 	
6406 	      currentnode->data.probingnode->ncols = SCIPlpGetNCols(lp);
6407 	      currentnode->data.probingnode->nrows = SCIPlpGetNRows(lp);
6408 	
6409 	      SCIPsetDebugMsg(set, "updated probingnode information of parent (%d cols, %d rows)\n",
6410 	         currentnode->data.probingnode->ncols, currentnode->data.probingnode->nrows);
6411 	   }
6412 	
6413 	   /* create the new active path */
6414 	   SCIP_CALL( treeEnsurePathMem(tree, set, tree->pathlen+1) );
6415 	   node->active = TRUE;
6416 	   tree->path[tree->pathlen] = node;
6417 	   tree->pathlen++;
6418 	
6419 	   /* update the path LP size for the previous node and set the (initial) path LP size for the newly created node */
6420 	   SCIP_CALL( treeUpdatePathLPSize(tree, tree->pathlen-2) );
6421 	
6422 	   /* mark the LP's size */
6423 	   SCIPlpMarkSize(lp);
6424 	   assert(tree->pathlen >= 2);
6425 	   assert(lp->firstnewrow == tree->pathnlprows[tree->pathlen-1]); /* marked LP size should be initial size of new node */
6426 	   assert(lp->firstnewcol == tree->pathnlpcols[tree->pathlen-1]);
6427 	
6428 	   /* the current probing node does not yet have a solved LP */
6429 	   tree->probingnodehaslp = FALSE;
6430 	
6431 	   return SCIP_OKAY;
6432 	}
6433 	
6434 	/** switches to probing mode and creates a probing root */
6435 	SCIP_RETCODE SCIPtreeStartProbing(
6436 	   SCIP_TREE*            tree,               /**< branch and bound tree */
6437 	   BMS_BLKMEM*           blkmem,             /**< block memory */
6438 	   SCIP_SET*             set,                /**< global SCIP settings */
6439 	   SCIP_LP*              lp,                 /**< current LP data */
6440 	   SCIP_RELAXATION*      relaxation,         /**< global relaxation data */
6441 	   SCIP_PROB*            transprob,          /**< transformed problem after presolve */
6442 	   SCIP_Bool             strongbranching     /**< is the probing mode used for strongbranching? */
6443 	   )
6444 	{
6445 	   assert(tree != NULL);
6446 	   assert(tree->probinglpistate == NULL);
6447 	   assert(tree->probinglpinorms == NULL);
6448 	   assert(!SCIPtreeProbing(tree));
6449 	   assert(lp != NULL);
6450 	
6451 	   SCIPsetDebugMsg(set, "probing started in depth %d (LP flushed: %u, LP solved: %u, solstat: %d), probing root in depth %d\n",
6452 	      tree->pathlen-1, lp->flushed, lp->solved, SCIPlpGetSolstat(lp), tree->pathlen);
6453 	
6454 	   /* store all marked constraints for propagation */
6455 	   SCIP_CALL( SCIPconshdlrsStorePropagationStatus(set, set->conshdlrs, set->nconshdlrs) );
6456 	
6457 	   /* inform LP about probing mode */
6458 	   SCIP_CALL( SCIPlpStartProbing(lp) );
6459 	
6460 	   assert(!lp->divingobjchg);
6461 	
6462 	   /* remember, whether the LP was flushed and solved */
6463 	   tree->probinglpwasflushed = lp->flushed;
6464 	   tree->probinglpwassolved = lp->solved;
6465 	   tree->probingloadlpistate = FALSE;
6466 	   tree->probinglpwasrelax = lp->isrelax;
6467 	   lp->isrelax = TRUE;
6468 	   tree->probingsolvedlp = FALSE;
6469 	   tree->probingobjchanged = FALSE;
6470 	   lp->divingobjchg = FALSE;
6471 	   tree->probingsumchgdobjs = 0;
6472 	   tree->sbprobing = strongbranching;
6473 	
6474 	   /* remember the LP state in order to restore the LP solution quickly after probing */
6475 	   /**@todo could the lp state be worth storing if the LP is not flushed (and hence not solved)? */
6476 	   if( lp->flushed && lp->solved )
6477 	   {
6478 	      SCIP_CALL( SCIPlpGetState(lp, blkmem, &tree->probinglpistate) );
6479 	      SCIP_CALL( SCIPlpGetNorms(lp, blkmem, &tree->probinglpinorms) );
6480 	      tree->probinglpwasprimfeas = lp->primalfeasible;
6481 	      tree->probinglpwasprimchecked = lp->primalchecked;
6482 	      tree->probinglpwasdualfeas = lp->dualfeasible;
6483 	      tree->probinglpwasdualchecked = lp->dualchecked;
6484 	   }
6485 	
6486 	   /* remember the relaxation solution to reset it later */
6487 	   if( SCIPrelaxationIsSolValid(relaxation) )
6488 	   {
6489 	      SCIP_CALL( SCIPtreeStoreRelaxSol(tree, set, relaxation, transprob) );
6490 	   }
6491 	
6492 	   /* create temporary probing root node */
6493 	   SCIP_CALL( treeCreateProbingNode(tree, blkmem, set, lp) );
6494 	   assert(SCIPtreeProbing(tree));
6495 	
6496 	   return SCIP_OKAY;
6497 	}
6498 	
6499 	/** creates a new probing child node in the probing path */
6500 	SCIP_RETCODE SCIPtreeCreateProbingNode(
6501 	   SCIP_TREE*            tree,               /**< branch and bound tree */
6502 	   BMS_BLKMEM*           blkmem,             /**< block memory */
6503 	   SCIP_SET*             set,                /**< global SCIP settings */
6504 	   SCIP_LP*              lp                  /**< current LP data */
6505 	   )
6506 	{
6507 	   assert(SCIPtreeProbing(tree));
6508 	
6509 	   SCIPsetDebugMsg(set, "new probing child in depth %d (probing depth: %d)\n", tree->pathlen, tree->pathlen-1 - SCIPnodeGetDepth(tree->probingroot));
6510 	
6511 	   /* create temporary probing root node */
6512 	   SCIP_CALL( treeCreateProbingNode(tree, blkmem, set, lp) );
6513 	
6514 	   return SCIP_OKAY;
6515 	}
6516 	
6517 	/** sets the LP state for the current probing node
6518 	 *
6519 	 *  @note state and norms are stored at the node and later released by SCIP; therefore, the pointers are set
6520 	 *        to NULL by the method
6521 	 *
6522 	 *  @note the pointers to state and norms must not be NULL; however, they may point to a NULL pointer if the
6523 	 *        respective information should not be set
6524 	 */
6525 	SCIP_RETCODE SCIPtreeSetProbingLPState(
6526 	   SCIP_TREE*            tree,               /**< branch and bound tree */
6527 	   BMS_BLKMEM*           blkmem,             /**< block memory */
6528 	   SCIP_LP*              lp,                 /**< current LP data */
6529 	   SCIP_LPISTATE**       lpistate,           /**< pointer to LP state information (like basis information) */
6530 	   SCIP_LPINORMS**       lpinorms,           /**< pointer to LP pricing norms information */
6531 	   SCIP_Bool             primalfeas,         /**< primal feasibility when LP state information was stored */
6532 	   SCIP_Bool             dualfeas            /**< dual feasibility when LP state information was stored */
6533 	   )
6534 	{
6535 	   SCIP_NODE* node;
6536 	
6537 	   assert(tree != NULL);
6538 	   assert(SCIPtreeProbing(tree));
6539 	   assert(lpistate != NULL);
6540 	   assert(lpinorms != NULL);
6541 	
6542 	   /* get the current probing node */
6543 	   node = SCIPtreeGetCurrentNode(tree);
6544 	
6545 	   /* this check is necessary to avoid cppcheck warnings */
6546 	   if( node == NULL )
6547 	      return SCIP_INVALIDDATA;
6548 	
6549 	   assert(SCIPnodeGetType(node) == SCIP_NODETYPE_PROBINGNODE);
6550 	   assert(node->data.probingnode != NULL);
6551 	
6552 	   /* free already present LP state */
6553 	   if( node->data.probingnode->lpistate != NULL )
6554 	   {
6555 	      SCIP_CALL( SCIPlpFreeState(lp, blkmem, &(node->data.probingnode->lpistate)) );
6556 	   }
6557 	
6558 	   /* free already present LP pricing norms */
6559 	   if( node->data.probingnode->lpinorms != NULL )
6560 	   {
6561 	      SCIP_CALL( SCIPlpFreeNorms(lp, blkmem, &(node->data.probingnode->lpinorms)) );
6562 	   }
6563 	
6564 	   node->data.probingnode->lpistate = *lpistate;
6565 	   node->data.probingnode->lpinorms = *lpinorms;
6566 	   node->data.probingnode->lpwasprimfeas = primalfeas;
6567 	   node->data.probingnode->lpwasdualfeas = dualfeas;
6568 	
6569 	   /* set the pointers to NULL to avoid that they are still used and modified by the caller */
6570 	   *lpistate = NULL;
6571 	   *lpinorms = NULL;
6572 	
6573 	   tree->probingloadlpistate = TRUE;
6574 	
6575 	   return SCIP_OKAY;
6576 	}
6577 	
6578 	/** loads the LP state for the current probing node */
6579 	SCIP_RETCODE SCIPtreeLoadProbingLPState(
6580 	   SCIP_TREE*            tree,               /**< branch and bound tree */
6581 	   BMS_BLKMEM*           blkmem,             /**< block memory buffers */
6582 	   SCIP_SET*             set,                /**< global SCIP settings */
6583 	   SCIP_PROB*            prob,               /**< problem data */
6584 	   SCIP_EVENTQUEUE*      eventqueue,         /**< event queue */
6585 	   SCIP_LP*              lp                  /**< current LP data */
6586 	   )
6587 	{
6588 	   assert(tree != NULL);
6589 	   assert(SCIPtreeProbing(tree));
6590 	
6591 	   /* loading the LP state is only necessary if we backtracked */
6592 	   if( tree->probingloadlpistate )
6593 	   {
6594 	      SCIP_NODE* node;
6595 	      SCIP_LPISTATE* lpistate;
6596 	      SCIP_LPINORMS* lpinorms;
6597 	      SCIP_Bool lpwasprimfeas = FALSE;
6598 	      SCIP_Bool lpwasprimchecked = FALSE;
6599 	      SCIP_Bool lpwasdualfeas = FALSE;
6600 	      SCIP_Bool lpwasdualchecked = FALSE;
6601 	
6602 	      /* get the current probing node */
6603 	      node = SCIPtreeGetCurrentNode(tree);
6604 	      assert(node != NULL);
6605 	      assert(SCIPnodeGetType(node) == SCIP_NODETYPE_PROBINGNODE);
6606 	
6607 	      /* search the last node where an LP state information was attached */
6608 	      lpistate = NULL;
6609 	      lpinorms = NULL;
6610 	      do
6611 	      {
6612 	         assert(SCIPnodeGetType(node) == SCIP_NODETYPE_PROBINGNODE);
6613 	         assert(node->data.probingnode != NULL);
6614 	         if( node->data.probingnode->lpistate != NULL )
6615 	         {
6616 	            lpistate = node->data.probingnode->lpistate;
6617 	            lpinorms = node->data.probingnode->lpinorms;
6618 	            lpwasprimfeas = node->data.probingnode->lpwasprimfeas;
6619 	            lpwasprimchecked = node->data.probingnode->lpwasprimchecked;
6620 	            lpwasdualfeas = node->data.probingnode->lpwasdualfeas;
6621 	            lpwasdualchecked = node->data.probingnode->lpwasdualchecked;
6622 	            break;
6623 	         }
6624 	         node = node->parent;
6625 	         assert(node != NULL); /* the root node cannot be a probing node! */
6626 	      }
6627 	      while( SCIPnodeGetType(node) == SCIP_NODETYPE_PROBINGNODE );
6628 	
6629 	      /* if there was no LP information stored in the probing nodes, use the one stored before probing started */
6630 	      if( lpistate == NULL )
6631 	      {
6632 	         lpistate = tree->probinglpistate;
6633 	         lpinorms = tree->probinglpinorms;
6634 	         lpwasprimfeas = tree->probinglpwasprimfeas;
6635 	         lpwasprimchecked = tree->probinglpwasprimchecked;
6636 	         lpwasdualfeas = tree->probinglpwasdualfeas;
6637 	         lpwasdualchecked = tree->probinglpwasdualchecked;
6638 	      }
6639 	
6640 	      /* set the LP state */
6641 	      if( lpistate != NULL )
6642 	      {
6643 	         SCIP_CALL( SCIPlpSetState(lp, blkmem, set, prob, eventqueue, lpistate,
6644 	               lpwasprimfeas, lpwasprimchecked, lpwasdualfeas, lpwasdualchecked) );
6645 	      }
6646 	
6647 	      /* set the LP pricing norms */
6648 	      if( lpinorms != NULL )
6649 	      {
6650 	         SCIP_CALL( SCIPlpSetNorms(lp, blkmem, lpinorms) );
6651 	      }
6652 	
6653 	      /* now we don't need to load the LP state again until the next backtracking */
6654 	      tree->probingloadlpistate = FALSE;
6655 	   }
6656 	
6657 	   return SCIP_OKAY;
6658 	}
6659 	
6660 	/** marks the probing node to have a solved LP relaxation */
6661 	SCIP_RETCODE SCIPtreeMarkProbingNodeHasLP(
6662 	   SCIP_TREE*            tree,               /**< branch and bound tree */
6663 	   BMS_BLKMEM*           blkmem,             /**< block memory */
6664 	   SCIP_LP*              lp                  /**< current LP data */
6665 	   )
6666 	{
6667 	   SCIP_NODE* node;
6668 	
6669 	   assert(tree != NULL);
6670 	   assert(SCIPtreeProbing(tree));
6671 	
6672 	   /* mark the probing node to have an LP */
6673 	   tree->probingnodehaslp = TRUE;
6674 	
6675 	   /* get current probing node */
6676 	   node = SCIPtreeGetCurrentNode(tree);
6677 	   assert(SCIPnodeGetType(node) == SCIP_NODETYPE_PROBINGNODE);
6678 	   assert(node != NULL && node->data.probingnode != NULL);
6679 	
6680 	   /* update LP information in probingnode data */
6681 	   /* cppcheck-suppress nullPointer */
6682 	   SCIP_CALL( probingnodeUpdate(node->data.probingnode, blkmem, tree, lp) );
6683 	
6684 	   return SCIP_OKAY;
6685 	}
6686 	
6687 	/** undoes all changes to the problem applied in probing up to the given probing depth */
6688 	static
6689 	SCIP_RETCODE treeBacktrackProbing(
6690 	   SCIP_TREE*            tree,               /**< branch and bound tree */
6691 	   SCIP_REOPT*           reopt,              /**< reoptimization data structure */
6692 	   BMS_BLKMEM*           blkmem,             /**< block memory buffers */
6693 	   SCIP_SET*             set,                /**< global SCIP settings */
6694 	   SCIP_STAT*            stat,               /**< problem statistics */
6695 	   SCIP_PROB*            transprob,          /**< transformed problem after presolve */
6696 	   SCIP_PROB*            origprob,           /**< original problem */
6697 	   SCIP_LP*              lp,                 /**< current LP data */
6698 	   SCIP_PRIMAL*          primal,             /**< primal data structure */
6699 	   SCIP_BRANCHCAND*      branchcand,         /**< branching candidate storage */
6700 	   SCIP_EVENTQUEUE*      eventqueue,         /**< event queue */
6701 	   SCIP_EVENTFILTER*     eventfilter,        /**< global event filter */
6702 	   SCIP_CLIQUETABLE*     cliquetable,        /**< clique table data structure */
6703 	   int                   probingdepth        /**< probing depth of the node in the probing path that should be reactivated,
6704 	                                              *   -1 to even deactivate the probing root, thus exiting probing mode */
6705 	   )
6706 	{
6707 	   int newpathlen;
6708 	   int i;
6709 	
6710 	   assert(tree != NULL);
6711 	   assert(SCIPtreeProbing(tree));
6712 	   assert(tree->probingroot != NULL);
6713 	   assert(tree->focusnode != NULL);
6714 	   assert(SCIPnodeGetType(tree->probingroot) == SCIP_NODETYPE_PROBINGNODE);
6715 	   assert(SCIPnodeGetType(tree->focusnode) == SCIP_NODETYPE_FOCUSNODE
6716 	      || SCIPnodeGetType(tree->focusnode) == SCIP_NODETYPE_REFOCUSNODE);
6717 	   assert(tree->probingroot->parent == tree->focusnode);
6718 	   assert(SCIPnodeGetDepth(tree->probingroot) == SCIPnodeGetDepth(tree->focusnode)+1);
6719 	   assert(tree->pathlen >= 2);
6720 	   assert(SCIPnodeGetType(tree->path[tree->pathlen-1]) == SCIP_NODETYPE_PROBINGNODE);
6721 	   assert(-1 <= probingdepth && probingdepth <= SCIPtreeGetProbingDepth(tree));
6722 	
6723 	   treeCheckPath(tree);
6724 	
6725 	   newpathlen = SCIPnodeGetDepth(tree->probingroot) + probingdepth + 1;
6726 	   assert(newpathlen >= 1); /* at least root node of the tree remains active */
6727 	
6728 	   /* check if we have to do any backtracking */
6729 	   if( newpathlen < tree->pathlen )
6730 	   {
6731 	      int ncols;
6732 	      int nrows;
6733 	
6734 	      /* the correct LP size of the node to which we backtracked is stored as initial LP size for its child */
6735 	      assert(SCIPnodeGetType(tree->path[newpathlen]) == SCIP_NODETYPE_PROBINGNODE);
6736 	      ncols = tree->path[newpathlen]->data.probingnode->ninitialcols;
6737 	      nrows = tree->path[newpathlen]->data.probingnode->ninitialrows;
6738 	      assert(ncols >= tree->pathnlpcols[newpathlen-1] || !tree->focuslpconstructed);
6739 	      assert(nrows >= tree->pathnlprows[newpathlen-1] || !tree->focuslpconstructed);
6740 	
6741 	      while( tree->pathlen > newpathlen )
6742 	      {
6743 	         SCIP_NODE* node;
6744 	
6745 	         node = tree->path[tree->pathlen-1];
6746 	
6747 	         assert(SCIPnodeGetType(node) == SCIP_NODETYPE_PROBINGNODE);
6748 	         assert(tree->pathlen-1 == SCIPnodeGetDepth(node));
6749 	         assert(tree->pathlen-1 >= SCIPnodeGetDepth(tree->probingroot));
6750 	
6751 	         if( node->data.probingnode->nchgdobjs > 0 )
6752 	         {
6753 	            /* @todo only do this if we don't backtrack to the root node - in that case, we can just restore the unchanged
6754 	             *       objective values
6755 	             */
6756 	            for( i = node->data.probingnode->nchgdobjs - 1; i >= 0; --i )
6757 	            {
6758 	               assert(tree->probingobjchanged);
6759 	
6760 	               SCIP_CALL( SCIPvarChgObj(node->data.probingnode->origobjvars[i], blkmem, set, transprob, primal, lp,
6761 	                     eventqueue, node->data.probingnode->origobjvals[i]) );
6762 	            }
6763 	            tree->probingsumchgdobjs -= node->data.probingnode->nchgdobjs;
6764 	            assert(tree->probingsumchgdobjs >= 0);
6765 	
6766 	            /* reset probingobjchanged flag and cutoff bound */
6767 	            if( tree->probingsumchgdobjs == 0 )
6768 	            {
6769 	               SCIPlpUnmarkDivingObjChanged(lp);
6770 	               tree->probingobjchanged = FALSE;
6771 	
6772 	               SCIP_CALL( SCIPlpSetCutoffbound(lp, set, transprob, primal->cutoffbound) );
6773 	            }
6774 	
6775 	            /* recompute global and local pseudo objective values */
6776 	            SCIPlpRecomputeLocalAndGlobalPseudoObjval(lp, set, transprob);
6777 	         }
6778 	
6779 	         /* undo bound changes by deactivating the probing node */
6780 	         SCIP_CALL( nodeDeactivate(node, blkmem, set, stat, tree, lp, branchcand, eventfilter, eventqueue) );
6781 	
6782 	         /* free the probing node */
6783 	         SCIP_CALL( SCIPnodeFree(&tree->path[tree->pathlen-1], blkmem, set, stat, eventfilter, eventqueue, tree, lp) );
6784 	         tree->pathlen--;
6785 	      }
6786 	      assert(tree->pathlen == newpathlen);
6787 	
6788 	      /* reset the path LP size to the initial size of the probing node */
6789 	      if( SCIPnodeGetType(tree->path[tree->pathlen-1]) == SCIP_NODETYPE_PROBINGNODE )
6790 	      {
6791 	         tree->pathnlpcols[tree->pathlen-1] = tree->path[tree->pathlen-1]->data.probingnode->ninitialcols;
6792 	         tree->pathnlprows[tree->pathlen-1] = tree->path[tree->pathlen-1]->data.probingnode->ninitialrows;
6793 	      }
6794 	      else
6795 	         assert(SCIPnodeGetType(tree->path[tree->pathlen-1]) == SCIP_NODETYPE_FOCUSNODE);
6796 	      treeCheckPath(tree);
6797 	
6798 	      /* undo LP extensions */
6799 	      SCIP_CALL( SCIPlpShrinkCols(lp, set, ncols) );
6800 	      SCIP_CALL( SCIPlpShrinkRows(lp, blkmem, set, eventqueue, eventfilter, nrows) );
6801 	      tree->probingloadlpistate = TRUE; /* LP state must be reloaded if the next LP is solved */
6802 	
6803 	      /* reset the LP's marked size to the initial size of the LP at the node stored in the path */
6804 	      assert(lp->nrows >= tree->pathnlprows[tree->pathlen-1] || !tree->focuslpconstructed);
6805 	      assert(lp->ncols >= tree->pathnlpcols[tree->pathlen-1] || !tree->focuslpconstructed);
6806 	      SCIPlpSetSizeMark(lp, tree->pathnlprows[tree->pathlen-1], tree->pathnlpcols[tree->pathlen-1]);
6807 	
6808 	      /* if the highest cutoff or repropagation depth is inside the deleted part of the probing path,
6809 	       * reset them to infinity
6810 	       */
6811 	      if( tree->cutoffdepth >= tree->pathlen )
6812 	      {
6813 	         /* apply the pending bound changes */
6814 	         SCIP_CALL( treeApplyPendingBdchgs(tree, reopt, blkmem, set, stat, transprob, origprob, lp, branchcand, eventqueue, cliquetable) );
6815 	
6816 	         /* applying the pending bound changes might have changed the cutoff depth; so the highest cutoff depth might
6817 	          * be outside of the deleted part of the probing path now
6818 	          */
6819 	         if( tree->cutoffdepth >= tree->pathlen )
6820 	            tree->cutoffdepth = INT_MAX;
6821 	      }
6822 	      if( tree->repropdepth >= tree->pathlen )
6823 	         tree->repropdepth = INT_MAX;
6824 	   }
6825 	
6826 	   SCIPsetDebugMsg(set, "probing backtracked to depth %d (%d cols, %d rows)\n", tree->pathlen-1, SCIPlpGetNCols(lp), SCIPlpGetNRows(lp));
6827 	
6828 	   return SCIP_OKAY;
6829 	}
6830 	
6831 	/** undoes all changes to the problem applied in probing up to the given probing depth;
6832 	 *  the changes of the probing node of the given probing depth are the last ones that remain active;
6833 	 *  changes that were applied before calling SCIPtreeCreateProbingNode() cannot be undone
6834 	 */
6835 	SCIP_RETCODE SCIPtreeBacktrackProbing(
6836 	   SCIP_TREE*            tree,               /**< branch and bound tree */
6837 	   SCIP_REOPT*           reopt,              /**< reoptimization data structure */
6838 	   BMS_BLKMEM*           blkmem,             /**< block memory buffers */
6839 	   SCIP_SET*             set,                /**< global SCIP settings */
6840 	   SCIP_STAT*            stat,               /**< problem statistics */
6841 	   SCIP_PROB*            transprob,          /**< transformed problem */
6842 	   SCIP_PROB*            origprob,           /**< original problem */
6843 	   SCIP_LP*              lp,                 /**< current LP data */
6844 	   SCIP_PRIMAL*          primal,             /**< primal data structure */
6845 	   SCIP_BRANCHCAND*      branchcand,         /**< branching candidate storage */
6846 	   SCIP_EVENTQUEUE*      eventqueue,         /**< event queue */
6847 	   SCIP_EVENTFILTER*     eventfilter,        /**< global event filter */
6848 	   SCIP_CLIQUETABLE*     cliquetable,        /**< clique table data structure */
6849 	   int                   probingdepth        /**< probing depth of the node in the probing path that should be reactivated */
6850 	   )
6851 	{
6852 	   assert(tree != NULL);
6853 	   assert(SCIPtreeProbing(tree));
6854 	   assert(0 <= probingdepth && probingdepth <= SCIPtreeGetProbingDepth(tree));
6855 	
6856 	   /* undo the domain and constraint set changes and free the temporary probing nodes below the given probing depth */
6857 	   SCIP_CALL( treeBacktrackProbing(tree, reopt, blkmem, set, stat, transprob, origprob, lp, primal, branchcand,
6858 	         eventqueue, eventfilter, cliquetable, probingdepth) );
6859 	
6860 	   assert(SCIPtreeProbing(tree));
6861 	   assert(SCIPnodeGetType(SCIPtreeGetCurrentNode(tree)) == SCIP_NODETYPE_PROBINGNODE);
6862 	
6863 	   return SCIP_OKAY;
6864 	}
6865 	
6866 	/** switches back from probing to normal operation mode, frees all nodes on the probing path, restores bounds of all
6867 	 *  variables and restores active constraints arrays of focus node
6868 	 */
6869 	SCIP_RETCODE SCIPtreeEndProbing(
6870 	   SCIP_TREE*            tree,               /**< branch and bound tree */
6871 	   SCIP_REOPT*           reopt,              /**< reoptimization data structure */
6872 	   BMS_BLKMEM*           blkmem,             /**< block memory buffers */
6873 	   SCIP_SET*             set,                /**< global SCIP settings */
6874 	   SCIP_MESSAGEHDLR*     messagehdlr,        /**< message handler */
6875 	   SCIP_STAT*            stat,               /**< problem statistics */
6876 	   SCIP_PROB*            transprob,          /**< transformed problem after presolve */
6877 	   SCIP_PROB*            origprob,           /**< original problem */
6878 	   SCIP_LP*              lp,                 /**< current LP data */
6879 	   SCIP_RELAXATION*      relaxation,         /**< global relaxation data */
6880 	   SCIP_PRIMAL*          primal,             /**< Primal LP data */
6881 	   SCIP_BRANCHCAND*      branchcand,         /**< branching candidate storage */
6882 	   SCIP_EVENTQUEUE*      eventqueue,         /**< event queue */
6883 	   SCIP_EVENTFILTER*     eventfilter,        /**< global event filter */
6884 	   SCIP_CLIQUETABLE*     cliquetable         /**< clique table data structure */
6885 	   )
6886 	{
6887 	   assert(tree != NULL);
6888 	   assert(SCIPtreeProbing(tree));
6889 	   assert(tree->probingroot != NULL);
6890 	   assert(tree->focusnode != NULL);
6891 	   assert(SCIPnodeGetType(tree->probingroot) == SCIP_NODETYPE_PROBINGNODE);
6892 	   assert(SCIPnodeGetType(tree->focusnode) == SCIP_NODETYPE_FOCUSNODE
6893 	      || SCIPnodeGetType(tree->focusnode) == SCIP_NODETYPE_REFOCUSNODE);
6894 	   assert(tree->probingroot->parent == tree->focusnode);
6895 	   assert(SCIPnodeGetDepth(tree->probingroot) == SCIPnodeGetDepth(tree->focusnode)+1);
6896 	   assert(tree->pathlen >= 2);
6897 	   assert(SCIPnodeGetType(tree->path[tree->pathlen-1]) == SCIP_NODETYPE_PROBINGNODE);
6898 	   assert(set != NULL);
6899 	
6900 	   /* undo the domain and constraint set changes of the temporary probing nodes and free the probing nodes */
6901 	   SCIP_CALL( treeBacktrackProbing(tree, reopt, blkmem, set, stat, transprob, origprob, lp, primal, branchcand,
6902 	         eventqueue, eventfilter, cliquetable, -1) );
6903 	   assert(tree->probingsumchgdobjs == 0);
6904 	   assert(!tree->probingobjchanged);
6905 	   assert(!lp->divingobjchg);
6906 	   assert(lp->cutoffbound == primal->cutoffbound); /*lint !e777*/
6907 	   assert(SCIPtreeGetCurrentNode(tree) == tree->focusnode);
6908 	   assert(!SCIPtreeProbing(tree));
6909 	
6910 	   /* if the LP was flushed before probing starts, flush it again */
6911 	   if( tree->probinglpwasflushed )
6912 	   {
6913 	      SCIP_CALL( SCIPlpFlush(lp, blkmem, set, transprob, eventqueue) );
6914 	
6915 	      /* if the LP was solved before probing starts, solve it again to restore the LP solution */
6916 	      if( tree->probinglpwassolved )
6917 	      {
6918 	         SCIP_Bool lperror;
6919 	
6920 	         /* reset the LP state before probing started */
6921 	         if( tree->probinglpistate == NULL )
6922 	         {
6923 	            assert(tree->probinglpinorms == NULL);
6924 	            SCIP_CALL( SCIPlpiClearState(lp->lpi) );
6925 	            lp->primalfeasible = (lp->nlpicols == 0 && lp->nlpirows == 0);
6926 	            lp->primalchecked = (lp->nlpicols == 0 && lp->nlpirows == 0);
6927 	            lp->dualfeasible = (lp->nlpicols == 0 && lp->nlpirows == 0);
6928 	            lp->dualchecked = (lp->nlpicols == 0 && lp->nlpirows == 0);
6929 	            lp->solisbasic = FALSE;
6930 	         }
6931 	         else
6932 	         {
6933 	            SCIP_CALL( SCIPlpSetState(lp, blkmem, set, transprob, eventqueue, tree->probinglpistate,
6934 	                  tree->probinglpwasprimfeas, tree->probinglpwasprimchecked, tree->probinglpwasdualfeas,
6935 	                  tree->probinglpwasdualchecked) );
6936 	            SCIP_CALL( SCIPlpFreeState(lp, blkmem, &tree->probinglpistate) );
6937 	
6938 	            if( tree->probinglpinorms != NULL )
6939 	            {
6940 	               SCIP_CALL( SCIPlpSetNorms(lp, blkmem, tree->probinglpinorms) );
6941 	               SCIP_CALL( SCIPlpFreeNorms(lp, blkmem, &tree->probinglpinorms) );
6942 	               tree->probinglpinorms = NULL;
6943 	            }
6944 	         }
6945 	         SCIPlpSetIsRelax(lp, tree->probinglpwasrelax);
6946 	
6947 	         /* resolve LP to reset solution */
6948 	         SCIP_CALL( SCIPlpSolveAndEval(lp, set, messagehdlr, blkmem, stat, eventqueue, eventfilter, transprob, -1LL, FALSE, FALSE, FALSE, &lperror) );
6949 	         if( lperror )
6950 	         {
6951 	            SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
6952 	               "(node %" SCIP_LONGINT_FORMAT ") unresolved numerical troubles while resolving LP %" SCIP_LONGINT_FORMAT " after probing\n",
6953 	               stat->nnodes, stat->nlps);
6954 	            lp->resolvelperror = TRUE;
6955 	            tree->focusnodehaslp = FALSE;
6956 	         }
6957 	         else if( SCIPlpGetSolstat(lp) != SCIP_LPSOLSTAT_OPTIMAL 
6958 	            && SCIPlpGetSolstat(lp) != SCIP_LPSOLSTAT_INFEASIBLE
6959 	            && SCIPlpGetSolstat(lp) != SCIP_LPSOLSTAT_UNBOUNDEDRAY
6960 	            && SCIPlpGetSolstat(lp) != SCIP_LPSOLSTAT_OBJLIMIT )
6961 	         {
6962 	            SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL,
6963 	               "LP was not resolved to a sufficient status after probing\n");
6964 	            lp->resolvelperror = TRUE;
6965 	            tree->focusnodehaslp = FALSE;
6966 	         }
6967 	         else if( tree->focuslpconstructed && SCIPlpIsRelax(lp) && SCIPprobAllColsInLP(transprob, set, lp))
6968 	         {
6969 	            SCIP_CALL( SCIPnodeUpdateLowerboundLP(tree->focusnode, set, stat, tree, transprob, origprob, lp) );
6970 	         }
6971 	      }
6972 	   }
6973 	   else
6974 	      lp->flushed = FALSE;
6975 	
6976 	   assert(tree->probinglpistate == NULL);
6977 	
6978 	   /* if no LP was solved during probing and the LP before probing was not solved, then it should not be solved now */
6979 	   assert(tree->probingsolvedlp || tree->probinglpwassolved || !lp->solved);
6980 	
6981 	   /* if the LP was solved (and hence flushed) before probing, then lp->solved should be TRUE unless we occured an error
6982 	    * during resolving right above
6983 	    */
6984 	   assert(!tree->probinglpwassolved || !tree->probinglpwasflushed || lp->solved || lp->resolvelperror);
6985 	
6986 	   /* if the LP was not solved before probing it should be marked unsolved now; this can occur if a probing LP was
6987 	    * solved in between
6988 	    */
6989 	   if( !tree->probinglpwassolved )
6990 	   {
6991 	      lp->solved = FALSE;
6992 	      lp->lpsolstat = SCIP_LPSOLSTAT_NOTSOLVED;
6993 	   }
6994 	
6995 	   /* if the LP was solved during probing, but had been unsolved before probing started, we discard the LP state */
6996 	   if( set->lp_clearinitialprobinglp && tree->probingsolvedlp && !tree->probinglpwassolved )
6997 	   {
6998 	      SCIPsetDebugMsg(set, "clearing lp state at end of probing mode because LP was initially unsolved\n");
6999 	      SCIP_CALL( SCIPlpiClearState(lp->lpi) );
7000 	   }
7001 	
7002 	   /* if a relaxation was stored before probing, restore it now */
7003 	   if( tree->probdiverelaxstored )
7004 	   {
7005 	      SCIP_CALL( SCIPtreeRestoreRelaxSol(tree, set, relaxation, transprob) );
7006 	   }
7007 	
7008 	   assert(tree->probingobjchanged == SCIPlpDivingObjChanged(lp));
7009 	
7010 	   /* reset flags */
7011 	   tree->probinglpwasflushed = FALSE;
7012 	   tree->probinglpwassolved = FALSE;
7013 	   tree->probingloadlpistate = FALSE;
7014 	   tree->probinglpwasrelax = FALSE;
7015 	   tree->probingsolvedlp = FALSE;
7016 	   tree->sbprobing = FALSE;
7017 	
7018 	   /* inform LP about end of probing mode */
7019 	   SCIP_CALL( SCIPlpEndProbing(lp) );
7020 	
7021 	   /* reset all marked constraints for propagation */
7022 	   SCIP_CALL( SCIPconshdlrsResetPropagationStatus(set, blkmem, set->conshdlrs, set->nconshdlrs) );
7023 	
7024 	   SCIPsetDebugMsg(set, "probing ended in depth %d (LP flushed: %u, solstat: %d)\n", tree->pathlen-1, lp->flushed, SCIPlpGetSolstat(lp));
7025 	
7026 	   return SCIP_OKAY;
7027 	}
7028 	
7029 	/** stores relaxation solution before diving or probing */
7030 	SCIP_RETCODE SCIPtreeStoreRelaxSol(
7031 	   SCIP_TREE*            tree,               /**< branch and bound tree */
7032 	   SCIP_SET*             set,                /**< global SCIP settings */
7033 	   SCIP_RELAXATION*      relaxation,         /**< global relaxation data */
7034 	   SCIP_PROB*            transprob           /**< transformed problem after presolve */
7035 	   )
7036 	{
7037 	   SCIP_VAR** vars;
7038 	   int nvars;
7039 	   int v;
7040 	
7041 	   assert(tree != NULL);
7042 	   assert(set != NULL);
7043 	   assert(relaxation != NULL);
7044 	   assert(transprob != NULL);
7045 	   assert(SCIPrelaxationIsSolValid(relaxation));
7046 	
7047 	   nvars = transprob->nvars;
7048 	   vars = transprob->vars;
7049 	
7050 	   /* check if memory still needs to be allocated or resized */
7051 	   if( tree->probdiverelaxsol == NULL )
7052 	   {
7053 	      SCIP_ALLOC( BMSallocMemoryArray(&(tree->probdiverelaxsol), nvars) );
7054 	      tree->nprobdiverelaxsol = nvars;
7055 	   }
7056 	   else if( nvars > tree->nprobdiverelaxsol )
7057 	   {
7058 	      SCIP_ALLOC( BMSreallocMemoryArray(&tree->probdiverelaxsol, nvars) );
7059 	      tree->nprobdiverelaxsol = nvars;
7060 	   }
7061 	   assert(tree->nprobdiverelaxsol >= nvars);
7062 	
7063 	   /* iterate over all variables to save the relaxation solution */
7064 	   for( v = 0; v < nvars; ++v )
7065 	      tree->probdiverelaxsol[v] = SCIPvarGetRelaxSol(vars[v], set);
7066 	
7067 	   tree->probdiverelaxstored = TRUE;
7068 	   tree->probdiverelaxincludeslp = SCIPrelaxationIsLpIncludedForSol(relaxation);
7069 	
7070 	   return SCIP_OKAY;
7071 	}
7072 	
7073 	/** restores relaxation solution after diving or probing */
7074 	SCIP_RETCODE SCIPtreeRestoreRelaxSol(
7075 	   SCIP_TREE*            tree,               /**< branch and bound tree */
7076 	   SCIP_SET*             set,                /**< global SCIP settings */
7077 	   SCIP_RELAXATION*      relaxation,         /**< global relaxation data */
7078 	   SCIP_PROB*            transprob           /**< transformed problem after presolve */
7079 	   )
7080 	{
7081 	   SCIP_VAR** vars;
7082 	   int nvars;
7083 	   int v;
7084 	
7085 	   assert(tree != NULL);
7086 	   assert(set != NULL);
7087 	   assert(tree->probdiverelaxstored);
7088 	   assert(tree->probdiverelaxsol != NULL);
7089 	
7090 	   nvars = transprob->nvars;
7091 	   vars = transprob->vars;
7092 	   assert( nvars <= tree->nprobdiverelaxsol );
7093 	
7094 	   /* iterate over all variables to restore the relaxation solution */
7095 	   for( v = 0; v < nvars; ++v )
7096 	   {
7097 	      SCIP_CALL( SCIPvarSetRelaxSol(vars[v], set, relaxation, tree->probdiverelaxsol[v], TRUE) );
7098 	   }
7099 	
7100 	   tree->probdiverelaxstored = FALSE;
7101 	   SCIPrelaxationSetSolValid(relaxation, TRUE, tree->probdiverelaxincludeslp);
7102 	
7103 	   return SCIP_OKAY;
7104 	}
7105 	
7106 	/** gets the best child of the focus node w.r.t. the node selection priority assigned by the branching rule */
7107 	SCIP_NODE* SCIPtreeGetPrioChild(
7108 	   SCIP_TREE*            tree                /**< branch and bound tree */
7109 	   )
7110 	{
7111 	   SCIP_NODE* bestnode;
7112 	   SCIP_Real bestprio;
7113 	   int i;
7114 	
7115 	   assert(tree != NULL);
7116 	
7117 	   bestnode = NULL;
7118 	   bestprio = SCIP_REAL_MIN;
7119 	   for( i = 0; i < tree->nchildren; ++i )
7120 	   {
7121 	      if( tree->childrenprio[i] > bestprio )
7122 	      {
7123 	         bestnode = tree->children[i];
7124 	         bestprio = tree->childrenprio[i];
7125 	      }
7126 	   }
7127 	   assert((tree->nchildren == 0) == (bestnode == NULL));
7128 	
7129 	   return bestnode;
7130 	}
7131 	
7132 	/** gets the best sibling of the focus node w.r.t. the node selection priority assigned by the branching rule */
7133 	SCIP_NODE* SCIPtreeGetPrioSibling(
7134 	   SCIP_TREE*            tree                /**< branch and bound tree */
7135 	   )
7136 	{
7137 	   SCIP_NODE* bestnode;
7138 	   SCIP_Real bestprio;
7139 	   int i;
7140 	
7141 	   assert(tree != NULL);
7142 	
7143 	   bestnode = NULL;
7144 	   bestprio = SCIP_REAL_MIN;
7145 	   for( i = 0; i < tree->nsiblings; ++i )
7146 	   {
7147 	      if( tree->siblingsprio[i] > bestprio )
7148 	      {
7149 	         bestnode = tree->siblings[i];
7150 	         bestprio = tree->siblingsprio[i];
7151 	      }
7152 	   }
7153 	   assert((tree->nsiblings == 0) == (bestnode == NULL));
7154 	
7155 	   return bestnode;
7156 	}
7157 	
7158 	/** gets the best child of the focus node w.r.t. the node selection strategy */
7159 	SCIP_NODE* SCIPtreeGetBestChild(
7160 	   SCIP_TREE*            tree,               /**< branch and bound tree */
7161 	   SCIP_SET*             set                 /**< global SCIP settings */
7162 	   )
7163 	{
7164 	   SCIP_NODESEL* nodesel;
7165 	   SCIP_NODE* bestnode;
7166 	   int i;
7167 	
7168 	   assert(tree != NULL);
7169 	
7170 	   nodesel = SCIPnodepqGetNodesel(tree->leaves);
7171 	   assert(nodesel != NULL);
7172 	
7173 	   bestnode = NULL;
7174 	   for( i = 0; i < tree->nchildren; ++i )
7175 	   {
7176 	      if( bestnode == NULL || SCIPnodeselCompare(nodesel, set, tree->children[i], bestnode) < 0 )
7177 	      {
7178 	         bestnode = tree->children[i];
7179 	      }
7180 	   }
7181 	
7182 	   return bestnode;
7183 	}
7184 	
7185 	/** gets the best sibling of the focus node w.r.t. the node selection strategy */
7186 	SCIP_NODE* SCIPtreeGetBestSibling(
7187 	   SCIP_TREE*            tree,               /**< branch and bound tree */
7188 	   SCIP_SET*             set                 /**< global SCIP settings */
7189 	   )
7190 	{
7191 	   SCIP_NODESEL* nodesel;
7192 	   SCIP_NODE* bestnode;
7193 	   int i;
7194 	
7195 	   assert(tree != NULL);
7196 	
7197 	   nodesel = SCIPnodepqGetNodesel(tree->leaves);
7198 	   assert(nodesel != NULL);
7199 	
7200 	   bestnode = NULL;
7201 	   for( i = 0; i < tree->nsiblings; ++i )
7202 	   {
7203 	      if( bestnode == NULL || SCIPnodeselCompare(nodesel, set, tree->siblings[i], bestnode) < 0 )
7204 	      {
7205 	         bestnode = tree->siblings[i];
7206 	      }
7207 	   }
7208 	
7209 	   return bestnode;
7210 	}
7211 	
7212 	/** gets the best leaf from the node queue w.r.t. the node selection strategy */
7213 	SCIP_NODE* SCIPtreeGetBestLeaf(
7214 	   SCIP_TREE*            tree                /**< branch and bound tree */
7215 	   )
7216 	{
7217 	   assert(tree != NULL);
7218 	
7219 	   return SCIPnodepqFirst(tree->leaves);
7220 	}
7221 	
7222 	/** gets the best node from the tree (child, sibling, or leaf) w.r.t. the node selection strategy */
7223 	SCIP_NODE* SCIPtreeGetBestNode(
7224 	   SCIP_TREE*            tree,               /**< branch and bound tree */
7225 	   SCIP_SET*             set                 /**< global SCIP settings */
7226 	   )
7227 	{
7228 	   SCIP_NODESEL* nodesel;
7229 	   SCIP_NODE* bestchild;
7230 	   SCIP_NODE* bestsibling;
7231 	   SCIP_NODE* bestleaf;
7232 	   SCIP_NODE* bestnode;
7233 	
7234 	   assert(tree != NULL);
7235 	
7236 	   nodesel = SCIPnodepqGetNodesel(tree->leaves);
7237 	   assert(nodesel != NULL);
7238 	
7239 	   /* get the best child, sibling, and leaf */
7240 	   bestchild = SCIPtreeGetBestChild(tree, set);
7241 	   bestsibling = SCIPtreeGetBestSibling(tree, set);
7242 	   bestleaf = SCIPtreeGetBestLeaf(tree);
7243 	
7244 	   /* return the best of the three */
7245 	   bestnode = bestchild;
7246 	   if( bestsibling != NULL && (bestnode == NULL || SCIPnodeselCompare(nodesel, set, bestsibling, bestnode) < 0) )
7247 	      bestnode = bestsibling;
7248 	   if( bestleaf != NULL && (bestnode == NULL || SCIPnodeselCompare(nodesel, set, bestleaf, bestnode) < 0) )
7249 	      bestnode = bestleaf;
7250 	
7251 	   assert(SCIPtreeGetNLeaves(tree) == 0 || bestnode != NULL);
7252 	
7253 	   return bestnode;
7254 	}
7255 	
7256 	/** gets the minimal lower bound of all nodes in the tree */
7257 	SCIP_Real SCIPtreeGetLowerbound(
7258 	   SCIP_TREE*            tree,               /**< branch and bound tree */
7259 	   SCIP_SET*             set                 /**< global SCIP settings */
7260 	   )
7261 	{
7262 	   SCIP_Real lowerbound;
7263 	   int i;
7264 	
7265 	   assert(tree != NULL);
7266 	   assert(set != NULL);
7267 	
7268 	   /* get the lower bound from the queue */
7269 	   lowerbound = SCIPnodepqGetLowerbound(tree->leaves, set);
7270 	
7271 	   /* compare lower bound with children */
7272 	   for( i = 0; i < tree->nchildren; ++i )
7273 	   {
7274 	      assert(tree->children[i] != NULL);
7275 	      lowerbound = MIN(lowerbound, tree->children[i]->lowerbound); 
7276 	   }
7277 	
7278 	   /* compare lower bound with siblings */
7279 	   for( i = 0; i < tree->nsiblings; ++i )
7280 	   {
7281 	      assert(tree->siblings[i] != NULL);
7282 	      lowerbound = MIN(lowerbound, tree->siblings[i]->lowerbound); 
7283 	   }
7284 	
7285 	   /* compare lower bound with focus node */
7286 	   if( tree->focusnode != NULL )
7287 	   {
7288 	      lowerbound = MIN(lowerbound, tree->focusnode->lowerbound);
7289 	   }
7290 	
7291 	   return lowerbound;
7292 	}
7293 	
7294 	/** gets the node with minimal lower bound of all nodes in the tree (child, sibling, or leaf) */
7295 	SCIP_NODE* SCIPtreeGetLowerboundNode(
7296 	   SCIP_TREE*            tree,               /**< branch and bound tree */
7297 	   SCIP_SET*             set                 /**< global SCIP settings */
7298 	   )
7299 	{
7300 	   SCIP_NODE* lowerboundnode;
7301 	   SCIP_Real lowerbound;
7302 	   SCIP_Real bestprio;
7303 	   int i;
7304 	
7305 	   assert(tree != NULL);
7306 	   assert(set != NULL);
7307 	
7308 	   /* get the lower bound from the queue */
7309 	   lowerboundnode = SCIPnodepqGetLowerboundNode(tree->leaves, set);
7310 	   lowerbound = lowerboundnode != NULL ? lowerboundnode->lowerbound : SCIPsetInfinity(set);
7311 	   bestprio = -SCIPsetInfinity(set);
7312 	
7313 	   /* compare lower bound with children */
7314 	   for( i = 0; i < tree->nchildren; ++i )
7315 	   {
7316 	      assert(tree->children[i] != NULL);
7317 	      if( SCIPsetIsLE(set, tree->children[i]->lowerbound, lowerbound) )
7318 	      {
7319 	         if( SCIPsetIsLT(set, tree->children[i]->lowerbound, lowerbound) || tree->childrenprio[i] > bestprio )
7320 	         {
7321 	            lowerboundnode = tree->children[i]; 
7322 	            lowerbound = lowerboundnode->lowerbound; 
7323 	            bestprio = tree->childrenprio[i];
7324 	         }
7325 	      }
7326 	   }
7327 	
7328 	   /* compare lower bound with siblings */
7329 	   for( i = 0; i < tree->nsiblings; ++i )
7330 	   {
7331 	      assert(tree->siblings[i] != NULL);
7332 	      if( SCIPsetIsLE(set, tree->siblings[i]->lowerbound, lowerbound) )
7333 	      {
7334 	         if( SCIPsetIsLT(set, tree->siblings[i]->lowerbound, lowerbound) || tree->siblingsprio[i] > bestprio )
7335 	         {
7336 	            lowerboundnode = tree->siblings[i]; 
7337 	            lowerbound = lowerboundnode->lowerbound; 
7338 	            bestprio = tree->siblingsprio[i];
7339 	         }
7340 	      }
7341 	   }
7342 	
7343 	   return lowerboundnode;
7344 	}
7345 	
7346 	/** gets the average lower bound of all nodes in the tree */
7347 	SCIP_Real SCIPtreeGetAvgLowerbound(
7348 	   SCIP_TREE*            tree,               /**< branch and bound tree */
7349 	   SCIP_Real             cutoffbound         /**< global cutoff bound */
7350 	   )
7351 	{
7352 	   SCIP_Real lowerboundsum;
7353 	   int nnodes;
7354 	   int i;
7355 	
7356 	   assert(tree != NULL);
7357 	
7358 	   /* get sum of lower bounds from nodes in the queue */
7359 	   lowerboundsum = SCIPnodepqGetLowerboundSum(tree->leaves);
7360 	   nnodes = SCIPtreeGetNLeaves(tree);
7361 	
7362 	   /* add lower bound of focus node */
7363 	   if( tree->focusnode != NULL && tree->focusnode->lowerbound < cutoffbound )
7364 	   {
7365 	      lowerboundsum += tree->focusnode->lowerbound;
7366 	      nnodes++;
7367 	   }
7368 	
7369 	   /* add lower bounds of siblings */
7370 	   for( i = 0; i < tree->nsiblings; ++i )
7371 	   {
7372 	      assert(tree->siblings[i] != NULL);
7373 	      lowerboundsum += tree->siblings[i]->lowerbound;
7374 	   }
7375 	   nnodes += tree->nsiblings;
7376 	
7377 	   /* add lower bounds of children */
7378 	   for( i = 0; i < tree->nchildren; ++i )
7379 	   {
7380 	      assert(tree->children[i] != NULL);
7381 	      lowerboundsum += tree->children[i]->lowerbound;
7382 	   }
7383 	   nnodes += tree->nchildren;
7384 	
7385 	   return nnodes == 0 ? 0.0 : lowerboundsum/nnodes;
7386 	}
7387 	
7388 	
7389 	
7390 	
7391 	/*
7392 	 * simple functions implemented as defines
7393 	 */
7394 	
7395 	/* In debug mode, the following methods are implemented as function calls to ensure
7396 	 * type validity.
7397 	 * In optimized mode, the methods are implemented as defines to improve performance.
7398 	 * However, we want to have them in the library anyways, so we have to undef the defines.
7399 	 */
7400 	
7401 	#undef SCIPnodeGetType
7402 	#undef SCIPnodeGetNumber
7403 	#undef SCIPnodeGetDepth
7404 	#undef SCIPnodeGetLowerbound
7405 	#undef SCIPnodeGetEstimate
7406 	#undef SCIPnodeGetDomchg
7407 	#undef SCIPnodeGetParent
7408 	#undef SCIPnodeGetConssetchg
7409 	#undef SCIPnodeIsActive
7410 	#undef SCIPnodeIsPropagatedAgain
7411 	#undef SCIPtreeGetNLeaves
7412 	#undef SCIPtreeGetNChildren
7413 	#undef SCIPtreeGetNSiblings
7414 	#undef SCIPtreeGetNNodes
7415 	#undef SCIPtreeIsPathComplete
7416 	#undef SCIPtreeProbing
7417 	#undef SCIPtreeGetProbingRoot
7418 	#undef SCIPtreeGetProbingDepth
7419 	#undef SCIPtreeGetFocusNode
7420 	#undef SCIPtreeGetFocusDepth
7421 	#undef SCIPtreeHasFocusNodeLP
7422 	#undef SCIPtreeSetFocusNodeLP 
7423 	#undef SCIPtreeIsFocusNodeLPConstructed
7424 	#undef SCIPtreeInRepropagation
7425 	#undef SCIPtreeGetCurrentNode
7426 	#undef SCIPtreeGetCurrentDepth
7427 	#undef SCIPtreeHasCurrentNodeLP
7428 	#undef SCIPtreeGetEffectiveRootDepth
7429 	#undef SCIPtreeGetRootNode
7430 	#undef SCIPtreeProbingObjChanged
7431 	#undef SCIPtreeMarkProbingObjChanged
7432 	
7433 	/** gets the type of the node */
7434 	SCIP_NODETYPE SCIPnodeGetType(
7435 	   SCIP_NODE*            node                /**< node */
7436 	   )
7437 	{
7438 	   assert(node != NULL);
7439 	
7440 	   return (SCIP_NODETYPE)(node->nodetype);
7441 	}
7442 	
7443 	/** gets successively assigned number of the node */
7444 	SCIP_Longint SCIPnodeGetNumber(
7445 	   SCIP_NODE*            node                /**< node */
7446 	   )
7447 	{
7448 	   assert(node != NULL);
7449 	
7450 	   return node->number;
7451 	}
7452 	
7453 	/** gets the depth of the node */
7454 	int SCIPnodeGetDepth(
7455 	   SCIP_NODE*            node                /**< node */
7456 	   )
7457 	{
7458 	   assert(node != NULL);
7459 	
7460 	   return (int) node->depth;
7461 	}
7462 	
7463 	/** gets the lower bound of the node */
7464 	SCIP_Real SCIPnodeGetLowerbound(
7465 	   SCIP_NODE*            node                /**< node */
7466 	   )
7467 	{
7468 	   assert(node != NULL);
7469 	
7470 	   return node->lowerbound;
7471 	}
7472 	
7473 	/** gets the estimated value of the best feasible solution in subtree of the node */
7474 	SCIP_Real SCIPnodeGetEstimate(
7475 	   SCIP_NODE*            node                /**< node */
7476 	   )
7477 	{
7478 	   assert(node != NULL);
7479 	
7480 	   return node->estimate;
7481 	}
7482 	
7483 	/** gets the reoptimization type of this node */
7484 	SCIP_REOPTTYPE SCIPnodeGetReopttype(
7485 	   SCIP_NODE*            node                /**< node */
7486 	   )
7487 	{
7488 	   assert(node != NULL);
7489 	
7490 	   return (SCIP_REOPTTYPE)node->reopttype;
7491 	}
7492 	
7493 	/** sets the reoptimization type of this node */
7494 	void SCIPnodeSetReopttype(
7495 	   SCIP_NODE*            node,               /**< node */
7496 	   SCIP_REOPTTYPE        reopttype           /**< reoptimization type */
7497 	   )
7498 	{
7499 	   assert(node != NULL);
7500 	   assert(reopttype == SCIP_REOPTTYPE_NONE
7501 	       || reopttype == SCIP_REOPTTYPE_TRANSIT
7502 	       || reopttype == SCIP_REOPTTYPE_INFSUBTREE
7503 	       || reopttype == SCIP_REOPTTYPE_STRBRANCHED
7504 	       || reopttype == SCIP_REOPTTYPE_LOGICORNODE
7505 	       || reopttype == SCIP_REOPTTYPE_LEAF
7506 	       || reopttype == SCIP_REOPTTYPE_PRUNED
7507 	       || reopttype == SCIP_REOPTTYPE_FEASIBLE);
7508 	
7509 	   node->reopttype = (unsigned int) reopttype;
7510 	}
7511 	
7512 	/** gets the unique id to identify the node during reoptimization; the id is 0 if the node is the root or not part of
7513 	 * the reoptimization tree
7514 	 */
7515 	unsigned int SCIPnodeGetReoptID(
7516 	   SCIP_NODE*            node                /**< node */
7517 	   )
7518 	{
7519 	   assert(node != NULL);
7520 	
7521 	   return node->reoptid; /*lint !e732*/
7522 	}
7523 	
7524 	/** set a unique id to identify the node during reoptimization */
7525 	void SCIPnodeSetReoptID(
7526 	   SCIP_NODE*            node,               /**< node */
7527 	   unsigned int          id                  /**< unique id */
7528 	   )
7529 	{
7530 	   assert(node != NULL);
7531 	   assert(id <= 536870911); /* id has only 29 bits and needs to be smaller than 2^29 */
7532 	
7533 	   node->reoptid = id;
7534 	}
7535 	
7536 	/** gets the domain change information of the node, i.e., the information about the differences in the
7537 	 *  variables domains to the parent node
7538 	 */
7539 	SCIP_DOMCHG* SCIPnodeGetDomchg(
7540 	   SCIP_NODE*            node                /**< node */
7541 	   )
7542 	{
7543 	   assert(node != NULL);
7544 	
7545 	   return node->domchg;
7546 	}
7547 	
7548 	/** counts the number of bound changes due to branching, constraint propagation, and propagation */
7549 	void SCIPnodeGetNDomchg(
7550 	   SCIP_NODE*            node,               /**< node */
7551 	   int*                  nbranchings,        /**< pointer to store number of branchings (or NULL if not needed) */
7552 	   int*                  nconsprop,          /**< pointer to store number of constraint propagations (or NULL if not needed) */
7553 	   int*                  nprop               /**< pointer to store number of propagations (or NULL if not needed) */
7554 	   )
7555 	{  /*lint --e{641}*/
7556 	   SCIP_Bool count_branchings;
7557 	   SCIP_Bool count_consprop;
7558 	   SCIP_Bool count_prop;
7559 	   int i;
7560 	
7561 	   assert(node != NULL);
7562 	
7563 	   count_branchings = (nbranchings != NULL);
7564 	   count_consprop = (nconsprop != NULL);
7565 	   count_prop = (nprop != NULL);
7566 	
7567 	   /* set counter to zero */
7568 	   if( count_branchings )
7569 	      *nbranchings = 0;
7570 	   if( count_consprop )
7571 	      *nconsprop = 0;
7572 	   if( count_prop )
7573 	      *nprop = 0;
7574 	
7575 	   if( node->domchg != NULL )
7576 	   {
7577 	      for( i = 0; i < (int) node->domchg->domchgbound.nboundchgs; i++ )
7578 	      {
7579 	         if( count_branchings && node->domchg->domchgbound.boundchgs[i].boundchgtype == SCIP_BOUNDCHGTYPE_BRANCHING )
7580 	            (*nbranchings)++; /*lint !e413*/
7581 	         else if( count_consprop && node->domchg->domchgbound.boundchgs[i].boundchgtype == SCIP_BOUNDCHGTYPE_CONSINFER )
7582 	            (*nconsprop)++; /*lint !e413*/
7583 	         else if( count_prop && node->domchg->domchgbound.boundchgs[i].boundchgtype == SCIP_BOUNDCHGTYPE_PROPINFER )
7584 	            (*nprop)++; /*lint !e413*/
7585 	      }
7586 	   }
7587 	}
7588 	
7589 	/* return the number of bound changes based on dual information.
7590 	 *
7591 	 * currently, this methods works only for bound changes made by strong branching on binary variables. we need this
7592 	 * method to ensure optimality within reoptimization.
7593 	 *
7594 	 * since the bound changes made by strong branching are stored as SCIP_BOUNDCHGTYPE_CONSINFER or SCIP_BOUNDCHGTYPE_PROPINFER
7595 	 * with no constraint or propagator, resp., we are are interested in bound changes with these attributes.
7596 	 *
7597 	 * all bound changes of type SCIP_BOUNDCHGTYPE_BRANCHING are stored in the beginning of the bound change array, afterwards,
7598 	 * we can find the other two types. thus, we start the search at the end of the list and stop when reaching the first
7599 	 * bound change of type SCIP_BOUNDCHGTYPE_BRANCHING.
7600 	 */
7601 	int SCIPnodeGetNDualBndchgs(
7602 	   SCIP_NODE*            node                /**< node */
7603 	   )
7604 	{  /*lint --e{641}*/
7605 	   SCIP_BOUNDCHG* boundchgs;
7606 	   int i;
7607 	   int nboundchgs;
7608 	   int npseudobranchvars;
7609 	
7610 	   assert(node != NULL);
7611 	
7612 	   if( node->domchg == NULL )
7613 	      return 0;
7614 	
7615 	   nboundchgs = (int)node->domchg->domchgbound.nboundchgs;
7616 	   boundchgs = node->domchg->domchgbound.boundchgs;
7617 	
7618 	   npseudobranchvars = 0;
7619 	
7620 	   assert(boundchgs != NULL);
7621 	   assert(nboundchgs >= 0);
7622 	
7623 	   /* count the number of pseudo-branching decisions; pseudo-branching decisions have to be in the ending of the bound change
7624 	    * array
7625 	    */
7626 	   for( i = nboundchgs-1; i >= 0; i--)
7627 	   {
7628 	      SCIP_Bool isint;
7629 	
7630 	      isint = boundchgs[i].var->vartype == SCIP_VARTYPE_BINARY || boundchgs[i].var->vartype == SCIP_VARTYPE_INTEGER
7631 	           || boundchgs[i].var->vartype == SCIP_VARTYPE_IMPLINT;
7632 	
7633 	      if( isint && ((boundchgs[i].boundchgtype == SCIP_BOUNDCHGTYPE_CONSINFER
7634 	            && boundchgs[i].data.inferencedata.reason.cons == NULL)
7635 	        || (boundchgs[i].boundchgtype == SCIP_BOUNDCHGTYPE_PROPINFER
7636 	            && boundchgs[i].data.inferencedata.reason.prop == NULL)) )
7637 	         npseudobranchvars++;
7638 	      else if( boundchgs[i].boundchgtype == SCIP_BOUNDCHGTYPE_BRANCHING )
7639 	         break;
7640 	   }
7641 	
7642 	   return npseudobranchvars;
7643 	}
7644 	
7645 	/** returns the set of variable branchings that were performed in the parent node to create this node */
7646 	void SCIPnodeGetDualBoundchgs(
7647 	   SCIP_NODE*            node,               /**< node data */
7648 	   SCIP_VAR**            vars,               /**< array of variables on which the bound change is based on dual information */
7649 	   SCIP_Real*            bounds,             /**< array of bounds which are based on dual information */
7650 	   SCIP_BOUNDTYPE*       boundtypes,         /**< array of boundtypes which are based on dual information */
7651 	   int*                  nvars,              /**< number of variables on which the bound change is based on dual information
7652 	                                              *   if this is larger than the array size, arrays should be reallocated and method
7653 	                                              *   should be called again */
7654 	   int                   varssize            /**< available slots in arrays */
7655 	   )
7656 	{  /*lint --e{641}*/
7657 	   SCIP_BOUNDCHG* boundchgs;
7658 	   int nboundchgs;
7659 	   int i;
7660 	
7661 	   assert(node != NULL);
7662 	   assert(vars != NULL);
7663 	   assert(bounds != NULL);
7664 	   assert(boundtypes != NULL);
7665 	   assert(nvars != NULL);
7666 	   assert(varssize >= 0);
7667 	
7668 	   (*nvars) = 0;
7669 	
7670 	   if( SCIPnodeGetDepth(node) == 0 || node->domchg == NULL )
7671 	      return;
7672 	
7673 	   nboundchgs = (int)node->domchg->domchgbound.nboundchgs;
7674 	   boundchgs = node->domchg->domchgbound.boundchgs;
7675 	
7676 	   assert(boundchgs != NULL);
7677 	   assert(nboundchgs >= 0);
7678 	
7679 	   /* count the number of pseudo-branching decisions; pseudo-branching decisions have to be in the ending of the bound change
7680 	    * array
7681 	    */
7682 	   for( i = nboundchgs-1; i >= 0; i--)
7683 	   {
7684 	      if( boundchgs[i].var->vartype == SCIP_VARTYPE_BINARY || boundchgs[i].var->vartype == SCIP_VARTYPE_INTEGER
7685 	       || boundchgs[i].var->vartype == SCIP_VARTYPE_IMPLINT )
7686 	      {
7687 	         if( (boundchgs[i].boundchgtype == SCIP_BOUNDCHGTYPE_CONSINFER
7688 	               && boundchgs[i].data.inferencedata.reason.cons == NULL)
7689 	          || (boundchgs[i].boundchgtype == SCIP_BOUNDCHGTYPE_PROPINFER
7690 	                && boundchgs[i].data.inferencedata.reason.prop == NULL) )
7691 	            (*nvars)++;
7692 	         else if( boundchgs[i].boundchgtype == SCIP_BOUNDCHGTYPE_BRANCHING )
7693 	            break;
7694 	      }
7695 	   }
7696 	
7697 	   /* if the arrays have enough space store the branching decisions */
7698 	   if( varssize >= *nvars )
7699 	   {
7700 	      int j;
7701 	      j = 0;
7702 	      for( i = i+1; i < nboundchgs; i++)
7703 	      {
7704 	         if( boundchgs[i].var->vartype == SCIP_VARTYPE_BINARY || boundchgs[i].var->vartype == SCIP_VARTYPE_INTEGER
7705 	          || boundchgs[i].var->vartype == SCIP_VARTYPE_IMPLINT )
7706 	         {
7707 	            assert( boundchgs[i].boundchgtype != SCIP_BOUNDCHGTYPE_BRANCHING );
7708 	            if( (boundchgs[i].boundchgtype == SCIP_BOUNDCHGTYPE_CONSINFER
7709 	                  && boundchgs[i].data.inferencedata.reason.cons == NULL)
7710 	             || (boundchgs[i].boundchgtype == SCIP_BOUNDCHGTYPE_PROPINFER
7711 	                  && boundchgs[i].data.inferencedata.reason.prop == NULL) )
7712 	            {
7713 	               vars[j] = boundchgs[i].var;
7714 	               bounds[j] = boundchgs[i].newbound;
7715 	               boundtypes[j] = (SCIP_BOUNDTYPE) boundchgs[i].boundtype;
7716 	               j++;
7717 	            }
7718 	         }
7719 	      }
7720 	   }
7721 	}
7722 	
7723 	/** gets the parent node of a node in the branch-and-bound tree, if any */
7724 	SCIP_NODE* SCIPnodeGetParent(
7725 	   SCIP_NODE*            node                /**< node */
7726 	   )
7727 	{
7728 	   assert(node != NULL);
7729 	
7730 	   return node->parent;
7731 	}
7732 	
7733 	/** returns the set of variable branchings that were performed in the parent node to create this node */
7734 	void SCIPnodeGetParentBranchings(
7735 	   SCIP_NODE*            node,               /**< node data */
7736 	   SCIP_VAR**            branchvars,         /**< array of variables on which the branching has been performed in the parent node */
7737 	   SCIP_Real*            branchbounds,       /**< array of bounds which the branching in the parent node set */
7738 	   SCIP_BOUNDTYPE*       boundtypes,         /**< array of boundtypes which the branching in the parent node set */
7739 	   int*                  nbranchvars,        /**< number of variables on which branching has been performed in the parent node
7740 	                                              *   if this is larger than the array size, arrays should be reallocated and method
7741 	                                              *   should be called again */
7742 	   int                   branchvarssize      /**< available slots in arrays */
7743 	   )
7744 	{
7745 	   SCIP_BOUNDCHG* boundchgs;
7746 	   int nboundchgs;
7747 	   int i;
7748 	
7749 	   assert(node != NULL);
7750 	   assert(branchvars != NULL);
7751 	   assert(branchbounds != NULL);
7752 	   assert(boundtypes != NULL);
7753 	   assert(nbranchvars != NULL);
7754 	   assert(branchvarssize >= 0);
7755 	
7756 	   (*nbranchvars) = 0;
7757 	
7758 	   if( SCIPnodeGetDepth(node) == 0 || node->domchg == NULL )
7759 	      return;
7760 	
7761 	   nboundchgs = (int)node->domchg->domchgbound.nboundchgs;
7762 	   boundchgs = node->domchg->domchgbound.boundchgs;
7763 	
7764 	   assert(boundchgs != NULL);
7765 	   assert(nboundchgs >= 0);
7766 	
7767 	   /* count the number of branching decisions; branching decisions have to be in the beginning of the bound change
7768 	    * array
7769 	    */
7770 	   for( i = 0; i < nboundchgs; i++)
7771 	   {
7772 	      if( boundchgs[i].boundchgtype != SCIP_BOUNDCHGTYPE_BRANCHING ) /*lint !e641*/
7773 	         break;
7774 	
7775 	      (*nbranchvars)++;
7776 	   }
7777 	
7778 	#ifndef NDEBUG
7779 	   /* check that the remaining bound change are no branching decisions */
7780 	   for( ; i < nboundchgs; i++)
7781 	      assert(boundchgs[i].boundchgtype != SCIP_BOUNDCHGTYPE_BRANCHING); /*lint !e641*/
7782 	#endif
7783 	
7784 	   /* if the arrays have enough space store the branching decisions */
7785 	   if( branchvarssize >= *nbranchvars )
7786 	   {
7787 	      for( i = 0; i < *nbranchvars; i++)
7788 	      {
7789 	         assert( boundchgs[i].boundchgtype == SCIP_BOUNDCHGTYPE_BRANCHING ); /*lint !e641*/
7790 	         branchvars[i] = boundchgs[i].var;
7791 	         boundtypes[i] = (SCIP_BOUNDTYPE) boundchgs[i].boundtype;
7792 	         branchbounds[i] = boundchgs[i].newbound;
7793 	      }
7794 	   }
7795 	}
7796 	
7797 	/** returns the set of variable branchings that were performed in all ancestor nodes (nodes on the path to the root) to create this node */
7798 	void SCIPnodeGetAncestorBranchings(
7799 	   SCIP_NODE*            node,               /**< node data */
7800 	   SCIP_VAR**            branchvars,         /**< array of variables on which the branchings has been performed in all ancestors */
7801 	   SCIP_Real*            branchbounds,       /**< array of bounds which the branchings in all ancestors set */
7802 	   SCIP_BOUNDTYPE*       boundtypes,         /**< array of boundtypes which the branchings in all ancestors set */
7803 	   int*                  nbranchvars,        /**< number of variables on which branchings have been performed in all ancestors
7804 	                                              *   if this is larger than the array size, arrays should be reallocated and method
7805 	                                              *   should be called again */
7806 	   int                   branchvarssize      /**< available slots in arrays */
7807 	   )
7808 	{
7809 	   assert(node != NULL);
7810 	   assert(branchvars != NULL);
7811 	   assert(branchbounds != NULL);
7812 	   assert(boundtypes != NULL);
7813 	   assert(nbranchvars != NULL);
7814 	   assert(branchvarssize >= 0);
7815 	
7816 	   (*nbranchvars) = 0;
7817 	
7818 	   while( SCIPnodeGetDepth(node) != 0 )
7819 	   {
7820 	      int nodenbranchvars;
7821 	      int start;
7822 	      int size;
7823 	
7824 	      start = *nbranchvars < branchvarssize - 1 ? *nbranchvars : branchvarssize - 1;
7825 	      size = *nbranchvars > branchvarssize ? 0 : branchvarssize-(*nbranchvars);
7826 	
7827 	      SCIPnodeGetParentBranchings(node, &branchvars[start], &branchbounds[start], &boundtypes[start], &nodenbranchvars, size);
7828 	      *nbranchvars += nodenbranchvars;
7829 	
7830 	      node = node->parent;
7831 	   }
7832 	}
7833 	
7834 	/** returns the set of variable branchings that were performed between the given @p node and the given @p parent node. */
7835 	void SCIPnodeGetAncestorBranchingsPart(
7836 	   SCIP_NODE*            node,               /**< node data */
7837 	   SCIP_NODE*            parent,             /**< node data of the last ancestor node */
7838 	   SCIP_VAR**            branchvars,         /**< array of variables on which the branchings has been performed in all ancestors */
7839 	   SCIP_Real*            branchbounds,       /**< array of bounds which the branchings in all ancestors set */
7840 	   SCIP_BOUNDTYPE*       boundtypes,         /**< array of boundtypes which the branchings in all ancestors set */
7841 	   int*                  nbranchvars,        /**< number of variables on which branchings have been performed in all ancestors
7842 	                                              *   if this is larger than the array size, arrays should be reallocated and method
7843 	                                              *   should be called again */
7844 	   int                   branchvarssize      /**< available slots in arrays */
7845 	   )
7846 	{
7847 	   assert(node != NULL);
7848 	   assert(parent != NULL);
7849 	   assert(branchvars != NULL);
7850 	   assert(branchbounds != NULL);
7851 	   assert(boundtypes != NULL);
7852 	   assert(nbranchvars != NULL);
7853 	   assert(branchvarssize >= 0);
7854 	
7855 	   (*nbranchvars) = 0;
7856 	
7857 	   while( node != parent )
7858 	   {
7859 	      int nodenbranchvars;
7860 	      int start;
7861 	      int size;
7862 	
7863 	      start = *nbranchvars < branchvarssize - 1 ? *nbranchvars : branchvarssize - 1;
7864 	      size = *nbranchvars > branchvarssize ? 0 : branchvarssize-(*nbranchvars);
7865 	
7866 	      SCIPnodeGetParentBranchings(node, &branchvars[start], &branchbounds[start], &boundtypes[start], &nodenbranchvars, size);
7867 	      *nbranchvars += nodenbranchvars;
7868 	
7869 	      node = node->parent;
7870 	   }
7871 	}
7872 	
7873 	/** return all bound changes based on constraint propagation; stop saving the bound changes if we reach a branching
7874 	 *  decision based on a dual information
7875 	 */
7876 	void SCIPnodeGetConsProps(
7877 	   SCIP_NODE*            node,               /**< node */
7878 	   SCIP_VAR**            vars,               /**< array of variables on which constraint propagation triggers a bound change */
7879 	   SCIP_Real*            varbounds,          /**< array of bounds set by constraint propagation */
7880 	   SCIP_BOUNDTYPE*       varboundtypes,      /**< array of boundtypes set by constraint propagation */
7881 	   int*                  nconspropvars,      /**< number of variables on which constraint propagation triggers a bound change
7882 	                                              *   if this is larger than the array size, arrays should be reallocated and method
7883 	                                              *   should be called again */
7884 	   int                   conspropvarssize    /**< available slots in arrays */
7885 	   )
7886 	{  /*lint --e{641}*/
7887 	   SCIP_BOUNDCHG* boundchgs;
7888 	   int nboundchgs;
7889 	   int first_dual;
7890 	   int nskip;
7891 	   int i;
7892 	
7893 	   assert(node != NULL);
7894 	   assert(vars != NULL);
7895 	   assert(varbounds != NULL);
7896 	   assert(varboundtypes != NULL);
7897 	   assert(nconspropvars != NULL);
7898 	   assert(conspropvarssize >= 0);
7899 	
7900 	   (*nconspropvars) = 0;
7901 	
7902 	   if( SCIPnodeGetDepth(node) == 0 || node->domchg == NULL )
7903 	      return;
7904 	
7905 	   nboundchgs = (int)node->domchg->domchgbound.nboundchgs;
7906 	   boundchgs = node->domchg->domchgbound.boundchgs;
7907 	
7908 	   assert(boundchgs != NULL);
7909 	   assert(nboundchgs >= 0);
7910 	
7911 	   SCIPnodeGetNDomchg(node, &nskip, NULL, NULL);
7912 	   i = nskip;
7913 	
7914 	   while( i < nboundchgs
7915 	       && !(boundchgs[i].boundchgtype == SCIP_BOUNDCHGTYPE_CONSINFER && boundchgs[i].data.inferencedata.reason.cons == NULL)
7916 	       && !(boundchgs[i].boundchgtype == SCIP_BOUNDCHGTYPE_PROPINFER && boundchgs[i].data.inferencedata.reason.prop == NULL) )
7917 	      i++;
7918 	
7919 	   first_dual = i;
7920 	
7921 	   /* count the number of bound changes because of constraint propagation and propagation */
7922 	   for(i = nskip; i < first_dual; i++)
7923 	   {
7924 	      assert(boundchgs[i].boundchgtype != SCIP_BOUNDCHGTYPE_BRANCHING);
7925 	
7926 	      if( (boundchgs[i].boundchgtype == SCIP_BOUNDCHGTYPE_CONSINFER && boundchgs[i].data.inferencedata.reason.cons != NULL)
7927 	       || (boundchgs[i].boundchgtype == SCIP_BOUNDCHGTYPE_PROPINFER && boundchgs[i].data.inferencedata.reason.prop != NULL) )
7928 	      {
7929 	         if( boundchgs[i].var->vartype != SCIP_VARTYPE_CONTINUOUS )
7930 	            (*nconspropvars)++;
7931 	      }
7932 	      else if( (boundchgs[i].boundchgtype == SCIP_BOUNDCHGTYPE_CONSINFER && boundchgs[i].data.inferencedata.reason.cons == NULL)
7933 	            || (boundchgs[i].boundchgtype == SCIP_BOUNDCHGTYPE_PROPINFER && boundchgs[i].data.inferencedata.reason.prop == NULL))
7934 	         break;
7935 	   }
7936 	
7937 	   /* if the arrays have enough space store the branching decisions */
7938 	   if( conspropvarssize >= *nconspropvars )
7939 	   {
7940 	      int pos;
7941 	
7942 	      for(i = nskip, pos = 0; i < first_dual; i++)
7943 	      {
7944 	         if( boundchgs[i].boundchgtype == SCIP_BOUNDCHGTYPE_CONSINFER && boundchgs[i].data.inferencedata.reason.cons != NULL )
7945 	         {
7946 	            if( boundchgs[i].var->vartype != SCIP_VARTYPE_CONTINUOUS )
7947 	            {
7948 	               vars[pos] = boundchgs[i].var;
7949 	               varboundtypes[pos] = (SCIP_BOUNDTYPE) boundchgs[i].boundtype;
7950 	               varbounds[pos] = boundchgs[i].newbound;
7951 	               pos++;
7952 	            }
7953 	         }
7954 	      }
7955 	   }
7956 	
7957 	   return;
7958 	}
7959 	
7960 	/** gets all bound changes applied after the first bound change based on dual information.
7961 	 *
7962 	 *  @note: currently, we can only detect bound changes based in dual information if they arise from strong branching.
7963 	 */
7964 	void SCIPnodeGetBdChgsAfterDual(
7965 	   SCIP_NODE*            node,               /**< node */
7966 	   SCIP_VAR**            vars,               /**< array of variables on which the branching has been performed in the parent node */
7967 	   SCIP_Real*            varbounds,          /**< array of bounds which the branching in the parent node set */
7968 	   SCIP_BOUNDTYPE*       varboundtypes,      /**< array of boundtypes which the branching in the parent node set */
7969 	   int                   start,              /**< first free slot in the arrays */
7970 	   int*                  nbranchvars,        /**< number of variables on which branching has been performed in the parent node
7971 	                                              *   if this is larger than the array size, arrays should be reallocated and method
7972 	                                              *   should be called again */
7973 	   int                   branchvarssize      /**< available slots in arrays */
7974 	   )
7975 	{  /*lint --e{641}*/
7976 	   SCIP_BOUNDCHG* boundchgs;
7977 	   int nboundchgs;
7978 	   int first_dual;
7979 	   int i;
7980 	
7981 	   assert(node != NULL);
7982 	   assert(vars != NULL);
7983 	   assert(varbounds != NULL);
7984 	   assert(varboundtypes != NULL);
7985 	   assert(nbranchvars != NULL);
7986 	   assert(branchvarssize >= 0);
7987 	
7988 	   (*nbranchvars) = 0;
7989 	
7990 	   if( SCIPnodeGetDepth(node) == 0 || node->domchg == NULL )
7991 	      return;
7992 	
7993 	   nboundchgs = (int)node->domchg->domchgbound.nboundchgs;
7994 	   boundchgs = node->domchg->domchgbound.boundchgs;
7995 	
7996 	   assert(boundchgs != NULL);
7997 	   assert(nboundchgs >= 0);
7998 	
7999 	   /* find the first based on dual information */
8000 	   i = 0;
8001 	   while( i < nboundchgs
8002 	       && !(boundchgs[i].boundchgtype == SCIP_BOUNDCHGTYPE_CONSINFER && boundchgs[i].data.inferencedata.reason.cons == NULL)
8003 	       && !(boundchgs[i].boundchgtype == SCIP_BOUNDCHGTYPE_PROPINFER && boundchgs[i].data.inferencedata.reason.prop == NULL) )
8004 	      i++;
8005 	
8006 	   first_dual = i;
8007 	
8008 	   /* count the number of branching decisions; branching decisions have to be in the beginning of the bound change array */
8009 	   for( ; i < nboundchgs; i++)
8010 	   {
8011 	      assert(boundchgs[i].boundchgtype != SCIP_BOUNDCHGTYPE_BRANCHING);
8012 	
8013 	      if( (boundchgs[i].boundchgtype == SCIP_BOUNDCHGTYPE_CONSINFER && boundchgs[i].data.inferencedata.reason.cons != NULL)
8014 	       || (boundchgs[i].boundchgtype == SCIP_BOUNDCHGTYPE_PROPINFER && boundchgs[i].data.inferencedata.reason.prop != NULL) )
8015 	      {
8016 	         if( boundchgs[i].var->vartype != SCIP_VARTYPE_CONTINUOUS )
8017 	            (*nbranchvars)++;
8018 	      }
8019 	   }
8020 	
8021 	   /* if the arrays have enough space store the branching decisions */
8022 	   if( branchvarssize >= *nbranchvars )
8023 	   {
8024 	      int p;
8025 	      for(i = first_dual, p = start; i < nboundchgs; i++)
8026 	      {
8027 	         if( (boundchgs[i].boundchgtype == SCIP_BOUNDCHGTYPE_CONSINFER && boundchgs[i].data.inferencedata.reason.cons != NULL)
8028 	          || (boundchgs[i].boundchgtype == SCIP_BOUNDCHGTYPE_PROPINFER && boundchgs[i].data.inferencedata.reason.prop != NULL)  )
8029 	         {
8030 	            if( boundchgs[i].var->vartype != SCIP_VARTYPE_CONTINUOUS )
8031 	            {
8032 	               vars[p] = boundchgs[i].var;
8033 	               varboundtypes[p] = (SCIP_BOUNDTYPE) boundchgs[i].boundtype;
8034 	               varbounds[p] = boundchgs[i].newbound;
8035 	               p++;
8036 	            }
8037 	         }
8038 	      }
8039 	   }
8040 	}
8041 	
8042 	/** outputs the path into given file stream in GML format */
8043 	SCIP_RETCODE SCIPnodePrintAncestorBranchings(
8044 	   SCIP_NODE*            node,               /**< node data */
8045 	   FILE*                 file                /**< file to output the path */
8046 	   )
8047 	{
8048 	   int nbranchings;
8049 	
8050 	   nbranchings = 0;
8051 	
8052 	   /* print opening in GML format */
8053 	   SCIPgmlWriteOpening(file, TRUE);
8054 	
8055 	   while( SCIPnodeGetDepth(node) != 0 )
8056 	   {
8057 	      SCIP_BOUNDCHG* boundchgs;
8058 	      char label[SCIP_MAXSTRLEN];
8059 	      int nboundchgs;
8060 	      int i;
8061 	
8062 	      nboundchgs = (int)node->domchg->domchgbound.nboundchgs;
8063 	      boundchgs = node->domchg->domchgbound.boundchgs;
8064 	
8065 	      for( i = 0; i < nboundchgs; i++)
8066 	      {
8067 	         if( boundchgs[i].boundchgtype != SCIP_BOUNDCHGTYPE_BRANCHING ) /*lint !e641*/
8068 	            break;
8069 	
8070 	         (void) SCIPsnprintf(label, SCIP_MAXSTRLEN, "%s %s %g", SCIPvarGetName(boundchgs[i].var),
8071 	            (SCIP_BOUNDTYPE) boundchgs[i].boundtype == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=", boundchgs[i].newbound);
8072 	
8073 	         SCIPgmlWriteNode(file, (unsigned int)nbranchings, label, "circle", NULL, NULL);
8074 	
8075 	         if( nbranchings > 0 )
8076 	         {
8077 	            SCIPgmlWriteArc(file, (unsigned int)nbranchings, (unsigned int)(nbranchings-1), NULL, NULL);
8078 	         }
8079 	
8080 	         nbranchings++;
8081 	      }
8082 	
8083 	      node = node->parent;
8084 	   }
8085 	
8086 	   /* print closing in GML format */
8087 	   SCIPgmlWriteClosing(file);
8088 	
8089 	   return SCIP_OKAY;
8090 	}
8091 	
8092 	/**  returns the set of variable branchings that were performed in all ancestor nodes (nodes on the path to the root) to create this node
8093 	 *  sorted by the nodes, starting from the current node going up to the root
8094 	 */
8095 	void SCIPnodeGetAncestorBranchingPath(
8096 	   SCIP_NODE*            node,               /**< node data */
8097 	   SCIP_VAR**            branchvars,         /**< array of variables on which the branchings has been performed in all ancestors */
8098 	   SCIP_Real*            branchbounds,       /**< array of bounds which the branchings in all ancestors set */
8099 	   SCIP_BOUNDTYPE*       boundtypes,         /**< array of boundtypes which the branchings in all ancestors set */
8100 	   int*                  nbranchvars,        /**< number of variables on which branchings have been performed in all ancestors
8101 	                                              *   if this is larger than the array size, arrays should be reallocated and method
8102 	                                              *   should be called again */
8103 	   int                   branchvarssize,     /**< available slots in arrays */
8104 	   int*                  nodeswitches,       /**< marks, where in the arrays the branching decisions of the next node on the path
8105 	                                              *   start branchings performed at the parent of node always start at position 0.
8106 	                                              *   For single variable branching, nodeswitches[i] = i holds */
8107 	   int*                  nnodes,             /**< number of nodes in the nodeswitch array */
8108 	   int                   nodeswitchsize      /**< available slots in node switch array */
8109 	   )
8110 	{
8111 	   assert(node != NULL);
8112 	   assert(branchvars != NULL);
8113 	   assert(branchbounds != NULL);
8114 	   assert(boundtypes != NULL);
8115 	   assert(nbranchvars != NULL);
8116 	   assert(branchvarssize >= 0);
8117 	
8118 	   (*nbranchvars) = 0;
8119 	   (*nnodes) = 0;
8120 	
8121 	   /* go up to the root, in the root no domains were changed due to branching */
8122 	   while( SCIPnodeGetDepth(node) != 0 )
8123 	   {
8124 	      int nodenbranchvars;
8125 	      int start;
8126 	      int size;
8127 	
8128 	      /* calculate the start position for the current node and the maximum remaining slots in the arrays */
8129 	      start = *nbranchvars < branchvarssize - 1 ? *nbranchvars : branchvarssize - 1;
8130 	      size = *nbranchvars > branchvarssize ? 0 : branchvarssize-(*nbranchvars);
8131 	      if( *nnodes < nodeswitchsize )         
8132 	         nodeswitches[*nnodes] = start;
8133 	
8134 	      /* get branchings for a single node */
8135 	      SCIPnodeGetParentBranchings(node, &branchvars[start], &branchbounds[start], &boundtypes[start], &nodenbranchvars, size);
8136 	      *nbranchvars += nodenbranchvars;
8137 	      (*nnodes)++;
8138 	
8139 	      node = node->parent;
8140 	   }
8141 	}
8142 	
8143 	/** checks for two nodes whether they share the same root path, i.e., whether one is an ancestor of the other */
8144 	SCIP_Bool SCIPnodesSharePath(
8145 	   SCIP_NODE*            node1,              /**< node data */
8146 	   SCIP_NODE*            node2               /**< node data */
8147 	   )
8148 	{
8149 	   assert(node1 != NULL);
8150 	   assert(node2 != NULL);
8151 	   assert(SCIPnodeGetDepth(node1) >= 0);
8152 	   assert(SCIPnodeGetDepth(node2) >= 0);
8153 	
8154 	   /* if node2 is deeper than node1, follow the path until the level of node2 */
8155 	   while( SCIPnodeGetDepth(node1) < SCIPnodeGetDepth(node2) )
8156 	      node2 = node2->parent;
8157 	
8158 	   /* if node1 is deeper than node2, follow the path until the level of node1 */
8159 	   while( SCIPnodeGetDepth(node2) < SCIPnodeGetDepth(node1) )
8160 	      node1 = node1->parent;
8161 	
8162 	   assert(SCIPnodeGetDepth(node2) == SCIPnodeGetDepth(node1));
8163 	
8164 	   return (node1 == node2);
8165 	}
8166 	
8167 	/** finds the common ancestor node of two given nodes */
8168 	SCIP_NODE* SCIPnodesGetCommonAncestor(
8169 	   SCIP_NODE*            node1,              /**< node data */
8170 	   SCIP_NODE*            node2               /**< node data */
8171 	   )
8172 	{
8173 	   assert(node1 != NULL);
8174 	   assert(node2 != NULL);
8175 	   assert(SCIPnodeGetDepth(node1) >= 0);
8176 	   assert(SCIPnodeGetDepth(node2) >= 0);
8177 	
8178 	   /* if node2 is deeper than node1, follow the path until the level of node2 */
8179 	   while( SCIPnodeGetDepth(node1) < SCIPnodeGetDepth(node2) )
8180 	      node2 = node2->parent;
8181 	
8182 	   /* if node1 is deeper than node2, follow the path until the level of node1 */
8183 	   while( SCIPnodeGetDepth(node2) < SCIPnodeGetDepth(node1) )
8184 	      node1 = node1->parent;
8185 	
8186 	   /* move up level by level until you found a common ancestor */
8187 	   while( node1 != node2 )
8188 	   {
8189 	      node1 = node1->parent;
8190 	      node2 = node2->parent;
8191 	      assert(SCIPnodeGetDepth(node1) == SCIPnodeGetDepth(node2));
8192 	   }
8193 	   assert(SCIPnodeGetDepth(node1) >= 0);
8194 	
8195 	   return node1;
8196 	}
8197 	
8198 	/** returns whether node is in the path to the current node */
8199 	SCIP_Bool SCIPnodeIsActive(
8200 	   SCIP_NODE*            node                /**< node */
8201 	   )
8202 	{
8203 	   assert(node != NULL);
8204 	
8205 	   return node->active;
8206 	}
8207 	
8208 	/** returns whether the node is marked to be propagated again */
8209 	SCIP_Bool SCIPnodeIsPropagatedAgain(
8210 	   SCIP_NODE*            node                /**< node data */
8211 	   )
8212 	{
8213 	   assert(node != NULL);
8214 	
8215 	   return node->reprop;
8216 	}
8217 	
8218 	/* returns the set of changed constraints for a particular node */
8219 	SCIP_CONSSETCHG* SCIPnodeGetConssetchg(
8220 	   SCIP_NODE*            node                /**< node data */
8221 	   )
8222 	{
8223 	   assert(node != NULL);
8224 	
8225 	   return node->conssetchg;
8226 	}
8227 	
8228 	/** gets number of children of the focus node */
8229 	int SCIPtreeGetNChildren(
8230 	   SCIP_TREE*            tree                /**< branch and bound tree */
8231 	   )
8232 	{
8233 	   assert(tree != NULL);
8234 	
8235 	   return tree->nchildren;
8236 	}
8237 	
8238 	/** gets number of siblings of the focus node  */
8239 	int SCIPtreeGetNSiblings(
8240 	   SCIP_TREE*            tree                /**< branch and bound tree */
8241 	   )
8242 	{
8243 	   assert(tree != NULL);
8244 	
8245 	   return tree->nsiblings;
8246 	}
8247 	
8248 	/** gets number of leaves in the tree (excluding children and siblings of focus nodes) */
8249 	int SCIPtreeGetNLeaves(
8250 	   SCIP_TREE*            tree                /**< branch and bound tree */
8251 	   )
8252 	{
8253 	   assert(tree != NULL);
8254 	
8255 	   return SCIPnodepqLen(tree->leaves);
8256 	}
8257 	
8258 	/** gets number of open nodes in the tree (children + siblings + leaves) */
8259 	int SCIPtreeGetNNodes(
8260 	   SCIP_TREE*            tree                /**< branch and bound tree */
8261 	   )
8262 	{
8263 	   assert(tree != NULL);
8264 	
8265 	   return tree->nchildren + tree->nsiblings + SCIPtreeGetNLeaves(tree);
8266 	}
8267 	
8268 	/** returns whether the active path goes completely down to the focus node */
8269 	SCIP_Bool SCIPtreeIsPathComplete(
8270 	   SCIP_TREE*            tree                /**< branch and bound tree */
8271 	   )
8272 	{
8273 	   assert(tree != NULL);
8274 	   assert(tree->focusnode != NULL || !SCIPtreeProbing(tree));
8275 	   assert(tree->pathlen == 0 || tree->focusnode != NULL);
8276 	   assert(tree->pathlen >= 2 || !SCIPtreeProbing(tree));
8277 	   assert(tree->pathlen == 0 || tree->path[tree->pathlen-1] != NULL);
8278 	   assert(tree->pathlen == 0 || tree->path[tree->pathlen-1]->depth == tree->pathlen-1);
8279 	   assert(tree->focusnode == NULL || (int)tree->focusnode->depth >= tree->pathlen
8280 	      || tree->path[tree->focusnode->depth] == tree->focusnode);
8281 	
8282 	   return (tree->focusnode == NULL || (int)tree->focusnode->depth < tree->pathlen);
8283 	}
8284 	
8285 	/** returns whether the current node is a temporary probing node */
8286 	SCIP_Bool SCIPtreeProbing(
8287 	   SCIP_TREE*            tree                /**< branch and bound tree */
8288 	   )
8289 	{
8290 	   assert(tree != NULL);
8291 	   assert(tree->probingroot == NULL || (SCIP_NODETYPE)tree->probingroot->nodetype == SCIP_NODETYPE_PROBINGNODE);
8292 	   assert(tree->probingroot == NULL || tree->pathlen > SCIPnodeGetDepth(tree->probingroot));
8293 	   assert(tree->probingroot == NULL || tree->path[SCIPnodeGetDepth(tree->probingroot)] == tree->probingroot);
8294 	
8295 	   return (tree->probingroot != NULL);
8296 	}
8297 	
8298 	/** returns the temporary probing root node, or NULL if the we are not in probing mode */
8299 	SCIP_NODE* SCIPtreeGetProbingRoot(
8300 	   SCIP_TREE*            tree                /**< branch and bound tree */
8301 	   )
8302 	{
8303 	   assert(tree != NULL);
8304 	   assert(tree->probingroot == NULL || (SCIP_NODETYPE)tree->probingroot->nodetype == SCIP_NODETYPE_PROBINGNODE);
8305 	   assert(tree->probingroot == NULL || tree->pathlen > SCIPnodeGetDepth(tree->probingroot));
8306 	   assert(tree->probingroot == NULL || tree->path[SCIPnodeGetDepth(tree->probingroot)] == tree->probingroot);
8307 	
8308 	   return tree->probingroot;
8309 	}
8310 	
8311 	/** gets focus node of the tree */
8312 	SCIP_NODE* SCIPtreeGetFocusNode(
8313 	   SCIP_TREE*            tree                /**< branch and bound tree */
8314 	   )
8315 	{
8316 	   assert(tree != NULL);
8317 	   assert(tree->focusnode != NULL || !SCIPtreeProbing(tree));
8318 	   assert(tree->pathlen == 0 || tree->focusnode != NULL);
8319 	   assert(tree->pathlen >= 2 || !SCIPtreeProbing(tree));
8320 	   assert(tree->pathlen == 0 || tree->path[tree->pathlen-1] != NULL);
8321 	   assert(tree->pathlen == 0 || tree->path[tree->pathlen-1]->depth == tree->pathlen-1);
8322 	   assert(tree->focusnode == NULL || (int)tree->focusnode->depth >= tree->pathlen
8323 	      || tree->path[tree->focusnode->depth] == tree->focusnode);
8324 	
8325 	   return tree->focusnode;
8326 	}
8327 	
8328 	/** gets depth of focus node in the tree */
8329 	int SCIPtreeGetFocusDepth(
8330 	   SCIP_TREE*            tree                /**< branch and bound tree */
8331 	   )
8332 	{
8333 	   assert(tree != NULL);
8334 	   assert(tree->focusnode != NULL || !SCIPtreeProbing(tree));
8335 	   assert(tree->pathlen == 0 || tree->focusnode != NULL);
8336 	   assert(tree->pathlen >= 2 || !SCIPtreeProbing(tree));
8337 	   assert(tree->pathlen == 0 || tree->path[tree->pathlen-1] != NULL);
8338 	   assert(tree->pathlen == 0 || tree->path[tree->pathlen-1]->depth == tree->pathlen-1);
8339 	   assert(tree->focusnode == NULL || (int)tree->focusnode->depth >= tree->pathlen
8340 	      || tree->path[tree->focusnode->depth] == tree->focusnode);
8341 	
8342 	   return tree->focusnode != NULL ? (int)tree->focusnode->depth : -1;
8343 	}
8344 	
8345 	/** returns, whether the LP was or is to be solved in the focus node */
8346 	SCIP_Bool SCIPtreeHasFocusNodeLP(
8347 	   SCIP_TREE*            tree                /**< branch and bound tree */
8348 	   )
8349 	{
8350 	   assert(tree != NULL);
8351 	
8352 	   return tree->focusnodehaslp;
8353 	}
8354 	
8355 	/** sets mark to solve or to ignore the LP while processing the focus node */
8356 	void SCIPtreeSetFocusNodeLP(
8357 	   SCIP_TREE*            tree,               /**< branch and bound tree */
8358 	   SCIP_Bool             solvelp             /**< should the LP be solved in focus node? */
8359 	   )
8360 	{
8361 	   assert(tree != NULL);
8362 	
8363 	   tree->focusnodehaslp = solvelp;
8364 	}
8365 	
8366 	/** returns whether the LP of the focus node is already constructed */
8367 	SCIP_Bool SCIPtreeIsFocusNodeLPConstructed(
8368 	   SCIP_TREE*            tree                /**< branch and bound tree */
8369 	   )
8370 	{
8371 	   assert(tree != NULL);
8372 	
8373 	   return tree->focuslpconstructed;
8374 	}
8375 	
8376 	/** returns whether the focus node is already solved and only propagated again */
8377 	SCIP_Bool SCIPtreeInRepropagation(
8378 	   SCIP_TREE*            tree                /**< branch and bound tree */
8379 	   )
8380 	{
8381 	   assert(tree != NULL);
8382 	
8383 	   return (tree->focusnode != NULL && SCIPnodeGetType(tree->focusnode) == SCIP_NODETYPE_REFOCUSNODE);
8384 	}
8385 	
8386 	/** gets current node of the tree, i.e. the last node in the active path, or NULL if no current node exists */
8387 	SCIP_NODE* SCIPtreeGetCurrentNode(
8388 	   SCIP_TREE*            tree                /**< branch and bound tree */
8389 	   )
8390 	{
8391 	   assert(tree != NULL);
8392 	   assert(tree->focusnode != NULL || !SCIPtreeProbing(tree));
8393 	   assert(tree->pathlen == 0 || tree->focusnode != NULL);
8394 	   assert(tree->pathlen >= 2 || !SCIPtreeProbing(tree));
8395 	   assert(tree->pathlen == 0 || tree->path[tree->pathlen-1] != NULL);
8396 	   assert(tree->pathlen == 0 || tree->path[tree->pathlen-1]->depth == tree->pathlen-1);
8397 	   assert(tree->focusnode == NULL || (int)tree->focusnode->depth >= tree->pathlen
8398 	      || tree->path[tree->focusnode->depth] == tree->focusnode);
8399 	
8400 	   return (tree->pathlen > 0 ? tree->path[tree->pathlen-1] : NULL);
8401 	}
8402 	
8403 	/** gets depth of current node in the tree, i.e. the length of the active path minus 1, or -1 if no current node exists */
8404 	int SCIPtreeGetCurrentDepth(
8405 	   SCIP_TREE*            tree                /**< branch and bound tree */
8406 	   )
8407 	{
8408 	   assert(tree != NULL);
8409 	   assert(tree->focusnode != NULL || !SCIPtreeProbing(tree));
8410 	   assert(tree->pathlen == 0 || tree->focusnode != NULL);
8411 	   assert(tree->pathlen >= 2 || !SCIPtreeProbing(tree));
8412 	   assert(tree->pathlen == 0 || tree->path[tree->pathlen-1] != NULL);
8413 	   assert(tree->pathlen == 0 || tree->path[tree->pathlen-1]->depth == tree->pathlen-1);
8414 	   assert(tree->focusnode == NULL || (int)tree->focusnode->depth >= tree->pathlen
8415 	      || tree->path[tree->focusnode->depth] == tree->focusnode);
8416 	
8417 	   return tree->pathlen-1;
8418 	}
8419 	
8420 	/** returns, whether the LP was or is to be solved in the current node */
8421 	SCIP_Bool SCIPtreeHasCurrentNodeLP(
8422 	   SCIP_TREE*            tree                /**< branch and bound tree */
8423 	   )
8424 	{
8425 	   assert(tree != NULL);
8426 	   assert(SCIPtreeIsPathComplete(tree));
8427 	
8428 	   return SCIPtreeProbing(tree) ? tree->probingnodehaslp : SCIPtreeHasFocusNodeLP(tree);
8429 	}
8430 	
8431 	/** returns the current probing depth, i.e. the number of probing sub nodes existing in the probing path */
8432 	int SCIPtreeGetProbingDepth(
8433 	   SCIP_TREE*            tree                /**< branch and bound tree */
8434 	   )
8435 	{
8436 	   assert(tree != NULL);
8437 	   assert(SCIPtreeProbing(tree));
8438 	
8439 	   return SCIPtreeGetCurrentDepth(tree) - SCIPnodeGetDepth(tree->probingroot);
8440 	}
8441 	
8442 	/** returns the depth of the effective root node (i.e. the first depth level of a node with at least two children) */
8443 	int SCIPtreeGetEffectiveRootDepth(
8444 	   SCIP_TREE*            tree                /**< branch and bound tree */
8445 	   )
8446 	{
8447 	   assert(tree != NULL);
8448 	   assert(tree->effectiverootdepth >= 0);
8449 	
8450 	   return tree->effectiverootdepth;
8451 	}
8452 	
8453 	/** gets the root node of the tree */
8454 	SCIP_NODE* SCIPtreeGetRootNode(
8455 	   SCIP_TREE*            tree                /**< branch and bound tree */
8456 	   )
8457 	{
8458 	   assert(tree != NULL);
8459 	
8460 	   return tree->root;
8461 	}
8462 	
8463 	/** returns whether we are in probing and the objective value of at least one column was changed */
8464 	
8465 	SCIP_Bool SCIPtreeProbingObjChanged(
8466 	   SCIP_TREE*            tree                /**< branch and bound tree */
8467 	   )
8468 	{
8469 	   assert(tree != NULL);
8470 	   assert(SCIPtreeProbing(tree) || !tree->probingobjchanged);
8471 	
8472 	   return tree->probingobjchanged;
8473 	}
8474 	
8475 	/** marks the current probing node to have a changed objective function */
8476 	void SCIPtreeMarkProbingObjChanged(
8477 	   SCIP_TREE*            tree                /**< branch and bound tree */
8478 	   )
8479 	{
8480 	   assert(tree != NULL);
8481 	   assert(SCIPtreeProbing(tree));
8482 	
8483 	   tree->probingobjchanged = TRUE;
8484 	}
8485