1    	/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2    	/*                                                                           */
3    	/*                  This file is part of the program and library             */
4    	/*         SCIP --- Solving Constraint Integer Programs                      */
5    	/*                                                                           */
6    	/*    Copyright (C) 2002-2021 Konrad-Zuse-Zentrum                            */
7    	/*                            fuer Informationstechnik Berlin                */
8    	/*                                                                           */
9    	/*  SCIP is distributed under the terms of the ZIB Academic License.         */
10   	/*                                                                           */
11   	/*  You should have received a copy of the ZIB Academic License              */
12   	/*  along with SCIP; see the file COPYING. If not visit scipopt.org.         */
13   	/*                                                                           */
14   	/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15   	
16   	/**@file   branch.c
17   	 * @ingroup OTHER_CFILES
18   	 * @brief  methods for branching rules and branching candidate storage
19   	 * @author Tobias Achterberg
20   	 * @author Timo Berthold
21   	 * @author Gerald Gamrath
22   	 * @author Stefan Heinz
23   	 * @author Michael Winkler
24   	 * @author Stefan Vigerske
25   	 */
26   	
27   	/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
28   	
29   	#include <assert.h>
30   	#include <string.h>
31   	
32   	#include "scip/def.h"
33   	#include "blockmemshell/memory.h"
34   	#include "scip/set.h"
35   	#include "scip/stat.h"
36   	#include "scip/clock.h"
37   	#include "scip/paramset.h"
38   	#include "scip/event.h"
39   	#include "scip/lp.h"
40   	#include "scip/var.h"
41   	#include "scip/prob.h"
42   	#include "scip/tree.h"
43   	#include "scip/sepastore.h"
44   	#include "scip/scip.h"
45   	#include "scip/branch.h"
46   	#include "scip/solve.h"
47   	
48   	#include "scip/struct_branch.h"
49   	
50   	/*
51   	 * memory growing methods for dynamically allocated arrays
52   	 */
53   	
54   	/** ensures, that lpcands array can store at least num entries */
55   	static
56   	SCIP_RETCODE ensureLpcandsSize(
57   	   SCIP_BRANCHCAND*      branchcand,         /**< branching candidate storage */
58   	   SCIP_SET*             set,                /**< global SCIP settings */
59   	   int                   num                 /**< minimum number of entries to store */
60   	   )
61   	{
62   	   assert(branchcand->nlpcands <= branchcand->lpcandssize);
63   	
64   	   if( num > branchcand->lpcandssize )
65   	   {
66   	      int newsize;
67   	
68   	      newsize = SCIPsetCalcMemGrowSize(set, num);
69   	      SCIP_ALLOC( BMSreallocMemoryArray(&branchcand->lpcands, newsize) );
70   	      SCIP_ALLOC( BMSreallocMemoryArray(&branchcand->lpcandssol, newsize) );
71   	      SCIP_ALLOC( BMSreallocMemoryArray(&branchcand->lpcandsfrac, newsize) );
72   	      branchcand->lpcandssize = newsize;
73   	   }
74   	   assert(num <= branchcand->lpcandssize);
75   	
76   	   return SCIP_OKAY;
77   	}
78   	
79   	/** ensures, that pseudocands array can store at least num entries */
80   	static
81   	SCIP_RETCODE ensurePseudocandsSize(
82   	   SCIP_BRANCHCAND*      branchcand,         /**< branching candidate storage */
83   	   SCIP_SET*             set,                /**< global SCIP settings */
84   	   int                   num                 /**< minimum number of entries to store */
85   	   )
86   	{
87   	   assert(branchcand->npseudocands <= branchcand->pseudocandssize);
88   	
89   	   if( num > branchcand->pseudocandssize )
90   	   {
91   	      int newsize;
92   	
93   	      newsize = SCIPsetCalcMemGrowSize(set, num);
94   	      SCIP_ALLOC( BMSreallocMemoryArray(&branchcand->pseudocands, newsize) );
95   	      branchcand->pseudocandssize = newsize;
96   	   }
97   	   assert(num <= branchcand->pseudocandssize);
98   	
99   	   return SCIP_OKAY;
100  	}
101  	
102  	/** ensures, that externcands array can store at least num entries */
103  	static
104  	SCIP_RETCODE ensureExterncandsSize(
105  	   SCIP_BRANCHCAND*      branchcand,         /**< branching candidate storage */
106  	   SCIP_SET*             set,                /**< global SCIP settings */
107  	   int                   num                 /**< minimum number of entries to store */
108  	   )
109  	{
110  	   assert(branchcand->nexterncands <= branchcand->externcandssize);
111  	
112  	   if( num > branchcand->externcandssize )
113  	   {
114  	      int newsize;
115  	
116  	      newsize = SCIPsetCalcMemGrowSize(set, num);
117  	      SCIP_ALLOC( BMSreallocMemoryArray(&branchcand->externcands, newsize) );
118  	      SCIP_ALLOC( BMSreallocMemoryArray(&branchcand->externcandsscore, newsize) );
119  	      SCIP_ALLOC( BMSreallocMemoryArray(&branchcand->externcandssol, newsize) );
120  	      branchcand->externcandssize = newsize;
121  	   }
122  	   assert(num <= branchcand->externcandssize);
123  	
124  	   return SCIP_OKAY;
125  	}
126  	
127  	
128  	
129  	/*
130  	 * branching candidate storage methods
131  	 */
132  	
133  	/** creates a branching candidate storage */
134  	SCIP_RETCODE SCIPbranchcandCreate(
135  	   SCIP_BRANCHCAND**     branchcand          /**< pointer to store branching candidate storage */
136  	   )
137  	{
138  	   assert(branchcand != NULL);
139  	
140  	   SCIP_ALLOC( BMSallocMemory(branchcand) );
141  	   (*branchcand)->lpcands = NULL;
142  	   (*branchcand)->lpcandssol = NULL;
143  	   (*branchcand)->lpcandsfrac = NULL;
144  	   (*branchcand)->externcands = NULL;
145  	   (*branchcand)->externcandssol = NULL;
146  	   (*branchcand)->externcandsscore = NULL;
147  	   (*branchcand)->pseudocands = NULL;
148  	   (*branchcand)->lpcandssize = 0;
149  	   (*branchcand)->nlpcands = 0;
150  	   (*branchcand)->nimpllpfracs = 0;
151  	   (*branchcand)->npriolpcands = 0;
152  	   (*branchcand)->npriolpbins = 0;
153  	   (*branchcand)->lpmaxpriority = INT_MIN;
154  	   (*branchcand)->externcandssize = 0;
155  	   (*branchcand)->nexterncands = 0;
156  	   (*branchcand)->nprioexterncands = 0;
157  	   (*branchcand)->nprioexternbins = 0;
158  	   (*branchcand)->nprioexternints = 0;
159  	   (*branchcand)->nprioexternimpls = 0;
160  	   (*branchcand)->externmaxpriority = INT_MIN;
161  	   (*branchcand)->pseudocandssize = 0;
162  	   (*branchcand)->npseudocands = 0;
163  	   (*branchcand)->npriopseudocands = 0;
164  	   (*branchcand)->npriopseudobins = 0;
165  	   (*branchcand)->npriopseudoints = 0;
166  	   (*branchcand)->pseudomaxpriority = INT_MIN;
167  	
168  	   SCIPbranchcandInvalidate(*branchcand);
169  	
170  	   return SCIP_OKAY;
171  	}
172  	
173  	/** frees branching candidate storage */
174  	SCIP_RETCODE SCIPbranchcandFree(
175  	   SCIP_BRANCHCAND**     branchcand          /**< pointer to store branching candidate storage */
176  	   )
177  	{
178  	   assert(branchcand != NULL);
179  	
180  	   BMSfreeMemoryArrayNull(&(*branchcand)->lpcands);
181  	   BMSfreeMemoryArrayNull(&(*branchcand)->lpcandssol);
182  	   BMSfreeMemoryArrayNull(&(*branchcand)->lpcandsfrac);
183  	   BMSfreeMemoryArrayNull(&(*branchcand)->pseudocands);
184  	   BMSfreeMemoryArrayNull(&(*branchcand)->externcands);
185  	   BMSfreeMemoryArrayNull(&(*branchcand)->externcandsscore);
186  	   BMSfreeMemoryArrayNull(&(*branchcand)->externcandssol);
187  	   BMSfreeMemory(branchcand);
188  	
189  	   return SCIP_OKAY;
190  	}
191  	
192  	/** resets branching candidates storage */
193  	void SCIPbranchcandInvalidate(
194  	   SCIP_BRANCHCAND*      branchcand          /**< pointer to store branching candidate storage */
195  	   )
196  	{
197  	   assert(branchcand != NULL);
198  	
199  	   branchcand->validlpcandslp = -1;
200  	}
201  	
202  	/** calculates branching candidates for LP solution branching (fractional variables) */
203  	static
204  	SCIP_RETCODE branchcandCalcLPCands(
205  	   SCIP_BRANCHCAND*      branchcand,         /**< branching candidate storage */
206  	   SCIP_SET*             set,                /**< global SCIP settings */
207  	   SCIP_STAT*            stat,               /**< problem statistics */
208  	   SCIP_LP*              lp                  /**< current LP data */
209  	   )
210  	{
211  	   assert(branchcand != NULL);
212  	   assert(stat != NULL);
213  	   assert(branchcand->validlpcandslp <= stat->lpcount);
214  	   assert(lp != NULL);
215  	   assert(lp->solved);
216  	   assert(SCIPlpGetSolstat(lp) == SCIP_LPSOLSTAT_OPTIMAL || SCIPlpGetSolstat(lp) == SCIP_LPSOLSTAT_UNBOUNDEDRAY);
217  	
218  	   SCIPsetDebugMsg(set, "calculating LP branching candidates: validlp=%" SCIP_LONGINT_FORMAT ", lpcount=%" SCIP_LONGINT_FORMAT "\n",
219  	      branchcand->validlpcandslp, stat->lpcount);
220  	
221  	   /* check, if the current LP branching candidate array is invalid */
222  	   if( branchcand->validlpcandslp < stat->lpcount )
223  	   {
224  	      SCIP_COL** cols;
225  	      SCIP_VAR* var;
226  	      SCIP_COL* col;
227  	      SCIP_Real primsol;
228  	      SCIP_Real frac;
229  	      SCIP_VARTYPE vartype;
230  	      int branchpriority;
231  	      int ncols;
232  	      int c;
233  	      int insertpos;
234  	
235  	      SCIPsetDebugMsg(set, " -> recalculating LP branching candidates\n");
236  	
237  	      cols = SCIPlpGetCols(lp);
238  	      ncols = SCIPlpGetNCols(lp);
239  	
240  	      /* construct the LP branching candidate set, moving the candidates with maximal priority to the front */
241  	      SCIP_CALL( ensureLpcandsSize(branchcand, set, ncols) );
242  	
243  	      branchcand->lpmaxpriority = INT_MIN / 2;
244  	      branchcand->nlpcands = 0;
245  	      branchcand->nimpllpfracs = 0;
246  	      branchcand->npriolpcands = 0;
247  	      branchcand->npriolpbins = 0;
248  	      for( c = 0; c < ncols; ++c )
249  	      {
250  	         col = cols[c];
251  	         assert(col != NULL);
252  	         assert(col->lppos == c);
253  	         assert(col->lpipos >= 0);
254  	
255  	         primsol = SCIPcolGetPrimsol(col);
256  	         assert(primsol < SCIP_INVALID);
257  	         assert(SCIPsetIsInfinity(set, -col->lb) || SCIPsetIsFeasGE(set, primsol, col->lb));
258  	         assert(SCIPsetIsInfinity(set, col->ub) || SCIPsetIsFeasLE(set, primsol, col->ub));
259  	
260  	         /* count values at infinity as integral */
261  	         if( SCIPsetIsInfinity(set, REALABS(primsol)) )
262  	            continue;
263  	
264  	         var = col->var;
265  	         assert(var != NULL);
266  	         assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_COLUMN);
267  	         assert(SCIPvarGetCol(var) == col);
268  	
269  	         /* LP branching candidates are fractional binary and integer variables; implicit variables are kept at the end
270  	          * of the candidates array for some rounding heuristics
271  	          */
272  	         vartype = SCIPvarGetType(var);
273  	         if( vartype == SCIP_VARTYPE_CONTINUOUS )
274  	            continue;
275  	
276  	         /* ignore fixed variables (due to numerics, it is possible, that the LP solution of a fixed integer variable
277  	          * (with large fixed value) is fractional in terms of absolute feasibility measure)
278  	          */
279  	         if( SCIPvarGetLbLocal(var) >= SCIPvarGetUbLocal(var) - 0.5 )
280  	            continue;
281  	
282  	         /* check, if the LP solution value is fractional */
283  	         frac = SCIPsetFeasFrac(set, primsol);
284  	
285  	         /* The fractionality should not be smaller than -feastol, however, if the primsol is large enough
286  	          * and close to an integer, fixed precision floating point arithmetic might give us values slightly
287  	          * smaller than -feastol. Originally, the "frac >= -feastol"-check was within SCIPsetIsFeasFracIntegral(),
288  	          * however, we relaxed it to "frac >= -2*feastol" and have the stricter check here for small-enough primsols.
289  	          */
290  	         assert(SCIPsetIsGE(set, frac, -SCIPsetFeastol(set)) || (primsol > 1e14 * SCIPsetFeastol(set)));
291  	
292  	         if( SCIPsetIsFeasFracIntegral(set, frac) )
293  	            continue;
294  	
295  	         /* insert candidate in candidate list */
296  	         branchpriority = SCIPvarGetBranchPriority(var);
297  	         insertpos = branchcand->nlpcands + branchcand->nimpllpfracs;
298  	         assert(insertpos < branchcand->lpcandssize);
299  	
300  	         if( vartype == SCIP_VARTYPE_IMPLINT )
301  	            branchpriority = INT_MIN;
302  	
303  	         assert(vartype == SCIP_VARTYPE_IMPLINT || branchpriority >= INT_MIN/2);
304  	         /* ensure that implicit variables are stored at the end of the array */
305  	         if( vartype != SCIP_VARTYPE_IMPLINT && branchcand->nimpllpfracs > 0 )
306  	         {
307  	            assert(branchcand->lpcands[branchcand->nlpcands] != NULL
308  	                  && SCIPvarGetType(branchcand->lpcands[branchcand->nlpcands]) == SCIP_VARTYPE_IMPLINT );
309  	
310  	            branchcand->lpcands[insertpos] = branchcand->lpcands[branchcand->nlpcands];
311  	            branchcand->lpcandssol[insertpos] = branchcand->lpcandssol[branchcand->nlpcands];
312  	            branchcand->lpcandsfrac[insertpos] = branchcand->lpcandsfrac[branchcand->nlpcands];
313  	
314  	            insertpos = branchcand->nlpcands;
315  	         }
316  	
317  	         if( branchpriority > branchcand->lpmaxpriority )
318  	         {
319  	            /* candidate has higher priority than the current maximum:
320  	             * move it to the front and declare it to be the single best candidate
321  	             */
322  	            if( insertpos != 0 )
323  	            {
324  	               branchcand->lpcands[insertpos] = branchcand->lpcands[0];
325  	               branchcand->lpcandssol[insertpos] = branchcand->lpcandssol[0];
326  	               branchcand->lpcandsfrac[insertpos] = branchcand->lpcandsfrac[0];
327  	               insertpos = 0;
328  	            }
329  	            branchcand->npriolpcands = 1;
330  	            branchcand->npriolpbins = (vartype == SCIP_VARTYPE_BINARY ? 1 : 0);
331  	            branchcand->lpmaxpriority = branchpriority;
332  	         }
333  	         else if( branchpriority == branchcand->lpmaxpriority )
334  	         {
335  	            /* candidate has equal priority as the current maximum:
336  	             * move away the first non-maximal priority candidate, move the current candidate to the correct
337  	             * slot (binaries first) and increase the number of maximal priority candidates
338  	             */
339  	            if( insertpos != branchcand->npriolpcands )
340  	            {
341  	               branchcand->lpcands[insertpos] = branchcand->lpcands[branchcand->npriolpcands];
342  	               branchcand->lpcandssol[insertpos] = branchcand->lpcandssol[branchcand->npriolpcands];
343  	               branchcand->lpcandsfrac[insertpos] = branchcand->lpcandsfrac[branchcand->npriolpcands];
344  	               insertpos = branchcand->npriolpcands;
345  	            }
346  	            branchcand->npriolpcands++;
347  	            if( vartype == SCIP_VARTYPE_BINARY )
348  	            {
349  	               if( insertpos != branchcand->npriolpbins )
350  	               {
351  	                  branchcand->lpcands[insertpos] = branchcand->lpcands[branchcand->npriolpbins];
352  	                  branchcand->lpcandssol[insertpos] = branchcand->lpcandssol[branchcand->npriolpbins];
353  	                  branchcand->lpcandsfrac[insertpos] = branchcand->lpcandsfrac[branchcand->npriolpbins];
354  	                  insertpos = branchcand->npriolpbins;
355  	               }
356  	               branchcand->npriolpbins++;
357  	            }
358  	         }
359  	         /* insert variable at the correct position of the candidates storage */
360  	         branchcand->lpcands[insertpos] = var;
361  	         branchcand->lpcandssol[insertpos] = primsol;
362  	         branchcand->lpcandsfrac[insertpos] = frac;
363  	
364  	         /* increase the counter depending on the variable type */
365  	         if( vartype != SCIP_VARTYPE_IMPLINT )
366  	            branchcand->nlpcands++;
367  	         else
368  	            branchcand->nimpllpfracs++;
369  	
370  	         SCIPsetDebugMsg(set, " -> candidate %d: var=<%s>, sol=%g, frac=%g, prio=%d (max: %d) -> pos %d\n",
371  	            branchcand->nlpcands, SCIPvarGetName(var), primsol, frac, branchpriority, branchcand->lpmaxpriority,
372  	            insertpos);
373  	      }
374  	
375  	#ifndef NDEBUG
376  	      /* in debug mode we assert that the variables are positioned correctly (binaries and integers first,
377  	       * implicit integers last)
378  	       */
379  	      for( c = 0; c < branchcand->nlpcands + branchcand->nimpllpfracs; ++c )
380  	      {
381  	         assert(c >= branchcand->nlpcands || SCIPvarGetType(branchcand->lpcands[c]) != SCIP_VARTYPE_IMPLINT);
382  	         assert(c < branchcand->nlpcands || SCIPvarGetType(branchcand->lpcands[c]) == SCIP_VARTYPE_IMPLINT);
383  	      }
384  	#endif
385  	
386  	      branchcand->validlpcandslp = stat->lpcount;
387  	   }
388  	   assert(0 <= branchcand->npriolpcands && branchcand->npriolpcands <= branchcand->nlpcands);
389  	
390  	   SCIPsetDebugMsg(set, " -> %d fractional variables (%d of maximal priority)\n", branchcand->nlpcands, branchcand->npriolpcands);
391  	
392  	   return SCIP_OKAY;
393  	}
394  	
395  	/** gets branching candidates for LP solution branching (fractional variables) */
396  	SCIP_RETCODE SCIPbranchcandGetLPCands(
397  	   SCIP_BRANCHCAND*      branchcand,         /**< branching candidate storage */
398  	   SCIP_SET*             set,                /**< global SCIP settings */
399  	   SCIP_STAT*            stat,               /**< problem statistics */
400  	   SCIP_LP*              lp,                 /**< current LP data */
401  	   SCIP_VAR***           lpcands,            /**< pointer to store the array of LP branching candidates, or NULL */
402  	   SCIP_Real**           lpcandssol,         /**< pointer to store the array of LP candidate solution values, or NULL */
403  	   SCIP_Real**           lpcandsfrac,        /**< pointer to store the array of LP candidate fractionalities, or NULL */
404  	   int*                  nlpcands,           /**< pointer to store the number of LP branching candidates, or NULL */
405  	   int*                  npriolpcands,       /**< pointer to store the number of candidates with maximal priority, or NULL */
406  	   int*                  nfracimplvars       /**< pointer to store the number of implicit fractional variables, or NULL */
407  	   )
408  	{
409  	   /* calculate branching candidates */
410  	   SCIP_CALL( branchcandCalcLPCands(branchcand, set, stat, lp) );
411  	
412  	   /* assign return values */
413  	   if( lpcands != NULL )
414  	      *lpcands = branchcand->lpcands;
415  	   if( lpcandssol != NULL )
416  	      *lpcandssol = branchcand->lpcandssol;
417  	   if( lpcandsfrac != NULL )
418  	      *lpcandsfrac = branchcand->lpcandsfrac;
419  	   if( nlpcands != NULL )
420  	      *nlpcands = branchcand->nlpcands;
421  	   if( npriolpcands != NULL )
422  	      *npriolpcands = (set->branch_preferbinary && branchcand->npriolpbins > 0 ? branchcand->npriolpbins
423  	         : branchcand->npriolpcands);
424  	   if( nfracimplvars != NULL )
425  	      *nfracimplvars = branchcand->nimpllpfracs;
426  	
427  	   return SCIP_OKAY;
428  	}
429  	
430  	/** gets external branching candidates */
431  	SCIP_RETCODE SCIPbranchcandGetExternCands(
432  	   SCIP_BRANCHCAND*      branchcand,         /**< branching candidate storage */
433  	   SCIP_VAR***           externcands,        /**< pointer to store the array of external branching candidates, or NULL */
434  	   SCIP_Real**           externcandssol,     /**< pointer to store the array of external candidate solution values, or NULL */
435  	   SCIP_Real**           externcandsscore,   /**< pointer to store the array of external candidate scores, or NULL */
436  	   int*                  nexterncands,       /**< pointer to store the number of external branching candidates, or NULL */
437  	   int*                  nprioexterncands,   /**< pointer to store the number of candidates with maximal priority, or NULL */
438  	   int*                  nprioexternbins,    /**< pointer to store the number of binary candidates with maximal priority, or NULL */
439  	   int*                  nprioexternints,    /**< pointer to store the number of integer candidates with maximal priority, or NULL */
440  	   int*                  nprioexternimpls    /**< pointer to store the number of implicit integer candidates with maximal priority, 
441  	                                              *   or NULL */
442  	   )
443  	{
444  	   assert(branchcand != NULL);
445  	
446  	   /* assign return values */
447  	   if( externcands != NULL )
448  	      *externcands = branchcand->externcands;
449  	   if( externcandssol != NULL )
450  	      *externcandssol = branchcand->externcandssol;
451  	   if( externcandsscore != NULL )
452  	      *externcandsscore = branchcand->externcandsscore;
453  	   if( nexterncands != NULL )
454  	      *nexterncands = branchcand->nexterncands;
455  	   if( nprioexterncands != NULL )
456  	      *nprioexterncands = branchcand->nprioexterncands;
457  	   if( nprioexternbins != NULL )
458  	      *nprioexternbins = branchcand->nprioexternbins;
459  	   if( nprioexternints != NULL )
460  	      *nprioexternints = branchcand->nprioexternints;
461  	   if( nprioexternimpls != NULL )
462  	      *nprioexternimpls = branchcand->nprioexternimpls;
463  	
464  	   return SCIP_OKAY;
465  	}
466  	
467  	/** gets maximal branching priority of LP branching candidates */
468  	int SCIPbranchcandGetLPMaxPrio(
469  	   SCIP_BRANCHCAND*      branchcand          /**< branching candidate storage */
470  	   )
471  	{
472  	   assert(branchcand != NULL);
473  	
474  	   return branchcand->lpmaxpriority;
475  	}
476  	
477  	/** gets number of LP branching candidates with maximal branch priority */
478  	int SCIPbranchcandGetNPrioLPCands(
479  	   SCIP_BRANCHCAND*      branchcand          /**< branching candidate storage */
480  	   )
481  	{
482  	   assert(branchcand != NULL);
483  	
484  	   return branchcand->npriolpcands;
485  	}
486  	
487  	/** gets maximal branching priority of external branching candidates */
488  	int SCIPbranchcandGetExternMaxPrio(
489  	   SCIP_BRANCHCAND*      branchcand          /**< branching candidate storage */
490  	   )
491  	{
492  	   assert(branchcand != NULL);
493  	
494  	   return branchcand->externmaxpriority;
495  	}
496  	
497  	/** gets number of external branching candidates */
498  	int SCIPbranchcandGetNExternCands(
499  	   SCIP_BRANCHCAND*      branchcand          /**< branching candidate storage */
500  	   )
501  	{
502  	   assert(branchcand != NULL);
503  	
504  	   return branchcand->nexterncands;
505  	}
506  	
507  	/** gets number of external branching candidates with maximal branch priority */
508  	int SCIPbranchcandGetNPrioExternCands(
509  	   SCIP_BRANCHCAND*      branchcand          /**< branching candidate storage */
510  	   )
511  	{
512  	   assert(branchcand != NULL);
513  	
514  	   return branchcand->nprioexterncands;
515  	}
516  	
517  	/** gets number of binary external branching candidates with maximal branch priority */
518  	int SCIPbranchcandGetNPrioExternBins(
519  	   SCIP_BRANCHCAND*      branchcand          /**< branching candidate storage */
520  	   )
521  	{
522  	   assert(branchcand != NULL);
523  	
524  	   return branchcand->nprioexternbins;
525  	}
526  	
527  	/** gets number of integer external branching candidates with maximal branch priority */
528  	int SCIPbranchcandGetNPrioExternInts(
529  	   SCIP_BRANCHCAND*      branchcand          /**< branching candidate storage */
530  	   )
531  	{
532  	   assert(branchcand != NULL);
533  	
534  	   return branchcand->nprioexternints;
535  	}
536  	
537  	/** gets number of implicit integer external branching candidates with maximal branch priority */
538  	int SCIPbranchcandGetNPrioExternImpls(
539  	   SCIP_BRANCHCAND*      branchcand          /**< branching candidate storage */
540  	   )
541  	{
542  	   assert(branchcand != NULL);
543  	
544  	   return branchcand->nprioexternimpls;
545  	}
546  	
547  	/** gets number of continuous external branching candidates with maximal branch priority */
548  	int SCIPbranchcandGetNPrioExternConts(
549  	   SCIP_BRANCHCAND*      branchcand          /**< branching candidate storage */
550  	   )
551  	{
552  	   assert(branchcand != NULL);
553  	
554  	   return branchcand->nprioexterncands - branchcand->nprioexternbins - branchcand->nprioexternints - branchcand->nprioexternimpls;
555  	}
556  	
557  	/** insert variable, its score and its solution value into the external branching candidate storage
558  	 * the absolute difference of the current lower and upper bounds of the variable must be at least epsilon
559  	 */
560  	SCIP_RETCODE SCIPbranchcandAddExternCand(
561  	   SCIP_BRANCHCAND*      branchcand,         /**< branching candidate storage */
562  	   SCIP_SET*             set,                /**< global SCIP settings */
563  	   SCIP_VAR*             var,                /**< variable to insert */
564  	   SCIP_Real             score,              /**< score of external candidate, e.g. infeasibility */
565  	   SCIP_Real             solval              /**< value of the variable in the current solution */
566  	   )
567  	{
568  	   SCIP_VARTYPE vartype;
569  	   int branchpriority;
570  	   int insertpos;
571  	
572  	   assert(branchcand != NULL);
573  	   assert(var != NULL);
574  	   assert(!SCIPsetIsEQ(set, SCIPvarGetLbLocal(var), SCIPvarGetUbLocal(var))); /* the variable should not be fixed yet */
575  	   assert(SCIPvarGetType(var) == SCIP_VARTYPE_CONTINUOUS || !SCIPsetIsEQ(set, SCIPsetCeil(set, SCIPvarGetLbLocal(var)), SCIPsetFloor(set, SCIPvarGetUbLocal(var)))); /* a discrete variable should also not be fixed, even after rounding bounds to integral values */
576  	   assert(SCIPvarGetStatus(var) != SCIP_VARSTATUS_MULTAGGR || !SCIPsetIsEQ(set, SCIPvarGetMultaggrLbLocal(var, set), SCIPvarGetMultaggrUbLocal(var, set))); /* also the current bounds of a multi-aggregated variable should not be fixed yet */
577  	   assert(branchcand->nprioexterncands <= branchcand->nexterncands);
578  	   assert(branchcand->nexterncands <= branchcand->externcandssize);
579  	
580  	   vartype = SCIPvarGetType(var);
581  	   branchpriority = SCIPvarGetBranchPriority(var);
582  	   insertpos = branchcand->nexterncands;
583  	
584  	   SCIP_CALL( ensureExterncandsSize(branchcand, set, branchcand->nexterncands+1) );
585  	
586  	   SCIPsetDebugMsg(set, "inserting external candidate <%s> of type %d and priority %d into candidate set (maxprio: %d), score = %g, solval = %g\n",
587  	      SCIPvarGetName(var), vartype, branchpriority, branchcand->externmaxpriority, score, solval);
588  	
589  	   /* insert the variable into externcands, making sure, that the highest priority candidates are at the front
590  	    * and ordered binaries, integers, implicit integers, continuous
591  	    */
592  	   if( branchpriority > branchcand->externmaxpriority )
593  	   {
594  	      /* candidate has higher priority than the current maximum:
595  	       * move it to the front and declare it to be the single best candidate
596  	       */
597  	      branchcand->externcands[insertpos] = branchcand->externcands[0];
598  	      branchcand->externcandsscore[insertpos] = branchcand->externcandsscore[0];
599  	      branchcand->externcandssol[insertpos] = branchcand->externcandssol[0];
600  	
601  	      insertpos = 0;
602  	
603  	      branchcand->nprioexterncands = 1;
604  	      branchcand->nprioexternbins = (vartype == SCIP_VARTYPE_BINARY ? 1 : 0);
605  	      branchcand->nprioexternints = (vartype == SCIP_VARTYPE_INTEGER ? 1 : 0);
606  	      branchcand->nprioexternimpls = (vartype == SCIP_VARTYPE_IMPLINT ? 1 : 0);
607  	      branchcand->externmaxpriority = branchpriority;
608  	   }
609  	   else if( branchpriority == branchcand->externmaxpriority )
610  	   {
611  	      /* candidate has equal priority as the current maximum:
612  	       * move away the first non-maximal priority candidate, move the current candidate to the correct
613  	       * slot (binaries first, integers next, implicit integers next, continuous last) and increase the number 
614  	       * of maximal priority candidates
615  	       */
616  	      if( insertpos != branchcand->nprioexterncands )
617  	      {
618  	         branchcand->externcands[insertpos] = branchcand->externcands[branchcand->nprioexterncands];
619  	         branchcand->externcandsscore[insertpos] = branchcand->externcandsscore[branchcand->nprioexterncands];
620  	         branchcand->externcandssol[insertpos] = branchcand->externcandssol[branchcand->nprioexterncands];
621  	
622  	         insertpos = branchcand->nprioexterncands;
623  	      }
624  	      branchcand->nprioexterncands++;
625  	      if( vartype == SCIP_VARTYPE_BINARY || vartype == SCIP_VARTYPE_INTEGER || vartype == SCIP_VARTYPE_IMPLINT )
626  	      {
627  	         if( insertpos != branchcand->nprioexternbins + branchcand->nprioexternints + branchcand->nprioexternimpls )
628  	         {
629  	            branchcand->externcands[insertpos] =
630  	               branchcand->externcands[branchcand->nprioexternbins + branchcand->nprioexternints + branchcand->nprioexternimpls];
631  	            branchcand->externcandsscore[insertpos] =
632  	               branchcand->externcandsscore[branchcand->nprioexternbins + branchcand->nprioexternints + branchcand->nprioexternimpls];
633  	            branchcand->externcandssol[insertpos] =
634  	               branchcand->externcandssol[branchcand->nprioexternbins + branchcand->nprioexternints + branchcand->nprioexternimpls];
635  	
636  	            insertpos = branchcand->nprioexternbins + branchcand->nprioexternints + branchcand->nprioexternimpls;
637  	         }
638  	         branchcand->nprioexternimpls++;
639  	
640  	         if( vartype == SCIP_VARTYPE_BINARY || vartype == SCIP_VARTYPE_INTEGER )
641  	         {
642  	            if( insertpos != branchcand->nprioexternbins + branchcand->nprioexternints )
643  	            {
644  	               branchcand->externcands[insertpos] = 
645  	                  branchcand->externcands[branchcand->nprioexternbins + branchcand->nprioexternints];
646  	               branchcand->externcandsscore[insertpos] = 
647  	                  branchcand->externcandsscore[branchcand->nprioexternbins + branchcand->nprioexternints];
648  	               branchcand->externcandssol[insertpos] = 
649  	                  branchcand->externcandssol[branchcand->nprioexternbins + branchcand->nprioexternints];
650  	
651  	               insertpos = branchcand->nprioexternbins + branchcand->nprioexternints;
652  	            }
653  	            branchcand->nprioexternints++;
654  	            branchcand->nprioexternimpls--;
655  	
656  	            if( vartype == SCIP_VARTYPE_BINARY )
657  	            {
658  	               if( insertpos != branchcand->nprioexternbins )
659  	               {
660  	                  branchcand->externcands[insertpos] = branchcand->externcands[branchcand->nprioexternbins];
661  	                  branchcand->externcandsscore[insertpos] = branchcand->externcandsscore[branchcand->nprioexternbins];
662  	                  branchcand->externcandssol[insertpos] = branchcand->externcandssol[branchcand->nprioexternbins];
663  	
664  	                  insertpos = branchcand->nprioexternbins;
665  	               }
666  	               branchcand->nprioexternbins++;
667  	               branchcand->nprioexternints--;
668  	            }
669  	         }
670  	      }
671  	   }
672  	   branchcand->externcands[insertpos] = var;
673  	   branchcand->externcandsscore[insertpos] = score;
674  	   branchcand->externcandssol[insertpos] = solval;
675  	   branchcand->nexterncands++;
676  	
677  	   SCIPsetDebugMsg(set, " -> inserted at position %d (nprioexterncands=%d)\n", insertpos, branchcand->nprioexterncands);
678  	
679  	   assert(0 <= branchcand->nprioexterncands && branchcand->nprioexterncands <= branchcand->nexterncands);
680  	   assert(0 <= branchcand->nprioexternbins && branchcand->nprioexternbins <= branchcand->nprioexterncands);
681  	   assert(0 <= branchcand->nprioexternints && branchcand->nprioexternints <= branchcand->nprioexterncands);
682  	   assert(0 <= branchcand->nprioexternimpls && branchcand->nprioexternimpls <= branchcand->nprioexterncands);
683  	
684  	   return SCIP_OKAY;
685  	}
686  	
687  	/** removes all external candidates from the storage for external branching */
688  	void SCIPbranchcandClearExternCands(
689  	   SCIP_BRANCHCAND*      branchcand          /**< branching candidate storage */
690  	   )
691  	{
692  	   assert(branchcand != NULL);
693  	
694  	   branchcand->nexterncands = 0;
695  	   branchcand->nprioexterncands = 0;
696  	   branchcand->nprioexternbins = 0;
697  	   branchcand->nprioexternints = 0;
698  	   branchcand->nprioexternimpls = 0;
699  	   branchcand->externmaxpriority = INT_MIN;
700  	}
701  	
702  	/** checks whether the given variable is contained in the candidate storage for external branching */
703  	SCIP_Bool SCIPbranchcandContainsExternCand(
704  	   SCIP_BRANCHCAND*      branchcand,         /**< branching candidate storage */
705  	   SCIP_VAR*             var                 /**< variable to look for */
706  	   )
707  	{
708  	   int branchpriority;
709  	   int i;
710  	
711  	   assert(branchcand != NULL);
712  	   assert(var != NULL);
713  	   assert(branchcand->nprioexterncands <= branchcand->nexterncands);
714  	   assert(branchcand->nexterncands <= branchcand->externcandssize);
715  	
716  	   branchpriority = SCIPvarGetBranchPriority(var);
717  	
718  	   /* look for the variable in the externcands, using the fact, that the highest priority candidates are at the front
719  	    * and ordered binaries, integers, implicit integers, continuous
720  	    */
721  	   if( branchpriority > branchcand->externmaxpriority )
722  	   {
723  	      /* the branching priority of the variable is higher than the maximal priority contained in the array;
724  	       * the variable can thus not be contained */
725  	      return FALSE;
726  	   }
727  	   if( branchpriority == branchcand->externmaxpriority )
728  	   {
729  	      SCIP_VARTYPE vartype;
730  	
731  	      vartype = SCIPvarGetType(var);
732  	
733  	      /* variable has equal priority as the current maximum:
734  	       * look for it in the correct slot (binaries first, integers next, implicit integers next, continuous last)
735  	       */
736  	      if( vartype == SCIP_VARTYPE_BINARY )
737  	      {
738  	         /* the variable is binary, look at the first branchcand->nprioexternbins slots */
739  	         for( i = 0; i < branchcand->nprioexternbins; i++ )
740  	            if( branchcand->externcands[i] == var )
741  	               return TRUE;
742  	         return FALSE;
743  	      }
744  	      if( vartype == SCIP_VARTYPE_INTEGER )
745  	      {
746  	         /* the variable is integer, look at the slots containing integers */
747  	         for( i = 0; i < branchcand->nprioexternints; i++ )
748  	            if( branchcand->externcands[branchcand->nprioexternbins + i] == var )
749  	               return TRUE;
750  	         return FALSE;
751  	      }
752  	      if( vartype == SCIP_VARTYPE_IMPLINT )
753  	      {
754  	         /* the variable is implicit integer, look at the slots containing implicit integers */
755  	         for( i = 0; i < branchcand->nprioexternimpls; i++ )
756  	            if( branchcand->externcands[branchcand->nprioexternbins + branchcand->nprioexternints + i] == var )
757  	               return TRUE;
758  	         return FALSE;
759  	      }
760  	      /* the variable is continuous, look at the slots containing continuous variables */
761  	      assert(vartype == SCIP_VARTYPE_CONTINUOUS);
762  	      for( i = branchcand->nprioexternbins + branchcand->nprioexternints + branchcand->nprioexternimpls; 
763  	           i < branchcand->nprioexterncands; i++ )
764  	         if( branchcand->externcands[i] == var )
765  	            return TRUE;
766  	      return FALSE;
767  	   }
768  	   /* the branching priority of the variable is lower than the maximal priority contained in the array;
769  	    * look for the variable in the candidates which do not have maximal priority */
770  	   assert(branchpriority < branchcand->externmaxpriority);
771  	
772  	   for( i = branchcand->nprioexterncands; i < branchcand->nexterncands; i++ )
773  	      if( branchcand->externcands[i] == var )
774  	         return TRUE;
775  	   return FALSE;
776  	}
777  	
778  	/** gets branching candidates for pseudo solution branching (non-fixed variables) */
779  	SCIP_RETCODE SCIPbranchcandGetPseudoCands(
780  	   SCIP_BRANCHCAND*      branchcand,         /**< branching candidate storage */
781  	   SCIP_SET*             set,                /**< global SCIP settings */
782  	   SCIP_PROB*            prob,               /**< problem data */
783  	   SCIP_VAR***           pseudocands,        /**< pointer to store the array of pseudo branching candidates, or NULL */
784  	   int*                  npseudocands,       /**< pointer to store the number of pseudo branching candidates, or NULL */
785  	   int*                  npriopseudocands    /**< pointer to store the number of candidates with maximal priority, or NULL */
786  	   )
787  	{
788  	   assert(branchcand != NULL);
789  	
790  	#ifndef NDEBUG
791  	   /* check, if the current pseudo branching candidate array is correct */
792  	   {
793  	      SCIP_VAR* var;
794  	      int npcs;
795  	      int v;
796  	
797  	      assert(prob != NULL);
798  	
799  	      /* pseudo branching candidates are non-fixed binary, integer, and implicit integer variables */
800  	      npcs = 0;
801  	      for( v = 0; v < prob->nbinvars + prob->nintvars + prob->nimplvars; ++v )
802  	      {
803  	         var = prob->vars[v];
804  	         assert(var != NULL);
805  	         assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_LOOSE || SCIPvarGetStatus(var) == SCIP_VARSTATUS_COLUMN);
806  	         assert(SCIPvarGetType(var) == SCIP_VARTYPE_BINARY
807  	            || SCIPvarGetType(var) == SCIP_VARTYPE_INTEGER
808  	            || SCIPvarGetType(var) == SCIP_VARTYPE_IMPLINT);
809  	         assert(SCIPsetIsFeasIntegral(set, SCIPvarGetLbLocal(var)));
810  	         assert(SCIPsetIsFeasIntegral(set, SCIPvarGetUbLocal(var)));
811  	         assert(SCIPsetIsLE(set, SCIPvarGetLbLocal(var), SCIPvarGetUbLocal(var)));
812  	
813  	         if( SCIPsetIsLT(set, SCIPvarGetLbLocal(var), SCIPvarGetUbLocal(var)) )
814  	         {
815  	            assert(0 <= var->pseudocandindex && var->pseudocandindex < branchcand->npseudocands);
816  	            assert(branchcand->pseudocands[var->pseudocandindex] == var);
817  	            npcs++;
818  	         }
819  	         else
820  	         {
821  	            assert(var->pseudocandindex == -1);
822  	         }
823  	      }
824  	      assert(branchcand->npseudocands == npcs);
825  	      for (v = 0; v < branchcand->npriopseudocands; ++v)
826  	         assert( branchcand->pseudocands[v]->branchpriority == branchcand->pseudomaxpriority );
827  	   }
828  	#endif
829  	
830  	   /* assign return values */
831  	   if( pseudocands != NULL )
832  	      *pseudocands = branchcand->pseudocands;
833  	   if( npseudocands != NULL )
834  	      *npseudocands = branchcand->npseudocands;
835  	   if( npriopseudocands != NULL )
836  	      *npriopseudocands = (set->branch_preferbinary && branchcand->npriopseudobins > 0 ? branchcand->npriopseudobins
837  	         : branchcand->npriopseudocands);
838  	
839  	   return SCIP_OKAY;
840  	}
841  	
842  	/** gets number of branching candidates for pseudo solution branching (non-fixed variables) */
843  	int SCIPbranchcandGetNPseudoCands(
844  	   SCIP_BRANCHCAND*      branchcand          /**< branching candidate storage */
845  	   )
846  	{
847  	   assert(branchcand != NULL);
848  	
849  	   return branchcand->npseudocands;
850  	}
851  	
852  	/** gets number of branching candidates with maximal branch priority for pseudo solution branching */
853  	int SCIPbranchcandGetNPrioPseudoCands(
854  	   SCIP_BRANCHCAND*      branchcand          /**< branching candidate storage */
855  	   )
856  	{
857  	   assert(branchcand != NULL);
858  	
859  	   return branchcand->npriopseudocands;
860  	}
861  	
862  	/** gets number of binary branching candidates with maximal branch priority for pseudo solution branching */
863  	int SCIPbranchcandGetNPrioPseudoBins(
864  	   SCIP_BRANCHCAND*      branchcand          /**< branching candidate storage */
865  	   )
866  	{
867  	   assert(branchcand != NULL);
868  	
869  	   return branchcand->npriopseudobins;
870  	}
871  	
872  	/** gets number of integer branching candidates with maximal branch priority for pseudo solution branching */
873  	int SCIPbranchcandGetNPrioPseudoInts(
874  	   SCIP_BRANCHCAND*      branchcand          /**< branching candidate storage */
875  	   )
876  	{
877  	   assert(branchcand != NULL);
878  	
879  	   return branchcand->npriopseudoints;
880  	}
881  	
882  	/** gets number of implicit integer branching candidates with maximal branch priority for pseudo solution branching */
883  	int SCIPbranchcandGetNPrioPseudoImpls(
884  	   SCIP_BRANCHCAND*      branchcand          /**< branching candidate storage */
885  	   )
886  	{
887  	   assert(branchcand != NULL);
888  	
889  	   return branchcand->npriopseudocands - branchcand->npriopseudobins - branchcand->npriopseudoints;
890  	}
891  	
892  	/** insert pseudocand at given position, or to the first positions of the maximal priority candidates, using the
893  	 *  given position as free slot for the other candidates
894  	 */
895  	static
896  	void branchcandInsertPseudoCand(
897  	   SCIP_BRANCHCAND*      branchcand,         /**< branching candidate storage */
898  	   SCIP_VAR*             var,                /**< variable to insert */
899  	   int                   insertpos           /**< free position to insert the variable */
900  	   )
901  	{
902  	   SCIP_VARTYPE vartype;
903  	   int branchpriority;
904  	
905  	   assert(branchcand != NULL);
906  	   assert(var != NULL);
907  	   assert(branchcand->npriopseudocands <= insertpos && insertpos < branchcand->npseudocands);
908  	   assert(branchcand->npseudocands <= branchcand->pseudocandssize);
909  	
910  	   vartype = SCIPvarGetType(var);
911  	   branchpriority = SCIPvarGetBranchPriority(var);
912  	
913  	   SCIPdebugMessage("inserting pseudo candidate <%s> of type %d and priority %d into candidate set at position %d (maxprio: %d)\n",
914  	      SCIPvarGetName(var), vartype, branchpriority, insertpos, branchcand->pseudomaxpriority);
915  	
916  	   /* insert the variable into pseudocands, making sure, that the highest priority candidates are at the front
917  	    * and ordered binaries, integers, implicit integers
918  	    */
919  	   if( branchpriority > branchcand->pseudomaxpriority )
920  	   {
921  	      /* candidate has higher priority than the current maximum:
922  	       * move it to the front and declare it to be the single best candidate
923  	       */
924  	      if( insertpos != 0 )
925  	      {
926  	         branchcand->pseudocands[insertpos] = branchcand->pseudocands[0];
927  	         branchcand->pseudocands[insertpos]->pseudocandindex = insertpos;
928  	         insertpos = 0;
929  	      }
930  	      branchcand->npriopseudocands = 1;
931  	      branchcand->npriopseudobins = (vartype == SCIP_VARTYPE_BINARY ? 1 : 0);
932  	      branchcand->npriopseudoints = (vartype == SCIP_VARTYPE_INTEGER ? 1 : 0);
933  	      branchcand->pseudomaxpriority = branchpriority;
934  	   }
935  	   else if( branchpriority == branchcand->pseudomaxpriority )
936  	   {
937  	      /* candidate has equal priority as the current maximum:
938  	       * move away the first non-maximal priority candidate, move the current candidate to the correct
939  	       * slot (binaries first, integers next, implicit integers last) and increase the number of maximal priority candidates
940  	       */
941  	      if( insertpos != branchcand->npriopseudocands )
942  	      {
943  	         branchcand->pseudocands[insertpos] = branchcand->pseudocands[branchcand->npriopseudocands];
944  	         branchcand->pseudocands[insertpos]->pseudocandindex = insertpos;
945  	         insertpos = branchcand->npriopseudocands;
946  	      }
947  	      branchcand->npriopseudocands++;
948  	      if( vartype == SCIP_VARTYPE_BINARY || vartype == SCIP_VARTYPE_INTEGER )
949  	      {
950  	         if( insertpos != branchcand->npriopseudobins + branchcand->npriopseudoints )
951  	         {
952  	            branchcand->pseudocands[insertpos] =
953  	               branchcand->pseudocands[branchcand->npriopseudobins + branchcand->npriopseudoints];
954  	            branchcand->pseudocands[insertpos]->pseudocandindex = insertpos;
955  	            insertpos = branchcand->npriopseudobins + branchcand->npriopseudoints;
956  	         }
957  	         branchcand->npriopseudoints++;
958  	
959  	         if( vartype == SCIP_VARTYPE_BINARY )
960  	         {
961  	            if( insertpos != branchcand->npriopseudobins )
962  	            {
963  	               branchcand->pseudocands[insertpos] = branchcand->pseudocands[branchcand->npriopseudobins];
964  	               branchcand->pseudocands[insertpos]->pseudocandindex = insertpos;
965  	               insertpos = branchcand->npriopseudobins;
966  	            }
967  	            branchcand->npriopseudobins++;
968  	            branchcand->npriopseudoints--;
969  	         }
970  	      }
971  	   }
972  	   branchcand->pseudocands[insertpos] = var;
973  	   var->pseudocandindex = insertpos;
974  	
975  	   SCIPdebugMessage(" -> inserted at position %d (npriopseudocands=%d)\n", insertpos, branchcand->npriopseudocands);
976  	
977  	   assert(0 <= branchcand->npriopseudocands && branchcand->npriopseudocands <= branchcand->npseudocands);
978  	   assert(0 <= branchcand->npriopseudobins && branchcand->npriopseudobins <= branchcand->npriopseudocands);
979  	   assert(0 <= branchcand->npriopseudoints && branchcand->npriopseudoints <= branchcand->npriopseudocands);
980  	}
981  	
982  	/** sorts the pseudo branching candidates, such that the candidates of maximal priority are at the front,
983  	 *  ordered by binaries, integers, implicit integers
984  	 */
985  	static
986  	void branchcandSortPseudoCands(
987  	   SCIP_BRANCHCAND*      branchcand          /**< branching candidate storage */
988  	   )
989  	{
990  	   SCIP_VAR* var;
991  	   int i;
992  	
993  	   assert(branchcand != NULL);
994  	   assert(branchcand->npriopseudocands == 0); /* is only be called after removal of last maximal candidate */
995  	   assert(branchcand->npriopseudobins == 0);
996  	   assert(branchcand->npriopseudoints == 0);
997  	
998  	   SCIPdebugMessage("resorting pseudo candidates\n");
999  	
1000 	   branchcand->pseudomaxpriority = INT_MIN;
1001 	
1002 	   for( i = 0; i < branchcand->npseudocands; ++i )
1003 	   {
1004 	      var = branchcand->pseudocands[i];
1005 	      assert(var->pseudocandindex == i);
1006 	
1007 	      if( SCIPvarGetBranchPriority(var) >= branchcand->pseudomaxpriority )
1008 	         branchcandInsertPseudoCand(branchcand, var, i);
1009 	   }
1010 	
1011 	   assert(0 <= branchcand->npriopseudocands && branchcand->npriopseudocands <= branchcand->npseudocands);
1012 	   assert(0 <= branchcand->npriopseudobins && branchcand->npriopseudobins <= branchcand->npriopseudocands);
1013 	   assert(0 <= branchcand->npriopseudoints && branchcand->npriopseudoints <= branchcand->npriopseudocands);
1014 	#ifndef NDEBUG
1015 	   {
1016 	      for (i = 0; i < branchcand->npriopseudocands; ++i)
1017 	         assert( branchcand->pseudocands[i]->branchpriority == branchcand->pseudomaxpriority );
1018 	   }
1019 	#endif
1020 	}
1021 	
1022 	/** removes pseudo candidate from pseudocands array
1023 	 */
1024 	static
1025 	void branchcandRemovePseudoCand(
1026 	   SCIP_BRANCHCAND*      branchcand,         /**< branching candidate storage */
1027 	   SCIP_VAR*             var                 /**< variable to remove */
1028 	   )
1029 	{
1030 	   int freepos;
1031 	
1032 	   assert(branchcand != NULL);
1033 	   assert(var != NULL);
1034 	   assert(var->pseudocandindex < branchcand->npseudocands);
1035 	   assert(branchcand->pseudocands[var->pseudocandindex] == var);
1036 	   assert(branchcand->pseudocands[branchcand->npseudocands-1] != NULL);
1037 	
1038 	   /* Note that the branching priority of the variable to be removed is not necessarily equal to pseudomaxpriority, since
1039 	    * the status of the variable might have changed, leading to a change in the branching priority. Moreover, if the
1040 	    * variable was part of an aggregation, even other variables might at this point have different priorities. */
1041 	   SCIPdebugMessage("removing pseudo candidate <%s> of type %d and priority %d at %d from candidate set (maxprio: %d)\n",
1042 	      SCIPvarGetName(var), SCIPvarGetType(var), SCIPvarGetBranchPriority(var), var->pseudocandindex,
1043 	      branchcand->pseudomaxpriority);
1044 	
1045 	   /* delete the variable from pseudocands, making sure, that the highest priority candidates are at the front
1046 	    * and ordered binaries, integers, implicit integers
1047 	    */
1048 	   freepos = var->pseudocandindex;
1049 	   var->pseudocandindex = -1;
1050 	   assert(0 <= freepos && freepos < branchcand->npseudocands);
1051 	
1052 	   if( freepos < branchcand->npriopseudobins )
1053 	   {
1054 	      /* a binary candidate of maximal priority was removed */
1055 	      assert(SCIPvarGetType(var) == SCIP_VARTYPE_BINARY);
1056 	      if( freepos != branchcand->npriopseudobins - 1 )
1057 	      {
1058 	         branchcand->pseudocands[freepos] = branchcand->pseudocands[branchcand->npriopseudobins - 1];
1059 	         branchcand->pseudocands[freepos]->pseudocandindex = freepos;
1060 	         freepos = branchcand->npriopseudobins - 1;
1061 	      }
1062 	      branchcand->npriopseudobins--;
1063 	      branchcand->npriopseudoints++;
1064 	   }
1065 	
1066 	   if( freepos < branchcand->npriopseudobins + branchcand->npriopseudoints )
1067 	   {
1068 	      /* a binary or integer candidate of maximal priority was removed */
1069 	      assert(SCIPvarGetType(var) == SCIP_VARTYPE_BINARY || SCIPvarGetType(var) == SCIP_VARTYPE_INTEGER);
1070 	      if( freepos != branchcand->npriopseudobins + branchcand->npriopseudoints - 1 )
1071 	      {
1072 	         branchcand->pseudocands[freepos] =
1073 	            branchcand->pseudocands[branchcand->npriopseudobins + branchcand->npriopseudoints - 1];
1074 	         branchcand->pseudocands[freepos]->pseudocandindex = freepos;
1075 	         freepos = branchcand->npriopseudobins + branchcand->npriopseudoints - 1;
1076 	      }
1077 	      branchcand->npriopseudoints--;
1078 	   }
1079 	
1080 	   if( freepos < branchcand->npriopseudocands )
1081 	   {
1082 	      /* a candidate of maximal priority was removed */
1083 	      if( freepos != branchcand->npriopseudocands - 1 )
1084 	      {
1085 	         branchcand->pseudocands[freepos] = branchcand->pseudocands[branchcand->npriopseudocands - 1];
1086 	         branchcand->pseudocands[freepos]->pseudocandindex = freepos;
1087 	         freepos = branchcand->npriopseudocands - 1;
1088 	      }
1089 	      branchcand->npriopseudocands--;
1090 	   }
1091 	   if( freepos != branchcand->npseudocands - 1 )
1092 	   {
1093 	      branchcand->pseudocands[freepos] = branchcand->pseudocands[branchcand->npseudocands - 1];
1094 	      branchcand->pseudocands[freepos]->pseudocandindex = freepos;
1095 	   }
1096 	   branchcand->npseudocands--;
1097 	
1098 	   assert(0 <= branchcand->npriopseudocands && branchcand->npriopseudocands <= branchcand->npseudocands);
1099 	   assert(0 <= branchcand->npriopseudobins && branchcand->npriopseudobins <= branchcand->npriopseudocands);
1100 	   assert(0 <= branchcand->npriopseudoints && branchcand->npriopseudoints <= branchcand->npriopseudocands);
1101 	
1102 	   /* if all maximal priority candidates were removed, resort the array s.t. the new maximal priority candidates
1103 	    * are at the front
1104 	    */
1105 	   if( branchcand->npriopseudocands == 0 )
1106 	      branchcandSortPseudoCands(branchcand);
1107 	}
1108 	
1109 	/** removes variable from branching candidate list */
1110 	SCIP_RETCODE SCIPbranchcandRemoveVar(
1111 	   SCIP_BRANCHCAND*      branchcand,         /**< branching candidate storage */
1112 	   SCIP_VAR*             var                 /**< variable that changed its bounds */
1113 	   )
1114 	{
1115 	   assert(var != NULL);
1116 	
1117 	   /* make sure, variable is not member of the pseudo branching candidate list */
1118 	   if( var->pseudocandindex >= 0 )
1119 	   {
1120 	      branchcandRemovePseudoCand(branchcand, var);
1121 	   }
1122 	
1123 	   return SCIP_OKAY;
1124 	}
1125 	
1126 	/** updates branching candidate list for a given variable */
1127 	SCIP_RETCODE SCIPbranchcandUpdateVar(
1128 	   SCIP_BRANCHCAND*      branchcand,         /**< branching candidate storage */
1129 	   SCIP_SET*             set,                /**< global SCIP settings */
1130 	   SCIP_VAR*             var                 /**< variable that changed its bounds */
1131 	   )
1132 	{
1133 	   assert(branchcand != NULL);
1134 	   assert(var != NULL);
1135 	
1136 	   if( (SCIPvarGetStatus(var) == SCIP_VARSTATUS_LOOSE || SCIPvarGetStatus(var) == SCIP_VARSTATUS_COLUMN)
1137 	      && SCIPvarGetType(var) != SCIP_VARTYPE_CONTINUOUS
1138 	      && SCIPsetIsLT(set, SCIPvarGetLbLocal(var), SCIPvarGetUbLocal(var)) )
1139 	   {
1140 	      /* variable is neither continuous nor fixed and has non-empty domain: make sure it is member of the pseudo branching candidate list */
1141 	      if( var->pseudocandindex == -1 )
1142 	      {
1143 	         SCIP_CALL( ensurePseudocandsSize(branchcand, set, branchcand->npseudocands+1) );
1144 	
1145 	         branchcand->npseudocands++;
1146 	         branchcandInsertPseudoCand(branchcand, var, branchcand->npseudocands-1);
1147 	      }
1148 	   }
1149 	   else
1150 	   {
1151 	      assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_ORIGINAL
1152 	         || SCIPvarGetStatus(var) == SCIP_VARSTATUS_FIXED
1153 	         || SCIPvarGetStatus(var) == SCIP_VARSTATUS_AGGREGATED
1154 	         || SCIPvarGetStatus(var) == SCIP_VARSTATUS_MULTAGGR
1155 	         || SCIPvarGetStatus(var) == SCIP_VARSTATUS_NEGATED
1156 	         || SCIPvarGetType(var) == SCIP_VARTYPE_CONTINUOUS
1157 	         || SCIPsetIsGE(set, SCIPvarGetLbLocal(var), SCIPvarGetUbLocal(var)));
1158 	
1159 	      /* variable is continuous or fixed or has empty domain: make sure it is not member of the pseudo branching candidate list */
1160 	      SCIP_CALL( SCIPbranchcandRemoveVar(branchcand, var) );
1161 	   }
1162 	
1163 	   return SCIP_OKAY;
1164 	}
1165 	
1166 	/** updates branching priority of the given variable and update the pseudo candidate array if needed */
1167 	SCIP_RETCODE SCIPbranchcandUpdateVarBranchPriority(
1168 	   SCIP_BRANCHCAND*      branchcand,         /**< branching candidate storage */
1169 	   SCIP_SET*             set,                /**< global SCIP settings */
1170 	   SCIP_VAR*             var,                /**< variable that changed its bounds */
1171 	   int                   branchpriority      /**< branch priority of the variable */
1172 	   )
1173 	{
1174 	   int oldbranchpriority;
1175 	   int pseudomaxpriority;
1176 	
1177 	   assert(branchcand != NULL);
1178 	
1179 	   oldbranchpriority = SCIPvarGetBranchPriority(var);
1180 	
1181 	   if( oldbranchpriority == branchpriority )
1182 	      return SCIP_OKAY;
1183 	
1184 	   pseudomaxpriority = branchcand->pseudomaxpriority;
1185 	
1186 	   /* if the variable currently belongs to the priority set or the new branching priority is larger than the current one,
1187 	    * remove it from the pseudo branch candidate array */
1188 	   if( oldbranchpriority == pseudomaxpriority || branchpriority > pseudomaxpriority )
1189 	   {
1190 	      SCIP_CALL( SCIPbranchcandRemoveVar(branchcand, var) );
1191 	      assert(var->pseudocandindex == -1);
1192 	   }
1193 	
1194 	   /* change the branching priority of the variable */
1195 	   SCIP_CALL( SCIPvarChgBranchPriority(var, branchpriority) );
1196 	
1197 	   /* if the variable is not part of the pseudo branching candidate array, check if it is a pseudo branching candidate
1198 	    * and add it if so */
1199 	   SCIP_CALL( SCIPbranchcandUpdateVar(branchcand, set, var) );
1200 	
1201 	   return SCIP_OKAY;
1202 	}
1203 	
1204 	
1205 	
1206 	/*
1207 	 * branching rule methods
1208 	 */
1209 	
1210 	/** compares two branching rules w. r. to their priority */
1211 	SCIP_DECL_SORTPTRCOMP(SCIPbranchruleComp)
1212 	{  /*lint --e{715}*/
1213 	   return ((SCIP_BRANCHRULE*)elem2)->priority - ((SCIP_BRANCHRULE*)elem1)->priority;
1214 	}
1215 	
1216 	/** comparison method for sorting branching rules w.r.t. to their name */
1217 	SCIP_DECL_SORTPTRCOMP(SCIPbranchruleCompName)
1218 	{
1219 	   return strcmp(SCIPbranchruleGetName((SCIP_BRANCHRULE*)elem1), SCIPbranchruleGetName((SCIP_BRANCHRULE*)elem2));
1220 	}
1221 	
1222 	/** method to call, when the priority of a branching rule was changed */
1223 	static
1224 	SCIP_DECL_PARAMCHGD(paramChgdBranchrulePriority)
1225 	{  /*lint --e{715}*/
1226 	   SCIP_PARAMDATA* paramdata;
1227 	
1228 	   paramdata = SCIPparamGetData(param);
1229 	   assert(paramdata != NULL);
1230 	
1231 	   /* use SCIPsetBranchrulePriority() to mark the branchrules unsorted */
1232 	   SCIP_CALL( SCIPsetBranchrulePriority(scip, (SCIP_BRANCHRULE*)paramdata, SCIPparamGetInt(param)) ); /*lint !e740*/
1233 	
1234 	   return SCIP_OKAY;
1235 	}
1236 	
1237 	/** copies the given branchrule to a new scip */
1238 	SCIP_RETCODE SCIPbranchruleCopyInclude(
1239 	   SCIP_BRANCHRULE*      branchrule,         /**< branchrule */
1240 	   SCIP_SET*             set                 /**< SCIP_SET of SCIP to copy to */
1241 	   )
1242 	{
1243 	   assert(branchrule != NULL);
1244 	   assert(set != NULL);
1245 	   assert(set->scip != NULL);
1246 	
1247 	   if( branchrule->branchcopy != NULL )
1248 	   {
1249 	      SCIPsetDebugMsg(set, "including branching rule %s in subscip %p\n", SCIPbranchruleGetName(branchrule), (void*)set->scip);
1250 	      SCIP_CALL( branchrule->branchcopy(set->scip, branchrule) );
1251 	   }
1252 	
1253 	   return SCIP_OKAY;
1254 	}
1255 	
1256 	/** internal method for creating a branching rule */
1257 	static
1258 	SCIP_RETCODE doBranchruleCreate(
1259 	   SCIP_BRANCHRULE**     branchrule,         /**< pointer to store branching rule */
1260 	   SCIP_SET*             set,                /**< global SCIP settings */
1261 	   SCIP_MESSAGEHDLR*     messagehdlr,        /**< message handler */
1262 	   BMS_BLKMEM*           blkmem,             /**< block memory for parameter settings */
1263 	   const char*           name,               /**< name of branching rule */
1264 	   const char*           desc,               /**< description of branching rule */
1265 	   int                   priority,           /**< priority of the branching rule */
1266 	   int                   maxdepth,           /**< maximal depth level, up to which this branching rule should be used (or -1) */
1267 	   SCIP_Real             maxbounddist,       /**< maximal relative distance from current node's dual bound to primal bound
1268 	                                              *   compared to best node's dual bound for applying branching rule
1269 	                                              *   (0.0: only on current best node, 1.0: on all nodes) */
1270 	   SCIP_DECL_BRANCHCOPY  ((*branchcopy)),    /**< copy method of branching rule */
1271 	   SCIP_DECL_BRANCHFREE  ((*branchfree)),    /**< destructor of branching rule */
1272 	   SCIP_DECL_BRANCHINIT  ((*branchinit)),    /**< initialize branching rule */
1273 	   SCIP_DECL_BRANCHEXIT  ((*branchexit)),    /**< deinitialize branching rule */
1274 	   SCIP_DECL_BRANCHINITSOL((*branchinitsol)),/**< solving process initialization method of branching rule */
1275 	   SCIP_DECL_BRANCHEXITSOL((*branchexitsol)),/**< solving process deinitialization method of branching rule */
1276 	   SCIP_DECL_BRANCHEXECLP((*branchexeclp)),  /**< branching execution method for fractional LP solutions */
1277 	   SCIP_DECL_BRANCHEXECEXT((*branchexecext)),/**< branching execution method for external solutions */
1278 	   SCIP_DECL_BRANCHEXECPS((*branchexecps)),  /**< branching execution method for not completely fixed pseudo solutions */
1279 	   SCIP_BRANCHRULEDATA*  branchruledata      /**< branching rule data */
1280 	   )
1281 	{
1282 	   char paramname[SCIP_MAXSTRLEN];
1283 	   char paramdesc[SCIP_MAXSTRLEN];
1284 	
1285 	   assert(branchrule != NULL);
1286 	   assert(name != NULL);
1287 	   assert(desc != NULL);
1288 	
1289 	   SCIP_ALLOC( BMSallocMemory(branchrule) );
1290 	   BMSclearMemory(*branchrule);
1291 	
1292 	   SCIP_ALLOC( BMSduplicateMemoryArray(&(*branchrule)->name, name, strlen(name)+1) );
1293 	   SCIP_ALLOC( BMSduplicateMemoryArray(&(*branchrule)->desc, desc, strlen(desc)+1) );
1294 	   (*branchrule)->priority = priority;
1295 	   (*branchrule)->maxdepth = maxdepth;
1296 	   (*branchrule)->maxbounddist = maxbounddist;
1297 	   (*branchrule)->branchcopy = branchcopy;
1298 	   (*branchrule)->branchfree = branchfree;
1299 	   (*branchrule)->branchinit = branchinit;
1300 	   (*branchrule)->branchexit = branchexit;
1301 	   (*branchrule)->branchinitsol = branchinitsol;
1302 	   (*branchrule)->branchexitsol = branchexitsol;
1303 	   (*branchrule)->branchexeclp = branchexeclp;
1304 	   (*branchrule)->branchexecext = branchexecext;
1305 	   (*branchrule)->branchexecps = branchexecps;
1306 	   (*branchrule)->branchruledata = branchruledata;
1307 	   SCIP_CALL( SCIPclockCreate(&(*branchrule)->setuptime, SCIP_CLOCKTYPE_DEFAULT) );
1308 	   SCIP_CALL( SCIPclockCreate(&(*branchrule)->branchclock, SCIP_CLOCKTYPE_DEFAULT) );
1309 	   (*branchrule)->nlpcalls = 0;
1310 	   (*branchrule)->nexterncalls = 0;
1311 	   (*branchrule)->npseudocalls = 0;
1312 	   (*branchrule)->ncutoffs = 0;
1313 	   (*branchrule)->ncutsfound = 0;
1314 	   (*branchrule)->nconssfound = 0;
1315 	   (*branchrule)->ndomredsfound = 0;
1316 	   (*branchrule)->nchildren = 0;
1317 	   (*branchrule)->initialized = FALSE;
1318 	
1319 	   /* add parameters */
1320 	   (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "branching/%s/priority", name);
1321 	   (void) SCIPsnprintf(paramdesc, SCIP_MAXSTRLEN, "priority of branching rule <%s>", name);
1322 	   SCIP_CALL( SCIPsetAddIntParam(set, messagehdlr, blkmem, paramname, paramdesc,
1323 	         &(*branchrule)->priority, FALSE, priority, INT_MIN/4, INT_MAX/4,
1324 	         paramChgdBranchrulePriority, (SCIP_PARAMDATA*)(*branchrule)) ); /*lint !e740*/
1325 	   (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "branching/%s/maxdepth", name);
1326 	   (void) SCIPsnprintf(paramdesc, SCIP_MAXSTRLEN, "maximal depth level, up to which branching rule <%s> should be used (-1 for no limit)", name);
1327 	   SCIP_CALL( SCIPsetAddIntParam(set, messagehdlr, blkmem, paramname, paramdesc,
1328 	         &(*branchrule)->maxdepth, FALSE, maxdepth, -1, SCIP_MAXTREEDEPTH,
1329 	         NULL, NULL) ); /*lint !e740*/
1330 	   (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "branching/%s/maxbounddist", name);
1331 	   (void) SCIPsnprintf(paramdesc, SCIP_MAXSTRLEN, "maximal relative distance from current node's dual bound to primal bound compared to best node's dual bound for applying branching rule (0.0: only on current best node, 1.0: on all nodes)");
1332 	   SCIP_CALL( SCIPsetAddRealParam(set, messagehdlr, blkmem, paramname, paramdesc,
1333 	         &(*branchrule)->maxbounddist, FALSE, maxbounddist, 0.0, 1.0,
1334 	         NULL, NULL) ); /*lint !e740*/
1335 	
1336 	   return SCIP_OKAY;
1337 	}
1338 	
1339 	/** creates a branching rule */
1340 	SCIP_RETCODE SCIPbranchruleCreate(
1341 	   SCIP_BRANCHRULE**     branchrule,         /**< pointer to store branching rule */
1342 	   SCIP_SET*             set,                /**< global SCIP settings */
1343 	   SCIP_MESSAGEHDLR*     messagehdlr,        /**< message handler */
1344 	   BMS_BLKMEM*           blkmem,             /**< block memory for parameter settings */
1345 	   const char*           name,               /**< name of branching rule */
1346 	   const char*           desc,               /**< description of branching rule */
1347 	   int                   priority,           /**< priority of the branching rule */
1348 	   int                   maxdepth,           /**< maximal depth level, up to which this branching rule should be used (or -1) */
1349 	   SCIP_Real             maxbounddist,       /**< maximal relative distance from current node's dual bound to primal bound
1350 	                                              *   compared to best node's dual bound for applying branching rule
1351 	                                              *   (0.0: only on current best node, 1.0: on all nodes) */
1352 	   SCIP_DECL_BRANCHCOPY  ((*branchcopy)),    /**< copy method of branching rule */
1353 	   SCIP_DECL_BRANCHFREE  ((*branchfree)),    /**< destructor of branching rule */
1354 	   SCIP_DECL_BRANCHINIT  ((*branchinit)),    /**< initialize branching rule */
1355 	   SCIP_DECL_BRANCHEXIT  ((*branchexit)),    /**< deinitialize branching rule */
1356 	   SCIP_DECL_BRANCHINITSOL((*branchinitsol)),/**< solving process initialization method of branching rule */
1357 	   SCIP_DECL_BRANCHEXITSOL((*branchexitsol)),/**< solving process deinitialization method of branching rule */
1358 	   SCIP_DECL_BRANCHEXECLP((*branchexeclp)),  /**< branching execution method for fractional LP solutions */
1359 	   SCIP_DECL_BRANCHEXECEXT((*branchexecext)),/**< branching execution method for external solutions */
1360 	   SCIP_DECL_BRANCHEXECPS((*branchexecps)),  /**< branching execution method for not completely fixed pseudo solutions */
1361 	   SCIP_BRANCHRULEDATA*  branchruledata      /**< branching rule data */
1362 	   )
1363 	{
1364 	   assert(branchrule != NULL);
1365 	   assert(name != NULL);
1366 	   assert(desc != NULL);
1367 	
1368 	   SCIP_CALL_FINALLY( doBranchruleCreate(branchrule, set, messagehdlr, blkmem, name, desc, priority, maxdepth,
1369 	      maxbounddist, branchcopy, branchfree, branchinit, branchexit, branchinitsol, branchexitsol, branchexeclp,
1370 	      branchexecext, branchexecps, branchruledata), (void) SCIPbranchruleFree(branchrule, set) );
1371 	
1372 	   return SCIP_OKAY;
1373 	}
1374 	
1375 	/** frees memory of branching rule */
1376 	SCIP_RETCODE SCIPbranchruleFree(
1377 	   SCIP_BRANCHRULE**     branchrule,         /**< pointer to branching rule data structure */
1378 	   SCIP_SET*             set                 /**< global SCIP settings */
1379 	   )
1380 	{
1381 	   assert(branchrule != NULL);
1382 	   if( *branchrule == NULL )
1383 	      return SCIP_OKAY;
1384 	   assert(!(*branchrule)->initialized);
1385 	   assert(set != NULL);
1386 	
1387 	   /* call destructor of branching rule */
1388 	   if( (*branchrule)->branchfree != NULL )
1389 	   {
1390 	      SCIP_CALL( (*branchrule)->branchfree(set->scip, *branchrule) );
1391 	   }
1392 	
1393 	   SCIPclockFree(&(*branchrule)->branchclock);
1394 	   SCIPclockFree(&(*branchrule)->setuptime);
1395 	   BMSfreeMemoryArrayNull(&(*branchrule)->name);
1396 	   BMSfreeMemoryArrayNull(&(*branchrule)->desc);
1397 	   BMSfreeMemory(branchrule);
1398 	
1399 	   return SCIP_OKAY;
1400 	}
1401 	
1402 	/** initializes branching rule */
1403 	SCIP_RETCODE SCIPbranchruleInit(
1404 	   SCIP_BRANCHRULE*      branchrule,         /**< branching rule */
1405 	   SCIP_SET*             set                 /**< global SCIP settings */
1406 	   )
1407 	{
1408 	   assert(branchrule != NULL);
1409 	   assert(set != NULL);
1410 	
1411 	   if( branchrule->initialized )
1412 	   {
1413 	      SCIPerrorMessage("branching rule <%s> already initialized\n", branchrule->name);
1414 	      return SCIP_INVALIDCALL;
1415 	   }
1416 	
1417 	   if( set->misc_resetstat )
1418 	   {
1419 	      SCIPclockReset(branchrule->setuptime);
1420 	      SCIPclockReset(branchrule->branchclock);
1421 	      branchrule->nlpcalls = 0;
1422 	      branchrule->nexterncalls = 0;
1423 	      branchrule->npseudocalls = 0;
1424 	      branchrule->ncutoffs = 0;
1425 	      branchrule->ncutsfound = 0;
1426 	      branchrule->nconssfound = 0;
1427 	      branchrule->ndomredsfound = 0;
1428 	      branchrule->nchildren = 0;
1429 	   }
1430 	
1431 	   if( branchrule->branchinit != NULL )
1432 	   {
1433 	      /* start timing */
1434 	      SCIPclockStart(branchrule->setuptime, set);
1435 	
1436 	      SCIP_CALL( branchrule->branchinit(set->scip, branchrule) );
1437 	
1438 	      /* stop timing */
1439 	      SCIPclockStop(branchrule->setuptime, set);
1440 	   }
1441 	   branchrule->initialized = TRUE;
1442 	
1443 	   return SCIP_OKAY;
1444 	}
1445 	
1446 	/** deinitializes branching rule */
1447 	SCIP_RETCODE SCIPbranchruleExit(
1448 	   SCIP_BRANCHRULE*      branchrule,         /**< branching rule */
1449 	   SCIP_SET*             set                 /**< global SCIP settings */
1450 	   )
1451 	{
1452 	   assert(branchrule != NULL);
1453 	   assert(set != NULL);
1454 	
1455 	   if( !branchrule->initialized )
1456 	   {
1457 	      SCIPerrorMessage("branching rule <%s> not initialized\n", branchrule->name);
1458 	      return SCIP_INVALIDCALL;
1459 	   }
1460 	
1461 	   if( branchrule->branchexit != NULL )
1462 	   {
1463 	      /* start timing */
1464 	      SCIPclockStart(branchrule->setuptime, set);
1465 	
1466 	      SCIP_CALL( branchrule->branchexit(set->scip, branchrule) );
1467 	
1468 	      /* stop timing */
1469 	      SCIPclockStop(branchrule->setuptime, set);
1470 	   }
1471 	   branchrule->initialized = FALSE;
1472 	
1473 	   return SCIP_OKAY;
1474 	}
1475 	
1476 	/** informs branching rule that the branch and bound process is being started */
1477 	SCIP_RETCODE SCIPbranchruleInitsol(
1478 	   SCIP_BRANCHRULE*      branchrule,         /**< branching rule */
1479 	   SCIP_SET*             set                 /**< global SCIP settings */
1480 	   )
1481 	{
1482 	   assert(branchrule != NULL);
1483 	   assert(set != NULL);
1484 	
1485 	   /* call solving process initialization method of branching rule */
1486 	   if( branchrule->branchinitsol != NULL )
1487 	   {
1488 	      /* start timing */
1489 	      SCIPclockStart(branchrule->setuptime, set);
1490 	
1491 	      SCIP_CALL( branchrule->branchinitsol(set->scip, branchrule) );
1492 	
1493 	      /* stop timing */
1494 	      SCIPclockStop(branchrule->setuptime, set);
1495 	   }
1496 	
1497 	   return SCIP_OKAY;
1498 	}
1499 	
1500 	/** informs branching rule that the branch and bound process data is being freed */
1501 	SCIP_RETCODE SCIPbranchruleExitsol(
1502 	   SCIP_BRANCHRULE*      branchrule,         /**< branching rule */
1503 	   SCIP_SET*             set                 /**< global SCIP settings */
1504 	   )
1505 	{
1506 	   assert(branchrule != NULL);
1507 	   assert(set != NULL);
1508 	
1509 	   /* call solving process deinitialization method of branching rule */
1510 	   if( branchrule->branchexitsol != NULL )
1511 	   {
1512 	      /* start timing */
1513 	      SCIPclockStart(branchrule->setuptime, set);
1514 	
1515 	      SCIP_CALL( branchrule->branchexitsol(set->scip, branchrule) );
1516 	
1517 	      /* stop timing */
1518 	      SCIPclockStop(branchrule->setuptime, set);
1519 	   }
1520 	
1521 	   return SCIP_OKAY;
1522 	}
1523 	
1524 	/** executes branching rule for fractional LP solution */
1525 	SCIP_RETCODE SCIPbranchruleExecLPSol(
1526 	   SCIP_BRANCHRULE*      branchrule,         /**< branching rule */
1527 	   SCIP_SET*             set,                /**< global SCIP settings */
1528 	   SCIP_STAT*            stat,               /**< problem statistics */
1529 	   SCIP_TREE*            tree,               /**< branch and bound tree */
1530 	   SCIP_SEPASTORE*       sepastore,          /**< separation storage */
1531 	   SCIP_Real             cutoffbound,        /**< global upper cutoff bound */
1532 	   SCIP_Bool             allowaddcons,       /**< should adding constraints be allowed to avoid a branching? */
1533 	   SCIP_RESULT*          result              /**< pointer to store the result of the callback method */
1534 	   )
1535 	{
1536 	   assert(branchrule != NULL);
1537 	   assert(set != NULL);
1538 	   assert(tree != NULL);
1539 	   assert(tree->focusnode != NULL);
1540 	   assert(tree->nchildren == 0);
1541 	   assert(result != NULL);
1542 	
1543 	   *result = SCIP_DIDNOTRUN;
1544 	   if( branchrule->branchexeclp != NULL
1545 	      && (branchrule->maxdepth == -1 || branchrule->maxdepth >= SCIPtreeGetCurrentDepth(tree)) )
1546 	   {
1547 	      SCIP_Real loclowerbound;
1548 	      SCIP_Real glblowerbound;
1549 	      SCIP_Bool runbranchrule;
1550 	
1551 	      loclowerbound = SCIPnodeGetLowerbound(tree->focusnode);
1552 	      glblowerbound = SCIPtreeGetLowerbound(tree, set);
1553 	
1554 	      /* we distinguish between finite and infinite global lower bounds to avoid comparisons between different values > SCIPinfinity() */
1555 	      if( SCIPsetIsInfinity(set, -glblowerbound) )
1556 	         runbranchrule = SCIPsetIsInfinity(set, -loclowerbound) || SCIPsetIsGE(set, branchrule->maxbounddist, 1.0);
1557 	      else
1558 	      {
1559 	         assert(!SCIPsetIsInfinity(set, -loclowerbound));
1560 	         runbranchrule = SCIPsetIsLE(set, loclowerbound - glblowerbound, branchrule->maxbounddist * (cutoffbound - glblowerbound));
1561 	      }
1562 	
1563 	      if( runbranchrule )
1564 	      {
1565 	         SCIP_Longint oldndomchgs;
1566 	         SCIP_Longint oldnprobdomchgs;
1567 	         SCIP_Longint oldnactiveconss;
1568 	         int oldncuts;
1569 	
1570 	         SCIPsetDebugMsg(set, "executing LP branching rule <%s>\n", branchrule->name);
1571 	
1572 	         oldndomchgs = stat->nboundchgs + stat->nholechgs;
1573 	         oldnprobdomchgs = stat->nprobboundchgs + stat->nprobholechgs;
1574 	         oldncuts = SCIPsepastoreGetNCuts(sepastore);
1575 	         oldnactiveconss = stat->nactiveconssadded;
1576 	
1577 	         /* start timing */
1578 	         SCIPclockStart(branchrule->branchclock, set);
1579 	
1580 	         /* call external method */
1581 	         SCIP_CALL( branchrule->branchexeclp(set->scip, branchrule, allowaddcons, result) );
1582 	
1583 	         /* stop timing */
1584 	         SCIPclockStop(branchrule->branchclock, set);
1585 	
1586 	         /* evaluate result */
1587 	         if( *result != SCIP_CUTOFF
1588 	            && *result != SCIP_CONSADDED
1589 	            && *result != SCIP_REDUCEDDOM
1590 	            && *result != SCIP_SEPARATED
1591 	            && *result != SCIP_BRANCHED
1592 	            && *result != SCIP_DIDNOTFIND
1593 	            && *result != SCIP_DIDNOTRUN )
1594 	         {
1595 	            SCIPerrorMessage("branching rule <%s> returned invalid result code <%d> from LP solution branching\n",
1596 	               branchrule->name, *result);
1597 	            return SCIP_INVALIDRESULT;
1598 	         }
1599 	         if( *result == SCIP_CONSADDED && !allowaddcons )
1600 	         {
1601 	            SCIPerrorMessage("branching rule <%s> added a constraint in LP solution branching without permission\n",
1602 	               branchrule->name);
1603 	            return SCIP_INVALIDRESULT;
1604 	         }
1605 	
1606 	         /* update statistics */
1607 	         if( *result != SCIP_DIDNOTRUN )
1608 	            branchrule->nlpcalls++;
1609 	         if( *result == SCIP_CUTOFF )
1610 	            branchrule->ncutoffs++;
1611 	         if( *result != SCIP_BRANCHED )
1612 	         {
1613 	            assert(tree->nchildren == 0);
1614 	
1615 	            /* update domain reductions; therefore remove the domain
1616 	             * reduction counts which were generated in probing mode */
1617 	            branchrule->ndomredsfound += stat->nboundchgs + stat->nholechgs - oldndomchgs;
1618 	            branchrule->ndomredsfound -= (stat->nprobboundchgs + stat->nprobholechgs - oldnprobdomchgs);
1619 	
1620 	            branchrule->ncutsfound += SCIPsepastoreGetNCuts(sepastore) - oldncuts; /*lint !e776*/
1621 	            branchrule->nconssfound += stat->nactiveconssadded - oldnactiveconss; /*lint !e776*/
1622 	         }
1623 	         else
1624 	            branchrule->nchildren += tree->nchildren;
1625 	      }
1626 	   }
1627 	
1628 	   return SCIP_OKAY;
1629 	}
1630 	
1631 	/** executes branching rule for external branching candidates */
1632 	SCIP_RETCODE SCIPbranchruleExecExternSol(
1633 	   SCIP_BRANCHRULE*      branchrule,         /**< branching rule */
1634 	   SCIP_SET*             set,                /**< global SCIP settings */
1635 	   SCIP_STAT*            stat,               /**< problem statistics */
1636 	   SCIP_TREE*            tree,               /**< branch and bound tree */
1637 	   SCIP_SEPASTORE*       sepastore,          /**< separation storage */
1638 	   SCIP_Real             cutoffbound,        /**< global upper cutoff bound */
1639 	   SCIP_Bool             allowaddcons,       /**< should adding constraints be allowed to avoid a branching? */
1640 	   SCIP_RESULT*          result              /**< pointer to store the result of the callback method */
1641 	   )
1642 	{
1643 	   assert(branchrule != NULL);
1644 	   assert(set != NULL);
1645 	   assert(tree != NULL);
1646 	   assert(tree->focusnode != NULL);
1647 	   assert(tree->nchildren == 0);
1648 	   assert(result != NULL);
1649 	
1650 	   *result = SCIP_DIDNOTRUN;
1651 	   if( branchrule->branchexecext != NULL
1652 	      && (branchrule->maxdepth == -1 || branchrule->maxdepth >= SCIPtreeGetCurrentDepth(tree)) )
1653 	   {
1654 	      SCIP_Real loclowerbound;
1655 	      SCIP_Real glblowerbound;
1656 	      SCIP_Bool runbranchrule;
1657 	
1658 	      loclowerbound = SCIPnodeGetLowerbound(tree->focusnode);
1659 	      glblowerbound = SCIPtreeGetLowerbound(tree, set);
1660 	      assert(!SCIPsetIsInfinity(set, loclowerbound));
1661 	
1662 	      /* we distinguish between finite and infinite global lower bounds to avoid comparisons between different values > SCIPinfinity() */
1663 	      if( SCIPsetIsInfinity(set, -glblowerbound) )
1664 	         runbranchrule = SCIPsetIsInfinity(set, -loclowerbound) || SCIPsetIsGE(set, branchrule->maxbounddist, 1.0);
1665 	      else
1666 	      {
1667 	         assert(!SCIPsetIsInfinity(set, -loclowerbound));
1668 	         runbranchrule = SCIPsetIsLE(set, loclowerbound - glblowerbound, branchrule->maxbounddist * (cutoffbound - glblowerbound));
1669 	      }
1670 	
1671 	      if( runbranchrule )
1672 	      {
1673 	         SCIP_Longint oldndomchgs;
1674 	         SCIP_Longint oldnprobdomchgs;
1675 	         int oldncuts;
1676 	         int oldnactiveconss;
1677 	
1678 	         SCIPsetDebugMsg(set, "executing external solution branching rule <%s>\n", branchrule->name);
1679 	
1680 	         oldndomchgs = stat->nboundchgs + stat->nholechgs;
1681 	         oldnprobdomchgs = stat->nprobboundchgs + stat->nprobholechgs;
1682 	         oldncuts = SCIPsepastoreGetNCuts(sepastore);
1683 	         oldnactiveconss = stat->nactiveconss;
1684 	
1685 	         /* start timing */
1686 	         SCIPclockStart(branchrule->branchclock, set);
1687 	
1688 	         /* call external method */
1689 	         SCIP_CALL( branchrule->branchexecext(set->scip, branchrule, allowaddcons, result) );
1690 	
1691 	         /* stop timing */
1692 	         SCIPclockStop(branchrule->branchclock, set);
1693 	
1694 	         /* evaluate result */
1695 	         if( *result != SCIP_CUTOFF
1696 	            && *result != SCIP_CONSADDED
1697 	            && *result != SCIP_REDUCEDDOM
1698 	            && *result != SCIP_SEPARATED
1699 	            && *result != SCIP_BRANCHED
1700 	            && *result != SCIP_DIDNOTFIND
1701 	            && *result != SCIP_DIDNOTRUN )
1702 	         {
1703 	            SCIPerrorMessage("branching rule <%s> returned invalid result code <%d> from external solution branching\n",
1704 	               branchrule->name, *result);
1705 	            return SCIP_INVALIDRESULT;
1706 	         }
1707 	         if( *result == SCIP_CONSADDED && !allowaddcons )
1708 	         {
1709 	            SCIPerrorMessage("branching rule <%s> added a constraint in external solution branching without permission\n",
1710 	               branchrule->name);
1711 	            return SCIP_INVALIDRESULT;
1712 	         }
1713 	
1714 	         /* update statistics */
1715 	         if( *result != SCIP_DIDNOTRUN )
1716 	            branchrule->nexterncalls++;
1717 	         if( *result == SCIP_CUTOFF )
1718 	            branchrule->ncutoffs++;
1719 	         if( *result != SCIP_BRANCHED )
1720 	         {
1721 	            assert(tree->nchildren == 0);
1722 	
1723 	            /* update domain reductions; therefore remove the domain
1724 	             * reduction counts which were generated in probing mode */
1725 	            branchrule->ndomredsfound += stat->nboundchgs + stat->nholechgs - oldndomchgs;
1726 	            branchrule->ndomredsfound -= (stat->nprobboundchgs + stat->nprobholechgs - oldnprobdomchgs);
1727 	
1728 	            branchrule->ncutsfound += SCIPsepastoreGetNCuts(sepastore) - oldncuts; /*lint !e776*/
1729 	            branchrule->nconssfound += stat->nactiveconss - oldnactiveconss; /*lint !e776*/
1730 	         }
1731 	         else
1732 	            branchrule->nchildren += tree->nchildren;
1733 	      }
1734 	   }
1735 	   return SCIP_OKAY;
1736 	}
1737 	
1738 	/** executes branching rule for not completely fixed pseudo solution */
1739 	SCIP_RETCODE SCIPbranchruleExecPseudoSol(
1740 	   SCIP_BRANCHRULE*      branchrule,         /**< branching rule */
1741 	   SCIP_SET*             set,                /**< global SCIP settings */
1742 	   SCIP_STAT*            stat,               /**< problem statistics */
1743 	   SCIP_TREE*            tree,               /**< branch and bound tree */
1744 	   SCIP_Real             cutoffbound,        /**< global upper cutoff bound */
1745 	   SCIP_Bool             allowaddcons,       /**< should adding constraints be allowed to avoid a branching? */
1746 	   SCIP_RESULT*          result              /**< pointer to store the result of the callback method */
1747 	   )
1748 	{
1749 	   assert(branchrule != NULL);
1750 	   assert(set != NULL);
1751 	   assert(tree != NULL);
1752 	   assert(tree->nchildren == 0);
1753 	   assert(result != NULL);
1754 	
1755 	   *result = SCIP_DIDNOTRUN;
1756 	   if( branchrule->branchexecps != NULL
1757 	      && (branchrule->maxdepth == -1 || branchrule->maxdepth >= SCIPtreeGetCurrentDepth(tree)) )
1758 	   {
1759 	      SCIP_Real loclowerbound;
1760 	      SCIP_Real glblowerbound;
1761 	      SCIP_Bool runbranchrule;
1762 	
1763 	      loclowerbound = SCIPnodeGetLowerbound(tree->focusnode);
1764 	      glblowerbound = SCIPtreeGetLowerbound(tree, set);
1765 	
1766 	      /* we distinguish between finite and infinite global lower bounds to avoid comparisons between different values > SCIPinfinity() */
1767 	      if( SCIPsetIsInfinity(set, -glblowerbound) )
1768 	         runbranchrule = SCIPsetIsInfinity(set, -loclowerbound) || SCIPsetIsGE(set, branchrule->maxbounddist, 1.0);
1769 	      else
1770 	      {
1771 	         assert(!SCIPsetIsInfinity(set, -loclowerbound));
1772 	         runbranchrule = SCIPsetIsLE(set, loclowerbound - glblowerbound, branchrule->maxbounddist * (cutoffbound - glblowerbound));
1773 	      }
1774 	
1775 	      if( runbranchrule )
1776 	      {
1777 	         SCIP_Longint oldndomchgs;
1778 	         SCIP_Longint oldnprobdomchgs;
1779 	         SCIP_Longint oldnactiveconss;
1780 	
1781 	         SCIPsetDebugMsg(set, "executing pseudo branching rule <%s>\n", branchrule->name);
1782 	
1783 	         oldndomchgs = stat->nboundchgs + stat->nholechgs;
1784 	         oldnprobdomchgs = stat->nprobboundchgs + stat->nprobholechgs;
1785 	         oldnactiveconss = stat->nactiveconss;
1786 	
1787 	         /* start timing */
1788 	         SCIPclockStart(branchrule->branchclock, set);
1789 	
1790 	         /* call external method */
1791 	         SCIP_CALL( branchrule->branchexecps(set->scip, branchrule, allowaddcons, result) );
1792 	
1793 	         /* stop timing */
1794 	         SCIPclockStop(branchrule->branchclock, set);
1795 	
1796 	         /* evaluate result */
1797 	         if( *result != SCIP_CUTOFF
1798 	            && *result != SCIP_CONSADDED
1799 	            && *result != SCIP_REDUCEDDOM
1800 	            && *result != SCIP_BRANCHED
1801 	            && *result != SCIP_DIDNOTFIND
1802 	            && *result != SCIP_DIDNOTRUN )
1803 	         {
1804 	            SCIPerrorMessage("branching rule <%s> returned invalid result code <%d> from pseudo solution branching\n",
1805 	               branchrule->name, *result);
1806 	            return SCIP_INVALIDRESULT;
1807 	         }
1808 	         if( *result == SCIP_CONSADDED && !allowaddcons )
1809 	         {
1810 	            SCIPerrorMessage("branching rule <%s> added a constraint in pseudo solution branching without permission\n",
1811 	               branchrule->name);
1812 	            return SCIP_INVALIDRESULT;
1813 	         }
1814 	
1815 	         /* update statistics */
1816 	         if( *result != SCIP_DIDNOTRUN )
1817 	            branchrule->npseudocalls++;
1818 	         if( *result == SCIP_CUTOFF )
1819 	            branchrule->ncutoffs++;
1820 	         if( *result != SCIP_BRANCHED )
1821 	         {
1822 	            assert(tree->nchildren == 0);
1823 	
1824 	            /* update domain reductions; therefore remove the domain
1825 	             * reduction counts which were generated in probing mode */
1826 	            branchrule->ndomredsfound += stat->nboundchgs + stat->nholechgs - oldndomchgs;
1827 	            branchrule->ndomredsfound -= (stat->nprobboundchgs + stat->nprobholechgs - oldnprobdomchgs);
1828 	
1829 	            branchrule->nconssfound += stat->nactiveconss - oldnactiveconss;
1830 	         }
1831 	         else
1832 	            branchrule->nchildren += tree->nchildren;
1833 	      }
1834 	   }
1835 	
1836 	   return SCIP_OKAY;
1837 	}
1838 	
1839 	/** gets user data of branching rule */
1840 	SCIP_BRANCHRULEDATA* SCIPbranchruleGetData(
1841 	   SCIP_BRANCHRULE*      branchrule          /**< branching rule */
1842 	   )
1843 	{
1844 	   assert(branchrule != NULL);
1845 	
(1) Event deref_parm: Directly dereferencing parameter "branchrule".
1846 	   return branchrule->branchruledata;
1847 	}
1848 	
1849 	/** sets user data of branching rule; user has to free old data in advance! */
1850 	void SCIPbranchruleSetData(
1851 	   SCIP_BRANCHRULE*      branchrule,         /**< branching rule */
1852 	   SCIP_BRANCHRULEDATA*  branchruledata      /**< new branching rule user data */
1853 	   )
1854 	{
1855 	   assert(branchrule != NULL);
1856 	
1857 	   branchrule->branchruledata = branchruledata;
1858 	}
1859 	
1860 	/** sets copy method of branching rule */
1861 	void SCIPbranchruleSetCopy(
1862 	   SCIP_BRANCHRULE*      branchrule,         /**< branching rule */
1863 	   SCIP_DECL_BRANCHCOPY  ((*branchcopy))     /**< copy method of branching rule or NULL if you don't want to copy your plugin into sub-SCIPs */
1864 	   )
1865 	{
1866 	   assert(branchrule != NULL);
1867 	
1868 	   branchrule->branchcopy = branchcopy;
1869 	}
1870 	
1871 	/** sets destructor method of branching rule */
1872 	void SCIPbranchruleSetFree(
1873 	   SCIP_BRANCHRULE*      branchrule,         /**< branching rule */
1874 	   SCIP_DECL_BRANCHFREE  ((*branchfree))     /**< destructor of branching rule */
1875 	   )
1876 	{
1877 	   assert(branchrule != NULL);
1878 	
1879 	   branchrule->branchfree = branchfree;
1880 	}
1881 	
1882 	/** sets initialization method of branching rule */
1883 	void SCIPbranchruleSetInit(
1884 	   SCIP_BRANCHRULE*      branchrule,         /**< branching rule */
1885 	   SCIP_DECL_BRANCHINIT  ((*branchinit))     /**< initialize branching rule */
1886 	   )
1887 	{
1888 	   assert(branchrule != NULL);
1889 	
1890 	   branchrule->branchinit = branchinit;
1891 	}
1892 	
1893 	/** sets deinitialization method of branching rule */
1894 	void SCIPbranchruleSetExit(
1895 	   SCIP_BRANCHRULE*      branchrule,         /**< branching rule */
1896 	   SCIP_DECL_BRANCHEXIT  ((*branchexit))     /**< deinitialize branching rule */
1897 	   )
1898 	{
1899 	   assert(branchrule != NULL);
1900 	
1901 	   branchrule->branchexit = branchexit;
1902 	}
1903 	
1904 	/** sets solving process initialization method of branching rule */
1905 	void SCIPbranchruleSetInitsol(
1906 	   SCIP_BRANCHRULE*      branchrule,         /**< branching rule */
1907 	   SCIP_DECL_BRANCHINITSOL((*branchinitsol)) /**< solving process initialization method of branching rule */
1908 	   )
1909 	{
1910 	   assert(branchrule != NULL);
1911 	
1912 	   branchrule->branchinitsol = branchinitsol;
1913 	}
1914 	
1915 	/** sets solving process deinitialization method of branching rule */
1916 	void SCIPbranchruleSetExitsol(
1917 	   SCIP_BRANCHRULE*      branchrule,         /**< branching rule */
1918 	   SCIP_DECL_BRANCHEXITSOL((*branchexitsol)) /**< solving process deinitialization method of branching rule */
1919 	   )
1920 	{
1921 	   assert(branchrule != NULL);
1922 	
1923 	   branchrule->branchexitsol = branchexitsol;
1924 	}
1925 	
1926 	
1927 	
1928 	/** sets branching execution method for fractional LP solutions */
1929 	void SCIPbranchruleSetExecLp(
1930 	   SCIP_BRANCHRULE*      branchrule,         /**< branching rule */
1931 	   SCIP_DECL_BRANCHEXECLP((*branchexeclp))   /**< branching execution method for fractional LP solutions */
1932 	   )
1933 	{
1934 	   assert(branchrule != NULL);
1935 	
1936 	   branchrule->branchexeclp = branchexeclp;
1937 	}
1938 	
1939 	/** sets branching execution method for external candidates  */
1940 	void SCIPbranchruleSetExecExt(
1941 	   SCIP_BRANCHRULE*      branchrule,         /**< branching rule */
1942 	   SCIP_DECL_BRANCHEXECEXT((*branchexecext)) /**< branching execution method for external candidates */
1943 	   )
1944 	{
1945 	   assert(branchrule != NULL);
1946 	
1947 	   branchrule->branchexecext = branchexecext;
1948 	}
1949 	
1950 	/** sets branching execution method for not completely fixed pseudo solutions */
1951 	void SCIPbranchruleSetExecPs(
1952 	   SCIP_BRANCHRULE*      branchrule,         /**< branching rule */
1953 	   SCIP_DECL_BRANCHEXECPS((*branchexecps))   /**< branching execution method for not completely fixed pseudo solutions */
1954 	   )
1955 	{
1956 	   assert(branchrule != NULL);
1957 	
1958 	   branchrule->branchexecps = branchexecps;
1959 	}
1960 	
1961 	/** gets name of branching rule */
1962 	const char* SCIPbranchruleGetName(
1963 	   SCIP_BRANCHRULE*      branchrule          /**< branching rule */
1964 	   )
1965 	{
1966 	   assert(branchrule != NULL);
1967 	
1968 	   return branchrule->name;
1969 	}
1970 	
1971 	/** gets description of branching rule */
1972 	const char* SCIPbranchruleGetDesc(
1973 	   SCIP_BRANCHRULE*      branchrule          /**< branching rule */
1974 	   )
1975 	{
1976 	   assert(branchrule != NULL);
1977 	
1978 	   return branchrule->desc;
1979 	}
1980 	
1981 	/** gets priority of branching rule */
1982 	int SCIPbranchruleGetPriority(
1983 	   SCIP_BRANCHRULE*      branchrule          /**< branching rule */
1984 	   )
1985 	{
1986 	   assert(branchrule != NULL);
1987 	
1988 	   return branchrule->priority;
1989 	}
1990 	
1991 	/** sets priority of branching rule */
1992 	void SCIPbranchruleSetPriority(
1993 	   SCIP_BRANCHRULE*      branchrule,         /**< branching rule */
1994 	   SCIP_SET*             set,                /**< global SCIP settings */
1995 	   int                   priority            /**< new priority of the branching rule */
1996 	   )
1997 	{
1998 	   assert(branchrule != NULL);
1999 	   assert(set != NULL);
2000 	
2001 	   branchrule->priority = priority;
2002 	   set->branchrulessorted = FALSE;
2003 	}
2004 	
2005 	/** gets maximal depth level, up to which this branching rule should be used (-1 for no limit) */
2006 	int SCIPbranchruleGetMaxdepth(
2007 	   SCIP_BRANCHRULE*      branchrule          /**< branching rule */
2008 	   )
2009 	{
2010 	   assert(branchrule != NULL);
2011 	
2012 	   return branchrule->maxdepth;
2013 	}
2014 	
2015 	/** sets maximal depth level, up to which this branching rule should be used (-1 for no limit) */
2016 	void SCIPbranchruleSetMaxdepth(
2017 	   SCIP_BRANCHRULE*      branchrule,         /**< branching rule */
2018 	   int                   maxdepth            /**< new maxdepth of the branching rule */
2019 	   )
2020 	{
2021 	   assert(branchrule != NULL);
2022 	   assert(maxdepth >= -1);
2023 	
2024 	   branchrule->maxdepth = maxdepth;
2025 	}
2026 	
2027 	/** gets maximal relative distance from current node's dual bound to primal bound for applying branching rule */
2028 	SCIP_Real SCIPbranchruleGetMaxbounddist(
2029 	   SCIP_BRANCHRULE*      branchrule          /**< branching rule */
2030 	   )
2031 	{
2032 	   assert(branchrule != NULL);
2033 	
2034 	   return branchrule->maxbounddist;
2035 	}
2036 	
2037 	/** sets maximal relative distance from current node's dual bound to primal bound for applying branching rule */
2038 	void SCIPbranchruleSetMaxbounddist(
2039 	   SCIP_BRANCHRULE*      branchrule,         /**< branching rule */
2040 	   SCIP_Real             maxbounddist        /**< new maxbounddist of the branching rule */
2041 	   )
2042 	{
2043 	   assert(branchrule != NULL);
2044 	   assert(maxbounddist >= -1);
2045 	
2046 	   branchrule->maxbounddist = maxbounddist;
2047 	}
2048 	
2049 	/** enables or disables all clocks of \p branchrule, depending on the value of the flag */
2050 	void SCIPbranchruleEnableOrDisableClocks(
2051 	   SCIP_BRANCHRULE*      branchrule,         /**< the branching rule for which all clocks should be enabled or disabled */
2052 	   SCIP_Bool             enable              /**< should the clocks of the branching rule be enabled? */
2053 	   )
2054 	{
2055 	   assert(branchrule != NULL);
2056 	
2057 	   SCIPclockEnableOrDisable(branchrule->setuptime, enable);
2058 	   SCIPclockEnableOrDisable(branchrule->branchclock, enable);
2059 	}
2060 	
2061 	/** gets time in seconds used in this branching rule for setting up for next stages */
2062 	SCIP_Real SCIPbranchruleGetSetupTime(
2063 	   SCIP_BRANCHRULE*      branchrule          /**< branching rule */
2064 	   )
2065 	{
2066 	   assert(branchrule != NULL);
2067 	
2068 	   return SCIPclockGetTime(branchrule->setuptime);
2069 	}
2070 	
2071 	/** gets time in seconds used in this branching rule */
2072 	SCIP_Real SCIPbranchruleGetTime(
2073 	   SCIP_BRANCHRULE*      branchrule          /**< branching rule */
2074 	   )
2075 	{
2076 	   assert(branchrule != NULL);
2077 	
2078 	   return SCIPclockGetTime(branchrule->branchclock);
2079 	}
2080 	
2081 	/** gets the total number of times, the branching rule was called on an LP solution */
2082 	SCIP_Longint SCIPbranchruleGetNLPCalls(
2083 	   SCIP_BRANCHRULE*      branchrule          /**< branching rule */
2084 	   )
2085 	{
2086 	   assert(branchrule != NULL);
2087 	
2088 	   return branchrule->nlpcalls;
2089 	}
2090 	
2091 	/** gets the total number of times, the branching rule was called on an external solution */
2092 	SCIP_Longint SCIPbranchruleGetNExternCalls(
2093 	   SCIP_BRANCHRULE*      branchrule          /**< branching rule */
2094 	   )
2095 	{
2096 	   assert(branchrule != NULL);
2097 	
2098 	   return branchrule->nexterncalls;
2099 	}
2100 	
2101 	/** gets the total number of times, the branching rule was called on a pseudo solution */
2102 	SCIP_Longint SCIPbranchruleGetNPseudoCalls(
2103 	   SCIP_BRANCHRULE*      branchrule          /**< branching rule */
2104 	   )
2105 	{
2106 	   assert(branchrule != NULL);
2107 	
2108 	   return branchrule->npseudocalls;
2109 	}
2110 	
2111 	/** gets the total number of times, the branching rule detected a cutoff */
2112 	SCIP_Longint SCIPbranchruleGetNCutoffs(
2113 	   SCIP_BRANCHRULE*      branchrule          /**< branching rule */
2114 	   )
2115 	{
2116 	   assert(branchrule != NULL);
2117 	
2118 	   return branchrule->ncutoffs;
2119 	}
2120 	
2121 	/** gets the total number of cuts, the branching rule separated */
2122 	SCIP_Longint SCIPbranchruleGetNCutsFound(
2123 	   SCIP_BRANCHRULE*      branchrule          /**< branching rule */
2124 	   )
2125 	{
2126 	   assert(branchrule != NULL);
2127 	
2128 	   return branchrule->ncutsfound;
2129 	}
2130 	
2131 	/** gets the total number of constraints, the branching rule added to the respective local nodes (not counting constraints
2132 	 *  that were added to the child nodes as branching decisions)
2133 	 */
2134 	SCIP_Longint SCIPbranchruleGetNConssFound(
2135 	   SCIP_BRANCHRULE*      branchrule          /**< branching rule */
2136 	   )
2137 	{
2138 	   assert(branchrule != NULL);
2139 	
2140 	   return branchrule->nconssfound;
2141 	}
2142 	
2143 	/** gets the total number of domain reductions, the branching rule found */
2144 	SCIP_Longint SCIPbranchruleGetNDomredsFound(
2145 	   SCIP_BRANCHRULE*      branchrule          /**< branching rule */
2146 	   )
2147 	{
2148 	   assert(branchrule != NULL);
2149 	
2150 	   return branchrule->ndomredsfound;
2151 	}
2152 	
2153 	/** gets the total number of children, the branching rule created */
2154 	SCIP_Longint SCIPbranchruleGetNChildren(
2155 	   SCIP_BRANCHRULE*      branchrule          /**< branching rule */
2156 	   )
2157 	{
2158 	   assert(branchrule != NULL);
2159 	
2160 	   return branchrule->nchildren;
2161 	}
2162 	
2163 	/** is branching rule initialized? */
2164 	SCIP_Bool SCIPbranchruleIsInitialized(
2165 	   SCIP_BRANCHRULE*      branchrule          /**< branching rule */
2166 	   )
2167 	{
2168 	   assert(branchrule != NULL);
2169 	
2170 	   return branchrule->initialized;
2171 	}
2172 	
2173 	
2174 	
2175 	
2176 	/*
2177 	 * branching methods
2178 	 */
2179 	
2180 	/** calculates the branching score out of the gain predictions for a binary branching */
2181 	SCIP_Real SCIPbranchGetScore(
2182 	   SCIP_SET*             set,                /**< global SCIP settings */
2183 	   SCIP_VAR*             var,                /**< variable, of which the branching factor should be applied, or NULL */
2184 	   SCIP_Real             downgain,           /**< prediction of objective gain for rounding downwards */
2185 	   SCIP_Real             upgain              /**< prediction of objective gain for rounding upwards */
2186 	   )
2187 	{
2188 	   SCIP_Real score;
2189 	   SCIP_Real eps;
2190 	
2191 	   assert(set != NULL);
2192 	
2193 	   /* adjust scores near zero to always yield product score greater than 0 */
2194 	   eps = SCIPsetSumepsilon(set);
2195 	   if( set->branch_sumadjustscore )
2196 	   {
2197 	      /* adjust scores by adding eps to keep near zero score differences between variables */
2198 	      downgain = downgain + eps;
2199 	      upgain = upgain + eps;
2200 	   }
2201 	   else
2202 	   {
2203 	      /* disregard near zero score differences between variables and consider the branching factor for them */
2204 	      downgain = MAX(downgain, eps);
2205 	      upgain = MAX(upgain, eps);
2206 	   }
2207 	
2208 	   switch( set->branch_scorefunc )
2209 	   {
2210 	   case 's':  /* linear sum score function */
2211 	      /* weigh the two child nodes with branchscorefac and 1-branchscorefac */
2212 	      if( downgain > upgain )
2213 	         score = set->branch_scorefac * downgain + (1.0-set->branch_scorefac) * upgain;
2214 	      else
2215 	         score = set->branch_scorefac * upgain + (1.0-set->branch_scorefac) * downgain;
2216 	      break;
2217 	
2218 	   case 'p':  /* product score function */
2219 	      score = downgain * upgain;
2220 	      break;
2221 	   case 'q': /* quotient score function */
2222 	      if( downgain > upgain )
2223 	         score = upgain * upgain / downgain;
2224 	      else
2225 	         score = downgain * downgain / upgain;
2226 	      break;
2227 	   default:
2228 	      SCIPerrorMessage("invalid branching score function <%c>\n", set->branch_scorefunc);
2229 	      SCIPABORT();
2230 	      score = 0.0;
2231 	   }
2232 	
2233 	   /* apply the branch factor of the variable */
2234 	   if( var != NULL )
2235 	      score *= SCIPvarGetBranchFactor(var);
2236 	
2237 	   return score;
2238 	}
2239 	
2240 	/** calculates the branching score out of the gain predictions for a branching with arbitrary many children */
2241 	SCIP_Real SCIPbranchGetScoreMultiple(
2242 	   SCIP_SET*             set,                /**< global SCIP settings */
2243 	   SCIP_VAR*             var,                /**< variable, of which the branching factor should be applied, or NULL */
2244 	   int                   nchildren,          /**< number of children that the branching will create */
2245 	   SCIP_Real*            gains               /**< prediction of objective gain for each child */
2246 	   )
2247 	{
2248 	   SCIP_Real min1;
2249 	   SCIP_Real min2;
2250 	   int c;
2251 	
2252 	   assert(nchildren == 0 || gains != NULL);
2253 	
2254 	   /* search for the two minimal gains in the child list and use these to calculate the branching score */
2255 	   min1 = SCIPsetInfinity(set);
2256 	   min2 = SCIPsetInfinity(set);
2257 	   for( c = 0; c < nchildren; ++c )
2258 	   {
2259 	      if( gains[c] < min1 )
2260 	      {
2261 	         min2 = min1;
2262 	         min1 = gains[c];
2263 	      }
2264 	      else if( gains[c] < min2 )
2265 	         min2 = gains[c];
2266 	   }
2267 	
2268 	   return SCIPbranchGetScore(set, var, min1, min2);
2269 	}
2270 	
2271 	/** computes a branching point for a (not necessarily discrete) variable
2272 	 * a suggested branching point is first projected onto the box
2273 	 * if no point is suggested, then the value in the current LP or pseudo solution is used
2274 	 * if this value is at infinity, then 0.0 projected onto the bounds and then moved inside the interval is used 
2275 	 * for a discrete variable, it is ensured that the returned value is fractional
2276 	 * for a continuous variable, the parameter branching/clamp defines how far a branching point need to be from the bounds of a variable
2277 	 * the latter is only applied if no point has been suggested, or the suggested point is not inside the variable's interval
2278 	 */
2279 	SCIP_Real SCIPbranchGetBranchingPoint(
2280 	   SCIP_SET*             set,                /**< global SCIP settings */
2281 	   SCIP_TREE*            tree,               /**< branch and bound tree */
2282 	   SCIP_VAR*             var,                /**< variable, of which the branching point should be computed */
2283 	   SCIP_Real             suggestion          /**< suggestion for branching point, or SCIP_INVALID if no suggestion */
2284 	   )
2285 	{
2286 	   SCIP_Real branchpoint;
2287 	   SCIP_Real lb;
2288 	   SCIP_Real ub;
2289 	
2290 	   assert(set != NULL);
2291 	   assert(var != NULL);
2292 	
2293 	   lb = SCIPvarGetLbLocal(var);
2294 	   ub = SCIPvarGetUbLocal(var);
2295 	
2296 	   /* for a fixed variable, we cannot branch further */
2297 	   assert(!SCIPsetIsEQ(set, lb, ub));
2298 	
2299 	   if( !SCIPsetIsInfinity(set, REALABS(suggestion)) )
2300 	   {
2301 	      /* use user suggested branching point */
2302 	
2303 	      /* first, project it onto the current domain */
2304 	      branchpoint = MAX(lb, MIN(suggestion, ub));
2305 	
2306 	      if( SCIPvarGetType(var) != SCIP_VARTYPE_CONTINUOUS )
2307 	      {
2308 	         /* if it is a discrete variable, then round it down and up and accept this choice */
2309 	         if( SCIPsetIsEQ(set, branchpoint, ub) )
2310 	         {
2311 	            /* in the right branch, variable is fixed to its current upper bound */
2312 	            return SCIPsetFloor(set, branchpoint) - 0.5;
2313 	         }
2314 	         else
2315 	         {
2316 	            /* in the  left branch, variable is fixed to its current lower bound */
2317 	            return SCIPsetFloor(set, branchpoint) + 0.5;
2318 	         }
2319 	      }
2320 	      else if( (SCIPsetIsInfinity(set, -lb) || SCIPsetIsRelGT(set, branchpoint, lb)) &&
2321 	                (SCIPsetIsInfinity(set,  ub) || SCIPsetIsRelLT(set, branchpoint, ub)) )
2322 	      {
2323 	         /* if it is continuous and inside the box, then accept it */ 
2324 	         return branchpoint;
2325 	      }
2326 	      /* if it is continuous and suggestion is on of the bounds, continue below */
2327 	   }
2328 	   else
2329 	   {
2330 	      /* if no point is suggested, try the LP or pseudo solution */
2331 	      branchpoint = SCIPvarGetSol(var, SCIPtreeHasCurrentNodeLP(tree));
2332 	
2333 	      if( REALABS(branchpoint) > 1e+12 )
2334 	      {
2335 	         /* if the value in the LP or pseudosolution is large (here 1e+12), use 0.0 (will be projected onto bounds below) */
2336 	         branchpoint = 0.0;
2337 	      }
2338 	      else if( SCIPtreeHasCurrentNodeLP(tree) && set->branch_midpull > 0.0 && !SCIPsetIsInfinity(set, -lb) && !SCIPsetIsInfinity(set, ub) )
2339 	      {
2340 	         /* if the value is from the LP and midpull is activated, then push towards middle of domain */
2341 	         SCIP_Real midpull = set->branch_midpull;
2342 	         SCIP_Real glb;
2343 	         SCIP_Real gub;
2344 	         SCIP_Real reldomainwidth;
2345 	
2346 	         /* shrink midpull if width of local domain, relative to global domain, is small
2347 	          * that is, if there has been already one or several branchings on this variable, then give more emphasis on LP solution
2348 	          *
2349 	          * do this only if the relative domain width is below the minreldomainwidth value
2350 	          */
2351 	         glb = SCIPvarGetLbGlobal(var);
2352 	         gub = SCIPvarGetUbGlobal(var);
2353 	         assert(glb < gub);
2354 	
2355 	         if( !SCIPsetIsInfinity(set, -glb) && !SCIPsetIsInfinity(set, gub) )
2356 	            reldomainwidth = (ub - lb) / (gub - glb);
2357 	         else
2358 	            reldomainwidth = SCIPsetEpsilon(set);
2359 	
2360 	         if( reldomainwidth < set->branch_midpullreldomtrig )
2361 	            midpull *= reldomainwidth;
2362 	
2363 	         branchpoint = midpull * (lb+ub) / 2.0 + (1.0 - midpull) * branchpoint;
2364 	      }
2365 	
2366 	      /* make sure branchpoint is on interval, below we make sure that it is within bounds for continuous vars */
2367 	      branchpoint = MAX(lb, MIN(branchpoint, ub));
2368 	   }
2369 	
2370 	   /* if value is at +/- infty, then choose some value a bit off from bounds or 0.0 */
2371 	   if( SCIPsetIsInfinity(set, branchpoint) )
2372 	   {
2373 	      /* if value is at +infty, then the upper bound should be at infinity */
2374 	      assert(SCIPsetIsInfinity(set, ub));
2375 	
2376 	      /* choose 0.0 or something above lower bound if lower bound > 0 */
2377 	      if( SCIPsetIsPositive(set, lb) )
2378 	         branchpoint = lb + 1000.0;
2379 	      else
2380 	         branchpoint = 0.0;
2381 	   }
2382 	   else if( SCIPsetIsInfinity(set, -branchpoint) )
2383 	   { 
2384 	      /* if value is at -infty, then the lower bound should be at -infinity */
2385 	      assert(SCIPsetIsInfinity(set, -lb));
2386 	
2387 	      /* choose 0.0 or something below upper bound if upper bound < 0 */
2388 	      if( SCIPsetIsNegative(set, ub) )
2389 	         branchpoint = ub - 1000.0;
2390 	      else
2391 	         branchpoint = 0.0;
2392 	   }
2393 	
2394 	   assert(SCIPsetIsInfinity(set,  ub) || SCIPsetIsLE(set, branchpoint, ub));
2395 	   assert(SCIPsetIsInfinity(set, -lb) || SCIPsetIsGE(set, branchpoint, lb));
2396 	
2397 	   if( SCIPvarGetType(var) >= SCIP_VARTYPE_IMPLINT )
2398 	   {
2399 	      if( !SCIPsetIsInfinity(set, -lb) || !SCIPsetIsInfinity(set, ub) )
2400 	      {
2401 	         /* if one bound is missing, we are temporarily guessing the other one, so we can apply the clamp below */
2402 	         if( SCIPsetIsInfinity(set, ub) )
2403 	         {
2404 	            ub = lb + MIN(MAX(0.5 * REALABS(lb), 1000), 0.9 * (SCIPsetInfinity(set) - lb)); /*lint !e666*/
2405 	         }
2406 	         else if( SCIPsetIsInfinity(set, -lb) )
2407 	         {
2408 	            lb = ub - MIN(MAX(0.5 * REALABS(ub), 1000), 0.9 * (SCIPsetInfinity(set) + ub)); /*lint !e666*/
2409 	         }
2410 	
2411 	         /* if branching point is too close to the bounds, move more into the middle of the interval */
2412 	         if( SCIPrelDiff(ub, lb) <= 2.02 * SCIPsetEpsilon(set) )
2413 	         {
2414 	            /* for very tiny intervals we set it exactly into the middle */
2415 	            branchpoint = (lb+ub)/2.0;
2416 	         }
2417 	         else
2418 	         {
2419 	            /* otherwise we project it away from the bounds */
2420 	            SCIP_Real minbrpoint;
2421 	            SCIP_Real maxbrpoint;
2422 	            SCIP_Real scale;
2423 	            SCIP_Real lbabs;
2424 	            SCIP_Real ubabs;
2425 	
2426 	            lbabs = REALABS(lb);
2427 	            ubabs = REALABS(ub);
2428 	
2429 	            scale = MAX3(lbabs, ubabs, 1.0);
2430 	
2431 	            /* the minimal branching point should be
2432 	             * - set->clamp away from the lower bound - relative to the local domain size
2433 	             * - SCIPsetEpsilon(set)*scale above the lower bound - in absolute value
2434 	             */
2435 	            minbrpoint = (1.0 - set->branch_clamp) * lb + set->branch_clamp * ub;
2436 	            minbrpoint = MAX(lb + 1.01*SCIPsetEpsilon(set)*scale, minbrpoint);  /*lint !e666*/
2437 	
2438 	            /* the maximal branching point should be
2439 	             * - set->clamp away from the upper bound - relative to the local domain size
2440 	             * - SCIPsetEpsilon(set)*scale below the upper bound - in absolute value
2441 	             */
2442 	            maxbrpoint = set->branch_clamp * lb + (1.0 - set->branch_clamp) * ub;
2443 	            maxbrpoint = MIN(ub - 1.01*SCIPsetEpsilon(set)*scale, maxbrpoint);  /*lint !e666*/
2444 	
2445 	            /* project branchpoint into [minbrpoint, maxbrpoint] */
2446 	            branchpoint = MAX(minbrpoint, MIN(branchpoint, maxbrpoint));
2447 	
2448 	            /* if selected branching point is close to 0.0 and bounds are away from 0.0, it often makes sense to branch exactly on 0.0 */
2449 	            if( SCIPsetIsFeasZero(set, branchpoint) && SCIPsetIsFeasNegative(set, lb) && SCIPsetIsFeasPositive(set, ub) )
2450 	               branchpoint = 0.0;
2451 	
2452 	            assert(SCIPsetIsRelLT(set, SCIPvarGetLbLocal(var), branchpoint));
2453 	            assert(SCIPsetIsRelLT(set, branchpoint, SCIPvarGetUbLocal(var)));
2454 	         }
2455 	      }
2456 	
2457 	      /* ensure fractional branching point for implicit integer variables */
2458 	      if( SCIPvarGetType(var) == SCIP_VARTYPE_IMPLINT && SCIPsetIsIntegral(set, branchpoint) )
2459 	      {
2460 	         /* if branchpoint is integral but not on bounds, then it should be one of the value {lb+1, ..., ub-1} */
2461 	         assert(SCIPsetIsGE(set, SCIPsetRound(set, branchpoint), lb + 1.0));
2462 	         assert(SCIPsetIsLE(set, SCIPsetRound(set, branchpoint), ub - 1.0));
2463 	         /* if branchpoint is integral, create one branch with x <= x'-1 and one with x >= x'
2464 	          * @todo could in the same way be x <= x' and x >= x'+1; is there some easy way to know which is better?
2465 	          */
2466 	         return branchpoint - 0.5;
2467 	      }
2468 	
2469 	      return branchpoint;
2470 	   }
2471 	   else
2472 	   {
2473 	      /* discrete variables */
2474 	      if( branchpoint <= lb + 0.5 )
2475 	      {
2476 	         /* if branchpoint is on lower bound, create one branch with x = lb and one with x >= lb+1 */
2477 	         return lb + 0.5;
2478 	      }
2479 	      else if( branchpoint >= ub - 0.5 )
2480 	      {
2481 	         /* if branchpoint is on upper bound, create one branch with x = ub and one with x <= ub-1 */
2482 	         return ub - 0.5;
2483 	      }
2484 	      else if( SCIPsetIsIntegral(set, branchpoint) )
2485 	      {
2486 	         /* if branchpoint is integral but not on bounds, then it should be one of the value {lb+1, ..., ub-1} */
2487 	         assert(SCIPsetIsGE(set, SCIPsetRound(set, branchpoint), lb + 1.0));
2488 	         assert(SCIPsetIsLE(set, SCIPsetRound(set, branchpoint), ub - 1.0));
2489 	         /* if branchpoint is integral, create one branch with x <= x'-1 and one with x >= x'
2490 	          * @todo could in the same way be x <= x' and x >= x'+1; is there some easy way to know which is better? */
2491 	         return branchpoint - 0.5;
2492 	      }
2493 	      else
2494 	      {
2495 	         /* branchpoint is somewhere between bounds and fractional, so just round down and up */
2496 	         return branchpoint;
2497 	      }
2498 	   }
2499 	}
2500 	
2501 	/** calls branching rules to branch on an LP solution; if no fractional variables exist, the result is SCIP_DIDNOTRUN;
2502 	 *  if the branch priority of an unfixed variable is larger than the maximal branch priority of the fractional
2503 	 *  variables, pseudo solution branching is applied on the unfixed variables with maximal branch priority
2504 	 */
2505 	SCIP_RETCODE SCIPbranchExecLP(
2506 	   BMS_BLKMEM*           blkmem,             /**< block memory for parameter settings */
2507 	   SCIP_SET*             set,                /**< global SCIP settings */
2508 	   SCIP_STAT*            stat,               /**< problem statistics */
2509 	   SCIP_PROB*            transprob,          /**< transformed problem after presolve */
2510 	   SCIP_PROB*            origprob,           /**< original problem */
2511 	   SCIP_TREE*            tree,               /**< branch and bound tree */
2512 	   SCIP_REOPT*           reopt,              /**< reoptimization data structure */
2513 	   SCIP_LP*              lp,                 /**< current LP data */
2514 	   SCIP_SEPASTORE*       sepastore,          /**< separation storage */
2515 	   SCIP_BRANCHCAND*      branchcand,         /**< branching candidate storage */
2516 	   SCIP_EVENTQUEUE*      eventqueue,         /**< event queue */
2517 	   SCIP_Real             cutoffbound,        /**< global upper cutoff bound */
2518 	   SCIP_Bool             allowaddcons,       /**< should adding constraints be allowed to avoid a branching? */
2519 	   SCIP_RESULT*          result              /**< pointer to store the result of the branching (s. branch.h) */
2520 	   )
2521 	{
2522 	   int i;
2523 	   int nalllpcands;  /* sum of binary, integer, and implicit branching candidates */
2524 	
2525 	   assert(branchcand != NULL);
2526 	   assert(result != NULL);
2527 	
2528 	   *result = SCIP_DIDNOTRUN;
2529 	
2530 	   /* calculate branching candidates */
2531 	   SCIP_CALL( branchcandCalcLPCands(branchcand, set, stat, lp) );
2532 	   assert(0 <= branchcand->npriolpcands && branchcand->npriolpcands <= branchcand->nlpcands);
2533 	   assert((branchcand->npriolpcands == 0) == (branchcand->nlpcands == 0));
2534 	
2535 	   SCIPsetDebugMsg(set, "branching on LP solution with %d (+%d) fractional (+implicit fractional) variables (%d of maximal priority)\n",
2536 	      branchcand->nlpcands, branchcand->nimpllpfracs, branchcand->npriolpcands);
2537 	
2538 	   nalllpcands = branchcand->nlpcands + branchcand->nimpllpfracs;
2539 	   /* do nothing, if no fractional variables exist */
2540 	   if( nalllpcands == 0 )
2541 	      return SCIP_OKAY;
2542 	
2543 	   /* if there is a non-fixed variable with higher priority than the maximal priority of the fractional candidates,
2544 	    * use pseudo solution branching instead
2545 	    */
2546 	   if( branchcand->pseudomaxpriority > branchcand->lpmaxpriority )
2547 	   {
2548 	      SCIP_CALL( SCIPbranchExecPseudo(blkmem, set, stat, transprob, origprob, tree, reopt, lp, branchcand, eventqueue, cutoffbound,
2549 	            allowaddcons, result) );
2550 	      assert(*result != SCIP_DIDNOTRUN && *result != SCIP_DIDNOTFIND);
2551 	      return SCIP_OKAY;
2552 	   }
2553 	
2554 	   /* sort the branching rules by priority */
2555 	   SCIPsetSortBranchrules(set);
2556 	
2557 	   /* try all branching rules until one succeeded to branch */
2558 	   for( i = 0; i < set->nbranchrules && (*result == SCIP_DIDNOTRUN || *result == SCIP_DIDNOTFIND); ++i )
2559 	   {
2560 	      SCIP_CALL( SCIPbranchruleExecLPSol(set->branchrules[i], set, stat, tree, sepastore, cutoffbound, allowaddcons, result) );
2561 	   }
2562 	
2563 	   if( *result == SCIP_DIDNOTRUN || *result == SCIP_DIDNOTFIND )
2564 	   {
2565 	      SCIP_VAR* var;
2566 	      SCIP_Real factor;
2567 	      SCIP_Real bestfactor;
2568 	      int priority;
2569 	      int bestpriority;
2570 	      int bestcand;
2571 	
2572 	      /* no branching method succeeded in choosing a branching: just branch on the first fractional variable with maximal
2573 	       * priority, and out of these on the one with maximal branch factor
2574 	       */
2575 	      bestcand = -1;
2576 	      bestpriority = INT_MIN;
2577 	      bestfactor = SCIP_REAL_MIN;
2578 	      for( i = 0; i < nalllpcands; ++i )
2579 	      {
2580 	         priority = SCIPvarGetBranchPriority(branchcand->lpcands[i]);
2581 	         factor = SCIPvarGetBranchFactor(branchcand->lpcands[i]);
2582 	         if( priority > bestpriority || (priority == bestpriority && factor > bestfactor) )
2583 	         {
2584 	            bestcand = i;
2585 	            bestpriority = priority;
2586 	            bestfactor = factor;
2587 	         }
2588 	      }
2589 	      assert(0 <= bestcand && bestcand < nalllpcands);
2590 	
2591 	      var = branchcand->lpcands[bestcand];
2592 	      assert(SCIPvarGetType(var) != SCIP_VARTYPE_CONTINUOUS);
2593 	      assert(branchcand->nlpcands == 0 || SCIPvarGetType(var) != SCIP_VARTYPE_IMPLINT);
2594 	
2595 	      assert(!SCIPsetIsEQ(set, SCIPvarGetLbLocal(var), SCIPvarGetUbLocal(var)));
2596 	
2597 	      SCIP_CALL( SCIPtreeBranchVar(tree, reopt, blkmem, set, stat, transprob, origprob, lp, branchcand, eventqueue, var, SCIP_INVALID,
2598 	            NULL, NULL, NULL) );
2599 	
2600 	      *result = SCIP_BRANCHED;
2601 	   }
2602 	
2603 	   return SCIP_OKAY;
2604 	}
2605 	
2606 	/** calls branching rules to branch on an external solution; if no external branching candidates exist, the result is SCIP_DIDNOTRUN */
2607 	SCIP_RETCODE SCIPbranchExecExtern(
2608 	   BMS_BLKMEM*           blkmem,             /**< block memory for parameter settings */
2609 	   SCIP_SET*             set,                /**< global SCIP settings */
2610 	   SCIP_STAT*            stat,               /**< problem statistics */
2611 	   SCIP_PROB*            transprob,          /**< transformed problem after presolve */
2612 	   SCIP_PROB*            origprob,           /**< original problem */
2613 	   SCIP_TREE*            tree,               /**< branch and bound tree */
2614 	   SCIP_REOPT*           reopt,              /**< reoptimization data structure */
2615 	   SCIP_LP*              lp,                 /**< current LP data */
2616 	   SCIP_SEPASTORE*       sepastore,          /**< separation storage */
2617 	   SCIP_BRANCHCAND*      branchcand,         /**< branching candidate storage */
2618 	   SCIP_EVENTQUEUE*      eventqueue,         /**< event queue */
2619 	   SCIP_Real             cutoffbound,        /**< global upper cutoff bound */
2620 	   SCIP_Bool             allowaddcons,       /**< should adding constraints be allowed to avoid a branching? */
2621 	   SCIP_RESULT*          result              /**< pointer to store the result of the branching (s. branch.h) */
2622 	   )
2623 	{
2624 	   int i;
2625 	
2626 	   assert(branchcand != NULL);
2627 	   assert(result != NULL);
2628 	   assert(0 <= branchcand->nprioexterncands && branchcand->nprioexterncands <= branchcand->nexterncands);
2629 	   assert((branchcand->nprioexterncands == 0) == (branchcand->nexterncands == 0));
2630 	
2631 	   *result = SCIP_DIDNOTRUN;
2632 	
2633 	   SCIPsetDebugMsg(set, "branching on external solution with %d branching candidates (%d of maximal priority)\n",
2634 	      branchcand->nexterncands, branchcand->nprioexterncands);
2635 	
2636 	   /* do nothing, if no external candidates exist */
2637 	   if( branchcand->nexterncands == 0 )
2638 	      return SCIP_OKAY;
2639 	
2640 	   /* if there is a non-fixed variable with higher priority than the maximal priority of the external candidates,
2641 	    * use pseudo solution branching instead
2642 	    */
2643 	   if( branchcand->pseudomaxpriority > branchcand->externmaxpriority )
2644 	   {
2645 	      /* @todo: adjust this, that also LP branching might be called, if lpmaxpriority != externmaxpriority.
2646 	       * Therefor, it has to be clear which of both has the higher priority
2647 	       */
2648 	      SCIP_CALL( SCIPbranchExecPseudo(blkmem, set, stat, transprob, origprob, tree, reopt, lp, branchcand, eventqueue, cutoffbound,
2649 	            allowaddcons, result) );
2650 	      assert(*result != SCIP_DIDNOTRUN && *result != SCIP_DIDNOTFIND);
2651 	      return SCIP_OKAY;
2652 	   }
2653 	
2654 	   /* sort the branching rules by priority */
2655 	   SCIPsetSortBranchrules(set);
2656 	
2657 	   /* try all branching rules until one succeeded to branch */
2658 	   for( i = 0; i < set->nbranchrules && (*result == SCIP_DIDNOTRUN || *result == SCIP_DIDNOTFIND); ++i )
2659 	   {
2660 	      SCIP_CALL( SCIPbranchruleExecExternSol(set->branchrules[i], set, stat, tree, sepastore, cutoffbound, allowaddcons, result) );
2661 	   }
2662 	
2663 	   if( *result == SCIP_DIDNOTRUN || *result == SCIP_DIDNOTFIND )
2664 	   {
2665 	      SCIP_VAR* var;
2666 	      SCIP_Real val;
2667 	      SCIP_Real bestfactor;
2668 	      SCIP_Real bestdomain;
2669 	      int bestpriority;
2670 	      int bestcand;
2671 	
2672 	      /* if all branching rules did nothing, then they should also not have cleared all branching candidates */
2673 	      assert(branchcand->nexterncands > 0);
2674 	
2675 	      /* no branching method succeeded in choosing a branching: just branch on the first branching candidates with maximal
2676 	       * priority, and out of these on the one with maximal branch factor, and out of these on the one with largest domain
2677 	       */
2678 	      bestcand = -1;
2679 	      bestpriority = INT_MIN;
2680 	      bestfactor = SCIP_REAL_MIN;
2681 	      bestdomain = 0.0;
2682 	      for( i = 0; i < branchcand->nexterncands; ++i )
2683 	      {
2684 	         SCIP_VAR* cand;
2685 	         SCIP_Real domain;
2686 	         SCIP_Real factor;
2687 	         int priority;
2688 	
2689 	         cand = branchcand->externcands[i];
2690 	         priority = SCIPvarGetBranchPriority(cand);
2691 	         factor = SCIPvarGetBranchFactor(cand);
2692 	
2693 	         /* the domain size is infinite, iff one of the bounds is infinite */
2694 	         if( SCIPsetIsInfinity(set, -SCIPvarGetLbLocal(cand)) || SCIPsetIsInfinity(set, SCIPvarGetUbLocal(cand)) )
2695 	            domain = SCIPsetInfinity(set);
2696 	         else
2697 	            domain = SCIPvarGetUbLocal(cand) - SCIPvarGetLbLocal(cand);
2698 	
2699 	         /* choose variable with higher priority, higher factor, larger domain (in that order) */
2700 	         if( priority > bestpriority || (priority == bestpriority && factor > bestfactor) || (priority == bestpriority && factor == bestfactor && domain > bestdomain) ) /*lint !e777*/
2701 	         {
2702 	            bestcand = i;
2703 	            bestpriority = priority;
2704 	            bestfactor = factor;
2705 	            bestdomain = domain;
2706 	         }
2707 	      }
2708 	      assert(0 <= bestcand && bestcand < branchcand->nexterncands);
2709 	
2710 	      var = branchcand->externcands[bestcand];
2711 	      val = SCIPbranchGetBranchingPoint(set, tree, var, branchcand->externcandssol[bestcand]);
2712 	      assert(!SCIPsetIsEQ(set, SCIPvarGetLbLocal(var), SCIPvarGetUbLocal(var)));
2713 	      assert(SCIPrelDiff(SCIPvarGetUbLocal(var), SCIPvarGetLbLocal(var)) <= 2.02 * SCIPsetEpsilon(set)
2714 	         || SCIPsetIsLT(set, SCIPvarGetLbLocal(var), val));
2715 	      assert(SCIPrelDiff(SCIPvarGetUbLocal(var), SCIPvarGetLbLocal(var)) <= 2.02 * SCIPsetEpsilon(set)
2716 	         || SCIPsetIsLT(set, val, SCIPvarGetUbLocal(var)));
2717 	
2718 	      SCIPsetDebugMsg(set, "no branching method succeeded; fallback selected to branch on variable <%s> with bounds [%g, %g] on value %g\n",
2719 	         SCIPvarGetName(var), SCIPvarGetLbLocal(var), SCIPvarGetUbLocal(var), val);
2720 	
2721 	      SCIP_CALL( SCIPtreeBranchVar(tree, reopt, blkmem, set, stat, transprob, origprob, lp, branchcand, eventqueue, var, val,
2722 	            NULL, NULL, NULL) );
2723 	
2724 	      if( tree->nchildren >= 1 )
2725 	         *result = SCIP_BRANCHED;
2726 	      /* if the bounds are too close, it may happen that we cannot branch but rather fix the variable */
2727 	      else
2728 	      {
2729 	         assert(SCIPsetIsEQ(set, SCIPvarGetLbLocal(var), SCIPvarGetUbLocal(var)));
2730 	         *result = SCIP_REDUCEDDOM;
2731 	      }
2732 	   }
2733 	
2734 	   return SCIP_OKAY;
2735 	}
2736 	
2737 	/** calls branching rules to branch on a pseudo solution; if no unfixed variables exist, the result is SCIP_DIDNOTRUN */
2738 	SCIP_RETCODE SCIPbranchExecPseudo(
2739 	   BMS_BLKMEM*           blkmem,             /**< block memory for parameter settings */
2740 	   SCIP_SET*             set,                /**< global SCIP settings */
2741 	   SCIP_STAT*            stat,               /**< problem statistics */
2742 	   SCIP_PROB*            transprob,          /**< transformed problem after presolve */
2743 	   SCIP_PROB*            origprob,           /**< original problem */
2744 	   SCIP_TREE*            tree,               /**< branch and bound tree */
2745 	   SCIP_REOPT*           reopt,              /**< reoptimization data structure */
2746 	   SCIP_LP*              lp,                 /**< current LP data */
2747 	   SCIP_BRANCHCAND*      branchcand,         /**< branching candidate storage */
2748 	   SCIP_EVENTQUEUE*      eventqueue,         /**< event queue */
2749 	   SCIP_Real             cutoffbound,        /**< global upper cutoff bound */
2750 	   SCIP_Bool             allowaddcons,       /**< should adding constraints be allowed to avoid a branching? */
2751 	   SCIP_RESULT*          result              /**< pointer to store the result of the branching (s. branch.h) */
2752 	   )
2753 	{
2754 	   int i;
2755 	
2756 	   assert(branchcand != NULL);
2757 	   assert(result != NULL);
2758 	
2759 	   SCIPsetDebugMsg(set, "branching on pseudo solution with %d unfixed variables\n", branchcand->npseudocands);
2760 	
2761 	   *result = SCIP_DIDNOTRUN;
2762 	
2763 	   /* do nothing, if no unfixed variables exist */
2764 	   if( branchcand->npseudocands == 0 )
2765 	      return SCIP_OKAY;
2766 	
2767 	   /* sort the branching rules by priority */
2768 	   SCIPsetSortBranchrules(set);
2769 	
2770 	   /* try all branching rules until one succeeded to branch */
2771 	   for( i = 0; i < set->nbranchrules && (*result == SCIP_DIDNOTRUN || *result == SCIP_DIDNOTFIND); ++i )
2772 	   {
2773 	      SCIP_CALL( SCIPbranchruleExecPseudoSol(set->branchrules[i], set, stat, tree, cutoffbound, allowaddcons, result) );
2774 	   }
2775 	
2776 	   if( *result == SCIP_DIDNOTRUN || *result == SCIP_DIDNOTFIND )
2777 	   {
2778 	      SCIP_VAR* var;
2779 	      SCIP_Real factor;
2780 	      SCIP_Real bestfactor;
2781 	      int priority;
2782 	      int bestpriority;
2783 	      int bestcand;
2784 	
2785 	      /* no branching method succeeded in choosing a branching: just branch on the first unfixed variable with maximal
2786 	       * priority, and out of these on the one with maximal branch factor
2787 	       */
2788 	      bestcand = -1;
2789 	      bestpriority = INT_MIN;
2790 	      bestfactor = SCIP_REAL_MIN;
2791 	      for( i = 0; i < branchcand->npseudocands; ++i )
2792 	      {
2793 	         priority = SCIPvarGetBranchPriority(branchcand->pseudocands[i]);
2794 	         factor = SCIPvarGetBranchFactor(branchcand->pseudocands[i]);
2795 	         if( priority > bestpriority || (priority == bestpriority && factor > bestfactor) )
2796 	         {
2797 	            bestcand = i;
2798 	            bestpriority = priority;
2799 	            bestfactor = factor;
2800 	         }
2801 	      }
2802 	      assert(0 <= bestcand && bestcand < branchcand->npseudocands);
2803 	
2804 	      var = branchcand->pseudocands[bestcand];
2805 	      assert(SCIPvarGetType(var) != SCIP_VARTYPE_CONTINUOUS);
2806 	      assert(!SCIPsetIsEQ(set, SCIPvarGetLbLocal(var), SCIPvarGetUbLocal(var)));
2807 	
2808 	      SCIP_CALL( SCIPtreeBranchVar(tree, reopt, blkmem, set, stat, transprob, origprob, lp, branchcand, eventqueue, var, SCIP_INVALID,
2809 	            NULL, NULL, NULL) );
2810 	
2811 	      *result = SCIP_BRANCHED;
2812 	   }
2813 	
2814 	   return SCIP_OKAY;
2815 	}
2816 	
2817