1    	/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2    	/*                                                                           */
3    	/*                  This file is part of the program and library             */
4    	/*         SCIP --- Solving Constraint Integer Programs                      */
5    	/*                                                                           */
6    	/*    Copyright (C) 2002-2022 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   misc.c
17   	 * @ingroup OTHER_CFILES
18   	 * @brief  miscellaneous methods
19   	 * @author Tobias Achterberg
20   	 * @author Gerald Gamrath
21   	 * @author Stefan Heinz
22   	 * @author Michael Winkler
23   	 * @author Kati Wolter
24   	 * @author Gregor Hendel
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   	#include <stdarg.h>
32   	#include <stdio.h>
33   	#include <stdlib.h>
34   	#include <errno.h>
35   	#include <ctype.h>
36   	
37   	#include "scip/def.h"
38   	#include "scip/pub_message.h"
39   	#include "scip/misc.h"
40   	#include "scip/intervalarith.h"
41   	#include "scip/pub_misc.h"
42   	
43   	#ifndef NDEBUG
44   	#include "scip/struct_misc.h"
45   	#endif
46   	
47   	/*
48   	 * methods for statistical tests
49   	 */
50   	
51   	#define SQRTOFTWO                  1.4142136 /**< the square root of 2 with sufficient precision */
52   	
53   	/**< contains all critical values for a one-sided two sample t-test up to 15 degrees of freedom
54   	 *   a critical value represents a threshold for rejecting the null-hypothesis in hypothesis testing at
55   	 *   a certain confidence level;
56   	 *
57   	 *   access through method SCIPstudentTGetCriticalValue()
58   	 *
59   	 *  source: German Wikipedia
60   	 *
61   	 *  for confidence levels
62   	 *  c =
63   	 *  0.75    0.875     0.90      0.95      0.975 (one-sided)
64   	 *  0.50    0.750     0.80      0.90      0.950 (two-sided)
65   	 *
66   	 */
67   	static const SCIP_Real studentt_quartiles[] = {      /* df:*/
68   	   1.000,    2.414,    3.078,    6.314,    12.706,   /*  1 */
69   	   0.816,    1.604,    1.886,    2.920,    4.303,    /*  2 */
70   	   0.765,    1.423,    1.638,    2.353,    3.182,    /*  3 */
71   	   0.741,    1.344,    1.533,    2.132,    2.776,    /*  4 */
72   	   0.727,    1.301,    1.476,    2.015,    2.571,    /*  5 */
73   	   0.718,    1.273,    1.440,    1.943,    2.447,    /*  6 */
74   	   0.711,    1.254,    1.415,    1.895,    2.365,    /*  7 */
75   	   0.706,    1.240,    1.397,    1.860,    2.306,    /*  8 */
76   	   0.703,    1.230,    1.383,    1.833,    2.262,    /*  9 */
77   	   0.700,    1.221,    1.372,    1.812,    2.228,    /* 10 */
78   	   0.697,    1.214,    1.363,    1.796,    2.201,    /* 11 */
79   	   0.695,    1.209,    1.356,    1.782,    2.179,    /* 12 */
80   	   0.694,    1.204,    1.350,    1.771,    2.160,    /* 13 */
81   	   0.692,    1.200,    1.345,    1.761,    2.145,    /* 14 */
82   	   0.691,    1.197,    1.341,    1.753,    2.131     /* 15 */
83   	};
84   	
85   	/**< critical values for higher degrees of freedom of Student-T distribution for the same error probabilities; infact,
86   	 *   these are critical values of the standard normal distribution with mean 0 and variance 1
87   	 */
88   	static const SCIP_Real studentt_quartilesabove[] = {
89   	   0.674,    1.150,    1.282,    1.645,    1.960
90   	};
91   	
92   	/** the maximum degrees of freedom represented before switching to normal approximation */
93   	static const int studentt_maxdf = sizeof(studentt_quartiles)/(5 * sizeof(SCIP_Real));
94   	
95   	/** get critical value of a Student-T distribution for a given number of degrees of freedom at a confidence level */
96   	SCIP_Real SCIPstudentTGetCriticalValue(
97   	   SCIP_CONFIDENCELEVEL  clevel,             /**< (one-sided) confidence level */
98   	   int                   df                  /**< degrees of freedom */
99   	   )
100  	{
101  	   if( df > studentt_maxdf )
102  	      return studentt_quartilesabove[(int)clevel];
103  	   else
104  	      return studentt_quartiles[(int)clevel + 5 * (df - 1)];
105  	}
106  	
107  	/** compute a t-value for the hypothesis that x and y are from the same population; Assuming that
108  	 *  x and y represent normally distributed random samples with equal variance, the returned value
109  	 *  comes from a Student-T distribution with countx + county - 2 degrees of freedom; this
110  	 *  value can be compared with a critical value (see also SCIPstudentTGetCriticalValue()) at
111  	 *  a predefined confidence level for checking if x and y significantly differ in location
112  	 */
113  	SCIP_Real SCIPcomputeTwoSampleTTestValue(
114  	   SCIP_Real             meanx,              /**< the mean of the first distribution */
115  	   SCIP_Real             meany,              /**< the mean of the second distribution */
116  	   SCIP_Real             variancex,          /**< the variance of the x-distribution */
117  	   SCIP_Real             variancey,          /**< the variance of the y-distribution */
118  	   SCIP_Real             countx,             /**< number of samples of x */
119  	   SCIP_Real             county              /**< number of samples of y */
120  	   )
121  	{
122  	   SCIP_Real pooledvariance;
123  	   SCIP_Real tresult;
124  	
125  	   /* too few samples */
126  	   if( countx < 1.9 || county < 1.9 )
127  	      return SCIP_INVALID;
128  	
129  	   /* pooled variance is the weighted average of the two variances */
130  	   pooledvariance = (countx - 1) * variancex + (county - 1) * variancey;
131  	   pooledvariance /= (countx + county - 2);
132  	
133  	   /* a variance close to zero means the distributions are basically constant */
134  	   pooledvariance = MAX(pooledvariance, 1e-9);
135  	
136  	   /* tresult can be understood as realization of a Student-T distributed variable with
137  	    * countx + county - 2 degrees of freedom
138  	    */
139  	   tresult = (meanx - meany) / SQRT(pooledvariance);
140  	   tresult *= SQRT(countx * county / (countx + county));
141  	
142  	   return tresult;
143  	}
144  	
145  	/** returns the value of the Gauss error function evaluated at a given point */
146  	SCIP_Real SCIPerf(
147  	   SCIP_Real             x                   /**< value to evaluate */
148  	   )
149  	{
150  	#if defined(_WIN32) || defined(_WIN64)
151  	   SCIP_Real a1, a2, a3, a4, a5, p, t, y;
152  	   int sign;
153  	
154  	   a1 =  0.254829592;
155  	   a2 = -0.284496736;
156  	   a3 =  1.421413741;
157  	   a4 = -1.453152027;
158  	   a5 =  1.061405429;
159  	   p  =  0.3275911;
160  	
161  	   sign = (x >= 0) ? 1 : -1;
162  	   x = REALABS(x);
163  	
164  	   t = 1.0/(1.0 + p*x);
165  	   y = 1.0 - (((((a5*t + a4)*t) + a3)*t + a2)*t + a1)*t*exp(-x*x);
166  	   return sign * y;
167  	#else
168  	   return erf(x);
169  	#endif
170  	}
171  	
172  	/** get critical value of a standard normal distribution  at a given confidence level */
173  	SCIP_Real SCIPnormalGetCriticalValue(
174  	   SCIP_CONFIDENCELEVEL  clevel              /**< (one-sided) confidence level */
175  	   )
176  	{
177  	   return studentt_quartilesabove[(int)clevel];
178  	}
179  	
180  	/** calculates the cumulative distribution P(-infinity <= x <= value) that a normally distributed
181  	 *  random variable x takes a value between -infinity and parameter \p value.
182  	 *
183  	 *  The distribution is given by the respective mean and deviation. This implementation
184  	 *  uses the error function SCIPerf().
185  	 */
186  	SCIP_Real SCIPnormalCDF(
187  	   SCIP_Real             mean,               /**< the mean value of the distribution */
188  	   SCIP_Real             variance,           /**< the square of the deviation of the distribution */
189  	   SCIP_Real             value               /**< the upper limit of the calculated distribution integral */
190  	   )
191  	{
192  	   SCIP_Real normvalue;
193  	   SCIP_Real std;
194  	
195  	   /* we need to calculate the standard deviation from the variance */
196  	   assert(variance >= -1e-9);
197  	   if( variance < 1e-9 )
198  	      std = 0.0;
199  	   else
200  	      std = sqrt(variance);
201  	
202  	   /* special treatment for zero variance */
203  	   if( std < 1e-9 )
204  	   {
205  	      if( value < mean + 1e-9 )
206  	         return 1.0;
207  	      else
208  	         return 0.0;
209  	   }
210  	   assert( std != 0.0 ); /* for lint */
211  	
212  	   /* scale and translate to standard normal distribution. Factor sqrt(2) is needed for SCIPerf() function */
213  	   normvalue = (value - mean)/(std * SQRTOFTWO);
214  	
215  	   SCIPdebugMessage(" Normalized value %g = ( %g - %g ) / (%g * 1.4142136)\n", normvalue, value, mean, std);
216  	
217  	   /* calculate the cumulative distribution function for normvalue. For negative normvalues, we negate the normvalue and
218  	    * use the oddness of the SCIPerf()-function; special treatment for values close to zero.
219  	    */
220  	   if( normvalue < 1e-9 && normvalue > -1e-9 )
221  	      return .5;
222  	   else if( normvalue > 0 )
223  	   {
224  	      SCIP_Real erfresult;
225  	
226  	      erfresult = SCIPerf(normvalue);
227  	      return  erfresult / 2.0 + 0.5;
228  	   }
229  	   else
230  	   {
231  	      SCIP_Real erfresult;
232  	
233  	      erfresult = SCIPerf(-normvalue);
234  	
235  	      return 0.5 - erfresult / 2.0;
236  	   }
237  	}
238  	
239  	/*
240  	 * SCIP regression methods
241  	 */
242  	
243  	/** returns the number of observations of this regression */
244  	int SCIPregressionGetNObservations(
245  	   SCIP_REGRESSION*      regression          /**< regression data structure */
246  	   )
247  	{
248  	   assert(regression != NULL);
249  	
250  	   return regression->nobservations;
251  	}
252  	
253  	/** return the current slope of the regression */
254  	SCIP_Real SCIPregressionGetSlope(
255  	   SCIP_REGRESSION*      regression          /**< regression data structure */
256  	   )
257  	{
258  	   assert(regression != NULL);
259  	
260  	   return regression->slope;
261  	}
262  	
263  	/** get the current y-intercept of the regression */
264  	SCIP_Real SCIPregressionGetIntercept(
265  	   SCIP_REGRESSION*      regression          /**< regression data structure */
266  	   )
267  	{
268  	   assert(regression != NULL);
269  	
270  	   return regression->intercept;
271  	}
272  	
273  	/** recomputes regression coefficients from available observation data */
274  	static
275  	void regressionRecompute(
276  	   SCIP_REGRESSION*      regression          /**< regression data structure */
277  	   )
278  	{
279  	   /* regression coefficients require two or more observations and variance in x */
280  	   if( regression->nobservations <= 1 || EPSZ(regression->variancesumx, 1e-9) )
281  	   {
282  	      regression->slope = SCIP_INVALID;
283  	      regression->intercept = SCIP_INVALID;
284  	      regression->corrcoef = SCIP_INVALID;
285  	   }
286  	   else if( EPSZ(regression->variancesumy, 1e-9) )
287  	   {
288  	      /* if there is no variance in the y's (but in the x's), the regression line is horizontal with y-intercept through the mean y */
289  	      regression->slope = 0.0;
290  	      regression->corrcoef = 0.0;
291  	      regression->intercept = regression->meany;
292  	   }
293  	   else
294  	   {
295  	      /* we ruled this case out already, but to please some compilers... */
296  	      assert(regression->variancesumx > 0.0);
297  	      assert(regression->variancesumy > 0.0);
298  	
299  	      /* compute slope */
300  	      regression->slope = (regression->sumxy  - regression->nobservations * regression->meanx * regression->meany) / regression->variancesumx;
301  	
302  	      /* compute y-intercept */
303  	      regression->intercept = regression->meany - regression->slope * regression->meanx;
304  	
305  	      /* compute empirical correlation coefficient */
306  	      regression->corrcoef = (regression->sumxy - regression->nobservations * regression->meanx * regression->meany) /
307  	         sqrt(regression->variancesumx * regression->variancesumy);
308  	   }
309  	}
310  	
311  	/* incremental update of statistics describing mean and variance */
312  	static
313  	void incrementalStatsUpdate(
314  	   SCIP_Real             value,              /**< current value to be added to incremental statistics */
315  	   SCIP_Real*            meanptr,            /**< pointer to value of current mean */
316  	   SCIP_Real*            sumvarptr,          /**< pointer to the value of the current variance sum term */
317  	   int                   nobservations,      /**< total number of observations */
318  	   SCIP_Bool             add                 /**< TRUE if the value should be added, FALSE for removing it */
319  	   )
320  	{
321  	   SCIP_Real oldmean;
322  	   SCIP_Real addfactor;
323  	   assert(meanptr != NULL);
324  	   assert(sumvarptr != NULL);
325  	   assert(nobservations > 0 || add);
326  	
327  	   addfactor = add ? 1.0 : -1.0;
328  	
329  	   oldmean = *meanptr;
330  	   *meanptr = oldmean + addfactor * (value - oldmean)/(SCIP_Real)nobservations;
331  	   *sumvarptr += addfactor * (value - oldmean) * (value - (*meanptr));
332  	
333  	   /* it may happen that *sumvarptr is slightly negative, especially after a series of add/removal operations */
334  	   assert(*sumvarptr >= -1e-4);
335  	   *sumvarptr = MAX(0.0, *sumvarptr);
336  	}
337  	
338  	/** removes an observation (x,y) from the regression */
339  	void SCIPregressionRemoveObservation(
340  	   SCIP_REGRESSION*      regression,         /**< regression data structure */
341  	   SCIP_Real             x,                  /**< X of observation */
342  	   SCIP_Real             y                   /**< Y of the observation */
343  	   )
344  	{
345  	   assert(regression != NULL);
346  	   assert(regression->nobservations > 0);
347  	
348  	   /* simply call the reset function in the case of a single remaining observation to avoid numerical troubles */
349  	   if( regression->nobservations == 1 )
350  	   {
351  	      SCIPregressionReset(regression);
352  	   }
353  	   else
354  	   {
355  	      SCIP_Bool add = FALSE;
356  	      --regression->nobservations;
357  	
358  	      /* decrement individual means and variances */
359  	      incrementalStatsUpdate(x, &regression->meanx, &regression->variancesumx, regression->nobservations, add);
360  	      incrementalStatsUpdate(y, &regression->meany, &regression->variancesumy, regression->nobservations, add);
361  	
362  	      /* decrement product sum */
363  	      regression->sumxy -= (x * y);
364  	   }
365  	
366  	   /* recompute regression parameters */
367  	   regressionRecompute(regression);
368  	}
369  	
370  	/** update regression by a new observation (x,y) */
371  	void SCIPregressionAddObservation(
372  	   SCIP_REGRESSION*      regression,         /**< regression data structure */
373  	   SCIP_Real             x,                  /**< X of observation */
374  	   SCIP_Real             y                   /**< Y of the observation */
375  	   )
376  	{
377  	   SCIP_Bool add = TRUE;
378  	   assert(regression != NULL);
379  	
380  	   ++(regression->nobservations);
381  	   incrementalStatsUpdate(x, &regression->meanx, &regression->variancesumx, regression->nobservations, add);
382  	   incrementalStatsUpdate(y, &regression->meany, &regression->variancesumy, regression->nobservations, add);
383  	
384  	   regression->sumxy += x * y;
385  	
386  	   regressionRecompute(regression);
387  	}
388  	
389  	/** reset regression data structure */
390  	void SCIPregressionReset(
391  	   SCIP_REGRESSION*      regression          /**< regression data structure */
392  	   )
393  	{
394  	   regression->intercept = SCIP_INVALID;
395  	   regression->slope = SCIP_INVALID;
396  	   regression->corrcoef = SCIP_INVALID;
397  	   regression->meanx = 0;
398  	   regression->variancesumx = 0;
399  	   regression->sumxy = 0;
400  	   regression->meany = 0;
401  	   regression->variancesumy = 0;
402  	   regression->nobservations = 0;
403  	}
404  	
405  	/** creates and resets a regression */
406  	SCIP_RETCODE SCIPregressionCreate(
407  	   SCIP_REGRESSION**     regression          /**< regression data structure */
408  	   )
409  	{
410  	   assert(regression != NULL);
411  	
412  	   /* allocate necessary memory */
413  	   SCIP_ALLOC (BMSallocMemory(regression) );
414  	
415  	   /* reset the regression */
416  	   SCIPregressionReset(*regression);
417  	
418  	   return SCIP_OKAY;
419  	}
420  	
421  	/** creates and resets a regression */
422  	void SCIPregressionFree(
423  	   SCIP_REGRESSION**     regression          /**< regression data structure */
424  	   )
425  	{
426  	   BMSfreeMemory(regression);
427  	}
428  	
429  	/** calculate memory size for dynamically allocated arrays (copied from scip/set.c) */
430  	static
431  	int calcGrowSize(
432  	   int                   initsize,           /**< initial size of array */
433  	   SCIP_Real             growfac,            /**< growing factor of array */
434  	   int                   num                 /**< minimum number of entries to store */
435  	   )
436  	{
437  	   int size;
438  	
439  	   assert(initsize >= 0);
440  	   assert(growfac >= 1.0);
441  	   assert(num >= 0);
442  	
443  	   if( growfac == 1.0 )
444  	      size = MAX(initsize, num);
445  	   else
446  	   {
447  	      int oldsize;
448  	
449  	      /* calculate the size with this loop, such that the resulting numbers are always the same (-> block memory) */
450  	      initsize = MAX(initsize, 4);
451  	      size = initsize;
452  	      oldsize = size - 1;
453  	
454  	      /* second condition checks against overflow */
455  	      while( size < num && size > oldsize )
456  	      {
457  	         oldsize = size;
458  	         size = (int)(growfac * size + initsize);
459  	      }
460  	
461  	      /* if an overflow happened, set the correct value */
462  	      if( size <= oldsize )
463  	         size = num;
464  	   }
465  	
466  	   assert(size >= initsize);
467  	   assert(size >= num);
468  	
469  	   return size;
470  	}
471  	
472  	/*
473  	 * GML graphical printing methods
474  	 * For a detailed format decription see http://docs.yworks.com/yfiles/doc/developers-guide/gml.html
475  	 */
476  	
477  	#define GMLNODEWIDTH 120.0
478  	#define GMLNODEHEIGTH 30.0
479  	#define GMLFONTSIZE 13
480  	#define GMLNODETYPE "rectangle"
481  	#define GMLNODEFILLCOLOR "#ff0000"
482  	#define GMLEDGECOLOR "black"
483  	#define GMLNODEBORDERCOLOR "#000000"
484  	
485  	
486  	/** writes a node section to the given graph file */
487  	void SCIPgmlWriteNode(
488  	   FILE*                 file,               /**< file to write to */
489  	   unsigned int          id,                 /**< id of the node */
490  	   const char*           label,              /**< label of the node */
491  	   const char*           nodetype,           /**< type of the node, or NULL */
492  	   const char*           fillcolor,          /**< color of the node's interior, or NULL */
493  	   const char*           bordercolor         /**< color of the node's border, or NULL */
494  	   )
495  	{
496  	   assert(file != NULL);
497  	   assert(label != NULL);
498  	
499  	   fprintf(file, "  node\n");
500  	   fprintf(file, "  [\n");
501  	   fprintf(file, "    id      %u\n", id);
502  	   fprintf(file, "    label   \"%s\"\n", label);
503  	   fprintf(file, "    graphics\n");
504  	   fprintf(file, "    [\n");
505  	   fprintf(file, "      w       %g\n", GMLNODEWIDTH);
506  	   fprintf(file, "      h       %g\n", GMLNODEHEIGTH);
507  	
508  	   if( nodetype != NULL )
509  	      fprintf(file, "      type    \"%s\"\n", nodetype);
510  	   else
511  	      fprintf(file, "      type    \"%s\"\n", GMLNODETYPE);
512  	
513  	   if( fillcolor != NULL )
514  	      fprintf(file, "      fill    \"%s\"\n", fillcolor);
515  	   else
516  	      fprintf(file, "      fill    \"%s\"\n", GMLNODEFILLCOLOR);
517  	
518  	   if( bordercolor != NULL )
519  	      fprintf(file, "      outline \"%s\"\n", bordercolor);
520  	   else
521  	      fprintf(file, "      outline \"%s\"\n", GMLNODEBORDERCOLOR);
522  	
523  	   fprintf(file, "    ]\n");
524  	   fprintf(file, "    LabelGraphics\n");
525  	   fprintf(file, "    [\n");
526  	   fprintf(file, "      text      \"%s\"\n", label);
527  	   fprintf(file, "      fontSize  %d\n", GMLFONTSIZE);
528  	   fprintf(file, "      fontName  \"Dialog\"\n");
529  	   fprintf(file, "      anchor    \"c\"\n");
530  	   fprintf(file, "    ]\n");
531  	   fprintf(file, "  ]\n");
532  	}
533  	
534  	/** writes a node section including weight to the given graph file */
535  	void SCIPgmlWriteNodeWeight(
536  	   FILE*                 file,               /**< file to write to */
537  	   unsigned int          id,                 /**< id of the node */
538  	   const char*           label,              /**< label of the node */
539  	   const char*           nodetype,           /**< type of the node, or NULL */
540  	   const char*           fillcolor,          /**< color of the node's interior, or NULL */
541  	   const char*           bordercolor,        /**< color of the node's border, or NULL */
542  	   SCIP_Real             weight              /**< weight of node */
543  	   )
544  	{
545  	   assert(file != NULL);
546  	   assert(label != NULL);
547  	
548  	   fprintf(file, "  node\n");
549  	   fprintf(file, "  [\n");
550  	   fprintf(file, "    id      %u\n", id);
551  	   fprintf(file, "    label   \"%s\"\n", label);
552  	   fprintf(file, "    weight  %g\n", weight);
553  	   fprintf(file, "    graphics\n");
554  	   fprintf(file, "    [\n");
555  	   fprintf(file, "      w       %g\n", GMLNODEWIDTH);
556  	   fprintf(file, "      h       %g\n", GMLNODEHEIGTH);
557  	
558  	   if( nodetype != NULL )
559  	      fprintf(file, "      type    \"%s\"\n", nodetype);
560  	   else
561  	      fprintf(file, "      type    \"%s\"\n", GMLNODETYPE);
562  	
563  	   if( fillcolor != NULL )
564  	      fprintf(file, "      fill    \"%s\"\n", fillcolor);
565  	   else
566  	      fprintf(file, "      fill    \"%s\"\n", GMLNODEFILLCOLOR);
567  	
568  	   if( bordercolor != NULL )
569  	      fprintf(file, "      outline \"%s\"\n", bordercolor);
570  	   else
571  	      fprintf(file, "      outline \"%s\"\n", GMLNODEBORDERCOLOR);
572  	
573  	   fprintf(file, "    ]\n");
574  	   fprintf(file, "    LabelGraphics\n");
575  	   fprintf(file, "    [\n");
576  	   fprintf(file, "      text      \"%s\"\n", label);
577  	   fprintf(file, "      fontSize  %d\n", GMLFONTSIZE);
578  	   fprintf(file, "      fontName  \"Dialog\"\n");
579  	   fprintf(file, "      anchor    \"c\"\n");
580  	   fprintf(file, "    ]\n");
581  	   fprintf(file, "  ]\n");
582  	}
583  	
584  	/** writes an edge section to the given graph file */
585  	void SCIPgmlWriteEdge(
586  	   FILE*                 file,               /**< file to write to */
587  	   unsigned int          source,             /**< source node id of the node */
588  	   unsigned int          target,             /**< target node id of the edge */
589  	   const char*           label,              /**< label of the edge, or NULL */
590  	   const char*           color               /**< color of the edge, or NULL */
591  	   )
592  	{
593  	   assert(file != NULL);
594  	
595  	   fprintf(file, "  edge\n");
596  	   fprintf(file, "  [\n");
597  	   fprintf(file, "    source  %u\n", source);
598  	   fprintf(file, "    target  %u\n", target);
599  	
600  	   if( label != NULL)
601  	      fprintf(file, "    label   \"%s\"\n", label);
602  	
603  	   fprintf(file, "    graphics\n");
604  	   fprintf(file, "    [\n");
605  	
606  	   if( color != NULL )
607  	      fprintf(file, "      fill    \"%s\"\n", color);
608  	   else
609  	      fprintf(file, "      fill    \"%s\"\n", GMLEDGECOLOR);
610  	
611  	   /* fprintf(file, "      arrow     \"both\"\n"); */
612  	   fprintf(file, "    ]\n");
613  	
614  	   if( label != NULL)
615  	   {
616  	      fprintf(file, "    LabelGraphics\n");
617  	      fprintf(file, "    [\n");
618  	      fprintf(file, "      text      \"%s\"\n", label);
619  	      fprintf(file, "      fontSize  %d\n", GMLFONTSIZE);
620  	      fprintf(file, "      fontName  \"Dialog\"\n");
621  	      fprintf(file, "      anchor    \"c\"\n");
622  	      fprintf(file, "    ]\n");
623  	   }
624  	
625  	   fprintf(file, "  ]\n");
626  	}
627  	
628  	/** writes an arc section to the given graph file */
629  	void SCIPgmlWriteArc(
630  	   FILE*                 file,               /**< file to write to */
631  	   unsigned int          source,             /**< source node id of the node */
632  	   unsigned int          target,             /**< target node id of the edge */
633  	   const char*           label,              /**< label of the edge, or NULL */
634  	   const char*           color               /**< color of the edge, or NULL */
635  	   )
636  	{
637  	   assert(file != NULL);
638  	
639  	   fprintf(file, "  edge\n");
640  	   fprintf(file, "  [\n");
641  	   fprintf(file, "    source  %u\n", source);
642  	   fprintf(file, "    target  %u\n", target);
643  	
644  	   if( label != NULL)
645  	      fprintf(file, "    label   \"%s\"\n", label);
646  	
647  	   fprintf(file, "    graphics\n");
648  	   fprintf(file, "    [\n");
649  	
650  	   if( color != NULL )
651  	      fprintf(file, "      fill    \"%s\"\n", color);
652  	   else
653  	      fprintf(file, "      fill    \"%s\"\n", GMLEDGECOLOR);
654  	
655  	   fprintf(file, "      targetArrow     \"standard\"\n");
656  	   fprintf(file, "    ]\n");
657  	
658  	   if( label != NULL)
659  	   {
660  	      fprintf(file, "    LabelGraphics\n");
661  	      fprintf(file, "    [\n");
662  	      fprintf(file, "      text      \"%s\"\n", label);
663  	      fprintf(file, "      fontSize  %d\n", GMLFONTSIZE);
664  	      fprintf(file, "      fontName  \"Dialog\"\n");
665  	      fprintf(file, "      anchor    \"c\"\n");
666  	      fprintf(file, "    ]\n");
667  	   }
668  	
669  	   fprintf(file, "  ]\n");
670  	}
671  	
672  	/** writes the starting line to a GML graph file, does not open a file */
673  	void SCIPgmlWriteOpening(
674  	   FILE*                 file,               /**< file to write to */
675  	   SCIP_Bool             directed            /**< is the graph directed */
676  	   )
677  	{
678  	   assert(file != NULL);
679  	
680  	   fprintf(file, "graph\n");
681  	   fprintf(file, "[\n");
682  	   fprintf(file, "  hierarchic      1\n");
683  	
684  	   if( directed )
685  	      fprintf(file, "  directed        1\n");
686  	}
687  	
688  	/** writes the ending lines to a GML graph file, does not close a file */
689  	void SCIPgmlWriteClosing(
690  	   FILE*                 file                /**< file to close */
691  	   )
692  	{
693  	   assert(file != NULL);
694  	
695  	   fprintf(file, "]\n");
696  	}
697  	
698  	
699  	/*
700  	 * Sparse solution
701  	 */
702  	
703  	/** creates a sparse solution */
704  	SCIP_RETCODE SCIPsparseSolCreate(
705  	   SCIP_SPARSESOL**      sparsesol,          /**< pointer to store the created sparse solution */
706  	   SCIP_VAR**            vars,               /**< variables in the sparse solution, must not contain continuous
707  						      *   variables
708  						      */
709  	   int                   nvars,              /**< number of variables to store, size of the lower and upper bound
710  						      *   arrays
711  						      */
712  	   SCIP_Bool             cleared             /**< should the lower and upper bound arrays be cleared (entries set to
713  						      *	  0)
714  						      */
715  	   )
716  	{
717  	   assert(sparsesol != NULL);
718  	   assert(vars != NULL);
719  	   assert(nvars >= 0);
720  	
721  	   SCIP_ALLOC( BMSallocMemory(sparsesol) );
722  	
723  	#ifndef NDEBUG
724  	   {
725  	      int v;
726  	
727  	      for( v = nvars - 1; v >= 0; --v )
728  	      {
729  		 assert(vars[v] != NULL);
730  		 /* assert(SCIPvarGetType(vars[v]) != SCIP_VARTYPE_CONTINUOUS); */
731  	      }
732  	   }
733  	#endif
734  	
735  	   /* copy variables */
736  	   SCIP_ALLOC( BMSduplicateMemoryArray(&((*sparsesol)->vars), vars, nvars) );
737  	
738  	   /* create bound arrays */
739  	   if( cleared )
740  	   {
741  	      SCIP_ALLOC( BMSallocClearMemoryArray(&((*sparsesol)->lbvalues), nvars) );
742  	      SCIP_ALLOC( BMSallocClearMemoryArray(&((*sparsesol)->ubvalues), nvars) );
743  	   }
744  	   else
745  	   {
746  	      SCIP_ALLOC( BMSallocMemoryArray(&((*sparsesol)->lbvalues), nvars) );
747  	      SCIP_ALLOC( BMSallocMemoryArray(&((*sparsesol)->ubvalues), nvars) );
748  	   }
749  	
750  	   (*sparsesol)->nvars = nvars;
751  	
752  	   return SCIP_OKAY;
753  	}
754  	
755  	/** frees sparse solution */
756  	void SCIPsparseSolFree(
757  	   SCIP_SPARSESOL**      sparsesol           /**< pointer to a sparse solution */
758  	   )
759  	{
760  	   assert(sparsesol != NULL);
761  	   assert(*sparsesol != NULL);
762  	
763  	   BMSfreeMemoryArray(&((*sparsesol)->vars));
764  	   BMSfreeMemoryArray(&((*sparsesol)->ubvalues));
765  	   BMSfreeMemoryArray(&((*sparsesol)->lbvalues));
766  	   BMSfreeMemory(sparsesol);
767  	}
768  	
769  	/** returns the variables stored in the given sparse solution */
770  	SCIP_VAR** SCIPsparseSolGetVars(
771  	   SCIP_SPARSESOL*       sparsesol           /**< a sparse solution */
772  	   )
773  	{
774  	   assert(sparsesol != NULL);
775  	
776  	   return sparsesol->vars;
777  	}
778  	
779  	/** returns the number of variables stored in the given sparse solution */
780  	int SCIPsparseSolGetNVars(
781  	   SCIP_SPARSESOL*       sparsesol           /**< a sparse solution */
782  	   )
783  	{
784  	   assert(sparsesol != NULL);
785  	
786  	   return sparsesol->nvars;
787  	}
788  	
789  	/** returns the lower bound array for all variables for a given sparse solution */
790  	SCIP_Longint* SCIPsparseSolGetLbs(
791  	   SCIP_SPARSESOL*       sparsesol           /**< a sparse solution */
792  	   )
793  	{
794  	   assert(sparsesol != NULL);
795  	
796  	   return sparsesol->lbvalues;
797  	}
798  	
799  	/** returns the upper bound array for all variables for a given sparse solution */
800  	SCIP_Longint* SCIPsparseSolGetUbs(
801  	   SCIP_SPARSESOL*       sparsesol           /**< a sparse solution */
802  	   )
803  	{
804  	   assert(sparsesol != NULL);
805  	
806  	   return sparsesol->ubvalues;
807  	}
808  	
809  	/** constructs the first solution of sparse solution (all variables are set to their lower bound value */
810  	void SCIPsparseSolGetFirstSol(
811  	   SCIP_SPARSESOL*       sparsesol,          /**< sparse solutions */
812  	   SCIP_Longint*         sol,                /**< array to store the first solution */
813  	   int                   nvars               /**< number of variables */
814  	   )
815  	{
816  	   SCIP_Longint* lbvalues;
817  	   int v;
818  	
819  	   assert(sparsesol != NULL);
820  	   assert(sol != NULL);
821  	   assert(nvars == SCIPsparseSolGetNVars(sparsesol));
822  	
823  	   lbvalues = SCIPsparseSolGetLbs(sparsesol);
824  	   assert(lbvalues != NULL);
825  	
826  	   /* copy the lower bounds */
827  	   for( v = 0; v < nvars; ++v )
828  	      sol[v] = lbvalues[v];
829  	}
830  	
831  	
832  	/** constructs the next solution of the sparse solution and return whether there was one more or not */
833  	SCIP_Bool SCIPsparseSolGetNextSol(
834  	   SCIP_SPARSESOL*       sparsesol,          /**< sparse solutions */
835  	   SCIP_Longint*         sol,                /**< current solution array which get changed to the next solution */
836  	   int                   nvars               /**< number of variables */
837  	   )
838  	{
839  	   SCIP_Longint* lbvalues;
840  	   SCIP_Longint* ubvalues;
841  	   SCIP_Longint lbvalue;
842  	   SCIP_Longint ubvalue;
843  	   SCIP_Bool singular;
844  	   SCIP_Bool carryflag;
845  	   int v;
846  	
847  	   assert(sparsesol != NULL);
848  	   assert(sol != NULL);
849  	
850  	   if( nvars == 0 )
851  	      return FALSE;
852  	
853  	   assert(nvars > 0);
854  	   assert(nvars == SCIPsparseSolGetNVars(sparsesol));
855  	
856  	   lbvalues = SCIPsparseSolGetLbs(sparsesol);
857  	   ubvalues = SCIPsparseSolGetUbs(sparsesol);
858  	   assert(lbvalues != NULL);
859  	   assert(ubvalues != NULL);
860  	
861  	   singular = TRUE;
862  	   carryflag = FALSE;
863  	
864  	   for( v = 0; v < nvars; ++v )
865  	   {
866  	      lbvalue = lbvalues[v];
867  	      ubvalue = ubvalues[v];
868  	
869  	      if( lbvalue < ubvalue )
870  	      {
871  	         singular = FALSE;
872  	
873  	         if( carryflag == FALSE )
874  	         {
875  	            if( sol[v] < ubvalue )
876  	            {
877  	               sol[v]++;
878  	               break;
879  	            }
880  	            else
881  	            {
882  	               /* in the last solution the variables v was set to its upper bound value */
883  	               assert(sol[v] == ubvalue);
884  	               sol[v] = lbvalue;
885  	               carryflag = TRUE;
886  	            }
887  	         }
888  	         else
889  	         {
890  	            if( sol[v] < ubvalue )
891  	            {
892  	               sol[v]++;
893  	               carryflag = FALSE;
894  	               break;
895  	            }
896  	            else
897  	            {
898  	               assert(sol[v] == ubvalue);
899  	               sol[v] = lbvalue;
900  	            }
901  	         }
902  	      }
903  	   }
904  	
905  	   return (!carryflag && !singular);
906  	}
907  	
908  	
909  	/*
910  	 * Queue
911  	 */
912  	
913  	/** resizes element memory to hold at least the given number of elements */
914  	static
915  	SCIP_RETCODE queueResize(
916  	   SCIP_QUEUE*           queue,              /**< pointer to a queue */
917  	   int                   minsize             /**< minimal number of storable elements */
918  	   )
919  	{
920  	   assert(queue != NULL);
921  	   assert(minsize > 0);
922  	
923  	   if( minsize <= queue->size )
924  	      return SCIP_OKAY;
925  	
926  	   queue->size = MAX(minsize, (int)(queue->size * queue->sizefac));
927  	   SCIP_ALLOC( BMSreallocMemoryArray(&queue->slots, queue->size) );
928  	
929  	   return SCIP_OKAY;
930  	}
931  	
932  	
933  	/** creates a (circular) queue, best used if the size will be fixed or will not be increased that much */
934  	SCIP_RETCODE SCIPqueueCreate(
935  	   SCIP_QUEUE**          queue,              /**< pointer to the new queue */
936  	   int                   initsize,           /**< initial number of available element slots */
937  	   SCIP_Real             sizefac             /**< memory growing factor applied, if more element slots are needed */
938  	   )
939  	{
940  	   assert(queue != NULL);
941  	
942  	   initsize = MAX(1, initsize);
943  	   sizefac = MAX(1.0, sizefac);
944  	
945  	   SCIP_ALLOC( BMSallocMemory(queue) );
946  	   (*queue)->firstfree = 0;
947  	   (*queue)->firstused = -1;
948  	   (*queue)->size = 0;
949  	   (*queue)->sizefac = sizefac;
950  	   (*queue)->slots = NULL;
951  	
952  	   SCIP_CALL( queueResize(*queue, initsize) );
953  	
954  	   return SCIP_OKAY;
955  	}
956  	
957  	/** frees queue, but not the data elements themselves */
958  	void SCIPqueueFree(
959  	   SCIP_QUEUE**          queue               /**< pointer to a queue */
960  	   )
961  	{
962  	   assert(queue != NULL);
963  	
964  	   BMSfreeMemoryArray(&(*queue)->slots);
965  	   BMSfreeMemory(queue);
966  	}
967  	
968  	/** clears the queue, but doesn't free the data elements themselves */
969  	void SCIPqueueClear(
970  	   SCIP_QUEUE*           queue               /**< queue */
971  	   )
972  	{
973  	   assert(queue != NULL);
974  	
975  	   queue->firstfree = 0;
976  	   queue->firstused = -1;
977  	}
978  	
979  	/** reallocates slots if queue is necessary */
980  	static
981  	SCIP_RETCODE queueCheckSize(
982  	   SCIP_QUEUE*           queue               /**< queue */
983  	   )
984  	{
985  	   if( queue->firstfree == queue->firstused )
986  	   {
987  	      int sizediff;
988  	      int oldsize = queue->size;
989  	
990  	      SCIP_CALL( queueResize(queue, queue->size+1) );
991  	      assert(oldsize < queue->size);
992  	
993  	      sizediff = queue->size - oldsize;
994  	
995  	      /* move the used memory at the slots to the end */
996  	      BMSmoveMemoryArray(&(queue->slots[queue->firstused + sizediff]), &(queue->slots[queue->firstused]), oldsize - queue->firstused); /*lint !e866*/
997  	      queue->firstused += sizediff;
998  	   }
999  	   assert(queue->firstfree != queue->firstused);
1000 	
1001 	   return SCIP_OKAY;
1002 	}
1003 	
1004 	/** checks and adjusts marker of first free and first used slot */
1005 	static
1006 	void queueCheckMarker(
1007 	   SCIP_QUEUE*           queue               /**< queue */
1008 	   )
1009 	{
1010 	   /* if we saved the value at the last position we need to reset the firstfree position */
1011 	   if( queue->firstfree == queue->size )
1012 	      queue->firstfree = 0;
1013 	
1014 	   /* if a first element was added, we need to update the firstused counter */
1015 	   if( queue->firstused == -1 )
1016 	      queue->firstused = 0;
1017 	}
1018 	
1019 	/** inserts pointer element at the end of the queue */
1020 	SCIP_RETCODE SCIPqueueInsert(
1021 	   SCIP_QUEUE*           queue,              /**< queue */
1022 	   void*                 elem                /**< element to be inserted */
1023 	   )
1024 	{
1025 	   assert(queue != NULL);
1026 	   assert(queue->slots != NULL);
1027 	   assert(queue->firstused >= -1 && queue->firstused < queue->size);
1028 	   assert(queue->firstfree >= 0 && queue->firstused < queue->size);
1029 	   assert(queue->firstused > -1 || queue->firstfree == 0);
1030 	   assert(elem != NULL);
1031 	
1032 	   /* check allocated memory */
1033 	   SCIP_CALL( queueCheckSize(queue) );
1034 	
1035 	   /* insert element at the first free slot */
1036 	   queue->slots[queue->firstfree].ptr = elem;
1037 	   ++(queue->firstfree);
1038 	
1039 	   /* check and adjust marker */
1040 	   queueCheckMarker(queue);
1041 	
1042 	   return SCIP_OKAY;
1043 	}
1044 	
1045 	/** inserts unsigned integer element at the end of the queue */
1046 	SCIP_RETCODE SCIPqueueInsertUInt(
1047 	   SCIP_QUEUE*           queue,              /**< queue */
1048 	   unsigned int          elem                /**< element to be inserted */
1049 	   )
1050 	{
1051 	   assert(queue != NULL);
1052 	   assert(queue->slots != NULL);
1053 	   assert(queue->firstused >= -1 && queue->firstused < queue->size);
1054 	   assert(queue->firstfree >= 0 && queue->firstused < queue->size);
1055 	   assert(queue->firstused > -1 || queue->firstfree == 0);
1056 	
1057 	   /* check allocated memory */
1058 	   SCIP_CALL( queueCheckSize(queue) );
1059 	
1060 	   /* insert element at the first free slot */
1061 	   queue->slots[queue->firstfree].uinteger = elem;
1062 	   ++(queue->firstfree);
1063 	
1064 	   /* check and adjust marker */
1065 	   queueCheckMarker(queue);
1066 	
1067 	   return SCIP_OKAY;
1068 	}
1069 	
1070 	/** removes and returns the first pointer element of the queue, or NULL if no element exists */
1071 	void* SCIPqueueRemove(
1072 	   SCIP_QUEUE*           queue               /**< queue */
1073 	   )
1074 	{
1075 	   int pos;
1076 	
1077 	   assert(queue != NULL);
1078 	   assert(queue->firstused >= -1 && queue->firstused < queue->size);
1079 	   assert(queue->firstfree >= 0 && queue->firstused < queue->size);
1080 	   assert(queue->firstused > -1 || queue->firstfree == 0);
1081 	
1082 	   if( queue->firstused == -1 )
1083 	      return NULL;
1084 	
1085 	   assert(queue->slots != NULL);
1086 	
1087 	   pos = queue->firstused;
1088 	   ++(queue->firstused);
1089 	
1090 	   /* if we removed the value at the last position we need to reset the firstused position */
1091 	   if( queue->firstused == queue->size )
1092 	      queue->firstused = 0;
1093 	
1094 	   /* if we reached the first free position we can reset both, firstused and firstused, positions */
1095 	   if( queue->firstused == queue->firstfree )
1096 	   {
1097 	      queue->firstused = -1;
1098 	      queue->firstfree = 0; /* this is not necessary but looks better if we have an empty list to reset this value */
1099 	   }
1100 	
1101 	   return (queue->slots[pos].ptr);
1102 	}
1103 	
1104 	/** removes and returns the first unsigned integer element of the queue, or UINT_MAX if no element exists */
1105 	unsigned int SCIPqueueRemoveUInt(
1106 	   SCIP_QUEUE*           queue               /**< queue */
1107 	   )
1108 	{
1109 	   int pos;
1110 	
1111 	   assert(queue != NULL);
1112 	   assert(queue->firstused >= -1 && queue->firstused < queue->size);
1113 	   assert(queue->firstfree >= 0 && queue->firstused < queue->size);
1114 	   assert(queue->firstused > -1 || queue->firstfree == 0);
1115 	
1116 	   if( queue->firstused == -1 )
1117 	      return UINT_MAX;
1118 	
1119 	   assert(queue->slots != NULL);
1120 	
1121 	   pos = queue->firstused;
1122 	   ++(queue->firstused);
1123 	
1124 	   /* if we removed the value at the last position we need to reset the firstused position */
1125 	   if( queue->firstused == queue->size )
1126 	      queue->firstused = 0;
1127 	
1128 	   /* if we reached the first free position we can reset both, firstused and firstused, positions */
1129 	   if( queue->firstused == queue->firstfree )
1130 	   {
1131 	      queue->firstused = -1;
1132 	      queue->firstfree = 0; /* this is not necessary but looks better if we have an empty list to reset this value */
1133 	   }
1134 	
1135 	   return (queue->slots[pos].uinteger);
1136 	}
1137 	
1138 	/** returns the first element of the queue without removing it, or NULL if no element exists */
1139 	void* SCIPqueueFirst(
1140 	   SCIP_QUEUE*           queue               /**< queue */
1141 	   )
1142 	{
1143 	   assert(queue != NULL);
1144 	   assert(queue->firstused >= -1 && queue->firstused < queue->size);
1145 	   assert(queue->firstfree >= 0 && queue->firstused < queue->size);
1146 	   assert(queue->firstused > -1 || queue->firstfree == 0);
1147 	
1148 	   if( queue->firstused == -1 )
1149 	      return NULL;
1150 	
1151 	   assert(queue->slots != NULL);
1152 	
1153 	   return queue->slots[queue->firstused].ptr;
1154 	}
1155 	
1156 	/** returns the first unsigned integer element of the queue without removing it, or UINT_MAX if no element exists */
1157 	unsigned int SCIPqueueFirstUInt(
1158 	   SCIP_QUEUE*           queue               /**< queue */
1159 	   )
1160 	{
1161 	   assert(queue != NULL);
1162 	   assert(queue->firstused >= -1 && queue->firstused < queue->size);
1163 	   assert(queue->firstfree >= 0 && queue->firstused < queue->size);
1164 	   assert(queue->firstused > -1 || queue->firstfree == 0);
1165 	
1166 	   if( queue->firstused == -1 )
1167 	      return UINT_MAX;
1168 	
1169 	   assert(queue->slots != NULL);
1170 	
1171 	   return queue->slots[queue->firstused].uinteger;
1172 	}
1173 	
1174 	/** returns whether the queue is empty */
1175 	SCIP_Bool SCIPqueueIsEmpty(
1176 	   SCIP_QUEUE*           queue               /**< queue */
1177 	   )
1178 	{
1179 	   assert(queue != NULL);
1180 	   assert(queue->firstused >= -1 && queue->firstused < queue->size);
1181 	   assert(queue->firstfree >= 0 && queue->firstused < queue->size);
1182 	   assert(queue->firstused > -1 || queue->firstfree == 0);
1183 	
1184 	   return (queue->firstused == -1);
1185 	}
1186 	
1187 	/** returns the number of elements in the queue */
1188 	int SCIPqueueNElems(
1189 	   SCIP_QUEUE*           queue               /**< queue */
1190 	   )
1191 	{
1192 	   assert(queue != NULL);
1193 	   assert(queue->firstused >= -1 && queue->firstused < queue->size);
1194 	   assert(queue->firstfree >= 0 && queue->firstused < queue->size);
1195 	   assert(queue->firstused > -1 || queue->firstfree == 0);
1196 	
1197 	   if( queue->firstused == -1 )
1198 	      return 0;
1199 	   else if( queue->firstused < queue->firstfree )
1200 	      return queue->firstfree - queue->firstused;
1201 	   else if( queue->firstused == queue->firstfree )
1202 	      return queue->size;
1203 	   else
1204 	      return queue->firstfree + (queue->size - queue->firstused);
1205 	}
1206 	
1207 	
1208 	/*
1209 	 * Priority Queue
1210 	 */
1211 	
1212 	#define PQ_PARENT(q) (((q)+1)/2-1)
1213 	#define PQ_LEFTCHILD(p) (2*(p)+1)
1214 	#define PQ_RIGHTCHILD(p) (2*(p)+2)
1215 	
1216 	
1217 	/** resizes element memory to hold at least the given number of elements */
1218 	static
1219 	SCIP_RETCODE pqueueResize(
1220 	   SCIP_PQUEUE*          pqueue,             /**< pointer to a priority queue */
1221 	   int                   minsize             /**< minimal number of storable elements */
1222 	   )
1223 	{
1224 	   assert(pqueue != NULL);
1225 	
1226 	   if( minsize <= pqueue->size )
1227 	      return SCIP_OKAY;
1228 	
1229 	   pqueue->size = MAX(minsize, (int)(pqueue->size * pqueue->sizefac));
1230 	   SCIP_ALLOC( BMSreallocMemoryArray(&pqueue->slots, pqueue->size) );
1231 	
1232 	   return SCIP_OKAY;
1233 	}
1234 	
1235 	/** creates priority queue */
1236 	SCIP_RETCODE SCIPpqueueCreate(
1237 	   SCIP_PQUEUE**         pqueue,             /**< pointer to a priority queue */
1238 	   int                   initsize,           /**< initial number of available element slots */
1239 	   SCIP_Real             sizefac,            /**< memory growing factor applied, if more element slots are needed */
1240 	   SCIP_DECL_SORTPTRCOMP((*ptrcomp)),        /**< data element comparator */
1241 	   SCIP_DECL_PQUEUEELEMCHGPOS((*elemchgpos)) /**< callback to act on position change of elem in priority queue, or NULL */
1242 	   )
1243 	{
1244 	   assert(pqueue != NULL);
1245 	   assert(ptrcomp != NULL);
1246 	
1247 	   initsize = MAX(1, initsize);
1248 	   sizefac = MAX(1.0, sizefac);
1249 	
1250 	   SCIP_ALLOC( BMSallocMemory(pqueue) );
1251 	   (*pqueue)->len = 0;
1252 	   (*pqueue)->size = 0;
1253 	   (*pqueue)->sizefac = sizefac;
1254 	   (*pqueue)->slots = NULL;
1255 	   (*pqueue)->ptrcomp = ptrcomp;
1256 	   (*pqueue)->elemchgpos = elemchgpos;
1257 	   SCIP_CALL( pqueueResize(*pqueue, initsize) );
1258 	
1259 	   return SCIP_OKAY;
1260 	}
1261 	
1262 	/** frees priority queue, but not the data elements themselves */
1263 	void SCIPpqueueFree(
1264 	   SCIP_PQUEUE**         pqueue              /**< pointer to a priority queue */
1265 	   )
1266 	{
1267 	   assert(pqueue != NULL);
1268 	
1269 	   BMSfreeMemoryArray(&(*pqueue)->slots);
1270 	   BMSfreeMemory(pqueue);
1271 	}
1272 	
1273 	/** clears the priority queue, but doesn't free the data elements themselves */
1274 	void SCIPpqueueClear(
1275 	   SCIP_PQUEUE*          pqueue              /**< priority queue */
1276 	   )
1277 	{
1278 	   assert(pqueue != NULL);
1279 	
1280 	   pqueue->len = 0;
1281 	}
1282 	
1283 	/** assign element to new slot in priority queue */
1284 	static
1285 	void pqueueElemChgPos(
1286 	   SCIP_PQUEUE*          pqueue,             /**< priority queue */
1287 	   void*                 elem,               /**< element whose position changes */
1288 	   int                   oldpos,             /**< old position or -1 if elem is newly inserted */
1289 	   int                   newpos              /**< new position */
1290 	   )
1291 	{
1292 	   pqueue->slots[newpos] = elem;
1293 	
1294 	   /* act on position change */
1295 	   if( pqueue->elemchgpos != NULL )
1296 	   {
1297 	      pqueue->elemchgpos(elem, oldpos, newpos);
1298 	   }
1299 	}
1300 	
1301 	#ifdef SCIP_MORE_DEBUG
1302 	/** ensure that the priority queue still has the heap property */
1303 	static
1304 	SCIP_Bool pqueueHasHeapProperty(
1305 	   SCIP_PQUEUE*          pqueue              /**< priority queue */
1306 	   )
1307 	{
1308 	   int i;
1309 	
1310 	   if( SCIPpqueueNElems(pqueue) == 0 )
1311 	      return TRUE;
1312 	
1313 	   /* check local heap property between parents and children */
1314 	   for( i = 0; i < SCIPpqueueNElems(pqueue); ++i )
1315 	   {
1316 	      if( i > 0 && pqueue->ptrcomp(pqueue->slots[i], pqueue->slots[PQ_PARENT(i)]) < 0 )
1317 	         return FALSE;
1318 	      if( i < PQ_PARENT(SCIPpqueueNElems(pqueue)) )
1319 	      {
1320 	         int leftchild = PQ_LEFTCHILD(i);
1321 	         int rightchild = PQ_RIGHTCHILD(i);
1322 	         assert(leftchild < SCIPpqueueNElems(pqueue));
1323 	         assert(rightchild <= SCIPpqueueNElems(pqueue));
1324 	         if( pqueue->ptrcomp(pqueue->slots[i], pqueue->slots[leftchild]) > 0 )
1325 	            return FALSE;
1326 	         if( rightchild < SCIPpqueueNElems(pqueue) && pqueue->ptrcomp(pqueue->slots[i], pqueue->slots[rightchild]) > 0)
1327 	            return FALSE;
1328 	      }
1329 	   }
1330 	   return TRUE;
1331 	}
1332 	#endif
1333 	
1334 	/** inserts element into priority queue */
1335 	SCIP_RETCODE SCIPpqueueInsert(
1336 	   SCIP_PQUEUE*          pqueue,             /**< priority queue */
1337 	   void*                 elem                /**< element to be inserted */
1338 	   )
1339 	{
1340 	   int pos;
1341 	   int parentpos;
1342 	
1343 	   assert(pqueue != NULL);
1344 	   assert(pqueue->len >= 0);
1345 	   assert(elem != NULL);
1346 	
1347 	   SCIP_CALL( pqueueResize(pqueue, pqueue->len+1) );
1348 	
1349 	   /* insert element as leaf in the tree, move it towards the root as long it is better than its parent */
1350 	   pos = pqueue->len;
1351 	   pqueue->len++;
1352 	   parentpos = PQ_PARENT(pos);
1353 	   while( pos > 0 && (*pqueue->ptrcomp)(elem, pqueue->slots[parentpos]) < 0 )
1354 	   {
1355 	      assert((*pqueue->ptrcomp)(pqueue->slots[parentpos], elem) >= 0);
1356 	      pqueueElemChgPos(pqueue, pqueue->slots[parentpos], parentpos, pos);
1357 	
1358 	      pos = parentpos;
1359 	      parentpos = PQ_PARENT(pos);
1360 	   }
1361 	
1362 	   /* insert element at the found position */
1363 	   pqueueElemChgPos(pqueue, elem, -1, pos);
1364 	
1365 	#ifdef SCIP_MORE_DEBUG
1366 	   assert(pqueueHasHeapProperty(pqueue));
1367 	#endif
1368 	
1369 	   return SCIP_OKAY;
1370 	}
1371 	
1372 	
1373 	/** delete element at specified position, maintaining the heap property */
1374 	void SCIPpqueueDelPos(
1375 	   SCIP_PQUEUE*          pqueue,             /**< priority queue */
1376 	   int                   pos                 /**< position of element that should be deleted */
1377 	   )
1378 	{
1379 	   void* last;
1380 	
1381 	   assert(pqueue != NULL);
1382 	   assert(pos >= 0);
1383 	   assert(pos < SCIPpqueueNElems(pqueue));
1384 	
1385 	   /* remove element at specified position of the tree, move the better child to its parents position until the last element
1386 	    * of the queue could be placed in the empty slot
1387 	    */
1388 	   pqueue->len--;
1389 	
1390 	   /* everything in place */
1391 	   if( pos == pqueue->len )
1392 	      return;
1393 	
1394 	   last = pqueue->slots[pqueue->len];
1395 	
1396 	   /* last element is brought to pos. it may now violate the heap property compared to its parent, or to its children.
1397 	    * In the first case, move it up, otherwise, move it down.
1398 	    */
1399 	   while( pos > 0 && (*pqueue->ptrcomp)(last, pqueue->slots[PQ_PARENT(pos)]) < 0 )
1400 	   {
1401 	      pqueueElemChgPos(pqueue, pqueue->slots[PQ_PARENT(pos)], PQ_PARENT(pos), pos);
1402 	      pos = PQ_PARENT(pos);
1403 	   }
1404 	
1405 	   while( pos <= PQ_PARENT(pqueue->len-1) )
1406 	   {
1407 	      int childpos = PQ_LEFTCHILD(pos);
1408 	      int brotherpos = PQ_RIGHTCHILD(pos);
1409 	
1410 	      /* determine better of the two children */
1411 	      if( brotherpos < pqueue->len && (*pqueue->ptrcomp)(pqueue->slots[brotherpos], pqueue->slots[childpos]) < 0 )
1412 	         childpos = brotherpos;
1413 	
1414 	      if( (*pqueue->ptrcomp)(last, pqueue->slots[childpos]) <= 0 )
1415 	         break;
1416 	
1417 	      /* move better element from childpos to pos */
1418 	      pqueueElemChgPos(pqueue, pqueue->slots[childpos], childpos, pos);
1419 	
1420 	      pos = childpos;
1421 	   }
1422 	
1423 	   /* pos must point into a valid position */
1424 	   assert(pos <= pqueue->len - 1);
1425 	
1426 	   pqueueElemChgPos(pqueue, last, pqueue->len, pos);
1427 	
1428 	#ifdef SCIP_MORE_DEBUG
1429 	   assert(pqueueHasHeapProperty(pqueue));
1430 	#endif
1431 	}
1432 	
1433 	/** removes and returns best element from the priority queue */
1434 	void* SCIPpqueueRemove(
1435 	   SCIP_PQUEUE*          pqueue              /**< priority queue */
1436 	   )
1437 	{
1438 	   void* root;
1439 	
1440 	   assert(pqueue != NULL);
1441 	   assert(pqueue->len >= 0);
1442 	
1443 	   if( pqueue->len == 0 )
1444 	      return NULL;
1445 	
1446 	   root = pqueue->slots[0];
1447 	
1448 	   SCIPpqueueDelPos(pqueue, 0);
1449 	
1450 	   return root;
1451 	}
1452 	
1453 	/** returns the best element of the queue without removing it */
1454 	void* SCIPpqueueFirst(
1455 	   SCIP_PQUEUE*          pqueue              /**< priority queue */
1456 	   )
1457 	{
1458 	   assert(pqueue != NULL);
1459 	   assert(pqueue->len >= 0);
1460 	
1461 	   if( pqueue->len == 0 )
1462 	      return NULL;
1463 	
1464 	   return pqueue->slots[0];
1465 	}
1466 	
1467 	/** returns the number of elements in the queue */
1468 	int SCIPpqueueNElems(
1469 	   SCIP_PQUEUE*          pqueue              /**< priority queue */
1470 	   )
1471 	{
1472 	   assert(pqueue != NULL);
1473 	   assert(pqueue->len >= 0);
1474 	
1475 	   return pqueue->len;
1476 	}
1477 	
1478 	/** returns the elements of the queue; changing the returned array may destroy the queue's ordering! */
1479 	void** SCIPpqueueElems(
1480 	   SCIP_PQUEUE*          pqueue              /**< priority queue */
1481 	   )
1482 	{
1483 	   assert(pqueue != NULL);
1484 	   assert(pqueue->len >= 0);
1485 	
1486 	   return pqueue->slots;
1487 	}
1488 	
1489 	/** return the position of @p elem in the priority queue, or -1 if element is not found */
1490 	int SCIPpqueueFind(
1491 	   SCIP_PQUEUE*          pqueue,             /**< priority queue */
1492 	   void*                 elem                /**< element to be inserted */
1493 	   )
1494 	{
1495 	   int pos = -1;
1496 	
1497 	   while( ++pos < SCIPpqueueNElems(pqueue) )
1498 	   {
1499 	      if( pqueue->slots[pos] == elem )
1500 	         return pos;
1501 	   }
1502 	
1503 	   return -1;
1504 	}
1505 	
1506 	
1507 	
1508 	
1509 	/*
1510 	 * Hash Table
1511 	 */
1512 	
1513 	/** table of some prime numbers */
1514 	static int primetable[] = {
1515 	   2,
1516 	   7,
1517 	   19,
1518 	   31,
1519 	   59,
1520 	   227,
1521 	   617,
1522 	   1523,
1523 	   3547,
1524 	   8011,
1525 	   17707,
1526 	   38723,
1527 	   83833,
1528 	   180317,
1529 	   385897,
1530 	   821411,
1531 	   1742369,
1532 	   3680893,
1533 	   5693959,
1534 	   7753849,
1535 	   9849703,
1536 	   11973277,
1537 	   14121853,
1538 	   17643961,
1539 	   24273817,
1540 	   32452843,
1541 	   49979687,
1542 	   67867967,
1543 	   86028121,
1544 	   104395301,
1545 	   122949823,
1546 	   141650939,
1547 	   160481183,
1548 	   179424673,
1549 	   198491317,
1550 	   217645177,
1551 	   256203161,
1552 	   314606869,
1553 	   373587883,
1554 	   433024223,
1555 	   492876847,
1556 	   553105243,
1557 	   613651349,
1558 	   694847533,
1559 	   756065159,
1560 	   817504243,
1561 	   879190747,
1562 	   941083981,
1563 	   982451653,
1564 	   INT_MAX
1565 	};
1566 	static const int primetablesize = sizeof(primetable)/sizeof(int);
1567 	
1568 	/** simple and fast 2-universal hash function using multiply and shift */
1569 	static
1570 	uint32_t hashvalue(
1571 	   uint64_t              input               /**< key value */
1572 	   )
1573 	{
1574 	   return ( (uint32_t) ((UINT64_C(0x9e3779b97f4a7c15) * input)>>32) ) | 1u;
1575 	}
1576 	
1577 	/** returns a reasonable hash table size (a prime number) that is at least as large as the specified value */
1578 	int SCIPcalcMultihashSize(
1579 	   int                   minsize             /**< minimal size of the hash table */
1580 	   )
1581 	{
1582 	   int pos;
1583 	
1584 	   (void) SCIPsortedvecFindInt(primetable, minsize, primetablesize, &pos);
1585 	   assert(0 <= pos && pos < primetablesize);
1586 	
1587 	   return primetable[pos];
1588 	}
1589 	
1590 	/** appends element to the multihash list */
1591 	static
1592 	SCIP_RETCODE multihashlistAppend(
1593 	   SCIP_MULTIHASHLIST**  multihashlist,      /**< pointer to hash list */
1594 	   BMS_BLKMEM*           blkmem,             /**< block memory */
1595 	   void*                 element             /**< element to append to the list */
1596 	   )
1597 	{
1598 	   SCIP_MULTIHASHLIST* newlist;
1599 	
1600 	   assert(multihashlist != NULL);
1601 	   assert(blkmem != NULL);
1602 	   assert(element != NULL);
1603 	
1604 	   SCIP_ALLOC( BMSallocBlockMemory(blkmem, &newlist) );
1605 	   newlist->element = element;
1606 	   newlist->next = *multihashlist;
1607 	   *multihashlist = newlist;
1608 	
1609 	   return SCIP_OKAY;
1610 	}
1611 	
1612 	/** frees a multihash list entry and all its successors */
1613 	static
1614 	void multihashlistFree(
1615 	   SCIP_MULTIHASHLIST**  multihashlist,      /**< pointer to multihash list to free */
1616 	   BMS_BLKMEM*           blkmem              /**< block memory */
1617 	   )
1618 	{
1619 	   SCIP_MULTIHASHLIST* list;
1620 	   SCIP_MULTIHASHLIST* nextlist;
1621 	
1622 	   assert(multihashlist != NULL);
1623 	   assert(blkmem != NULL);
1624 	
1625 	   list = *multihashlist;
1626 	   while( list != NULL )
1627 	   {
1628 	      nextlist = list->next;
1629 	      BMSfreeBlockMemory(blkmem, &list);
1630 	      list = nextlist;
1631 	   }
1632 	
1633 	   *multihashlist = NULL;
1634 	}
1635 	
1636 	/** finds multihash list entry pointing to element with given key in the multihash list, returns NULL if not found */
1637 	static
1638 	SCIP_MULTIHASHLIST* multihashlistFind(
1639 	   SCIP_MULTIHASHLIST*   multihashlist,      /**< multihash list */
1640 	   SCIP_DECL_HASHGETKEY((*hashgetkey)),      /**< gets the key of the given element */
1641 	   SCIP_DECL_HASHKEYEQ ((*hashkeyeq)),       /**< returns TRUE iff both keys are equal */
1642 	   SCIP_DECL_HASHKEYVAL((*hashkeyval)),      /**< returns the hash value of the key */
1643 	   void*                 userptr,            /**< user pointer */
1644 	   uint64_t              keyval,             /**< hash value of key */
1645 	   void*                 key                 /**< key to retrieve */
1646 	   )
1647 	{
1648 	   uint64_t currentkeyval;
1649 	   void* currentkey;
1650 	
1651 	   assert(hashkeyeq != NULL);
1652 	   assert(key != NULL);
1653 	
1654 	   while( multihashlist != NULL )
1655 	   {
1656 	      currentkey = hashgetkey(userptr, multihashlist->element);
1657 	      currentkeyval = hashkeyval(userptr, currentkey);
1658 	      if( currentkeyval == keyval && hashkeyeq(userptr, currentkey, key) )
1659 	         return multihashlist;
1660 	
1661 	      multihashlist = multihashlist->next;
1662 	   }
1663 	
1664 	   return NULL;
1665 	}
1666 	
1667 	/** retrieves element with given key from the multihash list, or NULL */
1668 	static
1669 	void* multihashlistRetrieve(
1670 	   SCIP_MULTIHASHLIST*   multihashlist,      /**< hash list */
1671 	   SCIP_DECL_HASHGETKEY((*hashgetkey)),      /**< gets the key of the given element */
1672 	   SCIP_DECL_HASHKEYEQ ((*hashkeyeq)),       /**< returns TRUE iff both keys are equal */
1673 	   SCIP_DECL_HASHKEYVAL((*hashkeyval)),      /**< returns the hash value of the key */
1674 	   void*                 userptr,            /**< user pointer */
1675 	   uint64_t              keyval,             /**< hash value of key */
1676 	   void*                 key                 /**< key to retrieve */
1677 	   )
1678 	{
1679 	   SCIP_MULTIHASHLIST* h;
1680 	
1681 	   /* find hash list entry */
1682 	   h = multihashlistFind(multihashlist, hashgetkey, hashkeyeq, hashkeyval, userptr, keyval, key);
1683 	
1684 	   /* return element */
1685 	   if( h != NULL )
1686 	   {
1687 	#ifndef NDEBUG
1688 	      SCIP_MULTIHASHLIST* h2;
1689 	
1690 	      h2 = multihashlistFind(h->next, hashgetkey, hashkeyeq, hashkeyval, userptr, keyval, key);
1691 	
1692 	      if( h2 != NULL )
1693 	      {
1694 	         void* key1;
1695 	         void* key2;
1696 	
1697 	         key1 = hashgetkey(userptr, h->element);
1698 	         key2 = hashgetkey(userptr, h2->element);
1699 	         assert(hashkeyval(userptr, key1) == hashkeyval(userptr, key2));
1700 	
1701 	         if( hashkeyeq(userptr, key1, key2) )
1702 	         {
1703 	            SCIPerrorMessage("WARNING: hashkey with same value exists multiple times (e.g. duplicate constraint/variable names), so the return value is maybe not correct\n");
1704 	         }
1705 	      }
1706 	#endif
1707 	
1708 	      return h->element;
1709 	   }
1710 	   else
1711 	      return NULL;
1712 	}
1713 	
1714 	
1715 	/** retrieves element with given key from the multihash list, or NULL
1716 	 *  returns pointer to multihash table list entry
1717 	 */
1718 	static
1719 	void* multihashlistRetrieveNext(
1720 	   SCIP_MULTIHASHLIST**  multihashlist,      /**< on input: hash list to search; on exit: hash list entry corresponding
1721 	                                              *   to element after retrieved one, or NULL */
1722 	   SCIP_DECL_HASHGETKEY((*hashgetkey)),      /**< gets the key of the given element */
1723 	   SCIP_DECL_HASHKEYEQ ((*hashkeyeq)),       /**< returns TRUE iff both keys are equal */
1724 	   SCIP_DECL_HASHKEYVAL((*hashkeyval)),      /**< returns the hash value of the key */
1725 	   void*                 userptr,            /**< user pointer */
1726 	   uint64_t              keyval,             /**< hash value of key */
1727 	   void*                 key                 /**< key to retrieve */
1728 	   )
1729 	{
1730 	   SCIP_MULTIHASHLIST* h;
1731 	
1732 	   assert(multihashlist != NULL);
1733 	
1734 	   /* find hash list entry */
1735 	   h = multihashlistFind(*multihashlist, hashgetkey, hashkeyeq, hashkeyval, userptr, keyval, key);
1736 	
1737 	   /* return element */
1738 	   if( h != NULL )
1739 	   {
1740 	      *multihashlist = h->next;
1741 	
1742 	      return h->element;
1743 	   }
1744 	
1745 	   *multihashlist = NULL;
1746 	
1747 	   return NULL;
1748 	}
1749 	
1750 	/** removes element from the multihash list */
1751 	static
1752 	SCIP_Bool multihashlistRemove(
1753 	   SCIP_MULTIHASHLIST**  multihashlist,      /**< pointer to hash list */
1754 	   BMS_BLKMEM*           blkmem,             /**< block memory */
1755 	   void*                 element             /**< element to remove from the list */
1756 	   )
1757 	{
1758 	   SCIP_MULTIHASHLIST* nextlist;
1759 	
1760 	   assert(multihashlist != NULL);
1761 	   assert(blkmem != NULL);
1762 	   assert(element != NULL);
1763 	
1764 	   while( *multihashlist != NULL && (*multihashlist)->element != element )
1765 	      multihashlist = &(*multihashlist)->next;
1766 	
1767 	   if( *multihashlist != NULL )
1768 	   {
1769 	      nextlist = (*multihashlist)->next;
1770 	      BMSfreeBlockMemory(blkmem, multihashlist);
1771 	      *multihashlist = nextlist;
1772 	
1773 	      return TRUE;
1774 	   }
1775 	
1776 	   return FALSE;
1777 	}
1778 	
1779 	#define SCIP_MULTIHASH_MAXSIZE 33554431 /* 2^25 - 1*/
1780 	#define SCIP_MULTIHASH_RESIZE_PERCENTAGE 65
1781 	#define SCIP_MULTIHASH_GROW_FACTOR 1.31
1782 	
1783 	/** resizing(increasing) the given multihash */
1784 	static
1785 	SCIP_RETCODE multihashResize(
1786 	   SCIP_MULTIHASH*       multihash           /**< hash table */
1787 	   )
1788 	{
1789 	   SCIP_MULTIHASHLIST** newlists;
1790 	   SCIP_MULTIHASHLIST* multihashlist;
1791 	   SCIP_Longint nelements;
1792 	   int nnewlists;
1793 	   int l;
1794 	
1795 	   assert(multihash != NULL);
1796 	   assert(multihash->lists != NULL);
1797 	   assert(multihash->nlists > 0);
1798 	   assert(multihash->hashgetkey != NULL);
1799 	   assert(multihash->hashkeyeq != NULL);
1800 	   assert(multihash->hashkeyval != NULL);
1801 	
1802 	   /* get new memeory for hash table lists */
1803 	   nnewlists = (int) MIN((unsigned int)(multihash->nlists * SCIP_MULTIHASH_GROW_FACTOR), SCIP_MULTIHASH_MAXSIZE);
1804 	   nnewlists = MAX(nnewlists, multihash->nlists);
1805 	
1806 	   SCIPdebugMessage("load = %g, nelements = %" SCIP_LONGINT_FORMAT ", nlists = %d, nnewlist = %d\n", SCIPmultihashGetLoad(multihash), multihash->nelements, multihash->nlists, nnewlists);
1807 	
1808 	   if( nnewlists > multihash->nlists )
1809 	   {
1810 	      SCIP_Bool onlyone;
1811 	      void* key;
1812 	      uint64_t keyval;
1813 	      unsigned int hashval;
1814 	
1815 	      SCIP_ALLOC( BMSallocClearBlockMemoryArray(multihash->blkmem, &newlists, nnewlists) );
1816 	
1817 	      /* move all lists */
1818 	      for( l = multihash->nlists - 1; l >= 0; --l )
1819 	      {
1820 	         multihashlist = multihash->lists[l];
1821 	         onlyone = TRUE;
1822 	
1823 	         /* move all elements frmm the old lists into the new lists */
1824 	         while( multihashlist != NULL )
1825 	         {
1826 	            /* get the hash key and its hash value */
1827 	            key = multihash->hashgetkey(multihash->userptr, multihashlist->element);
1828 	            keyval = multihash->hashkeyval(multihash->userptr, key);
1829 	            hashval = (unsigned int) (keyval % (unsigned) nnewlists); /*lint !e573*/
1830 	
1831 	            /* if the old hash table list consists of only one entry, we still can use this old memory block instead
1832 	             * of creating a new one
1833 	             */
1834 	            if( multihashlist->next == NULL && onlyone )
1835 	            {
1836 	               /* the new list is also empty, we can directly copy the entry */
1837 	               if( newlists[hashval] == NULL )
1838 	                  newlists[hashval] = multihashlist;
1839 	               /* the new list is not empty, so we need to find the first empty spot */
1840 	               else
1841 	               {
1842 	                  SCIP_MULTIHASHLIST* lastnext = newlists[hashval];
1843 	                  SCIP_MULTIHASHLIST* next = lastnext->next;
1844 	
1845 	                  while( next != NULL )
1846 	                  {
1847 	                     lastnext = next;
1848 	                     next = next->next;
1849 	                  }
1850 	
1851 	                  lastnext->next = multihashlist;
1852 	               }
1853 	
1854 	               multihash->lists[l] = NULL;
1855 	            }
1856 	            else
1857 	            {
1858 	               /* append old element to the list at the hash position */
1859 	               SCIP_CALL( multihashlistAppend(&(newlists[hashval]), multihash->blkmem, multihashlist->element) );
1860 	            }
1861 	
1862 	            onlyone = FALSE;
1863 	            multihashlist = multihashlist->next;
1864 	         }
1865 	      }
1866 	
1867 	      /* remember number of elements */
1868 	      nelements = multihash->nelements;
1869 	      /* clear old lists */
1870 	      SCIPmultihashRemoveAll(multihash);
1871 	      /* free old lists */
1872 	      BMSfreeBlockMemoryArray(multihash->blkmem, &(multihash->lists), multihash->nlists);
1873 	
1874 	      /* set new data */
1875 	      multihash->lists = newlists;
1876 	      multihash->nlists = nnewlists;
1877 	      multihash->nelements = nelements;
1878 	
1879 	#ifdef SCIP_MORE_DEBUG
1880 	      {
1881 	         SCIP_Longint sumslotsize = 0;
1882 	
1883 	         for( l = 0; l < multihash->nlists; ++l )
1884 	         {
1885 	            multihashlist = multihash->lists[l];
1886 	            while( multihashlist != NULL )
1887 	            {
1888 	               sumslotsize++;
1889 	               multihashlist = multihashlist->next;
1890 	            }
1891 	         }
1892 	         assert(sumslotsize == multihash->nelements);
1893 	      }
1894 	#endif
1895 	   }
1896 	
1897 	   return SCIP_OKAY;
1898 	}
1899 	
1900 	/** creates a multihash table */
1901 	SCIP_RETCODE SCIPmultihashCreate(
1902 	   SCIP_MULTIHASH**      multihash,          /**< pointer to store the created multihash table */
1903 	   BMS_BLKMEM*           blkmem,             /**< block memory used to store multihash table entries */
1904 	   int                   tablesize,          /**< size of the hash table */
1905 	   SCIP_DECL_HASHGETKEY((*hashgetkey)),      /**< gets the key of the given element */
1906 	   SCIP_DECL_HASHKEYEQ ((*hashkeyeq)),       /**< returns TRUE iff both keys are equal */
1907 	   SCIP_DECL_HASHKEYVAL((*hashkeyval)),      /**< returns the hash value of the key */
1908 	   void*                 userptr             /**< user pointer */
1909 	   )
1910 	{
1911 	   /* only assert non negative to catch overflow errors
1912 	    * but not zeros due to integer divison
1913 	    */
1914 	   assert(tablesize >= 0);
1915 	   assert(multihash != NULL);
1916 	   assert(hashgetkey != NULL);
1917 	   assert(hashkeyeq != NULL);
1918 	   assert(hashkeyval != NULL);
1919 	
1920 	   SCIP_ALLOC( BMSallocBlockMemory(blkmem, multihash) );
1921 	   SCIP_ALLOC( BMSallocClearBlockMemoryArray(blkmem, &(*multihash)->lists, tablesize) );
1922 	   (*multihash)->blkmem = blkmem;
1923 	   (*multihash)->nlists = tablesize;
1924 	   (*multihash)->hashgetkey = hashgetkey;
1925 	   (*multihash)->hashkeyeq = hashkeyeq;
1926 	   (*multihash)->hashkeyval = hashkeyval;
1927 	   (*multihash)->userptr = userptr;
1928 	   (*multihash)->nelements = 0;
1929 	
1930 	   return SCIP_OKAY;
1931 	}
1932 	
1933 	/** frees the multihash table */
1934 	void SCIPmultihashFree(
1935 	   SCIP_MULTIHASH**      multihash           /**< pointer to the multihash table */
1936 	   )
1937 	{
1938 	   int i;
1939 	   SCIP_MULTIHASH* table;
1940 	   BMS_BLKMEM* blkmem;
1941 	   SCIP_MULTIHASHLIST** lists;
1942 	
1943 	   assert(multihash != NULL);
1944 	   assert(*multihash != NULL);
1945 	
1946 	   table = (*multihash);
1947 	   blkmem = table->blkmem;
1948 	   lists = table->lists;
1949 	
1950 	   /* free hash lists */
1951 	   for( i = table->nlists - 1; i >= 0; --i )
1952 	      multihashlistFree(&lists[i], blkmem);
1953 	
1954 	   /* free main hash table data structure */
1955 	   BMSfreeBlockMemoryArray(blkmem, &table->lists, table->nlists);
1956 	   BMSfreeBlockMemory(blkmem, multihash);
1957 	}
1958 	
1959 	
1960 	/** inserts element in multihash table (multiple inserts of same element possible)
1961 	 *
1962 	 *  @note A pointer to a multihashlist returned by SCIPmultihashRetrieveNext() might get invalid when adding an element
1963 	 *        to the hash table, due to dynamic resizing.
1964 	 */
1965 	SCIP_RETCODE SCIPmultihashInsert(
1966 	   SCIP_MULTIHASH*       multihash,          /**< multihash table */
1967 	   void*                 element             /**< element to insert into the table */
1968 	   )
1969 	{
1970 	   void* key;
1971 	   uint64_t keyval;
1972 	   unsigned int hashval;
1973 	
1974 	   assert(multihash != NULL);
1975 	   assert(multihash->lists != NULL);
1976 	   assert(multihash->nlists > 0);
1977 	   assert(multihash->hashgetkey != NULL);
1978 	   assert(multihash->hashkeyeq != NULL);
1979 	   assert(multihash->hashkeyval != NULL);
1980 	   assert(element != NULL);
1981 	
1982 	   /* dynamically resizing the hashtables */
1983 	   if( SCIPmultihashGetLoad(multihash) > SCIP_MULTIHASH_RESIZE_PERCENTAGE )
1984 	   {
1985 	      SCIP_CALL( multihashResize(multihash) );
1986 	   }
1987 	
1988 	   /* get the hash key and its hash value */
1989 	   key = multihash->hashgetkey(multihash->userptr, element);
1990 	   keyval = multihash->hashkeyval(multihash->userptr, key);
1991 	   hashval = (unsigned int) (keyval % (unsigned) multihash->nlists); /*lint !e573*/
1992 	
1993 	   /* append element to the list at the hash position */
1994 	   SCIP_CALL( multihashlistAppend(&multihash->lists[hashval], multihash->blkmem, element) );
1995 	
1996 	   ++(multihash->nelements);
1997 	
1998 	   return SCIP_OKAY;
1999 	}
2000 	
2001 	/** inserts element in multihash table (multiple insertion of same element is checked and results in an error)
2002 	 *
2003 	 *  @note A pointer to a multihashlist returned by SCIPmultihashRetrieveNext() might get invalid when adding a new
2004 	 *        element to the multihash table, due to dynamic resizing.
2005 	 */
2006 	SCIP_RETCODE SCIPmultihashSafeInsert(
2007 	   SCIP_MULTIHASH*       multihash,          /**< multihash table */
2008 	   void*                 element             /**< element to insert into the table */
2009 	   )
2010 	{
2011 	   assert(multihash != NULL);
2012 	   assert(multihash->hashgetkey != NULL);
2013 	
2014 	   /* check, if key is already existing */
2015 	   if( SCIPmultihashRetrieve(multihash, multihash->hashgetkey(multihash->userptr, element)) != NULL )
2016 	      return SCIP_KEYALREADYEXISTING;
2017 	
2018 	   /* insert element in hash table */
2019 	   SCIP_CALL( SCIPmultihashInsert(multihash, element) );
2020 	
2021 	   return SCIP_OKAY;
2022 	}
2023 	
2024 	/** retrieve element with key from multihash table, returns NULL if not existing */
2025 	void* SCIPmultihashRetrieve(
2026 	   SCIP_MULTIHASH*       multihash,          /**< multihash table */
2027 	   void*                 key                 /**< key to retrieve */
2028 	   )
2029 	{
2030 	   uint64_t keyval;
2031 	   unsigned int hashval;
2032 	
2033 	   assert(multihash != NULL);
2034 	   assert(multihash->lists != NULL);
2035 	   assert(multihash->nlists > 0);
2036 	   assert(multihash->hashgetkey != NULL);
2037 	   assert(multihash->hashkeyeq != NULL);
2038 	   assert(multihash->hashkeyval != NULL);
2039 	   assert(key != NULL);
2040 	
2041 	   /* get the hash value of the key */
2042 	   keyval = multihash->hashkeyval(multihash->userptr, key);
2043 	   hashval = (unsigned int) (keyval % (unsigned) multihash->nlists); /*lint !e573*/
2044 	
2045 	   return multihashlistRetrieve(multihash->lists[hashval], multihash->hashgetkey, multihash->hashkeyeq,
2046 	      multihash->hashkeyval, multihash->userptr, keyval, key);
2047 	}
2048 	
2049 	/** retrieve element with key from multihash table, returns NULL if not existing
2050 	 *  can be used to retrieve all entries with the same key (one-by-one)
2051 	 *
2052 	 *  @note The returned multimultihashlist pointer might get invalid when adding a new element to the multihash table.
2053 	 */
2054 	void* SCIPmultihashRetrieveNext(
2055 	   SCIP_MULTIHASH*       multihash,          /**< multihash table */
2056 	   SCIP_MULTIHASHLIST**  multihashlist,      /**< input: entry in hash table list from which to start searching, or NULL
2057 	                                              *   output: entry in hash table list corresponding to element after
2058 	                                              *           retrieved one, or NULL */
2059 	   void*                 key                 /**< key to retrieve */
2060 	   )
2061 	{
2062 	   uint64_t keyval;
2063 	
2064 	   assert(multihash != NULL);
2065 	   assert(multihash->lists != NULL);
2066 	   assert(multihash->nlists > 0);
2067 	   assert(multihash->hashgetkey != NULL);
2068 	   assert(multihash->hashkeyeq != NULL);
2069 	   assert(multihash->hashkeyval != NULL);
2070 	   assert(multihashlist != NULL);
2071 	   assert(key != NULL);
2072 	
2073 	   keyval = multihash->hashkeyval(multihash->userptr, key);
2074 	
2075 	   if( *multihashlist == NULL )
2076 	   {
2077 	      unsigned int hashval;
2078 	
2079 	      /* get the hash value of the key */
2080 	      hashval = (unsigned int) (keyval % (unsigned) multihash->nlists); /*lint !e573*/
2081 	
2082 	      *multihashlist = multihash->lists[hashval];
2083 	   }
2084 	
2085 	   return multihashlistRetrieveNext(multihashlist, multihash->hashgetkey, multihash->hashkeyeq,
2086 	      multihash->hashkeyval, multihash->userptr, keyval, key);
2087 	}
2088 	
2089 	/** returns whether the given element exists in the multihash table */
2090 	SCIP_Bool SCIPmultihashExists(
2091 	   SCIP_MULTIHASH*       multihash,          /**< multihash table */
2092 	   void*                 element             /**< element to search in the table */
2093 	   )
2094 	{
2095 	   void* key;
2096 	   uint64_t keyval;
2097 	   unsigned int hashval;
2098 	
2099 	   assert(multihash != NULL);
2100 	   assert(multihash->lists != NULL);
2101 	   assert(multihash->nlists > 0);
2102 	   assert(multihash->hashgetkey != NULL);
2103 	   assert(multihash->hashkeyeq != NULL);
2104 	   assert(multihash->hashkeyval != NULL);
2105 	   assert(element != NULL);
2106 	
2107 	   /* get the hash key and its hash value */
2108 	   key = multihash->hashgetkey(multihash->userptr, element);
2109 	   keyval = multihash->hashkeyval(multihash->userptr, key);
2110 	   hashval = (unsigned int) (keyval % (unsigned) multihash->nlists); /*lint !e573*/
2111 	
2112 	   return (multihashlistFind(multihash->lists[hashval], multihash->hashgetkey, multihash->hashkeyeq,
2113 	         multihash->hashkeyval, multihash->userptr, keyval, key) != NULL);
2114 	}
2115 	
2116 	/** removes element from the multihash table, if it exists */
2117 	SCIP_RETCODE SCIPmultihashRemove(
2118 	   SCIP_MULTIHASH*       multihash,          /**< multihash table */
2119 	   void*                 element             /**< element to remove from the table */
2120 	   )
2121 	{
2122 	   void* key;
2123 	   uint64_t keyval;
2124 	   unsigned int hashval;
2125 	
2126 	   assert(multihash != NULL);
2127 	   assert(multihash->lists != NULL);
2128 	   assert(multihash->nlists > 0);
2129 	   assert(multihash->hashgetkey != NULL);
2130 	   assert(multihash->hashkeyeq != NULL);
2131 	   assert(multihash->hashkeyval != NULL);
2132 	   assert(element != NULL);
2133 	
2134 	   /* get the hash key and its hash value */
2135 	   key = multihash->hashgetkey(multihash->userptr, element);
2136 	   keyval = multihash->hashkeyval(multihash->userptr, key);
2137 	   hashval = (unsigned int) (keyval % (unsigned) multihash->nlists); /*lint !e573*/
2138 	
2139 	   /* remove element from the list at the hash position */
2140 	   if( multihashlistRemove(&multihash->lists[hashval], multihash->blkmem, element) )
2141 	      --(multihash->nelements);
2142 	
2143 	   return SCIP_OKAY;
2144 	}
2145 	
2146 	/** removes all elements of the multihash table
2147 	 *
2148 	 *  @note From a performance point of view you should not fill and clear a hash table too often since the clearing can
2149 	 *        be expensive. Clearing is done by looping over all buckets and removing the hash table lists one-by-one.
2150 	 */
2151 	void SCIPmultihashRemoveAll(
2152 	   SCIP_MULTIHASH*       multihash           /**< multihash table */
2153 	   )
2154 	{
2155 	   BMS_BLKMEM* blkmem;
2156 	   SCIP_MULTIHASHLIST** lists;
2157 	   int i;
2158 	
2159 	   assert(multihash != NULL);
2160 	
2161 	   blkmem = multihash->blkmem;
2162 	   lists = multihash->lists;
2163 	
2164 	   /* free hash lists */
2165 	   for( i = multihash->nlists - 1; i >= 0; --i )
2166 	      multihashlistFree(&lists[i], blkmem);
2167 	
2168 	   multihash->nelements = 0;
2169 	}
2170 	
2171 	/** returns number of multihash table elements */
2172 	SCIP_Longint SCIPmultihashGetNElements(
2173 	   SCIP_MULTIHASH*       multihash           /**< multihash table */
2174 	   )
2175 	{
2176 	   assert(multihash != NULL);
2177 	
2178 	   return multihash->nelements;
2179 	}
2180 	
2181 	/** returns the load of the given multihash table in percentage */
2182 	SCIP_Real SCIPmultihashGetLoad(
2183 	   SCIP_MULTIHASH*       multihash           /**< multihash table */
2184 	   )
2185 	{
2186 	   assert(multihash != NULL);
2187 	
2188 	   return ((SCIP_Real)(multihash->nelements) / (multihash->nlists) * 100.0);
2189 	}
2190 	
2191 	/** prints statistics about multihash table usage */
2192 	void SCIPmultihashPrintStatistics(
2193 	   SCIP_MULTIHASH*       multihash,          /**< multihash table */
2194 	   SCIP_MESSAGEHDLR*     messagehdlr         /**< message handler */
2195 	   )
2196 	{
2197 	   SCIP_MULTIHASHLIST* multihashlist;
2198 	   int usedslots;
2199 	   int maxslotsize;
2200 	   int sumslotsize;
2201 	   int slotsize;
2202 	   int i;
2203 	
2204 	   assert(multihash != NULL);
2205 	
2206 	   usedslots = 0;
2207 	   maxslotsize = 0;
2208 	   sumslotsize = 0;
2209 	   for( i = 0; i < multihash->nlists; ++i )
2210 	   {
2211 	      multihashlist = multihash->lists[i];
2212 	      if( multihashlist != NULL )
2213 	      {
2214 	         usedslots++;
2215 	         slotsize = 0;
2216 	         while( multihashlist != NULL )
2217 	         {
2218 	            slotsize++;
2219 	            multihashlist = multihashlist->next;
2220 	         }
2221 	         maxslotsize = MAX(maxslotsize, slotsize);
2222 	         sumslotsize += slotsize;
2223 	      }
2224 	   }
2225 	   assert(sumslotsize == multihash->nelements);
2226 	
2227 	   SCIPmessagePrintInfo(messagehdlr, "%" SCIP_LONGINT_FORMAT " multihash entries, used %d/%d slots (%.1f%%)",
2228 	      multihash->nelements, usedslots, multihash->nlists, 100.0*(SCIP_Real)usedslots/(SCIP_Real)(multihash->nlists));
2229 	   if( usedslots > 0 )
2230 	      SCIPmessagePrintInfo(messagehdlr, ", avg. %.1f entries/used slot, max. %d entries in slot",
2231 	         (SCIP_Real)(multihash->nelements)/(SCIP_Real)usedslots, maxslotsize);
2232 	   SCIPmessagePrintInfo(messagehdlr, "\n");
2233 	}
2234 	
2235 	/** creates a hash table */
2236 	SCIP_RETCODE SCIPhashtableCreate(
2237 	   SCIP_HASHTABLE**      hashtable,          /**< pointer to store the created hash table */
2238 	   BMS_BLKMEM*           blkmem,             /**< block memory used to store hash table entries */
2239 	   int                   tablesize,          /**< size of the hash table */
2240 	   SCIP_DECL_HASHGETKEY((*hashgetkey)),      /**< gets the key of the given element */
2241 	   SCIP_DECL_HASHKEYEQ ((*hashkeyeq)),       /**< returns TRUE iff both keys are equal */
2242 	   SCIP_DECL_HASHKEYVAL((*hashkeyval)),      /**< returns the hash value of the key */
2243 	   void*                 userptr             /**< user pointer */
2244 	   )
2245 	{
2246 	   unsigned int nslots;
2247 	
2248 	   /* only assert non negative to catch overflow errors
2249 	    * but not zeros due to integer divison
2250 	    */
2251 	   assert(tablesize >= 0);
2252 	   assert(hashtable != NULL);
2253 	   assert(hashgetkey != NULL);
2254 	   assert(hashkeyeq != NULL);
2255 	   assert(hashkeyval != NULL);
2256 	   assert(blkmem != NULL);
2257 	
2258 	   SCIP_ALLOC( BMSallocBlockMemory(blkmem, hashtable) );
2259 	
2260 	   /* dont create too small hashtables, i.e. at least size 32, and increase
2261 	    * the given size by divinding it by 0.9, since then no rebuilding will
2262 	    * be necessary if the given number of elements are inserted. Finally round
2263 	    * to the next power of two.
2264 	    */
2265 	   (*hashtable)->shift = 32;
2266 	   (*hashtable)->shift -= (unsigned int)ceil(LOG2(MAX(32.0, tablesize / 0.9)));
2267 	
2268 	   /* compute size from shift */
2269 	   nslots = 1u << (32 - (*hashtable)->shift);
2270 	
2271 	   /* compute mask to do a fast modulo by nslots using bitwise and */
2272 	   (*hashtable)->mask = nslots - 1;
2273 	   SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*hashtable)->slots, nslots) );
2274 	   SCIP_ALLOC( BMSallocClearBlockMemoryArray(blkmem, &(*hashtable)->hashes, nslots) );
2275 	   (*hashtable)->blkmem = blkmem;
2276 	   (*hashtable)->hashgetkey = hashgetkey;
2277 	   (*hashtable)->hashkeyeq = hashkeyeq;
2278 	   (*hashtable)->hashkeyval = hashkeyval;
2279 	   (*hashtable)->userptr = userptr;
2280 	   (*hashtable)->nelements = 0;
2281 	
2282 	   return SCIP_OKAY;
2283 	}
2284 	
2285 	/** frees the hash table */
2286 	void SCIPhashtableFree(
2287 	   SCIP_HASHTABLE**      hashtable           /**< pointer to the hash table */
2288 	   )
2289 	{
2290 	   uint32_t nslots;
2291 	   SCIP_HASHTABLE* table;
2292 	
2293 	   assert(hashtable != NULL);
2294 	   assert(*hashtable != NULL);
2295 	   table = *hashtable;
2296 	   nslots = (*hashtable)->mask + 1;
2297 	#ifdef SCIP_DEBUG
2298 	   {
2299 	      uint32_t maxprobelen = 0;
2300 	      uint64_t probelensum = 0;
2301 	      uint32_t i;
2302 	
2303 	      assert(table != NULL);
2304 	
2305 	      for( i = 0; i < nslots; ++i )
2306 	      {
2307 	         if( table->hashes[i] != 0 )
2308 	         {
2309 	            uint32_t probelen = ((i + table->mask + 1 - (table->hashes[i]>>(table->shift))) & table->mask) + 1;
2310 	            probelensum += probelen;
2311 	            maxprobelen = MAX(probelen, maxprobelen);
2312 	         }
2313 	      }
2314 	
2315 	      SCIPdebugMessage("%u hash table entries, used %u/%u slots (%.1f%%)",
2316 	                       (unsigned int)table->nelements, (unsigned int)table->nelements, (unsigned int)nslots,
2317 	                       100.0*(SCIP_Real)table->nelements/(SCIP_Real)(nslots));
2318 	      if( table->nelements > 0 )
2319 	         SCIPdebugMessage(", avg. probe length is %.1f, max. probe length is %u",
2320 	                              (SCIP_Real)(probelensum)/(SCIP_Real)table->nelements, (unsigned int)maxprobelen);
2321 	      SCIPdebugMessage("\n");
2322 	   }
2323 	#endif
2324 	
2325 	   /* free main hash table data structure */
2326 	   BMSfreeBlockMemoryArray((*hashtable)->blkmem, &table->hashes, nslots);
2327 	   BMSfreeBlockMemoryArray((*hashtable)->blkmem, &table->slots, nslots);
2328 	   BMSfreeBlockMemory((*hashtable)->blkmem, hashtable);
2329 	}
2330 	
2331 	/** removes all elements of the hash table
2332 	 *
2333 	 *  @note From a performance point of view you should not fill and clear a hash table too often since the clearing can
2334 	 *        be expensive. Clearing is done by looping over all buckets and removing the hash table lists one-by-one.
2335 	 *
2336 	 *  @deprecated Please use SCIPhashtableRemoveAll()
2337 	 */
2338 	void SCIPhashtableClear(
2339 	   SCIP_HASHTABLE*       hashtable           /**< hash table */
2340 	   )
2341 	{
2342 	   SCIPhashtableRemoveAll(hashtable);
2343 	}
2344 	
2345 	/* computes the distance from it's desired position for the element stored at pos */
2346 	#define ELEM_DISTANCE(pos) (((pos) + hashtable->mask + 1 - (hashtable->hashes[(pos)]>>(hashtable->shift))) & hashtable->mask)
2347 	
2348 	/** inserts element in hash table (multiple inserts of same element overrides previous one) */
2349 	static
2350 	SCIP_RETCODE hashtableInsert(
2351 	   SCIP_HASHTABLE*       hashtable,          /**< hash table */
2352 	   void*                 element,            /**< element to insert into the table */
2353 	   void*                 key,                /**< key of element */
2354 	   uint32_t              hashval,            /**< hash value of element */
2355 	   SCIP_Bool             override            /**< should element be overridden or an error be returned if already existing */
2356 	   )
2357 	{
2358 	   uint32_t elemdistance;
2359 	   uint32_t pos;
2360 	#ifndef NDEBUG
2361 	   SCIP_Bool swapped = FALSE;
2362 	#endif
2363 	
2364 	   assert(hashtable != NULL);
2365 	   assert(hashtable->slots != NULL);
2366 	   assert(hashtable->hashes != NULL);
2367 	   assert(hashtable->mask > 0);
2368 	   assert(hashtable->hashgetkey != NULL);
2369 	   assert(hashtable->hashkeyeq != NULL);
2370 	   assert(hashtable->hashkeyval != NULL);
2371 	   assert(element != NULL);
2372 	
2373 	   pos = hashval>>(hashtable->shift);
2374 	   elemdistance = 0;
2375 	   while( TRUE ) /*lint !e716*/
2376 	   {
2377 	      uint32_t distance;
2378 	
2379 	      /* if position is empty or key equal insert element */
2380 	      if( hashtable->hashes[pos] == 0 )
2381 	      {
2382 	         hashtable->slots[pos] = element;
2383 	         hashtable->hashes[pos] = hashval;
2384 	         ++hashtable->nelements;
2385 	         return SCIP_OKAY;
2386 	      }
2387 	
2388 	      if( hashtable->hashes[pos] == hashval && hashtable->hashkeyeq(hashtable->userptr,
2389 	             hashtable->hashgetkey(hashtable->userptr, hashtable->slots[pos]), key) )
2390 	      {
2391 	         if( override )
2392 	         {
2393 	#ifndef NDEBUG
2394 	            assert(! swapped);
2395 	#endif
2396 	            hashtable->slots[pos] = element;
2397 	            hashtable->hashes[pos] = hashval;
2398 	            return SCIP_OKAY;
2399 	         }
2400 	         else
2401 	         {
2402 	            return SCIP_KEYALREADYEXISTING;
2403 	         }
2404 	      }
2405 	
2406 	      /* otherwise check if the current element at this position is closer to its hashvalue */
2407 	      distance = ELEM_DISTANCE(pos);
2408 	      if( distance < elemdistance )
2409 	      {
2410 	         uint32_t tmp;
2411 	
2412 	         /* if this is the case we insert the new element here and find a new position for the old one */
2413 	         elemdistance = distance;
2414 	         SCIPswapPointers(&hashtable->slots[pos], &element);
2415 	         tmp = hashval;
2416 	         hashval = hashtable->hashes[pos];
2417 	         hashtable->hashes[pos] = tmp;
2418 	         key = hashtable->hashgetkey(hashtable->userptr, element);
2419 	
2420 	         /* after doing a swap the case that other elements are replaced must not happen anymore */
2421 	#ifndef NDEBUG
2422 	         swapped = TRUE;
2423 	#endif
2424 	      }
2425 	
2426 	      /* continue until we have found an empty position */
2427 	      pos = (pos + 1) & hashtable->mask;
2428 	      ++elemdistance;
2429 	   }
2430 	}
2431 	
2432 	/** check if the load factor of the hashtable is too high and rebuild if necessary */
2433 	static
2434 	SCIP_RETCODE hashtableCheckLoad(
2435 	   SCIP_HASHTABLE*       hashtable           /**< hash table */
2436 	   )
2437 	{
2438 	   assert(hashtable != NULL);
2439 	   assert(hashtable->shift < 32);
2440 	
2441 	   /* use integer arithmetic to approximately check if load factor is above 90% */
2442 	   if( ((((uint64_t)hashtable->nelements)<<10)>>(32-hashtable->shift) > 921) )
2443 	   {
2444 	      void** slots;
2445 	      uint32_t* hashes;
2446 	      uint32_t nslots;
2447 	      uint32_t newnslots;
2448 	      uint32_t i;
2449 	
2450 	      /* calculate new size (always power of two) */
2451 	      nslots = hashtable->mask + 1;
2452 	      newnslots = 2*nslots;
2453 	      hashtable->mask = newnslots-1;
2454 	      --hashtable->shift;
2455 	
2456 	      /* reallocate array */
2457 	      SCIP_ALLOC( BMSallocBlockMemoryArray(hashtable->blkmem, &slots, newnslots) );
2458 	      SCIP_ALLOC( BMSallocClearBlockMemoryArray(hashtable->blkmem, &hashes, newnslots) );
2459 	
2460 	      SCIPswapPointers((void**) &slots, (void**) &hashtable->slots);
2461 	      SCIPswapPointers((void**) &hashes, (void**) &hashtable->hashes);
2462 	      hashtable->nelements = 0;
2463 	
2464 	      /* reinsert all elements */
2465 	      for( i = 0; i < nslots; ++i )
2466 	      {
2467 	         /* using SCIP_CALL_ABORT since there are no allocations or duplicates
2468 	          * and thus no bad return codes when inserting the elements
2469 	          */
2470 	         if( hashes[i] != 0 )
2471 	         {
2472 	            SCIP_CALL_ABORT( hashtableInsert(hashtable, slots[i], hashtable->hashgetkey(hashtable->userptr, slots[i]), hashes[i], FALSE) );
2473 	         }
2474 	      }
2475 	      BMSfreeBlockMemoryArray(hashtable->blkmem, &hashes, nslots);
2476 	      BMSfreeBlockMemoryArray(hashtable->blkmem, &slots, nslots);
2477 	   }
2478 	
2479 	   return SCIP_OKAY;
2480 	}
2481 	
2482 	
2483 	/** inserts element in hash table
2484 	 *
2485 	 *  @note multiple inserts of same element overrides previous one
2486 	 */
2487 	SCIP_RETCODE SCIPhashtableInsert(
2488 	   SCIP_HASHTABLE*       hashtable,          /**< hash table */
2489 	   void*                 element             /**< element to insert into the table */
2490 	   )
2491 	{
2492 	   void* key;
2493 	   uint64_t keyval;
2494 	   uint32_t hashval;
2495 	
2496 	   assert(hashtable != NULL);
2497 	   assert(hashtable->slots != NULL);
2498 	   assert(hashtable->hashes != NULL);
2499 	   assert(hashtable->mask > 0);
2500 	   assert(hashtable->hashgetkey != NULL);
2501 	   assert(hashtable->hashkeyeq != NULL);
2502 	   assert(hashtable->hashkeyval != NULL);
2503 	   assert(element != NULL);
2504 	
2505 	   SCIP_CALL( hashtableCheckLoad(hashtable) );
2506 	
2507 	   /* get the hash key and its hash value */
2508 	   key = hashtable->hashgetkey(hashtable->userptr, element);
2509 	   keyval = hashtable->hashkeyval(hashtable->userptr, key);
2510 	   hashval = hashvalue(keyval);
2511 	
2512 	   return hashtableInsert(hashtable, element, key, hashval, TRUE);
2513 	}
2514 	
2515 	/** inserts element in hash table
2516 	 *
2517 	 *  @note multiple insertion of same element is checked and results in an error
2518 	 */
2519 	SCIP_RETCODE SCIPhashtableSafeInsert(
2520 	   SCIP_HASHTABLE*       hashtable,          /**< hash table */
2521 	   void*                 element             /**< element to insert into the table */
2522 	   )
2523 	{
2524 	   void* key;
2525 	   uint64_t keyval;
2526 	   uint32_t hashval;
2527 	
2528 	   assert(hashtable != NULL);
2529 	   assert(hashtable->slots != NULL);
2530 	   assert(hashtable->hashes != NULL);
2531 	   assert(hashtable->mask > 0);
2532 	   assert(hashtable->hashgetkey != NULL);
2533 	   assert(hashtable->hashkeyeq != NULL);
2534 	   assert(hashtable->hashkeyval != NULL);
2535 	   assert(element != NULL);
2536 	
2537 	   SCIP_CALL( hashtableCheckLoad(hashtable) );
2538 	
2539 	   /* get the hash key and its hash value */
2540 	   key = hashtable->hashgetkey(hashtable->userptr, element);
2541 	   keyval = hashtable->hashkeyval(hashtable->userptr, key);
2542 	   hashval = hashvalue(keyval);
2543 	
2544 	   return hashtableInsert(hashtable, element, key, hashval, FALSE);
2545 	}
2546 	
2547 	/** retrieve element with key from hash table, returns NULL if not existing */
2548 	void* SCIPhashtableRetrieve(
2549 	   SCIP_HASHTABLE*       hashtable,          /**< hash table */
2550 	   void*                 key                 /**< key to retrieve */
2551 	   )
2552 	{
2553 	   uint64_t keyval;
2554 	   uint32_t hashval;
2555 	   uint32_t pos;
2556 	   uint32_t elemdistance;
2557 	
2558 	   assert(hashtable != NULL);
2559 	   assert(hashtable->slots != NULL);
2560 	   assert(hashtable->hashes != NULL);
2561 	   assert(hashtable->mask > 0);
2562 	   assert(hashtable->hashgetkey != NULL);
2563 	   assert(hashtable->hashkeyeq != NULL);
2564 	   assert(hashtable->hashkeyval != NULL);
2565 	   assert(key != NULL);
2566 	
2567 	   /* get the hash value of the key */
2568 	   keyval = hashtable->hashkeyval(hashtable->userptr, key);
2569 	   hashval = hashvalue(keyval);
2570 	
2571 	   pos = hashval>>(hashtable->shift);
2572 	   elemdistance = 0;
2573 	
2574 	   while( TRUE ) /*lint !e716*/
2575 	   {
2576 	      uint32_t distance;
2577 	
2578 	      /* slots is empty so element cannot be contained */
2579 	      if( hashtable->hashes[pos] == 0 )
2580 	         return NULL;
2581 	
2582 	      distance = ELEM_DISTANCE(pos);
2583 	
2584 	      /* element cannot be contained since otherwise we would have swapped it with this one during insert */
2585 	      if( elemdistance > distance )
2586 	         return NULL;
2587 	
2588 	      /* found element */
2589 	      if( hashtable->hashes[pos] == hashval && hashtable->hashkeyeq(hashtable->userptr,
2590 	             hashtable->hashgetkey(hashtable->userptr, hashtable->slots[pos]), key) )
2591 	         return hashtable->slots[pos];
2592 	
2593 	      pos = (pos + 1) & hashtable->mask;
2594 	      ++elemdistance;
2595 	   }
2596 	}
2597 	
2598 	/** returns whether the given element exists in the table */
2599 	SCIP_Bool SCIPhashtableExists(
2600 	   SCIP_HASHTABLE*       hashtable,          /**< hash table */
2601 	   void*                 element             /**< element to search in the table */
2602 	   )
2603 	{
2604 	   assert(hashtable != NULL);
2605 	   assert(hashtable->slots != NULL);
2606 	   assert(hashtable->hashes != NULL);
2607 	   assert(hashtable->mask > 0);
2608 	   assert(hashtable->hashgetkey != NULL);
2609 	   assert(hashtable->hashkeyeq != NULL);
2610 	   assert(hashtable->hashkeyval != NULL);
2611 	   assert(element != NULL);
2612 	
2613 	   return (SCIPhashtableRetrieve(hashtable, hashtable->hashgetkey(hashtable->userptr, element)) != NULL);
2614 	}
2615 	
2616 	/** removes element from the hash table, if it exists */
2617 	SCIP_RETCODE SCIPhashtableRemove(
2618 	   SCIP_HASHTABLE*       hashtable,          /**< hash table */
2619 	   void*                 element             /**< element to remove from the table */
2620 	   )
2621 	{
2622 	   void* key;
2623 	   uint64_t keyval;
2624 	   uint32_t hashval;
2625 	   uint32_t elemdistance;
2626 	   uint32_t distance;
2627 	   uint32_t pos;
2628 	
2629 	   assert(hashtable != NULL);
2630 	   assert(hashtable->slots != NULL);
2631 	   assert(hashtable->hashes != NULL);
2632 	   assert(hashtable->mask > 0);
2633 	   assert(hashtable->hashgetkey != NULL);
2634 	   assert(hashtable->hashkeyeq != NULL);
2635 	   assert(hashtable->hashkeyval != NULL);
2636 	   assert(element != NULL);
2637 	
2638 	   /* get the hash key and its hash value */
2639 	   key = hashtable->hashgetkey(hashtable->userptr, element);
2640 	   keyval = hashtable->hashkeyval(hashtable->userptr, key);
2641 	   hashval = hashvalue(keyval);
2642 	
2643 	   elemdistance = 0;
2644 	   pos = hashval>>(hashtable->shift);
2645 	   while( TRUE ) /*lint !e716*/
2646 	   {
2647 	      /* slots empty so element not contained */
2648 	      if( hashtable->hashes[pos] == 0 )
2649 	         return SCIP_OKAY;
2650 	
2651 	      distance = ELEM_DISTANCE(pos);
2652 	
2653 	      /* element can not be contained since otherwise we would have swapped it with this one */
2654 	      if( elemdistance > distance )
2655 	         return SCIP_OKAY;
2656 	
2657 	      if( hashtable->hashes[pos] == hashval && hashtable->hashkeyeq(hashtable->userptr,
2658 	             hashtable->hashgetkey(hashtable->userptr, hashtable->slots[pos]), key) )
2659 	      {
2660 	         /* element exists at pos so break out of loop */
2661 	         break;
2662 	      }
2663 	
2664 	      pos = (pos + 1) & hashtable->mask;
2665 	      ++elemdistance;
2666 	   }
2667 	
2668 	   /* remove element */
2669 	   hashtable->hashes[pos] = 0;
2670 	   --hashtable->nelements;
2671 	   while( TRUE ) /*lint !e716*/
2672 	   {
2673 	      uint32_t nextpos = (pos + 1) & hashtable->mask;
2674 	
2675 	      /* nothing to do since there is no chain that needs to be moved */
2676 	      if( hashtable->hashes[nextpos] == 0 )
2677 	         break;
2678 	
2679 	      /* check if the element is the start of a new chain and return if that is the case */
2680 	      if( (hashtable->hashes[nextpos]>>(hashtable->shift)) == nextpos )
2681 	         break;
2682 	
2683 	      /* element should be moved to the left and next element needs to be checked */
2684 	      hashtable->slots[pos] = hashtable->slots[nextpos];
2685 	      hashtable->hashes[pos] = hashtable->hashes[nextpos];
2686 	      hashtable->hashes[nextpos] = 0;
2687 	
2688 	      pos = nextpos;
2689 	   }
2690 	
2691 	   return SCIP_OKAY;
2692 	}
2693 	
2694 	/** removes all elements of the hash table */
2695 	void SCIPhashtableRemoveAll(
2696 	   SCIP_HASHTABLE*       hashtable           /**< hash table */
2697 	   )
2698 	{
2699 	   assert(hashtable != NULL);
2700 	
2701 	   BMSclearMemoryArray(hashtable->hashes, hashtable->mask + 1);
2702 	
2703 	   hashtable->nelements = 0;
2704 	}
2705 	
2706 	/** returns number of hash table elements */
2707 	SCIP_Longint SCIPhashtableGetNElements(
2708 	   SCIP_HASHTABLE*       hashtable           /**< hash table */
2709 	   )
2710 	{
2711 	   assert(hashtable != NULL);
2712 	
2713 	   return hashtable->nelements;
2714 	}
2715 	
2716 	/** gives the number of entries in the internal arrays of a hash table */
2717 	int SCIPhashtableGetNEntries(
2718 	   SCIP_HASHTABLE*       hashtable           /**< hash table */
2719 	   )
2720 	{
2721 	   return (int) hashtable->mask + 1;
2722 	}
2723 	
2724 	/** gives the element at the given index or NULL if entry at that index has no element */
2725 	void* SCIPhashtableGetEntry(
2726 	   SCIP_HASHTABLE*       hashtable,          /**< hash table */
2727 	   int                   entryidx            /**< index of hash table entry */
2728 	   )
2729 	{
2730 	   return hashtable->hashes[entryidx] == 0 ? NULL : hashtable->slots[entryidx];
2731 	}
2732 	
2733 	/** returns the load of the given hash table in percentage */
2734 	SCIP_Real SCIPhashtableGetLoad(
2735 	   SCIP_HASHTABLE*       hashtable           /**< hash table */
2736 	   )
2737 	{
2738 	   assert(hashtable != NULL);
2739 	
2740 	   return ((SCIP_Real)(hashtable->nelements) / (hashtable->mask + 1) * 100.0);
2741 	}
2742 	
2743 	/** prints statistics about hash table usage */
2744 	void SCIPhashtablePrintStatistics(
2745 	   SCIP_HASHTABLE*       hashtable,          /**< hash table */
2746 	   SCIP_MESSAGEHDLR*     messagehdlr         /**< message handler */
2747 	   )
2748 	{
2749 	   uint32_t maxprobelen = 0;
2750 	   uint64_t probelensum = 0;
2751 	   uint32_t nslots;
2752 	   uint32_t i;
2753 	
2754 	   assert(hashtable != NULL);
2755 	
2756 	   nslots = hashtable->mask + 1;
2757 	
2758 	   /* compute the maximum and average probe length */
2759 	   for( i = 0; i < nslots; ++i )
2760 	   {
2761 	      if( hashtable->hashes[i] != 0 )
2762 	      {
2763 	         uint32_t probelen = ELEM_DISTANCE(i) + 1;
2764 	         probelensum += probelen;
2765 	         maxprobelen = MAX(probelen, maxprobelen);
2766 	      }
2767 	   }
2768 	
2769 	   /* print general hash table statistics */
2770 	   SCIPmessagePrintInfo(messagehdlr, "%u hash entries, used %u/%u slots (%.1f%%)",
2771 	                        (unsigned int)hashtable->nelements, (unsigned int)hashtable->nelements,
2772 	                        (unsigned int)nslots, 100.0*(SCIP_Real)hashtable->nelements/(SCIP_Real)(nslots));
2773 	
2774 	   /* if not empty print average and maximum probe length */
2775 	   if( hashtable->nelements > 0 )
2776 	      SCIPmessagePrintInfo(messagehdlr, ", avg. probe length is %.1f, max. probe length is %u",
2777 	         (SCIP_Real)(probelensum)/(SCIP_Real)hashtable->nelements, (unsigned int)maxprobelen);
2778 	   SCIPmessagePrintInfo(messagehdlr, "\n");
2779 	}
2780 	
2781 	/** returns TRUE iff both keys (i.e. strings) are equal */
2782 	SCIP_DECL_HASHKEYEQ(SCIPhashKeyEqString)
2783 	{  /*lint --e{715}*/
2784 	   const char* string1 = (const char*)key1;
2785 	   const char* string2 = (const char*)key2;
2786 	
2787 	   return (strcmp(string1, string2) == 0);
2788 	}
2789 	
2790 	/** returns the hash value of the key (i.e. string) */
2791 	SCIP_DECL_HASHKEYVAL(SCIPhashKeyValString)
2792 	{  /*lint --e{715}*/
2793 	   const char* str;
2794 	   uint64_t hash;
2795 	
2796 	   str = (const char*)key;
2797 	   hash = 37;
2798 	   while( *str != '\0' )
2799 	   {
2800 	      hash *= 11;
2801 	      hash += (unsigned int)(*str); /*lint !e571*/
2802 	      str++;
2803 	   }
2804 	
2805 	   return hash;
2806 	}
2807 	
2808 	
2809 	/** gets the element as the key */
2810 	SCIP_DECL_HASHGETKEY(SCIPhashGetKeyStandard)
2811 	{  /*lint --e{715}*/
2812 	   /* the key is the element itself */
2813 	   return elem;
2814 	}
2815 	
2816 	/** returns TRUE iff both keys(pointer) are equal */
2817 	SCIP_DECL_HASHKEYEQ(SCIPhashKeyEqPtr)
2818 	{  /*lint --e{715}*/
2819 	   return (key1 == key2);
2820 	}
2821 	
2822 	/** returns the hash value of the key */
2823 	SCIP_DECL_HASHKEYVAL(SCIPhashKeyValPtr)
2824 	{  /*lint --e{715}*/
2825 	   /* the key is used as the keyvalue too */
2826 	   return (uint64_t) (uintptr_t) key;
2827 	}
2828 	
2829 	
2830 	
2831 	/*
2832 	 * Hash Map
2833 	 */
2834 	
2835 	/* redefine ELEM_DISTANCE macro for hashmap */
2836 	#undef ELEM_DISTANCE
2837 	/* computes the distance from it's desired position for the element stored at pos */
2838 	#define ELEM_DISTANCE(pos) (((pos) + hashmap->mask + 1 - (hashmap->hashes[(pos)]>>(hashmap->shift))) & hashmap->mask)
2839 	
2840 	/** inserts element in hash table */
2841 	static
2842 	SCIP_RETCODE hashmapInsert(
2843 	   SCIP_HASHMAP*         hashmap,            /**< hash map */
2844 	   void*                 origin,             /**< element to insert into the table */
2845 	   SCIP_HASHMAPIMAGE     image,              /**< key of element */
2846 	   uint32_t              hashval,            /**< hash value of element */
2847 	   SCIP_Bool             override            /**< should element be overridden or error be returned if already existing */
2848 	   )
2849 	{
2850 	   uint32_t elemdistance;
2851 	   uint32_t pos;
2852 	
2853 	   assert(hashmap != NULL);
2854 	   assert(hashmap->slots != NULL);
2855 	   assert(hashmap->hashes != NULL);
2856 	   assert(hashmap->mask > 0);
2857 	   assert(hashval != 0);
2858 	
2859 	   pos = hashval>>(hashmap->shift);
2860 	   elemdistance = 0;
2861 	   while( TRUE ) /*lint !e716*/
2862 	   {
2863 	      uint32_t distance;
2864 	
2865 	      /* if position is empty or key equal insert element */
2866 	      if( hashmap->hashes[pos] == 0 )
2867 	      {
2868 	         hashmap->slots[pos].origin = origin;
2869 	         hashmap->slots[pos].image = image;
2870 	         hashmap->hashes[pos] = hashval;
2871 	         ++hashmap->nelements;
2872 	         return SCIP_OKAY;
2873 	      }
2874 	
2875 	      if( hashval == hashmap->hashes[pos] && origin == hashmap->slots[pos].origin )
2876 	      {
2877 	         if( override )
2878 	         {
2879 	            hashmap->slots[pos].origin = origin;
2880 	            hashmap->slots[pos].image = image;
2881 	            hashmap->hashes[pos] = hashval;
2882 	            return SCIP_OKAY;
2883 	         }
2884 	         else
2885 	         {
2886 	            return SCIP_KEYALREADYEXISTING;
2887 	         }
2888 	      }
2889 	
2890 	      /* otherwise check if the current element at this position is closer to its hashvalue */
2891 	      distance = ELEM_DISTANCE(pos);
2892 	      if( distance < elemdistance )
2893 	      {
2894 	         SCIP_HASHMAPIMAGE tmp;
2895 	         uint32_t tmphash;
2896 	
2897 	         /* if this is the case we insert the new element here and find a new position for the old one */
2898 	         elemdistance = distance;
2899 	         tmphash = hashval;
2900 	         hashval = hashmap->hashes[pos];
2901 	         hashmap->hashes[pos] = tmphash;
2902 	         SCIPswapPointers(&hashmap->slots[pos].origin, &origin);
2903 	         tmp = image;
2904 	         image = hashmap->slots[pos].image;
2905 	         hashmap->slots[pos].image = tmp;
2906 	      }
2907 	
2908 	      /* continue until we have found an empty position */
2909 	      pos = (pos + 1) & hashmap->mask;
2910 	      ++elemdistance;
2911 	   }
2912 	}
2913 	
2914 	/** lookup origin in the hashmap. If element is found returns true and the position of the element,
2915 	 *  otherwise returns FALSE.
2916 	 */
2917 	static
2918 	SCIP_Bool hashmapLookup(
2919 	   SCIP_HASHMAP*         hashmap,            /**< hash table */
2920 	   void*                 origin,             /**< origin to lookup */
2921 	   uint32_t*             pos                 /**< pointer to store position of element, if exists */
2922 	   )
2923 	{
2924 	   uint32_t hashval;
2925 	   uint32_t elemdistance;
2926 	
2927 	   assert(hashmap != NULL);
2928 	   assert(hashmap->slots != NULL);
2929 	   assert(hashmap->hashes != NULL);
2930 	   assert(hashmap->mask > 0);
2931 	
2932 	   /* get the hash value */
2933 	   hashval = hashvalue((size_t)origin);
2934 	   assert(hashval != 0);
2935 	
2936 	   *pos = hashval>>(hashmap->shift);
2937 	   elemdistance = 0;
2938 	
2939 	   while( TRUE ) /*lint !e716*/
2940 	   {
2941 	      uint32_t distance;
2942 	
2943 	      /* slots is empty so element cannot be contained */
2944 	      if( hashmap->hashes[*pos] == 0 )
2945 	         return FALSE;
2946 	
2947 	      distance = ELEM_DISTANCE(*pos);
2948 	      /* element can not be contained since otherwise we would have swapped it with this one during insert */
2949 	      if( elemdistance > distance )
2950 	         return FALSE;
2951 	
2952 	      /* found element */
2953 	      if( hashmap->hashes[*pos] == hashval && hashmap->slots[*pos].origin == origin )
2954 	         return TRUE;
2955 	
2956 	      *pos = (*pos + 1) & hashmap->mask;
2957 	      ++elemdistance;
2958 	   }
2959 	}
2960 	
2961 	/** check if the load factor of the hashmap is too high and rebuild if necessary */
2962 	static
2963 	SCIP_RETCODE hashmapCheckLoad(
2964 	   SCIP_HASHMAP*         hashmap             /**< hash table */
2965 	   )
2966 	{
2967 	   assert(hashmap != NULL);
2968 	   assert(hashmap->shift < 32);
2969 	
2970 	   /* use integer arithmetic to approximately check if load factor is above 90% */
2971 	   if( ((((uint64_t)hashmap->nelements)<<10)>>(32-hashmap->shift) > 921) )
2972 	   {
2973 	      SCIP_HASHMAPENTRY* slots;
2974 	      uint32_t* hashes;
2975 	      uint32_t nslots;
2976 	      uint32_t newnslots;
2977 	      uint32_t i;
2978 	
2979 	      /* calculate new size (always power of two) */
2980 	      nslots = hashmap->mask + 1;
2981 	      --hashmap->shift;
2982 	      newnslots = 2*nslots;
2983 	      hashmap->mask = newnslots-1;
2984 	
2985 	      /* reallocate array */
2986 	      SCIP_ALLOC( BMSallocBlockMemoryArray(hashmap->blkmem, &slots, newnslots) );
2987 	      SCIP_ALLOC( BMSallocClearBlockMemoryArray(hashmap->blkmem, &hashes, newnslots) );
2988 	
2989 	      SCIPswapPointers((void**) &slots, (void**) &hashmap->slots);
2990 	      SCIPswapPointers((void**) &hashes, (void**) &hashmap->hashes);
2991 	      hashmap->nelements = 0;
2992 	
2993 	      /* reinsert all elements */
2994 	      for( i = 0; i < nslots; ++i )
2995 	      {
2996 	         /* using SCIP_CALL_ABORT since there are no allocations or duplicates
2997 	          * and thus no bad return codes when inserting the elements
2998 	          */
2999 	         if( hashes[i] != 0 )
3000 	         {
3001 	            SCIP_CALL_ABORT( hashmapInsert(hashmap, slots[i].origin, slots[i].image, hashes[i], FALSE) );
3002 	         }
3003 	      }
3004 	
3005 	      /* free old arrays */
3006 	      BMSfreeBlockMemoryArray(hashmap->blkmem, &hashes, nslots);
3007 	      BMSfreeBlockMemoryArray(hashmap->blkmem, &slots, nslots);
3008 	   }
3009 	
3010 	   return SCIP_OKAY;
3011 	}
3012 	
3013 	/** creates a hash map mapping pointers to pointers */
3014 	SCIP_RETCODE SCIPhashmapCreate(
3015 	   SCIP_HASHMAP**        hashmap,            /**< pointer to store the created hash map */
3016 	   BMS_BLKMEM*           blkmem,             /**< block memory used to store hash map entries */
3017 	   int                   mapsize             /**< size of the hash map */
3018 	   )
3019 	{
3020 	   uint32_t nslots;
3021 	
3022 	   assert(hashmap != NULL);
3023 	   assert(mapsize >= 0);
3024 	   assert(blkmem != NULL);
3025 	
3026 	   SCIP_ALLOC( BMSallocBlockMemory(blkmem, hashmap) );
3027 	
3028 	   /* dont create too small hashtables, i.e. at least size 32, and increase
3029 	    * the given size by divinding it by 0.9, since then no rebuilding will
3030 	    * be necessary if the given number of elements are inserted. Finally round
3031 	    * to the next power of two.
3032 	    */
3033 	   (*hashmap)->shift = 32;
3034 	   (*hashmap)->shift -= (unsigned int)ceil(log(MAX(32, mapsize / 0.9)) / log(2.0));
3035 	   nslots = 1u << (32 - (*hashmap)->shift);
3036 	   (*hashmap)->mask = nslots - 1;
3037 	   (*hashmap)->blkmem = blkmem;
3038 	   (*hashmap)->nelements = 0;
3039 	   (*hashmap)->hashmaptype = SCIP_HASHMAPTYPE_UNKNOWN;
3040 	
3041 	   SCIP_ALLOC( BMSallocBlockMemoryArray((*hashmap)->blkmem, &(*hashmap)->slots, nslots) );
3042 	   SCIP_ALLOC( BMSallocClearBlockMemoryArray((*hashmap)->blkmem, &(*hashmap)->hashes, nslots) );
3043 	
3044 	   return SCIP_OKAY;
3045 	}
3046 	
3047 	/** frees the hash map */
3048 	void SCIPhashmapFree(
3049 	   SCIP_HASHMAP**        hashmap             /**< pointer to the hash map */
3050 	   )
3051 	{
3052 	   uint32_t nslots;
3053 	
3054 	   assert(hashmap != NULL);
3055 	   assert(*hashmap != NULL);
3056 	
3057 	   nslots = (*hashmap)->mask + 1;
3058 	#ifdef SCIP_DEBUG
3059 	   {
3060 	      uint32_t maxprobelen = 0;
3061 	      uint64_t probelensum = 0;
3062 	      uint32_t i;
3063 	
3064 	      assert(hashmap != NULL);
3065 	
3066 	      for( i = 0; i < nslots; ++i )
3067 	      {
3068 	         if( (*hashmap)->hashes[i] != 0 )
3069 	         {
3070 	            uint32_t probelen = ((i + (*hashmap)->mask + 1 - ((*hashmap)->hashes[i]>>((*hashmap)->shift))) & (*hashmap)->mask) + 1;
3071 	            probelensum += probelen;
3072 	            maxprobelen = MAX(probelen, maxprobelen);
3073 	         }
3074 	      }
3075 	
3076 	      SCIPdebugMessage("%u hash map entries, used %u/%u slots (%.1f%%)",
3077 	                       (unsigned int)(*hashmap)->nelements, (unsigned int)(*hashmap)->nelements, (unsigned int)nslots,
3078 	                       100.0*(SCIP_Real)(*hashmap)->nelements/(SCIP_Real)(nslots));
3079 	      if( (*hashmap)->nelements > 0 )
3080 	         SCIPdebugPrintf(", avg. probe length is %.1f, max. probe length is %u",
3081 	                          (SCIP_Real)(probelensum)/(SCIP_Real)(*hashmap)->nelements, (unsigned int)maxprobelen);
3082 	      SCIPdebugPrintf("\n");
3083 	   }
3084 	#endif
3085 	
3086 	   /* free main hash map data structure */
3087 	   BMSfreeBlockMemoryArray((*hashmap)->blkmem, &(*hashmap)->hashes, nslots);
3088 	   BMSfreeBlockMemoryArray((*hashmap)->blkmem, &(*hashmap)->slots, nslots);
3089 	   BMSfreeBlockMemory((*hashmap)->blkmem, hashmap);
3090 	}
3091 	
3092 	/** inserts new origin->image pair in hash map
3093 	 *
3094 	 *  @note multiple insertion of same element is checked and results in an error
3095 	 */
3096 	SCIP_RETCODE SCIPhashmapInsert(
3097 	   SCIP_HASHMAP*         hashmap,            /**< hash map */
3098 	   void*                 origin,             /**< origin to set image for */
3099 	   void*                 image               /**< new image for origin */
3100 	   )
3101 	{
3102 	   uint32_t hashval;
3103 	   SCIP_HASHMAPIMAGE img;
3104 	
3105 	   assert(hashmap != NULL);
3106 	   assert(hashmap->slots != NULL);
3107 	   assert(hashmap->hashes != NULL);
3108 	   assert(hashmap->mask > 0);
3109 	   assert(hashmap->hashmaptype == SCIP_HASHMAPTYPE_UNKNOWN || hashmap->hashmaptype == SCIP_HASHMAPTYPE_POINTER);
3110 	
3111 	#ifndef NDEBUG
3112 	   if( hashmap->hashmaptype == SCIP_HASHMAPTYPE_UNKNOWN )
3113 	      hashmap->hashmaptype = SCIP_HASHMAPTYPE_POINTER;
3114 	#endif
3115 	
3116 	   SCIP_CALL( hashmapCheckLoad(hashmap) );
3117 	
3118 	   /* get the hash value */
3119 	   hashval = hashvalue((size_t)origin);
3120 	
3121 	   /* append origin->image pair to hash map */
3122 	   img.ptr = image;
3123 	   SCIP_CALL( hashmapInsert(hashmap, origin, img, hashval, FALSE) );
3124 	
3125 	   return SCIP_OKAY;
3126 	}
3127 	
3128 	/** inserts new origin->image pair in hash map
3129 	 *
3130 	 *  @note multiple insertion of same element is checked and results in an error
3131 	 */
3132 	SCIP_RETCODE SCIPhashmapInsertInt(
3133 	   SCIP_HASHMAP*         hashmap,            /**< hash map */
3134 	   void*                 origin,             /**< origin to set image for */
3135 	   int                   image               /**< new image for origin */
3136 	   )
3137 	{
3138 	   uint32_t hashval;
3139 	   SCIP_HASHMAPIMAGE img;
3140 	
3141 	   assert(hashmap != NULL);
3142 	   assert(hashmap->slots != NULL);
3143 	   assert(hashmap->hashes != NULL);
3144 	   assert(hashmap->mask > 0);
3145 	   assert(hashmap->hashmaptype == SCIP_HASHMAPTYPE_UNKNOWN || hashmap->hashmaptype == SCIP_HASHMAPTYPE_INT);
3146 	
3147 	#ifndef NDEBUG
3148 	   if( hashmap->hashmaptype == SCIP_HASHMAPTYPE_UNKNOWN )
3149 	      hashmap->hashmaptype = SCIP_HASHMAPTYPE_INT;
3150 	#endif
3151 	
3152 	   SCIP_CALL( hashmapCheckLoad(hashmap) );
3153 	
3154 	   /* get the hash value */
3155 	   hashval = hashvalue((size_t)origin);
3156 	
3157 	   /* append origin->image pair to hash map */
3158 	   img.integer = image;
3159 	   SCIP_CALL( hashmapInsert(hashmap, origin, img, hashval, FALSE) );
3160 	
3161 	   return SCIP_OKAY;
3162 	}
3163 	
3164 	/** inserts new origin->image pair in hash map
3165 	 *
3166 	 *  @note multiple insertion of same element is checked and results in an error
3167 	 */
3168 	SCIP_RETCODE SCIPhashmapInsertReal(
3169 	   SCIP_HASHMAP*         hashmap,            /**< hash map */
3170 	   void*                 origin,             /**< origin to set image for */
3171 	   SCIP_Real             image               /**< new image for origin */
3172 	   )
3173 	{
3174 	   uint32_t hashval;
3175 	   SCIP_HASHMAPIMAGE img;
3176 	
3177 	   assert(hashmap != NULL);
3178 	   assert(hashmap->slots != NULL);
3179 	   assert(hashmap->hashes != NULL);
3180 	   assert(hashmap->mask > 0);
3181 	   assert(hashmap->hashmaptype == SCIP_HASHMAPTYPE_UNKNOWN || hashmap->hashmaptype == SCIP_HASHMAPTYPE_REAL);
3182 	
3183 	#ifndef NDEBUG
3184 	   if( hashmap->hashmaptype == SCIP_HASHMAPTYPE_UNKNOWN )
3185 	      hashmap->hashmaptype = SCIP_HASHMAPTYPE_REAL;
3186 	#endif
3187 	
3188 	   SCIP_CALL( hashmapCheckLoad(hashmap) );
3189 	
3190 	   /* get the hash value */
3191 	   hashval = hashvalue((size_t)origin);
3192 	
3193 	   /* append origin->image pair to hash map */
3194 	   img.real = image;
3195 	   SCIP_CALL( hashmapInsert(hashmap, origin, img, hashval, FALSE) );
3196 	
3197 	   return SCIP_OKAY;
3198 	}
3199 	
3200 	/** retrieves image of given origin from the hash map, or NULL if no image exists */
3201 	void* SCIPhashmapGetImage(
3202 	   SCIP_HASHMAP*         hashmap,            /**< hash map */
3203 	   void*                 origin              /**< origin to retrieve image for */
3204 	   )
3205 	{
3206 	   uint32_t pos;
3207 	
3208 	   assert(hashmap != NULL);
3209 	   assert(hashmap->slots != NULL);
3210 	   assert(hashmap->hashes != NULL);
3211 	   assert(hashmap->mask > 0);
3212 	   assert(hashmap->hashmaptype == SCIP_HASHMAPTYPE_UNKNOWN || hashmap->hashmaptype == SCIP_HASHMAPTYPE_POINTER);
3213 	
3214 	   if( hashmapLookup(hashmap, origin, &pos) )
3215 	      return hashmap->slots[pos].image.ptr;
3216 	
3217 	   return NULL;
3218 	}
3219 	
3220 	/** retrieves image of given origin from the hash map, or INT_MAX if no image exists */
3221 	int SCIPhashmapGetImageInt(
3222 	   SCIP_HASHMAP*         hashmap,            /**< hash map */
3223 	   void*                 origin              /**< origin to retrieve image for */
3224 	   )
3225 	{
3226 	   uint32_t pos;
3227 	
3228 	   assert(hashmap != NULL);
3229 	   assert(hashmap->slots != NULL);
3230 	   assert(hashmap->hashes != NULL);
3231 	   assert(hashmap->mask > 0);
3232 	   assert(hashmap->hashmaptype == SCIP_HASHMAPTYPE_UNKNOWN || hashmap->hashmaptype == SCIP_HASHMAPTYPE_INT);
3233 	
3234 	   if( hashmapLookup(hashmap, origin, &pos) )
3235 	      return hashmap->slots[pos].image.integer;
3236 	
3237 	   return INT_MAX;
3238 	}
3239 	
3240 	/** retrieves image of given origin from the hash map, or SCIP_INVALID if no image exists */
3241 	SCIP_Real SCIPhashmapGetImageReal(
3242 	   SCIP_HASHMAP*         hashmap,            /**< hash map */
3243 	   void*                 origin              /**< origin to retrieve image for */
3244 	   )
3245 	{
3246 	   uint32_t pos;
3247 	
3248 	   assert(hashmap != NULL);
3249 	   assert(hashmap->slots != NULL);
3250 	   assert(hashmap->hashes != NULL);
3251 	   assert(hashmap->mask > 0);
3252 	   assert(hashmap->hashmaptype == SCIP_HASHMAPTYPE_UNKNOWN || hashmap->hashmaptype == SCIP_HASHMAPTYPE_REAL);
3253 	
3254 	   if( hashmapLookup(hashmap, origin, &pos) )
3255 	      return hashmap->slots[pos].image.real;
3256 	
3257 	   return SCIP_INVALID;
3258 	}
3259 	
3260 	/** sets image for given origin in the hash map, either by modifying existing origin->image pair
3261 	 *  or by appending a new origin->image pair
3262 	 */
3263 	SCIP_RETCODE SCIPhashmapSetImage(
3264 	   SCIP_HASHMAP*         hashmap,            /**< hash map */
3265 	   void*                 origin,             /**< origin to set image for */
3266 	   void*                 image               /**< new image for origin */
3267 	   )
3268 	{
3269 	   uint32_t hashval;
3270 	   SCIP_HASHMAPIMAGE img;
3271 	
3272 	   assert(hashmap != NULL);
3273 	   assert(hashmap->slots != NULL);
3274 	   assert(hashmap->mask > 0);
3275 	   assert(hashmap->hashmaptype == SCIP_HASHMAPTYPE_UNKNOWN || hashmap->hashmaptype == SCIP_HASHMAPTYPE_POINTER);
3276 	
3277 	#ifndef NDEBUG
3278 	   if( hashmap->hashmaptype == SCIP_HASHMAPTYPE_UNKNOWN )
3279 	      hashmap->hashmaptype = SCIP_HASHMAPTYPE_POINTER;
3280 	#endif
3281 	
3282 	   SCIP_CALL( hashmapCheckLoad(hashmap) );
3283 	
3284 	   /* get the hash value */
3285 	   hashval = hashvalue((size_t)origin);
3286 	
3287 	   /* append origin->image pair to hash map */
3288 	   img.ptr = image;
3289 	   SCIP_CALL( hashmapInsert(hashmap, origin, img, hashval, TRUE) );
3290 	
3291 	   return SCIP_OKAY;
3292 	}
3293 	
3294 	/** sets image for given origin in the hash map, either by modifying existing origin->image pair
3295 	 *  or by appending a new origin->image pair
3296 	 */
3297 	SCIP_RETCODE SCIPhashmapSetImageInt(
3298 	   SCIP_HASHMAP*         hashmap,            /**< hash map */
3299 	   void*                 origin,             /**< origin to set image for */
3300 	   int                   image               /**< new image for origin */
3301 	   )
3302 	{
3303 	   uint32_t hashval;
3304 	   SCIP_HASHMAPIMAGE img;
3305 	
3306 	   assert(hashmap != NULL);
3307 	   assert(hashmap->slots != NULL);
3308 	   assert(hashmap->mask > 0);
3309 	   assert(hashmap->hashmaptype == SCIP_HASHMAPTYPE_UNKNOWN || hashmap->hashmaptype == SCIP_HASHMAPTYPE_INT);
3310 	
3311 	#ifndef NDEBUG
3312 	   if( hashmap->hashmaptype == SCIP_HASHMAPTYPE_UNKNOWN )
3313 	      hashmap->hashmaptype = SCIP_HASHMAPTYPE_INT;
3314 	#endif
3315 	
3316 	   SCIP_CALL( hashmapCheckLoad(hashmap) );
3317 	
3318 	   /* get the hash value */
3319 	   hashval = hashvalue((size_t)origin);
3320 	
3321 	   /* append origin->image pair to hash map */
3322 	   img.integer = image;
3323 	   SCIP_CALL( hashmapInsert(hashmap, origin, img, hashval, TRUE) );
3324 	
3325 	   return SCIP_OKAY;
3326 	}
3327 	
3328 	/** sets image for given origin in the hash map, either by modifying existing origin->image pair
3329 	 *  or by appending a new origin->image pair
3330 	 */
3331 	SCIP_RETCODE SCIPhashmapSetImageReal(
3332 	   SCIP_HASHMAP*         hashmap,            /**< hash map */
3333 	   void*                 origin,             /**< origin to set image for */
3334 	   SCIP_Real             image               /**< new image for origin */
3335 	   )
3336 	{
3337 	   uint32_t hashval;
3338 	   SCIP_HASHMAPIMAGE img;
3339 	
3340 	   assert(hashmap != NULL);
3341 	   assert(hashmap->slots != NULL);
3342 	   assert(hashmap->mask > 0);
3343 	   assert(hashmap->hashmaptype == SCIP_HASHMAPTYPE_UNKNOWN || hashmap->hashmaptype == SCIP_HASHMAPTYPE_REAL);
3344 	
3345 	#ifndef NDEBUG
3346 	   if( hashmap->hashmaptype == SCIP_HASHMAPTYPE_UNKNOWN )
3347 	      hashmap->hashmaptype = SCIP_HASHMAPTYPE_REAL;
3348 	#endif
3349 	
3350 	   SCIP_CALL( hashmapCheckLoad(hashmap) );
3351 	
3352 	   /* get the hash value */
3353 	   hashval = hashvalue((size_t)origin);
3354 	
3355 	   /* append origin->image pair to hash map */
3356 	   img.real = image;
3357 	   SCIP_CALL( hashmapInsert(hashmap, origin, img, hashval, TRUE) );
3358 	
3359 	   return SCIP_OKAY;
3360 	}
3361 	
3362 	/** checks whether an image to the given origin exists in the hash map */
3363 	SCIP_Bool SCIPhashmapExists(
3364 	   SCIP_HASHMAP*         hashmap,            /**< hash map */
3365 	   void*                 origin              /**< origin to search for */
3366 	   )
3367 	{
3368 	   uint32_t pos;
3369 	
3370 	   assert(hashmap != NULL);
3371 	   assert(hashmap->slots != NULL);
3372 	   assert(hashmap->hashes != NULL);
3373 	   assert(hashmap->mask > 0);
3374 	
3375 	   return hashmapLookup(hashmap, origin, &pos);
3376 	}
3377 	
3378 	/** removes origin->image pair from the hash map, if it exists */
3379 	SCIP_RETCODE SCIPhashmapRemove(
3380 	   SCIP_HASHMAP*         hashmap,            /**< hash map */
3381 	   void*                 origin              /**< origin to remove from the list */
3382 	   )
3383 	{
3384 	   uint32_t pos;
3385 	
3386 	   assert(hashmap != NULL);
3387 	   assert(hashmap->slots != NULL);
3388 	   assert(hashmap->mask > 0);
3389 	
3390 	   assert(origin != NULL);
3391 	
3392 	   if( hashmapLookup(hashmap, origin, &pos) )
3393 	   {
3394 	      /* remove element */
3395 	      hashmap->hashes[pos] = 0;
3396 	      --hashmap->nelements;
3397 	
3398 	      /* move other elements if necessary */
3399 	      while( TRUE ) /*lint !e716*/
3400 	      {
3401 	         uint32_t nextpos = (pos + 1) & hashmap->mask;
3402 	
3403 	         /* nothing to do since there is no chain that needs to be moved */
3404 	         if( hashmap->hashes[nextpos] == 0 )
3405 	            return SCIP_OKAY;
3406 	
3407 	         /* check if the element is the start of a new chain and return if that is the case */
3408 	         if( (hashmap->hashes[nextpos]>>(hashmap->shift)) == nextpos )
3409 	            return SCIP_OKAY;
3410 	
3411 	         /* element should be moved to the left and next element needs to be checked */
3412 	         hashmap->slots[pos].origin = hashmap->slots[nextpos].origin;
3413 	         hashmap->slots[pos].image = hashmap->slots[nextpos].image;
3414 	         hashmap->hashes[pos] = hashmap->hashes[nextpos];
3415 	         hashmap->hashes[nextpos] = 0;
3416 	
3417 	         pos = nextpos;
3418 	      }
3419 	   }
3420 	
3421 	   return SCIP_OKAY;
3422 	}
3423 	
3424 	/** prints statistics about hash map usage */
3425 	void SCIPhashmapPrintStatistics(
3426 	   SCIP_HASHMAP*         hashmap,            /**< hash map */
3427 	   SCIP_MESSAGEHDLR*     messagehdlr         /**< message handler */
3428 	   )
3429 	{
3430 	   uint32_t maxprobelen = 0;
3431 	   uint64_t probelensum = 0;
3432 	   uint32_t nslots;
3433 	   uint32_t i;
3434 	
3435 	   assert(hashmap != NULL);
3436 	
3437 	   nslots = hashmap->mask + 1;
3438 	
3439 	   /* compute the maximum and average probe length */
3440 	   for( i = 0; i < nslots; ++i )
3441 	   {
3442 	      if( hashmap->hashes[i] != 0 )
3443 	      {
3444 	         uint32_t probelen = ELEM_DISTANCE(i) + 1;
3445 	         probelensum += probelen;
3446 	         maxprobelen = MAX(probelen, maxprobelen);
3447 	      }
3448 	   }
3449 	
3450 	   /* print general hash map statistics */
3451 	   SCIPmessagePrintInfo(messagehdlr, "%u hash entries, used %u/%u slots (%.1f%%)",
3452 	                        (unsigned int)hashmap->nelements, (unsigned int)hashmap->nelements,
3453 	                        (unsigned int)nslots, 100.0*(SCIP_Real)hashmap->nelements/(SCIP_Real)(nslots));
3454 	
3455 	   /* if not empty print average and maximum probe length */
3456 	   if( hashmap->nelements > 0 )
3457 	      SCIPmessagePrintInfo(messagehdlr, ", avg. probe length is %.1f, max. probe length is %u",
3458 	         (SCIP_Real)(probelensum)/(SCIP_Real)hashmap->nelements, (unsigned int)maxprobelen);
3459 	   SCIPmessagePrintInfo(messagehdlr, "\n");
3460 	}
3461 	
3462 	/** indicates whether a hash map has no entries */
3463 	SCIP_Bool SCIPhashmapIsEmpty(
3464 	   SCIP_HASHMAP*         hashmap             /**< hash map */
3465 	   )
3466 	{
3467 	   assert(hashmap != NULL);
3468 	
3469 	   return hashmap->nelements == 0;
3470 	}
3471 	
3472 	/** gives the number of elements in a hash map */
3473 	int SCIPhashmapGetNElements(
3474 	   SCIP_HASHMAP*         hashmap             /**< hash map */
3475 	   )
3476 	{
3477 	   return (int) hashmap->nelements;
3478 	}
3479 	
3480 	/** gives the number of entries in the internal arrays of a hash map */
3481 	int SCIPhashmapGetNEntries(
3482 	   SCIP_HASHMAP*         hashmap             /**< hash map */
3483 	   )
3484 	{
3485 	   return (int) hashmap->mask + 1;
3486 	}
3487 	
3488 	/** gives the hashmap entry at the given index or NULL if entry is empty */
3489 	SCIP_HASHMAPENTRY* SCIPhashmapGetEntry(
3490 	   SCIP_HASHMAP*         hashmap,            /**< hash map */
3491 	   int                   entryidx            /**< index of hash map entry */
3492 	   )
3493 	{
3494 	   assert(hashmap != NULL);
3495 	
3496 	   return hashmap->hashes[entryidx] == 0 ? NULL : &hashmap->slots[entryidx];
3497 	}
3498 	
3499 	/** gives the origin of the hashmap entry */
3500 	void* SCIPhashmapEntryGetOrigin(
3501 	   SCIP_HASHMAPENTRY*    entry               /**< hash map entry */
3502 	   )
3503 	{
3504 	   assert(entry != NULL);
3505 	
3506 	   return entry->origin;
3507 	}
3508 	
3509 	/** gives the image of the hashmap entry */
3510 	void* SCIPhashmapEntryGetImage(
3511 	   SCIP_HASHMAPENTRY*    entry               /**< hash map entry */
3512 	   )
3513 	{
3514 	   assert(entry != NULL);
3515 	
3516 	   return entry->image.ptr;
3517 	}
3518 	
3519 	/** gives the image of the hashmap entry */
3520 	int SCIPhashmapEntryGetImageInt(
3521 	   SCIP_HASHMAPENTRY*    entry               /**< hash map entry */
3522 	   )
3523 	{
3524 	   assert(entry != NULL);
3525 	
3526 	   return entry->image.integer;
3527 	}
3528 	
3529 	/** gives the image of the hashmap entry */
3530 	SCIP_Real SCIPhashmapEntryGetImageReal(
3531 	   SCIP_HASHMAPENTRY*    entry               /**< hash map entry */
3532 	   )
3533 	{
3534 	   assert(entry != NULL);
3535 	
3536 	   return entry->image.real;
3537 	}
3538 	
3539 	/** sets pointer image of a hashmap entry */
3540 	void SCIPhashmapEntrySetImage(
3541 	   SCIP_HASHMAPENTRY*    entry,              /**< hash map entry */
3542 	   void*                 image               /**< new image */
3543 	   )
3544 	{
3545 	   assert(entry != NULL);
3546 	
3547 	   entry->image.ptr = image;
3548 	}
3549 	
3550 	/** sets integer image of a hashmap entry */
3551 	void SCIPhashmapEntrySetImageInt(
3552 	   SCIP_HASHMAPENTRY*    entry,              /**< hash map entry */
3553 	   int                   image               /**< new image */
3554 	   )
3555 	{
3556 	   assert(entry != NULL);
3557 	
3558 	   entry->image.integer = image;
3559 	}
3560 	
3561 	/** sets real image of a hashmap entry */
3562 	void SCIPhashmapEntrySetImageReal(
3563 	   SCIP_HASHMAPENTRY*    entry,              /**< hash map entry */
3564 	   SCIP_Real             image               /**< new image */
3565 	   )
3566 	{
3567 	   assert(entry != NULL);
3568 	
3569 	   entry->image.real = image;
3570 	}
3571 	
3572 	/** removes all entries in a hash map. */
3573 	SCIP_RETCODE SCIPhashmapRemoveAll(
3574 	   SCIP_HASHMAP*         hashmap             /**< hash map */
3575 	   )
3576 	{
3577 	   assert(hashmap != NULL);
3578 	
3579 	   BMSclearMemoryArray(hashmap->hashes, hashmap->mask + 1);
3580 	
3581 	   hashmap->nelements = 0;
3582 	
3583 	   return SCIP_OKAY;
3584 	}
3585 	
3586 	
3587 	/*
3588 	 * Hash Set
3589 	 */
3590 	
3591 	/* redefine ELEM_DISTANCE macro for hashset */
3592 	#undef ELEM_DISTANCE
3593 	/* computes the distance from it's desired position for the element stored at pos */
3594 	#define ELEM_DISTANCE(pos) (((pos) + nslots - hashSetDesiredPos(hashset, hashset->slots[(pos)])) & mask)
3595 	
3596 	/* calculate desired position of element in hash set */
3597 	static
3598 	uint32_t hashSetDesiredPos(
3599 	   SCIP_HASHSET*         hashset,            /**< the hash set */
3600 	   void*                 element             /**< element to calculate position for */
3601 	   )
3602 	{
3603 	   return (uint32_t)((UINT64_C(0x9e3779b97f4a7c15) * (uintptr_t)element)>>(hashset->shift));
3604 	}
3605 	
3606 	static
3607 	void hashsetInsert(
3608 	   SCIP_HASHSET*         hashset,            /**< hash set */
3609 	   void*                 element             /**< element to insert */
3610 	   )
3611 	{
3612 	   uint32_t elemdistance;
3613 	   uint32_t pos;
3614 	   uint32_t nslots;
3615 	   uint32_t mask;
3616 	
3617 	   assert(hashset != NULL);
3618 	   assert(hashset->slots != NULL);
3619 	   assert(element != NULL);
3620 	
3621 	   pos = hashSetDesiredPos(hashset, element);
3622 	   nslots = (uint32_t)SCIPhashsetGetNSlots(hashset);
3623 	   mask = nslots - 1;
3624 	
3625 	   elemdistance = 0;
3626 	   while( TRUE ) /*lint !e716*/
3627 	   {
3628 	      uint32_t distance;
3629 	
3630 	      /* if position is empty or key equal insert element */
3631 	      if( hashset->slots[pos] == NULL )
3632 	      {
3633 	         hashset->slots[pos] = element;
3634 	         ++hashset->nelements;
3635 	         return;
3636 	      }
3637 	
3638 	      if( hashset->slots[pos] == element )
3639 	         return;
3640 	
3641 	      /* otherwise check if the current element at this position is closer to its hashvalue */
3642 	      distance = ELEM_DISTANCE(pos);
3643 	      if( distance < elemdistance )
3644 	      {
3645 	         /* if this is the case we insert the new element here and find a new position for the old one */
3646 	         elemdistance = distance;
3647 	         SCIPswapPointers(&hashset->slots[pos], &element);
3648 	      }
3649 	
3650 	      /* continue until we have found an empty position */
3651 	      pos = (pos + 1) & mask;
3652 	      ++elemdistance;
3653 	   }
3654 	}
3655 	
3656 	/** check if the load factor of the hash set is too high and rebuild if necessary */
3657 	static
3658 	SCIP_RETCODE hashsetCheckLoad(
3659 	   SCIP_HASHSET*         hashset,            /**< hash set */
3660 	   BMS_BLKMEM*           blkmem              /**< block memory used to store hash set entries */
3661 	   )
3662 	{
3663 	   assert(hashset != NULL);
3664 	   assert(hashset->shift < 64);
3665 	
3666 	   /* use integer arithmetic to approximately check if load factor is above 90% */
3667 	   if( ((((uint64_t)hashset->nelements)<<10)>>(64-hashset->shift) > 921) )
3668 	   {
3669 	      void** slots;
3670 	      uint32_t nslots;
3671 	      uint32_t newnslots;
3672 	      uint32_t i;
3673 	
3674 	      /* calculate new size (always power of two) */
3675 	      nslots = (uint32_t)SCIPhashsetGetNSlots(hashset);
3676 	      newnslots = 2*nslots;
3677 	      --hashset->shift;
3678 	
3679 	      /* reallocate array */
3680 	      SCIP_ALLOC( BMSallocClearBlockMemoryArray(blkmem, &slots, newnslots) );
3681 	
3682 	      SCIPswapPointers((void**) &slots, (void**) &hashset->slots);
3683 	      hashset->nelements = 0;
3684 	
3685 	      /* reinsert all elements */
3686 	      for( i = 0; i < nslots; ++i )
3687 	      {
3688 	         if( slots[i] != NULL )
3689 	            hashsetInsert(hashset, slots[i]);
3690 	      }
3691 	
3692 	      BMSfreeBlockMemoryArray(blkmem, &slots, nslots);
3693 	   }
3694 	
3695 	   return SCIP_OKAY;
3696 	}
3697 	
3698 	/** creates a hash set of pointers */
3699 	SCIP_RETCODE SCIPhashsetCreate(
3700 	   SCIP_HASHSET**        hashset,            /**< pointer to store the created hash set */
3701 	   BMS_BLKMEM*           blkmem,             /**< block memory used to store hash set entries */
3702 	   int                   size                /**< initial size of the hash set; it is guaranteed that the set is not
3703 	                                              *   resized if at most that many elements are inserted */
3704 	   )
3705 	{
3706 	   uint32_t nslots;
3707 	
3708 	   assert(hashset != NULL);
3709 	   assert(size >= 0);
3710 	   assert(blkmem != NULL);
3711 	
3712 	   SCIP_ALLOC( BMSallocBlockMemory(blkmem, hashset) );
3713 	
3714 	   /* do not create too small hashtables, i.e. at least size 32, and increase
3715 	    * the given size by dividing it by 0.9, since then no rebuilding will
3716 	    * be necessary if the given number of elements are inserted. Finally round
3717 	    * to the next power of two.
3718 	    */
3719 	   (*hashset)->shift = 64;
3720 	   (*hashset)->shift -= (unsigned int)ceil(log(MAX(8.0, size / 0.9)) / log(2.0));
3721 	   nslots = (uint32_t)SCIPhashsetGetNSlots(*hashset);
3722 	   (*hashset)->nelements = 0;
3723 	
3724 	   SCIP_ALLOC( BMSallocClearBlockMemoryArray(blkmem, &(*hashset)->slots, nslots) );
3725 	
3726 	   return SCIP_OKAY;
3727 	}
3728 	
3729 	/** frees the hash set */
3730 	void SCIPhashsetFree(
3731 	   SCIP_HASHSET**        hashset,            /**< pointer to the hash set */
3732 	   BMS_BLKMEM*           blkmem              /**< block memory used to store hash set entries */
3733 	   )
3734 	{
3735 	   BMSfreeBlockMemoryArray(blkmem, &(*hashset)->slots, SCIPhashsetGetNSlots(*hashset));
3736 	   BMSfreeBlockMemory(blkmem, hashset);
3737 	}
3738 	
3739 	/** inserts new element into the hash set */
3740 	SCIP_RETCODE SCIPhashsetInsert(
3741 	   SCIP_HASHSET*         hashset,            /**< hash set */
3742 	   BMS_BLKMEM*           blkmem,             /**< block memory used to store hash set entries */
3743 	   void*                 element             /**< element to insert */
3744 	   )
3745 	{
3746 	   assert(hashset != NULL);
3747 	   assert(hashset->slots != NULL);
3748 	
3749 	   SCIP_CALL( hashsetCheckLoad(hashset, blkmem) );
3750 	
3751 	   hashsetInsert(hashset, element);
3752 	
3753 	   return SCIP_OKAY;
3754 	}
3755 	
3756 	/** checks whether an element exists in the hash set */
3757 	SCIP_Bool SCIPhashsetExists(
3758 	   SCIP_HASHSET*         hashset,            /**< hash set */
3759 	   void*                 element             /**< element to search for */
3760 	   )
3761 	{
3762 	   uint32_t pos;
3763 	   uint32_t nslots;
3764 	   uint32_t mask;
3765 	   uint32_t elemdistance;
3766 	
3767 	   assert(hashset != NULL);
3768 	   assert(hashset->slots != NULL);
3769 	
3770 	   pos = hashSetDesiredPos(hashset, element);
3771 	   nslots = (uint32_t)SCIPhashsetGetNSlots(hashset);
3772 	   mask = nslots - 1;
3773 	   elemdistance = 0;
3774 	
3775 	   while( TRUE ) /*lint !e716*/
3776 	   {
3777 	      uint32_t distance;
3778 	
3779 	      /* found element */
3780 	      if( hashset->slots[pos] == element )
3781 	         return TRUE;
3782 	
3783 	      /* slots is empty so element cannot be contained */
3784 	      if( hashset->slots[pos] == NULL )
3785 	         return FALSE;
3786 	
3787 	      distance = ELEM_DISTANCE(pos);
3788 	      /* element can not be contained since otherwise we would have swapped it with this one during insert */
3789 	      if( elemdistance > distance )
3790 	         return FALSE;
3791 	
3792 	      pos = (pos + 1) & mask;
3793 	      ++elemdistance;
3794 	   }
3795 	}
3796 	
3797 	/** removes an element from the hash set, if it exists */
3798 	SCIP_RETCODE SCIPhashsetRemove(
3799 	   SCIP_HASHSET*         hashset,            /**< hash set */
3800 	   void*                 element             /**< origin to remove from the list */
3801 	   )
3802 	{
3803 	   uint32_t pos;
3804 	   uint32_t nslots;
3805 	   uint32_t mask;
3806 	   uint32_t elemdistance;
3807 	
3808 	   assert(hashset != NULL);
3809 	   assert(hashset->slots != NULL);
3810 	   assert(element != NULL);
3811 	
3812 	   pos = hashSetDesiredPos(hashset, element);
3813 	   nslots = (uint32_t)SCIPhashsetGetNSlots(hashset);
3814 	   mask = nslots - 1;
3815 	   elemdistance = 0;
3816 	
3817 	   while( TRUE ) /*lint !e716*/
3818 	   {
3819 	      uint32_t distance;
3820 	
3821 	      /* found element */
3822 	      if( hashset->slots[pos] == element )
3823 	         break;
3824 	
3825 	      /* slots is empty so element cannot be contained */
3826 	      if( hashset->slots[pos] == NULL )
3827 	         return SCIP_OKAY;
3828 	
3829 	      distance = ELEM_DISTANCE(pos);
3830 	      /* element can not be contained since otherwise we would have swapped it with this one during insert */
3831 	      if( elemdistance > distance )
3832 	         return SCIP_OKAY;
3833 	
3834 	      pos = (pos + 1) & mask;
3835 	      ++elemdistance;
3836 	   }
3837 	
3838 	   assert(hashset->slots[pos] == element);
3839 	   assert(SCIPhashsetExists(hashset, element));
3840 	
3841 	   /* remove element */
3842 	   --hashset->nelements;
3843 	
3844 	   /* move other elements if necessary */
3845 	   while( TRUE ) /*lint !e716*/
3846 	   {
3847 	      uint32_t nextpos = (pos + 1) & mask;
3848 	
3849 	      /* nothing to do since there is no chain that needs to be moved */
3850 	      if( hashset->slots[nextpos] == NULL )
3851 	      {
3852 	         hashset->slots[pos] = NULL;
3853 	         assert(!SCIPhashsetExists(hashset, element));
3854 	         return SCIP_OKAY;
3855 	      }
3856 	
3857 	      /* check if the element is the start of a new chain and return if that is the case */
3858 	      if( hashSetDesiredPos(hashset, hashset->slots[nextpos]) == nextpos )
3859 	      {
3860 	         hashset->slots[pos] = NULL;
3861 	         assert(!SCIPhashsetExists(hashset, element));
3862 	         return SCIP_OKAY;
3863 	      }
3864 	
3865 	      /* element should be moved to the left and next element needs to be checked */
3866 	      hashset->slots[pos] = hashset->slots[nextpos];
3867 	
3868 	      pos = nextpos;
3869 	   }
3870 	}
3871 	
3872 	/** prints statistics about hash set usage */
3873 	void SCIPhashsetPrintStatistics(
3874 	   SCIP_HASHSET*         hashset,            /**< hash set */
3875 	   SCIP_MESSAGEHDLR*     messagehdlr         /**< message handler */
3876 	   )
3877 	{
3878 	   uint32_t maxprobelen = 0;
3879 	   uint64_t probelensum = 0;
3880 	   uint32_t nslots;
3881 	   uint32_t mask;
3882 	   uint32_t i;
3883 	
3884 	   assert(hashset != NULL);
3885 	
3886 	   nslots = (uint32_t)SCIPhashsetGetNSlots(hashset);
3887 	   mask = nslots - 1;
3888 	
3889 	   /* compute the maximum and average probe length */
3890 	   for( i = 0; i < nslots; ++i )
3891 	   {
3892 	      if( hashset->slots[i] != NULL )
3893 	      {
3894 	         uint32_t probelen = ((hashSetDesiredPos(hashset, hashset->slots[i]) + nslots - i) & mask) + 1;
3895 	         probelensum += probelen;
3896 	         maxprobelen = MAX(probelen, maxprobelen);
3897 	      }
3898 	   }
3899 	
3900 	   /* print general hash set statistics */
3901 	   SCIPmessagePrintInfo(messagehdlr, "%u hash entries, used %u/%u slots (%.1f%%)",
3902 	                        (unsigned int)hashset->nelements, (unsigned int)hashset->nelements,
3903 	                        (unsigned int)nslots, 100.0*(SCIP_Real)hashset->nelements/(SCIP_Real)(nslots));
3904 	
3905 	   /* if not empty print average and maximum probe length */
3906 	   if( hashset->nelements > 0 )
3907 	      SCIPmessagePrintInfo(messagehdlr, ", avg. probe length is %.1f, max. probe length is %u",
3908 	         (SCIP_Real)(probelensum)/(SCIP_Real)hashset->nelements, (unsigned int)maxprobelen);
3909 	   SCIPmessagePrintInfo(messagehdlr, "\n");
3910 	}
3911 	
3912 	/* In debug mode, the following methods are implemented as function calls to ensure
3913 	 * type validity.
3914 	 * In optimized mode, the methods are implemented as defines to improve performance.
3915 	 * However, we want to have them in the library anyways, so we have to undef the defines.
3916 	 */
3917 	
3918 	#undef SCIPhashsetIsEmpty
3919 	#undef SCIPhashsetGetNElements
3920 	#undef SCIPhashsetGetNSlots
3921 	#undef SCIPhashsetGetSlots
3922 	
3923 	/** indicates whether a hash set has no entries */
3924 	SCIP_Bool SCIPhashsetIsEmpty(
3925 	   SCIP_HASHSET*         hashset             /**< hash set */
3926 	   )
3927 	{
3928 	   return hashset->nelements == 0;
3929 	}
3930 	
3931 	/** gives the number of elements in a hash set */
3932 	int SCIPhashsetGetNElements(
3933 	   SCIP_HASHSET*         hashset             /**< hash set */
3934 	   )
3935 	{
3936 	   return (int)hashset->nelements;
3937 	}
3938 	
3939 	/** gives the number of slots of a hash set */
3940 	int SCIPhashsetGetNSlots(
3941 	   SCIP_HASHSET*         hashset             /**< hash set */
3942 	   )
3943 	{
3944 	   return (int) (1u << (64 - hashset->shift));
3945 	}
3946 	
3947 	/** gives the array of hash set slots; contains all elements in indetermined order and may contain NULL values */
3948 	void** SCIPhashsetGetSlots(
3949 	   SCIP_HASHSET*         hashset             /**< hash set */
3950 	   )
3951 	{
3952 	   return hashset->slots;
3953 	}
3954 	
3955 	/** removes all entries in a hash set. */
3956 	void SCIPhashsetRemoveAll(
3957 	   SCIP_HASHSET*         hashset             /**< hash set */
3958 	   )
3959 	{
3960 	   BMSclearMemoryArray(hashset->slots, SCIPhashsetGetNSlots(hashset));
3961 	
3962 	   hashset->nelements = 0;
3963 	}
3964 	
3965 	/*
3966 	 * Dynamic Arrays
3967 	 */
3968 	
3969 	/** creates a dynamic array of real values */
3970 	SCIP_RETCODE SCIPrealarrayCreate(
3971 	   SCIP_REALARRAY**      realarray,          /**< pointer to store the real array */
3972 	   BMS_BLKMEM*           blkmem              /**< block memory */
3973 	   )
3974 	{
3975 	   assert(realarray != NULL);
3976 	   assert(blkmem != NULL);
3977 	
3978 	   SCIP_ALLOC( BMSallocBlockMemory(blkmem, realarray) );
3979 	   (*realarray)->blkmem = blkmem;
3980 	   (*realarray)->vals = NULL;
3981 	   (*realarray)->valssize = 0;
3982 	   (*realarray)->firstidx = -1;
3983 	   (*realarray)->minusedidx = INT_MAX;
3984 	   (*realarray)->maxusedidx = INT_MIN;
3985 	
3986 	   return SCIP_OKAY;
3987 	}
3988 	
3989 	/** creates a copy of a dynamic array of real values */
3990 	SCIP_RETCODE SCIPrealarrayCopy(
3991 	   SCIP_REALARRAY**      realarray,          /**< pointer to store the copied real array */
3992 	   BMS_BLKMEM*           blkmem,             /**< block memory */
3993 	   SCIP_REALARRAY*       sourcerealarray     /**< dynamic real array to copy */
3994 	   )
3995 	{
3996 	   assert(realarray != NULL);
3997 	   assert(sourcerealarray != NULL);
3998 	
3999 	   SCIP_CALL( SCIPrealarrayCreate(realarray, blkmem) );
4000 	   if( sourcerealarray->valssize > 0 )
4001 	   {
4002 	      SCIP_ALLOC( BMSduplicateBlockMemoryArray(blkmem, &(*realarray)->vals, sourcerealarray->vals, \
4003 	                     sourcerealarray->valssize) );
4004 	   }
4005 	   (*realarray)->valssize = sourcerealarray->valssize;
4006 	   (*realarray)->firstidx = sourcerealarray->firstidx;
4007 	   (*realarray)->minusedidx = sourcerealarray->minusedidx;
4008 	   (*realarray)->maxusedidx = sourcerealarray->maxusedidx;
4009 	
4010 	   return SCIP_OKAY;
4011 	}
4012 	
4013 	/** frees a dynamic array of real values */
4014 	SCIP_RETCODE SCIPrealarrayFree(
4015 	   SCIP_REALARRAY**      realarray           /**< pointer to the real array */
4016 	   )
4017 	{
4018 	   assert(realarray != NULL);
4019 	   assert(*realarray != NULL);
4020 	
4021 	   BMSfreeBlockMemoryArrayNull((*realarray)->blkmem, &(*realarray)->vals, (*realarray)->valssize);
4022 	   BMSfreeBlockMemory((*realarray)->blkmem, realarray);
4023 	
4024 	   return SCIP_OKAY;
4025 	}
4026 	
4027 	/** extends dynamic array to be able to store indices from minidx to maxidx */
4028 	SCIP_RETCODE SCIPrealarrayExtend(
4029 	   SCIP_REALARRAY*       realarray,          /**< dynamic real array */
4030 	   int                   arraygrowinit,      /**< initial size of array */
4031 	   SCIP_Real             arraygrowfac,       /**< growing factor of array */
4032 	   int                   minidx,             /**< smallest index to allocate storage for */
4033 	   int                   maxidx              /**< largest index to allocate storage for */
4034 	   )
4035 	{
4036 	   int nused;
4037 	   int nfree;
4038 	   int newfirstidx;
4039 	   int i;
4040 	
4041 	   assert(realarray != NULL);
4042 	   assert(realarray->minusedidx == INT_MAX || realarray->firstidx >= 0);
4043 	   assert(realarray->maxusedidx == INT_MIN || realarray->firstidx >= 0);
4044 	   assert(realarray->minusedidx == INT_MAX || realarray->minusedidx >= realarray->firstidx);
4045 	   assert(realarray->maxusedidx == INT_MIN || realarray->maxusedidx < realarray->firstidx + realarray->valssize);
4046 	   assert(0 <= minidx);
4047 	   assert(minidx <= maxidx);
4048 	
4049 	   minidx = MIN(minidx, realarray->minusedidx);
4050 	   maxidx = MAX(maxidx, realarray->maxusedidx);
4051 	   assert(0 <= minidx);
4052 	   assert(minidx <= maxidx);
4053 	
4054 	   SCIPdebugMessage("extending realarray %p (firstidx=%d, size=%d, range=[%d,%d]) to range [%d,%d]\n",
4055 	      (void*)realarray, realarray->firstidx, realarray->valssize, realarray->minusedidx, realarray->maxusedidx, minidx, maxidx);
4056 	
4057 	   /* check, whether we have to allocate additional memory, or shift the array */
4058 	   nused = maxidx - minidx + 1;
4059 	   if( nused > realarray->valssize )
4060 	   {
4061 	      SCIP_Real* newvals;
4062 	      int newvalssize;
4063 	
4064 	      /* allocate new memory storage */
4065 	      newvalssize = calcGrowSize(arraygrowinit, arraygrowfac, nused);
4066 	      SCIP_ALLOC( BMSallocBlockMemoryArray(realarray->blkmem, &newvals, newvalssize) );
4067 	      nfree = newvalssize - nused;
4068 	      newfirstidx = minidx - nfree/2;
4069 	      newfirstidx = MAX(newfirstidx, 0);
4070 	      assert(newfirstidx <= minidx);
4071 	      assert(maxidx < newfirstidx + newvalssize);
4072 	
4073 	      /* initialize memory array by copying old values and setting new values to zero */
4074 	      if( realarray->firstidx != -1 )
4075 	      {
4076 	         for( i = 0; i < realarray->minusedidx - newfirstidx; ++i )
4077 	            newvals[i] = 0.0;
4078 	
4079 	         /* check for possible overflow or negative value */
4080 	         assert(realarray->maxusedidx - realarray->minusedidx + 1 > 0);
4081 	
4082 	         BMScopyMemoryArray(&newvals[realarray->minusedidx - newfirstidx],
4083 	            &(realarray->vals[realarray->minusedidx - realarray->firstidx]),
4084 	            realarray->maxusedidx - realarray->minusedidx + 1); /*lint !e866 !e776*/
4085 	         for( i = realarray->maxusedidx - newfirstidx + 1; i < newvalssize; ++i )
4086 	            newvals[i] = 0.0;
4087 	      }
4088 	      else
4089 	      {
4090 	         for( i = 0; i < newvalssize; ++i )
4091 	            newvals[i] = 0.0;
4092 	      }
4093 	
4094 	      /* free old memory storage, and set the new array parameters */
4095 	      BMSfreeBlockMemoryArrayNull(realarray->blkmem, &realarray->vals, realarray->valssize);
4096 	      realarray->vals = newvals;
4097 	      realarray->valssize = newvalssize;
4098 	      realarray->firstidx = newfirstidx;
4099 	   }
4100 	   else if( realarray->firstidx == -1 )
4101 	   {
4102 	      /* a sufficiently large memory storage exists, but it was cleared */
4103 	      nfree = realarray->valssize - nused;
4104 	      assert(nfree >= 0);
4105 	      realarray->firstidx = minidx - nfree/2;
4106 	      assert(realarray->firstidx <= minidx);
4107 	      assert(maxidx < realarray->firstidx + realarray->valssize);
4108 	#ifndef NDEBUG
4109 	      for( i = 0; i < realarray->valssize; ++i )
4110 	         assert(realarray->vals[i] == 0.0);
4111 	#endif
4112 	   }
4113 	   else if( minidx < realarray->firstidx )
4114 	   {
4115 	      /* a sufficiently large memory storage exists, but it has to be shifted to the right */
4116 	      nfree = realarray->valssize - nused;
4117 	      assert(nfree >= 0);
4118 	      newfirstidx = minidx - nfree/2;
4119 	      newfirstidx = MAX(newfirstidx, 0);
4120 	      assert(newfirstidx <= minidx);
4121 	      assert(maxidx < newfirstidx + realarray->valssize);
4122 	
4123 	      if( realarray->minusedidx <= realarray->maxusedidx )
4124 	      {
4125 	         int shift;
4126 	
4127 	         assert(realarray->firstidx <= realarray->minusedidx);
4128 	         assert(realarray->maxusedidx < realarray->firstidx + realarray->valssize);
4129 	
4130 	         /* shift used part of array to the right */
4131 	         shift = realarray->firstidx - newfirstidx;
4132 	         assert(shift > 0);
4133 	         for( i = realarray->maxusedidx - realarray->firstidx; i >= realarray->minusedidx - realarray->firstidx; --i )
4134 	         {
4135 	            assert(0 <= i + shift && i + shift < realarray->valssize);
4136 	            realarray->vals[i + shift] = realarray->vals[i];
4137 	         }
4138 	         /* clear the formerly used head of the array */
4139 	         for( i = 0; i < shift; ++i )
4140 	            realarray->vals[realarray->minusedidx - realarray->firstidx + i] = 0.0;
4141 	      }
4142 	      realarray->firstidx = newfirstidx;
4143 	   }
4144 	   else if( maxidx >= realarray->firstidx + realarray->valssize )
4145 	   {
4146 	      /* a sufficiently large memory storage exists, but it has to be shifted to the left */
4147 	      nfree = realarray->valssize - nused;
4148 	      assert(nfree >= 0);
4149 	      newfirstidx = minidx - nfree/2;
4150 	      newfirstidx = MAX(newfirstidx, 0);
4151 	      assert(newfirstidx <= minidx);
4152 	      assert(maxidx < newfirstidx + realarray->valssize);
4153 	
4154 	      if( realarray->minusedidx <= realarray->maxusedidx )
4155 	      {
4156 	         int shift;
4157 	
4158 	         assert(realarray->firstidx <= realarray->minusedidx);
4159 	         assert(realarray->maxusedidx < realarray->firstidx + realarray->valssize);
4160 	
4161 	         /* shift used part of array to the left */
4162 	         shift = newfirstidx - realarray->firstidx;
4163 	         assert(shift > 0);
4164 	         for( i = realarray->minusedidx - realarray->firstidx; i <= realarray->maxusedidx - realarray->firstidx; ++i )
4165 	         {
4166 	            assert(0 <= i - shift && i - shift < realarray->valssize);
4167 	            realarray->vals[i - shift] = realarray->vals[i];
4168 	         }
4169 	         /* clear the formerly used tail of the array */
4170 	         for( i = 0; i < shift; ++i )
4171 	            realarray->vals[realarray->maxusedidx - realarray->firstidx - i] = 0.0;
4172 	      }
4173 	      realarray->firstidx = newfirstidx;
4174 	   }
4175 	
4176 	   assert(minidx >= realarray->firstidx);
4177 	   assert(maxidx < realarray->firstidx + realarray->valssize);
4178 	
4179 	   return SCIP_OKAY;
4180 	}
4181 	
4182 	/** clears a dynamic real array */
4183 	SCIP_RETCODE SCIPrealarrayClear(
4184 	   SCIP_REALARRAY*       realarray           /**< dynamic real array */
4185 	   )
4186 	{
4187 	   assert(realarray != NULL);
4188 	
4189 	   SCIPdebugMessage("clearing realarray %p (firstidx=%d, size=%d, range=[%d,%d])\n",
4190 	      (void*)realarray, realarray->firstidx, realarray->valssize, realarray->minusedidx, realarray->maxusedidx);
4191 	
4192 	   if( realarray->minusedidx <= realarray->maxusedidx )
4193 	   {
4194 	      assert(realarray->firstidx <= realarray->minusedidx);
4195 	      assert(realarray->maxusedidx < realarray->firstidx + realarray->valssize);
4196 	      assert(realarray->firstidx != -1);
4197 	      assert(realarray->valssize > 0);
4198 	
4199 	      /* clear the used part of array */
4200 	      BMSclearMemoryArray(&realarray->vals[realarray->minusedidx - realarray->firstidx],
4201 	         realarray->maxusedidx - realarray->minusedidx + 1); /*lint !e866*/
4202 	
4203 	      /* mark the array cleared */
4204 	      realarray->minusedidx = INT_MAX;
4205 	      realarray->maxusedidx = INT_MIN;
4206 	   }
4207 	   assert(realarray->minusedidx == INT_MAX);
4208 	   assert(realarray->maxusedidx == INT_MIN);
4209 	
4210 	   return SCIP_OKAY;
4211 	}
4212 	
4213 	/** gets value of entry in dynamic array */
4214 	SCIP_Real SCIPrealarrayGetVal(
4215 	   SCIP_REALARRAY*       realarray,          /**< dynamic real array */
4216 	   int                   idx                 /**< array index to get value for */
4217 	   )
4218 	{
4219 	   assert(realarray != NULL);
4220 	   assert(idx >= 0);
4221 	
4222 	   if( idx < realarray->minusedidx || idx > realarray->maxusedidx )
4223 	      return 0.0;
4224 	   else
4225 	   {
4226 	      assert(realarray->vals != NULL);
4227 	      assert(idx - realarray->firstidx >= 0);
4228 	      assert(idx - realarray->firstidx < realarray->valssize);
4229 	
4230 	      return realarray->vals[idx - realarray->firstidx];
4231 	   }
4232 	}
4233 	
4234 	/** sets value of entry in dynamic array */
4235 	SCIP_RETCODE SCIPrealarraySetVal(
4236 	   SCIP_REALARRAY*       realarray,          /**< dynamic real array */
4237 	   int                   arraygrowinit,      /**< initial size of array */
4238 	   SCIP_Real             arraygrowfac,       /**< growing factor of array */
4239 	   int                   idx,                /**< array index to set value for */
4240 	   SCIP_Real             val                 /**< value to set array index to */
4241 	   )
4242 	{
4243 	   assert(realarray != NULL);
4244 	   assert(idx >= 0);
4245 	
4246 	   SCIPdebugMessage("setting realarray %p (firstidx=%d, size=%d, range=[%d,%d]) index %d to %g\n",
4247 	      (void*)realarray, realarray->firstidx, realarray->valssize, realarray->minusedidx, realarray->maxusedidx, idx, val);
4248 	
4249 	   if( val != 0.0 )
4250 	   {
4251 	      /* extend array to be able to store the index */
4252 	      SCIP_CALL( SCIPrealarrayExtend(realarray, arraygrowinit, arraygrowfac, idx, idx) );
4253 	      assert(idx >= realarray->firstidx);
4254 	      assert(idx < realarray->firstidx + realarray->valssize);
4255 	
4256 	      /* set the array value of the index */
4257 	      realarray->vals[idx - realarray->firstidx] = val;
4258 	
4259 	      /* update min/maxusedidx */
4260 	      realarray->minusedidx = MIN(realarray->minusedidx, idx);
4261 	      realarray->maxusedidx = MAX(realarray->maxusedidx, idx);
4262 	   }
4263 	   else if( idx >= realarray->firstidx && idx < realarray->firstidx + realarray->valssize )
4264 	   {
4265 	      /* set the array value of the index to zero */
4266 	      realarray->vals[idx - realarray->firstidx] = 0.0;
4267 	
4268 	      /* check, if we can tighten the min/maxusedidx */
4269 	      if( idx == realarray->minusedidx )
4270 	      {
4271 	         assert(realarray->maxusedidx >= 0);
4272 	         assert(realarray->maxusedidx < realarray->firstidx + realarray->valssize);
4273 	         do
4274 	         {
4275 	            realarray->minusedidx++;
4276 	         }
4277 	         while( realarray->minusedidx <= realarray->maxusedidx
4278 	            && realarray->vals[realarray->minusedidx - realarray->firstidx] == 0.0 );
4279 	
4280 	         if( realarray->minusedidx > realarray->maxusedidx )
4281 	         {
4282 	            realarray->minusedidx = INT_MAX;
4283 	            realarray->maxusedidx = INT_MIN;
4284 	         }
4285 	      }
4286 	      else if( idx == realarray->maxusedidx )
4287 	      {
4288 	         assert(realarray->minusedidx >= 0);
4289 	         assert(realarray->minusedidx < realarray->maxusedidx);
4290 	         assert(realarray->maxusedidx < realarray->firstidx + realarray->valssize);
4291 	         do
4292 	         {
4293 	            realarray->maxusedidx--;
4294 	            assert(realarray->minusedidx <= realarray->maxusedidx);
4295 	         }
4296 	         while( realarray->vals[realarray->maxusedidx - realarray->firstidx] == 0.0 );
4297 	      }
4298 	   }
4299 	
4300 	   return SCIP_OKAY;
4301 	}
4302 	
4303 	/** increases value of entry in dynamic array */
4304 	SCIP_RETCODE SCIPrealarrayIncVal(
4305 	   SCIP_REALARRAY*       realarray,          /**< dynamic real array */
4306 	   int                   arraygrowinit,      /**< initial size of array */
4307 	   SCIP_Real             arraygrowfac,       /**< growing factor of array */
4308 	   int                   idx,                /**< array index to increase value for */
4309 	   SCIP_Real             incval              /**< value to increase array index */
4310 	   )
4311 	{
4312 	   SCIP_Real oldval;
4313 	
4314 	   oldval = SCIPrealarrayGetVal(realarray, idx);
4315 	   if( oldval != SCIP_INVALID ) /*lint !e777*/
4316 	      return SCIPrealarraySetVal(realarray, arraygrowinit, arraygrowfac, idx, oldval + incval);
4317 	   else
4318 	      return SCIP_OKAY;
4319 	}
4320 	
4321 	/** returns the minimal index of all stored non-zero elements */
4322 	int SCIPrealarrayGetMinIdx(
4323 	   SCIP_REALARRAY*       realarray           /**< dynamic real array */
4324 	   )
4325 	{
4326 	   assert(realarray != NULL);
4327 	
4328 	   return realarray->minusedidx;
4329 	}
4330 	
4331 	/** returns the maximal index of all stored non-zero elements */
4332 	int SCIPrealarrayGetMaxIdx(
4333 	   SCIP_REALARRAY*       realarray           /**< dynamic real array */
4334 	   )
4335 	{
4336 	   assert(realarray != NULL);
4337 	
4338 	   return realarray->maxusedidx;
4339 	}
4340 	
4341 	/** creates a dynamic array of int values */
4342 	SCIP_RETCODE SCIPintarrayCreate(
4343 	   SCIP_INTARRAY**       intarray,           /**< pointer to store the int array */
4344 	   BMS_BLKMEM*           blkmem              /**< block memory */
4345 	   )
4346 	{
4347 	   assert(intarray != NULL);
4348 	   assert(blkmem != NULL);
4349 	
4350 	   SCIP_ALLOC( BMSallocBlockMemory(blkmem, intarray) );
4351 	   (*intarray)->blkmem = blkmem;
4352 	   (*intarray)->vals = NULL;
4353 	   (*intarray)->valssize = 0;
4354 	   (*intarray)->firstidx = -1;
4355 	   (*intarray)->minusedidx = INT_MAX;
4356 	   (*intarray)->maxusedidx = INT_MIN;
4357 	
4358 	   return SCIP_OKAY;
4359 	}
4360 	
4361 	/** creates a copy of a dynamic array of int values */
4362 	SCIP_RETCODE SCIPintarrayCopy(
4363 	   SCIP_INTARRAY**       intarray,           /**< pointer to store the copied int array */
4364 	   BMS_BLKMEM*           blkmem,             /**< block memory */
4365 	   SCIP_INTARRAY*        sourceintarray      /**< dynamic int array to copy */
4366 	   )
4367 	{
4368 	   assert(intarray != NULL);
4369 	   assert(sourceintarray != NULL);
4370 	
4371 	   SCIP_CALL( SCIPintarrayCreate(intarray, blkmem) );
4372 	   if( sourceintarray->valssize > 0 )
4373 	   {
4374 	      SCIP_ALLOC( BMSduplicateBlockMemoryArray(blkmem, &(*intarray)->vals, sourceintarray->vals, sourceintarray->valssize) );
4375 	   }
4376 	   (*intarray)->valssize = sourceintarray->valssize;
4377 	   (*intarray)->firstidx = sourceintarray->firstidx;
4378 	   (*intarray)->minusedidx = sourceintarray->minusedidx;
4379 	   (*intarray)->maxusedidx = sourceintarray->maxusedidx;
4380 	
4381 	   return SCIP_OKAY;
4382 	}
4383 	
4384 	/** frees a dynamic array of int values */
4385 	SCIP_RETCODE SCIPintarrayFree(
4386 	   SCIP_INTARRAY**       intarray            /**< pointer to the int array */
4387 	   )
4388 	{
4389 	   assert(intarray != NULL);
4390 	   assert(*intarray != NULL);
4391 	
4392 	   BMSfreeBlockMemoryArrayNull((*intarray)->blkmem, &(*intarray)->vals, (*intarray)->valssize);
4393 	   BMSfreeBlockMemory((*intarray)->blkmem, intarray);
4394 	
4395 	   return SCIP_OKAY;
4396 	}
4397 	
4398 	/** extends dynamic array to be able to store indices from minidx to maxidx */
4399 	SCIP_RETCODE SCIPintarrayExtend(
4400 	   SCIP_INTARRAY*        intarray,           /**< dynamic int array */
4401 	   int                   arraygrowinit,      /**< initial size of array */
4402 	   SCIP_Real             arraygrowfac,       /**< growing factor of array */
4403 	   int                   minidx,             /**< smallest index to allocate storage for */
4404 	   int                   maxidx              /**< largest index to allocate storage for */
4405 	   )
4406 	{
4407 	   int nused;
4408 	   int nfree;
4409 	   int newfirstidx;
4410 	   int i;
4411 	
4412 	   assert(intarray != NULL);
4413 	   assert(intarray->minusedidx == INT_MAX || intarray->firstidx >= 0);
4414 	   assert(intarray->maxusedidx == INT_MIN || intarray->firstidx >= 0);
4415 	   assert(intarray->minusedidx == INT_MAX || intarray->minusedidx >= intarray->firstidx);
4416 	   assert(intarray->maxusedidx == INT_MIN || intarray->maxusedidx < intarray->firstidx + intarray->valssize);
4417 	   assert(0 <= minidx);
4418 	   assert(minidx <= maxidx);
4419 	
4420 	   minidx = MIN(minidx, intarray->minusedidx);
4421 	   maxidx = MAX(maxidx, intarray->maxusedidx);
4422 	   assert(0 <= minidx);
4423 	   assert(minidx <= maxidx);
4424 	
4425 	   SCIPdebugMessage("extending intarray %p (firstidx=%d, size=%d, range=[%d,%d]) to range [%d,%d]\n",
4426 	      (void*)intarray, intarray->firstidx, intarray->valssize, intarray->minusedidx, intarray->maxusedidx, minidx, maxidx);
4427 	
4428 	   /* check, whether we have to allocate additional memory, or shift the array */
4429 	   nused = maxidx - minidx + 1;
4430 	   if( nused > intarray->valssize )
4431 	   {
4432 	      int* newvals;
4433 	      int newvalssize;
4434 	
4435 	      /* allocate new memory storage */
4436 	      newvalssize = calcGrowSize(arraygrowinit, arraygrowfac, nused);
4437 	      SCIP_ALLOC( BMSallocBlockMemoryArray(intarray->blkmem, &newvals, newvalssize) );
4438 	      nfree = newvalssize - nused;
4439 	      newfirstidx = minidx - nfree/2;
4440 	      newfirstidx = MAX(newfirstidx, 0);
4441 	      assert(newfirstidx <= minidx);
4442 	      assert(maxidx < newfirstidx + newvalssize);
4443 	
4444 	      /* initialize memory array by copying old values and setting new values to zero */
4445 	      if( intarray->firstidx != -1 )
4446 	      {
4447 	         for( i = 0; i < intarray->minusedidx - newfirstidx; ++i )
4448 	            newvals[i] = 0;
4449 	
4450 	         /* check for possible overflow or negative value */
4451 	         assert(intarray->maxusedidx - intarray->minusedidx + 1 > 0);
4452 	
4453 	         BMScopyMemoryArray(&newvals[intarray->minusedidx - newfirstidx],
4454 	            &intarray->vals[intarray->minusedidx - intarray->firstidx],
4455 	            intarray->maxusedidx - intarray->minusedidx + 1); /*lint !e866 !e776*/
4456 	         for( i = intarray->maxusedidx - newfirstidx + 1; i < newvalssize; ++i )
4457 	            newvals[i] = 0;
4458 	      }
4459 	      else
4460 	      {
4461 	         for( i = 0; i < newvalssize; ++i )
4462 	            newvals[i] = 0;
4463 	      }
4464 	
4465 	      /* free old memory storage, and set the new array parameters */
4466 	      BMSfreeBlockMemoryArrayNull(intarray->blkmem, &intarray->vals, intarray->valssize);
4467 	      intarray->vals = newvals;
4468 	      intarray->valssize = newvalssize;
4469 	      intarray->firstidx = newfirstidx;
4470 	   }
4471 	   else if( intarray->firstidx == -1 )
4472 	   {
4473 	      /* a sufficiently large memory storage exists, but it was cleared */
4474 	      nfree = intarray->valssize - nused;
4475 	      assert(nfree >= 0);
4476 	      intarray->firstidx = minidx - nfree/2;
4477 	      assert(intarray->firstidx <= minidx);
4478 	      assert(maxidx < intarray->firstidx + intarray->valssize);
4479 	#ifndef NDEBUG
4480 	      for( i = 0; i < intarray->valssize; ++i )
4481 	         assert(intarray->vals[i] == 0);
4482 	#endif
4483 	   }
4484 	   else if( minidx < intarray->firstidx )
4485 	   {
4486 	      /* a sufficiently large memory storage exists, but it has to be shifted to the right */
4487 	      nfree = intarray->valssize - nused;
4488 	      assert(nfree >= 0);
4489 	      newfirstidx = minidx - nfree/2;
4490 	      newfirstidx = MAX(newfirstidx, 0);
4491 	      assert(newfirstidx <= minidx);
4492 	      assert(maxidx < newfirstidx + intarray->valssize);
4493 	
4494 	      if( intarray->minusedidx <= intarray->maxusedidx )
4495 	      {
4496 	         int shift;
4497 	
4498 	         assert(intarray->firstidx <= intarray->minusedidx);
4499 	         assert(intarray->maxusedidx < intarray->firstidx + intarray->valssize);
4500 	
4501 	         /* shift used part of array to the right */
4502 	         shift = intarray->firstidx - newfirstidx;
4503 	         assert(shift > 0);
4504 	         for( i = intarray->maxusedidx - intarray->firstidx; i >= intarray->minusedidx - intarray->firstidx; --i )
4505 	         {
4506 	            assert(0 <= i + shift && i + shift < intarray->valssize);
4507 	            intarray->vals[i + shift] = intarray->vals[i];
4508 	         }
4509 	         /* clear the formerly used head of the array */
4510 	         for( i = 0; i < shift; ++i )
4511 	            intarray->vals[intarray->minusedidx - intarray->firstidx + i] = 0;
4512 	      }
4513 	      intarray->firstidx = newfirstidx;
4514 	   }
4515 	   else if( maxidx >= intarray->firstidx + intarray->valssize )
4516 	   {
4517 	      /* a sufficiently large memory storage exists, but it has to be shifted to the left */
4518 	      nfree = intarray->valssize - nused;
4519 	      assert(nfree >= 0);
4520 	      newfirstidx = minidx - nfree/2;
4521 	      newfirstidx = MAX(newfirstidx, 0);
4522 	      assert(newfirstidx <= minidx);
4523 	      assert(maxidx < newfirstidx + intarray->valssize);
4524 	
4525 	      if( intarray->minusedidx <= intarray->maxusedidx )
4526 	      {
4527 	         int shift;
4528 	
4529 	         assert(intarray->firstidx <= intarray->minusedidx);
4530 	         assert(intarray->maxusedidx < intarray->firstidx + intarray->valssize);
4531 	
4532 	         /* shift used part of array to the left */
4533 	         shift = newfirstidx - intarray->firstidx;
4534 	         assert(shift > 0);
4535 	         for( i = intarray->minusedidx - intarray->firstidx; i <= intarray->maxusedidx - intarray->firstidx; ++i )
4536 	         {
4537 	            assert(0 <= i - shift && i - shift < intarray->valssize);
4538 	            intarray->vals[i - shift] = intarray->vals[i];
4539 	         }
4540 	         /* clear the formerly used tail of the array */
4541 	         for( i = 0; i < shift; ++i )
4542 	            intarray->vals[intarray->maxusedidx - intarray->firstidx - i] = 0;
4543 	      }
4544 	      intarray->firstidx = newfirstidx;
4545 	   }
4546 	
4547 	   assert(minidx >= intarray->firstidx);
4548 	   assert(maxidx < intarray->firstidx + intarray->valssize);
4549 	
4550 	   return SCIP_OKAY;
4551 	}
4552 	
4553 	/** clears a dynamic int array */
4554 	SCIP_RETCODE SCIPintarrayClear(
4555 	   SCIP_INTARRAY*        intarray            /**< dynamic int array */
4556 	   )
4557 	{
4558 	   assert(intarray != NULL);
4559 	
4560 	   SCIPdebugMessage("clearing intarray %p (firstidx=%d, size=%d, range=[%d,%d])\n",
4561 	      (void*)intarray, intarray->firstidx, intarray->valssize, intarray->minusedidx, intarray->maxusedidx);
4562 	
4563 	   if( intarray->minusedidx <= intarray->maxusedidx )
4564 	   {
4565 	      assert(intarray->firstidx <= intarray->minusedidx);
4566 	      assert(intarray->maxusedidx < intarray->firstidx + intarray->valssize);
4567 	      assert(intarray->firstidx != -1);
4568 	      assert(intarray->valssize > 0);
4569 	
4570 	      /* clear the used part of array */
4571 	      BMSclearMemoryArray(&intarray->vals[intarray->minusedidx - intarray->firstidx],
4572 	         intarray->maxusedidx - intarray->minusedidx + 1); /*lint !e866*/
4573 	
4574 	      /* mark the array cleared */
4575 	      intarray->minusedidx = INT_MAX;
4576 	      intarray->maxusedidx = INT_MIN;
4577 	   }
4578 	   assert(intarray->minusedidx == INT_MAX);
4579 	   assert(intarray->maxusedidx == INT_MIN);
4580 	
4581 	   return SCIP_OKAY;
4582 	}
4583 	
4584 	/** gets value of entry in dynamic array */
4585 	int SCIPintarrayGetVal(
4586 	   SCIP_INTARRAY*        intarray,           /**< dynamic int array */
4587 	   int                   idx                 /**< array index to get value for */
4588 	   )
4589 	{
4590 	   assert(intarray != NULL);
4591 	   assert(idx >= 0);
4592 	
4593 	   if( idx < intarray->minusedidx || idx > intarray->maxusedidx )
4594 	      return 0;
4595 	   else
4596 	   {
4597 	      assert(intarray->vals != NULL);
4598 	      assert(idx - intarray->firstidx >= 0);
4599 	      assert(idx - intarray->firstidx < intarray->valssize);
4600 	
4601 	      return intarray->vals[idx - intarray->firstidx];
4602 	   }
4603 	}
4604 	
4605 	/** sets value of entry in dynamic array */
4606 	SCIP_RETCODE SCIPintarraySetVal(
4607 	   SCIP_INTARRAY*        intarray,           /**< dynamic int array */
4608 	   int                   arraygrowinit,      /**< initial size of array */
4609 	   SCIP_Real             arraygrowfac,       /**< growing factor of array */
4610 	   int                   idx,                /**< array index to set value for */
4611 	   int                   val                 /**< value to set array index to */
4612 	   )
4613 	{
4614 	   assert(intarray != NULL);
4615 	   assert(idx >= 0);
4616 	
4617 	   SCIPdebugMessage("setting intarray %p (firstidx=%d, size=%d, range=[%d,%d]) index %d to %d\n",
4618 	      (void*)intarray, intarray->firstidx, intarray->valssize, intarray->minusedidx, intarray->maxusedidx, idx, val);
4619 	
4620 	   if( val != 0 )
4621 	   {
4622 	      /* extend array to be able to store the index */
4623 	      SCIP_CALL( SCIPintarrayExtend(intarray, arraygrowinit, arraygrowfac, idx, idx) );
4624 	      assert(idx >= intarray->firstidx);
4625 	      assert(idx < intarray->firstidx + intarray->valssize);
4626 	
4627 	      /* set the array value of the index */
4628 	      intarray->vals[idx - intarray->firstidx] = val;
4629 	
4630 	      /* update min/maxusedidx */
4631 	      intarray->minusedidx = MIN(intarray->minusedidx, idx);
4632 	      intarray->maxusedidx = MAX(intarray->maxusedidx, idx);
4633 	   }
4634 	   else if( idx >= intarray->firstidx && idx < intarray->firstidx + intarray->valssize )
4635 	   {
4636 	      /* set the array value of the index to zero */
4637 	      intarray->vals[idx - intarray->firstidx] = 0;
4638 	
4639 	      /* check, if we can tighten the min/maxusedidx */
4640 	      if( idx == intarray->minusedidx )
4641 	      {
4642 	         assert(intarray->maxusedidx >= 0);
4643 	         assert(intarray->maxusedidx < intarray->firstidx + intarray->valssize);
4644 	         do
4645 	         {
4646 	            intarray->minusedidx++;
4647 	         }
4648 	         while( intarray->minusedidx <= intarray->maxusedidx
4649 	            && intarray->vals[intarray->minusedidx - intarray->firstidx] == 0 );
4650 	         if( intarray->minusedidx > intarray->maxusedidx )
4651 	         {
4652 	            intarray->minusedidx = INT_MAX;
4653 	            intarray->maxusedidx = INT_MIN;
4654 	         }
4655 	      }
4656 	      else if( idx == intarray->maxusedidx )
4657 	      {
4658 	         assert(intarray->minusedidx >= 0);
4659 	         assert(intarray->minusedidx < intarray->maxusedidx);
4660 	         assert(intarray->maxusedidx < intarray->firstidx + intarray->valssize);
4661 	         do
4662 	         {
4663 	            intarray->maxusedidx--;
4664 	            assert(intarray->minusedidx <= intarray->maxusedidx);
4665 	         }
4666 	         while( intarray->vals[intarray->maxusedidx - intarray->firstidx] == 0 );
4667 	      }
4668 	   }
4669 	
4670 	   return SCIP_OKAY;
4671 	}
4672 	
4673 	/** increases value of entry in dynamic array */
4674 	SCIP_RETCODE SCIPintarrayIncVal(
4675 	   SCIP_INTARRAY*        intarray,           /**< dynamic int array */
4676 	   int                   arraygrowinit,      /**< initial size of array */
4677 	   SCIP_Real             arraygrowfac,       /**< growing factor of array */
4678 	   int                   idx,                /**< array index to increase value for */
4679 	   int                   incval              /**< value to increase array index */
4680 	   )
4681 	{
4682 	   return SCIPintarraySetVal(intarray, arraygrowinit, arraygrowfac, idx, SCIPintarrayGetVal(intarray, idx) + incval);
4683 	}
4684 	
4685 	/** returns the minimal index of all stored non-zero elements */
4686 	int SCIPintarrayGetMinIdx(
4687 	   SCIP_INTARRAY*        intarray            /**< dynamic int array */
4688 	   )
4689 	{
4690 	   assert(intarray != NULL);
4691 	
4692 	   return intarray->minusedidx;
4693 	}
4694 	
4695 	/** returns the maximal index of all stored non-zero elements */
4696 	int SCIPintarrayGetMaxIdx(
4697 	   SCIP_INTARRAY*        intarray            /**< dynamic int array */
4698 	   )
4699 	{
4700 	   assert(intarray != NULL);
4701 	
4702 	   return intarray->maxusedidx;
4703 	}
4704 	
4705 	
4706 	/** creates a dynamic array of bool values */
4707 	SCIP_RETCODE SCIPboolarrayCreate(
4708 	   SCIP_BOOLARRAY**      boolarray,          /**< pointer to store the bool array */
4709 	   BMS_BLKMEM*           blkmem              /**< block memory */
4710 	   )
4711 	{
4712 	   assert(boolarray != NULL);
4713 	   assert(blkmem != NULL);
4714 	
4715 	   SCIP_ALLOC( BMSallocBlockMemory(blkmem, boolarray) );
4716 	   (*boolarray)->blkmem = blkmem;
4717 	   (*boolarray)->vals = NULL;
4718 	   (*boolarray)->valssize = 0;
4719 	   (*boolarray)->firstidx = -1;
4720 	   (*boolarray)->minusedidx = INT_MAX;
4721 	   (*boolarray)->maxusedidx = INT_MIN;
4722 	
4723 	   return SCIP_OKAY;
4724 	}
4725 	
4726 	/** creates a copy of a dynamic array of bool values */
4727 	SCIP_RETCODE SCIPboolarrayCopy(
4728 	   SCIP_BOOLARRAY**      boolarray,          /**< pointer to store the copied bool array */
4729 	   BMS_BLKMEM*           blkmem,             /**< block memory */
4730 	   SCIP_BOOLARRAY*       sourceboolarray     /**< dynamic bool array to copy */
4731 	   )
4732 	{
4733 	   assert(boolarray != NULL);
4734 	   assert(sourceboolarray != NULL);
4735 	
4736 	   SCIP_CALL( SCIPboolarrayCreate(boolarray, blkmem) );
4737 	   if( sourceboolarray->valssize > 0 )
4738 	   {
4739 	      SCIP_ALLOC( BMSduplicateBlockMemoryArray(blkmem, &(*boolarray)->vals, sourceboolarray->vals, \
4740 	                     sourceboolarray->valssize) );
4741 	   }
4742 	   (*boolarray)->valssize = sourceboolarray->valssize;
4743 	   (*boolarray)->firstidx = sourceboolarray->firstidx;
4744 	   (*boolarray)->minusedidx = sourceboolarray->minusedidx;
4745 	   (*boolarray)->maxusedidx = sourceboolarray->maxusedidx;
4746 	
4747 	   return SCIP_OKAY;
4748 	}
4749 	
4750 	/** frees a dynamic array of bool values */
4751 	SCIP_RETCODE SCIPboolarrayFree(
4752 	   SCIP_BOOLARRAY**      boolarray           /**< pointer to the bool array */
4753 	   )
4754 	{
4755 	   assert(boolarray != NULL);
4756 	   assert(*boolarray != NULL);
4757 	
4758 	   BMSfreeBlockMemoryArrayNull((*boolarray)->blkmem, &(*boolarray)->vals, (*boolarray)->valssize);
4759 	   BMSfreeBlockMemory((*boolarray)->blkmem, boolarray);
4760 	
4761 	   return SCIP_OKAY;
4762 	}
4763 	
4764 	/** extends dynamic array to be able to store indices from minidx to maxidx */
4765 	SCIP_RETCODE SCIPboolarrayExtend(
4766 	   SCIP_BOOLARRAY*       boolarray,          /**< dynamic bool array */
4767 	   int                   arraygrowinit,      /**< initial size of array */
4768 	   SCIP_Real             arraygrowfac,       /**< growing factor of array */
4769 	   int                   minidx,             /**< smallest index to allocate storage for */
4770 	   int                   maxidx              /**< largest index to allocate storage for */
4771 	   )
4772 	{
4773 	   int nused;
4774 	   int nfree;
4775 	   int newfirstidx;
4776 	   int i;
4777 	
4778 	   assert(boolarray != NULL);
4779 	   assert(boolarray->minusedidx == INT_MAX || boolarray->firstidx >= 0);
4780 	   assert(boolarray->maxusedidx == INT_MIN || boolarray->firstidx >= 0);
4781 	   assert(boolarray->minusedidx == INT_MAX || boolarray->minusedidx >= boolarray->firstidx);
4782 	   assert(boolarray->maxusedidx == INT_MIN || boolarray->maxusedidx < boolarray->firstidx + boolarray->valssize);
4783 	   assert(0 <= minidx);
4784 	   assert(minidx <= maxidx);
4785 	
4786 	   minidx = MIN(minidx, boolarray->minusedidx);
4787 	   maxidx = MAX(maxidx, boolarray->maxusedidx);
4788 	   assert(0 <= minidx);
4789 	   assert(minidx <= maxidx);
4790 	
4791 	   SCIPdebugMessage("extending boolarray %p (firstidx=%d, size=%d, range=[%d,%d]) to range [%d,%d]\n",
4792 	      (void*)boolarray, boolarray->firstidx, boolarray->valssize, boolarray->minusedidx, boolarray->maxusedidx, minidx, maxidx);
4793 	
4794 	   /* check, whether we have to allocate additional memory, or shift the array */
4795 	   nused = maxidx - minidx + 1;
4796 	   if( nused > boolarray->valssize )
4797 	   {
4798 	      SCIP_Bool* newvals;
4799 	      int newvalssize;
4800 	
4801 	      /* allocate new memory storage */
4802 	      newvalssize = calcGrowSize(arraygrowinit, arraygrowfac, nused);
4803 	      SCIP_ALLOC( BMSallocBlockMemoryArray(boolarray->blkmem, &newvals, newvalssize) );
4804 	      nfree = newvalssize - nused;
4805 	      newfirstidx = minidx - nfree/2;
4806 	      newfirstidx = MAX(newfirstidx, 0);
4807 	      assert(newfirstidx <= minidx);
4808 	      assert(maxidx < newfirstidx + newvalssize);
4809 	
4810 	      /* initialize memory array by copying old values and setting new values to zero */
4811 	      if( boolarray->firstidx != -1 )
4812 	      {
4813 	         for( i = 0; i < boolarray->minusedidx - newfirstidx; ++i )
4814 	            newvals[i] = FALSE;
4815 	
4816 	         /* check for possible overflow or negative value */
4817 	         assert(boolarray->maxusedidx - boolarray->minusedidx + 1 > 0);
4818 	
4819 	         BMScopyMemoryArray(&newvals[boolarray->minusedidx - newfirstidx],
4820 	            &boolarray->vals[boolarray->minusedidx - boolarray->firstidx],
4821 	            boolarray->maxusedidx - boolarray->minusedidx + 1); /*lint !e866 !e776*/
4822 	         for( i = boolarray->maxusedidx - newfirstidx + 1; i < newvalssize; ++i )
4823 	            newvals[i] = FALSE;
4824 	      }
4825 	      else
4826 	      {
4827 	         for( i = 0; i < newvalssize; ++i )
4828 	            newvals[i] = FALSE;
4829 	      }
4830 	
4831 	      /* free old memory storage, and set the new array parameters */
4832 	      BMSfreeBlockMemoryArrayNull(boolarray->blkmem, &boolarray->vals, boolarray->valssize);
4833 	      boolarray->vals = newvals;
4834 	      boolarray->valssize = newvalssize;
4835 	      boolarray->firstidx = newfirstidx;
4836 	   }
4837 	   else if( boolarray->firstidx == -1 )
4838 	   {
4839 	      /* a sufficiently large memory storage exists, but it was cleared */
4840 	      nfree = boolarray->valssize - nused;
4841 	      assert(nfree >= 0);
4842 	      boolarray->firstidx = minidx - nfree/2;
4843 	      assert(boolarray->firstidx <= minidx);
4844 	      assert(maxidx < boolarray->firstidx + boolarray->valssize);
4845 	#ifndef NDEBUG
4846 	      for( i = 0; i < boolarray->valssize; ++i )
4847 	         assert(boolarray->vals[i] == FALSE);
4848 	#endif
4849 	   }
4850 	   else if( minidx < boolarray->firstidx )
4851 	   {
4852 	      /* a sufficiently large memory storage exists, but it has to be shifted to the right */
4853 	      nfree = boolarray->valssize - nused;
4854 	      assert(nfree >= 0);
4855 	      newfirstidx = minidx - nfree/2;
4856 	      newfirstidx = MAX(newfirstidx, 0);
4857 	      assert(newfirstidx <= minidx);
4858 	      assert(maxidx < newfirstidx + boolarray->valssize);
4859 	
4860 	      if( boolarray->minusedidx <= boolarray->maxusedidx )
4861 	      {
4862 	         int shift;
4863 	
4864 	         assert(boolarray->firstidx <= boolarray->minusedidx);
4865 	         assert(boolarray->maxusedidx < boolarray->firstidx + boolarray->valssize);
4866 	
4867 	         /* shift used part of array to the right */
4868 	         shift = boolarray->firstidx - newfirstidx;
4869 	         assert(shift > 0);
4870 	         for( i = boolarray->maxusedidx - boolarray->firstidx; i >= boolarray->minusedidx - boolarray->firstidx; --i )
4871 	         {
4872 	            assert(0 <= i + shift && i + shift < boolarray->valssize);
4873 	            boolarray->vals[i + shift] = boolarray->vals[i];
4874 	         }
4875 	         /* clear the formerly used head of the array */
4876 	         for( i = 0; i < shift; ++i )
4877 	            boolarray->vals[boolarray->minusedidx - boolarray->firstidx + i] = FALSE;
4878 	      }
4879 	      boolarray->firstidx = newfirstidx;
4880 	   }
4881 	   else if( maxidx >= boolarray->firstidx + boolarray->valssize )
4882 	   {
4883 	      /* a sufficiently large memory storage exists, but it has to be shifted to the left */
4884 	      nfree = boolarray->valssize - nused;
4885 	      assert(nfree >= 0);
4886 	      newfirstidx = minidx - nfree/2;
4887 	      newfirstidx = MAX(newfirstidx, 0);
4888 	      assert(newfirstidx <= minidx);
4889 	      assert(maxidx < newfirstidx + boolarray->valssize);
4890 	
4891 	      if( boolarray->minusedidx <= boolarray->maxusedidx )
4892 	      {
4893 	         int shift;
4894 	
4895 	         assert(boolarray->firstidx <= boolarray->minusedidx);
4896 	         assert(boolarray->maxusedidx < boolarray->firstidx + boolarray->valssize);
4897 	
4898 	         /* shift used part of array to the left */
4899 	         shift = newfirstidx - boolarray->firstidx;
4900 	         assert(shift > 0);
4901 	
4902 		 assert(0 <= boolarray->minusedidx - boolarray->firstidx - shift);
4903 	         assert(boolarray->maxusedidx - boolarray->firstidx - shift < boolarray->valssize);
4904 		 BMSmoveMemoryArray(&(boolarray->vals[boolarray->minusedidx - boolarray->firstidx - shift]),
4905 	            &(boolarray->vals[boolarray->minusedidx - boolarray->firstidx]),
4906 	            boolarray->maxusedidx - boolarray->minusedidx + 1); /*lint !e866*/
4907 	
4908 	         /* clear the formerly used tail of the array */
4909 	         for( i = 0; i < shift; ++i )
4910 	            boolarray->vals[boolarray->maxusedidx - boolarray->firstidx - i] = FALSE;
4911 	      }
4912 	      boolarray->firstidx = newfirstidx;
4913 	   }
4914 	
4915 	   assert(minidx >= boolarray->firstidx);
4916 	   assert(maxidx < boolarray->firstidx + boolarray->valssize);
4917 	
4918 	   return SCIP_OKAY;
4919 	}
4920 	
4921 	/** clears a dynamic bool array */
4922 	SCIP_RETCODE SCIPboolarrayClear(
4923 	   SCIP_BOOLARRAY*       boolarray           /**< dynamic bool array */
4924 	   )
4925 	{
4926 	   assert(boolarray != NULL);
4927 	
4928 	   SCIPdebugMessage("clearing boolarray %p (firstidx=%d, size=%d, range=[%d,%d])\n",
4929 	      (void*)boolarray, boolarray->firstidx, boolarray->valssize, boolarray->minusedidx, boolarray->maxusedidx);
4930 	
4931 	   if( boolarray->minusedidx <= boolarray->maxusedidx )
4932 	   {
4933 	      assert(boolarray->firstidx <= boolarray->minusedidx);
4934 	      assert(boolarray->maxusedidx < boolarray->firstidx + boolarray->valssize);
4935 	      assert(boolarray->firstidx != -1);
4936 	      assert(boolarray->valssize > 0);
4937 	
4938 	      /* clear the used part of array */
4939 	      BMSclearMemoryArray(&boolarray->vals[boolarray->minusedidx - boolarray->firstidx],
4940 	         boolarray->maxusedidx - boolarray->minusedidx + 1); /*lint !e866*/
4941 	
4942 	      /* mark the array cleared */
4943 	      boolarray->minusedidx = INT_MAX;
4944 	      boolarray->maxusedidx = INT_MIN;
4945 	   }
4946 	   assert(boolarray->minusedidx == INT_MAX);
4947 	   assert(boolarray->maxusedidx == INT_MIN);
4948 	
4949 	   return SCIP_OKAY;
4950 	}
4951 	
4952 	/** gets value of entry in dynamic array */
4953 	SCIP_Bool SCIPboolarrayGetVal(
4954 	   SCIP_BOOLARRAY*       boolarray,          /**< dynamic bool array */
4955 	   int                   idx                 /**< array index to get value for */
4956 	   )
4957 	{
4958 	   assert(boolarray != NULL);
4959 	   assert(idx >= 0);
4960 	
4961 	   if( idx < boolarray->minusedidx || idx > boolarray->maxusedidx )
4962 	      return FALSE;
4963 	   else
4964 	   {
4965 	      assert(boolarray->vals != NULL);
4966 	      assert(idx - boolarray->firstidx >= 0);
4967 	      assert(idx - boolarray->firstidx < boolarray->valssize);
4968 	
4969 	      return boolarray->vals[idx - boolarray->firstidx];
4970 	   }
4971 	}
4972 	
4973 	/** sets value of entry in dynamic array */
4974 	SCIP_RETCODE SCIPboolarraySetVal(
4975 	   SCIP_BOOLARRAY*       boolarray,          /**< dynamic bool array */
4976 	   int                   arraygrowinit,      /**< initial size of array */
4977 	   SCIP_Real             arraygrowfac,       /**< growing factor of array */
4978 	   int                   idx,                /**< array index to set value for */
4979 	   SCIP_Bool             val                 /**< value to set array index to */
4980 	   )
4981 	{
4982 	   assert(boolarray != NULL);
4983 	   assert(idx >= 0);
4984 	
4985 	   SCIPdebugMessage("setting boolarray %p (firstidx=%d, size=%d, range=[%d,%d]) index %d to %u\n",
4986 	      (void*)boolarray, boolarray->firstidx, boolarray->valssize, boolarray->minusedidx, boolarray->maxusedidx, idx, val);
4987 	
4988 	   if( val != FALSE )
4989 	   {
4990 	      /* extend array to be able to store the index */
4991 	      SCIP_CALL( SCIPboolarrayExtend(boolarray, arraygrowinit, arraygrowfac, idx, idx) );
4992 	      assert(idx >= boolarray->firstidx);
4993 	      assert(idx < boolarray->firstidx + boolarray->valssize);
4994 	
4995 	      /* set the array value of the index */
4996 	      boolarray->vals[idx - boolarray->firstidx] = val;
4997 	
4998 	      /* update min/maxusedidx */
4999 	      boolarray->minusedidx = MIN(boolarray->minusedidx, idx);
5000 	      boolarray->maxusedidx = MAX(boolarray->maxusedidx, idx);
5001 	   }
5002 	   else if( idx >= boolarray->firstidx && idx < boolarray->firstidx + boolarray->valssize )
5003 	   {
5004 	      /* set the array value of the index to zero */
5005 	      boolarray->vals[idx - boolarray->firstidx] = FALSE;
5006 	
5007 	      /* check, if we can tighten the min/maxusedidx */
5008 	      if( idx == boolarray->minusedidx )
5009 	      {
5010 	         assert(boolarray->maxusedidx >= 0);
5011 	         assert(boolarray->maxusedidx < boolarray->firstidx + boolarray->valssize);
5012 	         do
5013 	         {
5014 	            boolarray->minusedidx++;
5015 	         }
5016 	         while( boolarray->minusedidx <= boolarray->maxusedidx
5017 	            && boolarray->vals[boolarray->minusedidx - boolarray->firstidx] == FALSE );
5018 	         if( boolarray->minusedidx > boolarray->maxusedidx )
5019 	         {
5020 	            boolarray->minusedidx = INT_MAX;
5021 	            boolarray->maxusedidx = INT_MIN;
5022 	         }
5023 	      }
5024 	      else if( idx == boolarray->maxusedidx )
5025 	      {
5026 	         assert(boolarray->minusedidx >= 0);
5027 	         assert(boolarray->minusedidx < boolarray->maxusedidx);
5028 	         assert(boolarray->maxusedidx < boolarray->firstidx + boolarray->valssize);
5029 	         do
5030 	         {
5031 	            boolarray->maxusedidx--;
5032 	            assert(boolarray->minusedidx <= boolarray->maxusedidx);
5033 	         }
5034 	         while( boolarray->vals[boolarray->maxusedidx - boolarray->firstidx] == FALSE );
5035 	      }
5036 	   }
5037 	
5038 	   return SCIP_OKAY;
5039 	}
5040 	
5041 	/** returns the minimal index of all stored non-zero elements */
5042 	int SCIPboolarrayGetMinIdx(
5043 	   SCIP_BOOLARRAY*       boolarray           /**< dynamic bool array */
5044 	   )
5045 	{
5046 	   assert(boolarray != NULL);
5047 	
5048 	   return boolarray->minusedidx;
5049 	}
5050 	
5051 	/** returns the maximal index of all stored non-zero elements */
5052 	int SCIPboolarrayGetMaxIdx(
5053 	   SCIP_BOOLARRAY*       boolarray           /**< dynamic bool array */
5054 	   )
5055 	{
5056 	   assert(boolarray != NULL);
5057 	
5058 	   return boolarray->maxusedidx;
5059 	}
5060 	
5061 	
5062 	/** creates a dynamic array of pointer values */
5063 	SCIP_RETCODE SCIPptrarrayCreate(
5064 	   SCIP_PTRARRAY**       ptrarray,           /**< pointer to store the ptr array */
5065 	   BMS_BLKMEM*           blkmem              /**< block memory */
5066 	   )
5067 	{
5068 	   assert(ptrarray != NULL);
5069 	   assert(blkmem != NULL);
5070 	
5071 	   SCIP_ALLOC( BMSallocBlockMemory(blkmem, ptrarray) );
5072 	   (*ptrarray)->blkmem = blkmem;
5073 	   (*ptrarray)->vals = NULL;
5074 	   (*ptrarray)->valssize = 0;
5075 	   (*ptrarray)->firstidx = -1;
5076 	   (*ptrarray)->minusedidx = INT_MAX;
5077 	   (*ptrarray)->maxusedidx = INT_MIN;
5078 	
5079 	   return SCIP_OKAY;
5080 	}
5081 	
5082 	/** creates a copy of a dynamic array of pointer values */
5083 	SCIP_RETCODE SCIPptrarrayCopy(
5084 	   SCIP_PTRARRAY**       ptrarray,           /**< pointer to store the copied ptr array */
5085 	   BMS_BLKMEM*           blkmem,             /**< block memory */
5086 	   SCIP_PTRARRAY*        sourceptrarray      /**< dynamic ptr array to copy */
5087 	   )
5088 	{
5089 	   assert(ptrarray != NULL);
5090 	   assert(sourceptrarray != NULL);
5091 	
5092 	   SCIP_CALL( SCIPptrarrayCreate(ptrarray, blkmem) );
5093 	   if( sourceptrarray->valssize > 0 )
5094 	   {
5095 	      SCIP_ALLOC( BMSduplicateBlockMemoryArray(blkmem, &(*ptrarray)->vals, sourceptrarray->vals, sourceptrarray->valssize) );
5096 	   }
5097 	   (*ptrarray)->valssize = sourceptrarray->valssize;
5098 	   (*ptrarray)->firstidx = sourceptrarray->firstidx;
5099 	   (*ptrarray)->minusedidx = sourceptrarray->minusedidx;
5100 	   (*ptrarray)->maxusedidx = sourceptrarray->maxusedidx;
5101 	
5102 	   return SCIP_OKAY;
5103 	}
5104 	
5105 	/** frees a dynamic array of pointer values */
5106 	SCIP_RETCODE SCIPptrarrayFree(
5107 	   SCIP_PTRARRAY**       ptrarray            /**< pointer to the ptr array */
5108 	   )
5109 	{
5110 	   assert(ptrarray != NULL);
5111 	   assert(*ptrarray != NULL);
5112 	
5113 	   BMSfreeBlockMemoryArrayNull((*ptrarray)->blkmem, &(*ptrarray)->vals, (*ptrarray)->valssize);
5114 	   BMSfreeBlockMemory((*ptrarray)->blkmem, ptrarray);
5115 	
5116 	   return SCIP_OKAY;
5117 	}
5118 	
5119 	/** extends dynamic array to be able to store indices from minidx to maxidx */
5120 	SCIP_RETCODE SCIPptrarrayExtend(
5121 	   SCIP_PTRARRAY*        ptrarray,           /**< dynamic ptr array */
5122 	   int                   arraygrowinit,      /**< initial size of array */
5123 	   SCIP_Real             arraygrowfac,       /**< growing factor of array */
5124 	   int                   minidx,             /**< smallest index to allocate storage for */
5125 	   int                   maxidx              /**< largest index to allocate storage for */
5126 	   )
5127 	{
5128 	   int nused;
5129 	   int nfree;
5130 	   int newfirstidx;
5131 	   int i;
5132 	
5133 	   assert(ptrarray != NULL);
5134 	   assert(ptrarray->minusedidx == INT_MAX || ptrarray->firstidx >= 0);
5135 	   assert(ptrarray->maxusedidx == INT_MIN || ptrarray->firstidx >= 0);
5136 	   assert(ptrarray->minusedidx == INT_MAX || ptrarray->minusedidx >= ptrarray->firstidx);
5137 	   assert(ptrarray->maxusedidx == INT_MIN || ptrarray->maxusedidx < ptrarray->firstidx + ptrarray->valssize);
5138 	   assert(0 <= minidx);
5139 	   assert(minidx <= maxidx);
5140 	
5141 	   minidx = MIN(minidx, ptrarray->minusedidx);
5142 	   maxidx = MAX(maxidx, ptrarray->maxusedidx);
5143 	   assert(0 <= minidx);
5144 	   assert(minidx <= maxidx);
5145 	
5146 	   SCIPdebugMessage("extending ptrarray %p (firstidx=%d, size=%d, range=[%d,%d]) to range [%d,%d]\n",
5147 	      (void*)ptrarray, ptrarray->firstidx, ptrarray->valssize, ptrarray->minusedidx, ptrarray->maxusedidx, minidx, maxidx);
5148 	
5149 	   /* check, whether we have to allocate additional memory, or shift the array */
5150 	   nused = maxidx - minidx + 1;
5151 	   if( nused > ptrarray->valssize )
5152 	   {
5153 	      void** newvals;
5154 	      int newvalssize;
5155 	
5156 	      /* allocate new memory storage */
5157 	      newvalssize = calcGrowSize(arraygrowinit, arraygrowfac, nused);
5158 	      SCIP_ALLOC( BMSallocBlockMemoryArray(ptrarray->blkmem, &newvals, newvalssize) );
5159 	      nfree = newvalssize - nused;
5160 	      newfirstidx = minidx - nfree/2;
5161 	      newfirstidx = MAX(newfirstidx, 0);
5162 	      assert(newfirstidx <= minidx);
5163 	      assert(maxidx < newfirstidx + newvalssize);
5164 	
5165 	      /* initialize memory array by copying old values and setting new values to zero */
5166 	      if( ptrarray->firstidx != -1 )
5167 	      {
5168 	         for( i = 0; i < ptrarray->minusedidx - newfirstidx; ++i )
5169 	            newvals[i] = NULL;
5170 	
5171 	         /* check for possible overflow or negative value */
5172 	         assert(ptrarray->maxusedidx - ptrarray->minusedidx + 1 > 0);
5173 	
5174 	         BMScopyMemoryArray(&newvals[ptrarray->minusedidx - newfirstidx],
5175 	            &(ptrarray->vals[ptrarray->minusedidx - ptrarray->firstidx]),
5176 	            ptrarray->maxusedidx - ptrarray->minusedidx + 1); /*lint !e866 !e776*/
5177 	         for( i = ptrarray->maxusedidx - newfirstidx + 1; i < newvalssize; ++i )
5178 	            newvals[i] = NULL;
5179 	      }
5180 	      else
5181 	      {
5182 	         for( i = 0; i < newvalssize; ++i )
5183 	            newvals[i] = NULL;
5184 	      }
5185 	
5186 	      /* free old memory storage, and set the new array parameters */
5187 	      BMSfreeBlockMemoryArrayNull(ptrarray->blkmem, &ptrarray->vals, ptrarray->valssize);
5188 	      ptrarray->vals = newvals;
5189 	      ptrarray->valssize = newvalssize;
5190 	      ptrarray->firstidx = newfirstidx;
5191 	   }
5192 	   else if( ptrarray->firstidx == -1 )
5193 	   {
5194 	      /* a sufficiently large memory storage exists, but it was cleared */
5195 	      nfree = ptrarray->valssize - nused;
5196 	      assert(nfree >= 0);
5197 	      ptrarray->firstidx = minidx - nfree/2;
5198 	      assert(ptrarray->firstidx <= minidx);
5199 	      assert(maxidx < ptrarray->firstidx + ptrarray->valssize);
5200 	#ifndef NDEBUG
5201 	      for( i = 0; i < ptrarray->valssize; ++i )
5202 	         assert(ptrarray->vals[i] == NULL);
5203 	#endif
5204 	   }
5205 	   else if( minidx < ptrarray->firstidx )
5206 	   {
5207 	      /* a sufficiently large memory storage exists, but it has to be shifted to the right */
5208 	      nfree = ptrarray->valssize - nused;
5209 	      assert(nfree >= 0);
5210 	      newfirstidx = minidx - nfree/2;
5211 	      newfirstidx = MAX(newfirstidx, 0);
5212 	      assert(newfirstidx <= minidx);
5213 	      assert(maxidx < newfirstidx + ptrarray->valssize);
5214 	
5215 	      if( ptrarray->minusedidx <= ptrarray->maxusedidx )
5216 	      {
5217 	         int shift;
5218 	
5219 	         assert(ptrarray->firstidx <= ptrarray->minusedidx);
5220 	         assert(ptrarray->maxusedidx < ptrarray->firstidx + ptrarray->valssize);
5221 	
5222 	         /* shift used part of array to the right */
5223 	         shift = ptrarray->firstidx - newfirstidx;
5224 	         assert(shift > 0);
5225 	         for( i = ptrarray->maxusedidx - ptrarray->firstidx; i >= ptrarray->minusedidx - ptrarray->firstidx; --i )
5226 	         {
5227 	            assert(0 <= i + shift && i + shift < ptrarray->valssize);
5228 	            ptrarray->vals[i + shift] = ptrarray->vals[i];
5229 	         }
5230 	         /* clear the formerly used head of the array */
5231 	         for( i = 0; i < shift; ++i )
5232 	            ptrarray->vals[ptrarray->minusedidx - ptrarray->firstidx + i] = NULL;
5233 	      }
5234 	      ptrarray->firstidx = newfirstidx;
5235 	   }
5236 	   else if( maxidx >= ptrarray->firstidx + ptrarray->valssize )
5237 	   {
5238 	      /* a sufficiently large memory storage exists, but it has to be shifted to the left */
5239 	      nfree = ptrarray->valssize - nused;
5240 	      assert(nfree >= 0);
5241 	      newfirstidx = minidx - nfree/2;
5242 	      newfirstidx = MAX(newfirstidx, 0);
5243 	      assert(newfirstidx <= minidx);
5244 	      assert(maxidx < newfirstidx + ptrarray->valssize);
5245 	
5246 	      if( ptrarray->minusedidx <= ptrarray->maxusedidx )
5247 	      {
5248 	         int shift;
5249 	
5250 	         assert(ptrarray->firstidx <= ptrarray->minusedidx);
5251 	         assert(ptrarray->maxusedidx < ptrarray->firstidx + ptrarray->valssize);
5252 	
5253 	         /* shift used part of array to the left */
5254 	         shift = newfirstidx - ptrarray->firstidx;
5255 	         assert(shift > 0);
5256 	         for( i = ptrarray->minusedidx - ptrarray->firstidx; i <= ptrarray->maxusedidx - ptrarray->firstidx; ++i )
5257 	         {
5258 	            assert(0 <= i - shift && i - shift < ptrarray->valssize);
5259 	            ptrarray->vals[i - shift] = ptrarray->vals[i];
5260 	         }
5261 	         /* clear the formerly used tail of the array */
5262 	         for( i = 0; i < shift; ++i )
5263 	            ptrarray->vals[ptrarray->maxusedidx - ptrarray->firstidx - i] = NULL;
5264 	      }
5265 	      ptrarray->firstidx = newfirstidx;
5266 	   }
5267 	
5268 	   assert(minidx >= ptrarray->firstidx);
5269 	   assert(maxidx < ptrarray->firstidx + ptrarray->valssize);
5270 	
5271 	   return SCIP_OKAY;
5272 	}
5273 	
5274 	/** clears a dynamic pointer array */
5275 	SCIP_RETCODE SCIPptrarrayClear(
5276 	   SCIP_PTRARRAY*        ptrarray            /**< dynamic ptr array */
5277 	   )
5278 	{
5279 	   assert(ptrarray != NULL);
5280 	
5281 	   SCIPdebugMessage("clearing ptrarray %p (firstidx=%d, size=%d, range=[%d,%d])\n",
5282 	      (void*)ptrarray, ptrarray->firstidx, ptrarray->valssize, ptrarray->minusedidx, ptrarray->maxusedidx);
5283 	
5284 	   if( ptrarray->minusedidx <= ptrarray->maxusedidx )
5285 	   {
5286 	      assert(ptrarray->firstidx <= ptrarray->minusedidx);
5287 	      assert(ptrarray->maxusedidx < ptrarray->firstidx + ptrarray->valssize);
5288 	      assert(ptrarray->firstidx != -1);
5289 	      assert(ptrarray->valssize > 0);
5290 	
5291 	      /* clear the used part of array */
5292 	      BMSclearMemoryArray(&ptrarray->vals[ptrarray->minusedidx - ptrarray->firstidx],
5293 	         ptrarray->maxusedidx - ptrarray->minusedidx + 1); /*lint !e866*/
5294 	
5295 	      /* mark the array cleared */
5296 	      ptrarray->minusedidx = INT_MAX;
5297 	      ptrarray->maxusedidx = INT_MIN;
5298 	   }
5299 	   assert(ptrarray->minusedidx == INT_MAX);
5300 	   assert(ptrarray->maxusedidx == INT_MIN);
5301 	
5302 	   return SCIP_OKAY;
5303 	}
5304 	
5305 	/** gets value of entry in dynamic array */
5306 	void* SCIPptrarrayGetVal(
5307 	   SCIP_PTRARRAY*        ptrarray,           /**< dynamic ptr array */
5308 	   int                   idx                 /**< array index to get value for */
5309 	   )
5310 	{
5311 	   assert(ptrarray != NULL);
5312 	   assert(idx >= 0);
5313 	
5314 	   if( idx < ptrarray->minusedidx || idx > ptrarray->maxusedidx )
5315 	      return NULL;
5316 	   else
5317 	   {
5318 	      assert(ptrarray->vals != NULL);
5319 	      assert(idx - ptrarray->firstidx >= 0);
5320 	      assert(idx - ptrarray->firstidx < ptrarray->valssize);
5321 	
5322 	      return ptrarray->vals[idx - ptrarray->firstidx];
5323 	   }
5324 	}
5325 	
5326 	/** sets value of entry in dynamic array */
5327 	SCIP_RETCODE SCIPptrarraySetVal(
5328 	   SCIP_PTRARRAY*        ptrarray,           /**< dynamic ptr array */
5329 	   int                   arraygrowinit,      /**< initial size of array */
5330 	   SCIP_Real             arraygrowfac,       /**< growing factor of array */
5331 	   int                   idx,                /**< array index to set value for */
5332 	   void*                 val                 /**< value to set array index to */
5333 	   )
5334 	{
5335 	   assert(ptrarray != NULL);
5336 	   assert(idx >= 0);
5337 	
5338 	   SCIPdebugMessage("setting ptrarray %p (firstidx=%d, size=%d, range=[%d,%d]) index %d to %p\n",
5339 	      (void*)ptrarray, ptrarray->firstidx, ptrarray->valssize, ptrarray->minusedidx, ptrarray->maxusedidx, idx, val);
5340 	
5341 	   if( val != NULL )
5342 	   {
5343 	      /* extend array to be able to store the index */
5344 	      SCIP_CALL( SCIPptrarrayExtend(ptrarray, arraygrowinit, arraygrowfac, idx, idx) );
5345 	      assert(idx >= ptrarray->firstidx);
5346 	      assert(idx < ptrarray->firstidx + ptrarray->valssize);
5347 	
5348 	      /* set the array value of the index */
5349 	      ptrarray->vals[idx - ptrarray->firstidx] = val;
5350 	
5351 	      /* update min/maxusedidx */
5352 	      ptrarray->minusedidx = MIN(ptrarray->minusedidx, idx);
5353 	      ptrarray->maxusedidx = MAX(ptrarray->maxusedidx, idx);
5354 	   }
5355 	   else if( idx >= ptrarray->firstidx && idx < ptrarray->firstidx + ptrarray->valssize )
5356 	   {
5357 	      /* set the array value of the index to zero */
5358 	      ptrarray->vals[idx - ptrarray->firstidx] = NULL;
5359 	
5360 	      /* check, if we can tighten the min/maxusedidx */
5361 	      if( idx == ptrarray->minusedidx )
5362 	      {
5363 	         assert(ptrarray->maxusedidx >= 0);
5364 	         assert(ptrarray->maxusedidx < ptrarray->firstidx + ptrarray->valssize);
5365 	         do
5366 	         {
5367 	            ptrarray->minusedidx++;
5368 	         }
5369 	         while( ptrarray->minusedidx <= ptrarray->maxusedidx
5370 	            && ptrarray->vals[ptrarray->minusedidx - ptrarray->firstidx] == NULL );
5371 	         if( ptrarray->minusedidx > ptrarray->maxusedidx )
5372 	         {
5373 	            ptrarray->minusedidx = INT_MAX;
5374 	            ptrarray->maxusedidx = INT_MIN;
5375 	         }
5376 	      }
5377 	      else if( idx == ptrarray->maxusedidx )
5378 	      {
5379 	         assert(ptrarray->minusedidx >= 0);
5380 	         assert(ptrarray->minusedidx < ptrarray->maxusedidx);
5381 	         assert(ptrarray->maxusedidx < ptrarray->firstidx + ptrarray->valssize);
5382 	         do
5383 	         {
5384 	            ptrarray->maxusedidx--;
5385 	            assert(ptrarray->minusedidx <= ptrarray->maxusedidx);
5386 	         }
5387 	         while( ptrarray->vals[ptrarray->maxusedidx - ptrarray->firstidx] == NULL );
5388 	      }
5389 	   }
5390 	
5391 	   return SCIP_OKAY;
5392 	}
5393 	
5394 	/** returns the minimal index of all stored non-zero elements */
5395 	int SCIPptrarrayGetMinIdx(
5396 	   SCIP_PTRARRAY*        ptrarray            /**< dynamic ptr array */
5397 	   )
5398 	{
5399 	   assert(ptrarray != NULL);
5400 	
5401 	   return ptrarray->minusedidx;
5402 	}
5403 	
5404 	/** returns the maximal index of all stored non-zero elements */
5405 	int SCIPptrarrayGetMaxIdx(
5406 	   SCIP_PTRARRAY*        ptrarray            /**< dynamic ptr array */
5407 	   )
5408 	{
5409 	   assert(ptrarray != NULL);
5410 	
5411 	   return ptrarray->maxusedidx;
5412 	}
5413 	
5414 	
5415 	/*
5416 	 * Sorting algorithms
5417 	 */
5418 	
5419 	/** default comparer for integers */
5420 	SCIP_DECL_SORTPTRCOMP(SCIPsortCompInt)
5421 	{
5422 	   int value1;
5423 	   int value2;
5424 	
5425 	   value1 = (int)(size_t)elem1;
5426 	   value2 = (int)(size_t)elem2;
5427 	
5428 	   if( value1 < value2 )
5429 	      return -1;
5430 	
5431 	   if( value2 < value1 )
5432 	      return 1;
5433 	
5434 	   return 0;
5435 	}
5436 	
5437 	/* first all upwards-sorting methods */
5438 	
5439 	/** sort an indexed element set in non-decreasing order, resulting in a permutation index array */
5440 	void SCIPsort(
5441 	   int*                  perm,               /**< pointer to store the resulting permutation */
5442 	   SCIP_DECL_SORTINDCOMP((*indcomp)),        /**< data element comparator */
5443 	   void*                 dataptr,            /**< pointer to data field that is given to the external compare method */
5444 	   int                   len                 /**< number of elements to be sorted (valid index range) */
5445 	   )
5446 	{
5447 	   int pos;
5448 	
5449 	   assert(indcomp != NULL);
5450 	   assert(len == 0 || perm != NULL);
5451 	
5452 	   /* create identity permutation */
5453 	   for( pos = 0; pos < len; ++pos )
5454 	      perm[pos] = pos;
5455 	
5456 	   SCIPsortInd(perm, indcomp, dataptr, len);
5457 	}
5458 	
5459 	/* SCIPsortInd(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
5460 	#define SORTTPL_NAMEEXT     Ind
5461 	#define SORTTPL_KEYTYPE     int
5462 	#define SORTTPL_INDCOMP
5463 	#include "scip/sorttpl.c" /*lint !e451*/
5464 	
5465 	
5466 	/* SCIPsortPtr(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
5467 	#define SORTTPL_NAMEEXT     Ptr
5468 	#define SORTTPL_KEYTYPE     void*
5469 	#define SORTTPL_PTRCOMP
5470 	#include "scip/sorttpl.c" /*lint !e451*/
5471 	
5472 	
5473 	/* SCIPsortPtrPtr(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
5474 	#define SORTTPL_NAMEEXT     PtrPtr
5475 	#define SORTTPL_KEYTYPE     void*
5476 	#define SORTTPL_FIELD1TYPE  void*
5477 	#define SORTTPL_PTRCOMP
5478 	#include "scip/sorttpl.c" /*lint !e451*/
5479 	
5480 	
5481 	/* SCIPsortPtrReal(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
5482 	#define SORTTPL_NAMEEXT     PtrReal
5483 	#define SORTTPL_KEYTYPE     void*
5484 	#define SORTTPL_FIELD1TYPE  SCIP_Real
5485 	#define SORTTPL_PTRCOMP
5486 	#include "scip/sorttpl.c" /*lint !e451*/
5487 	
5488 	
5489 	/* SCIPsortPtrInt(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
5490 	#define SORTTPL_NAMEEXT     PtrInt
5491 	#define SORTTPL_KEYTYPE     void*
5492 	#define SORTTPL_FIELD1TYPE  int
5493 	#define SORTTPL_PTRCOMP
5494 	#include "scip/sorttpl.c" /*lint !e451*/
5495 	
5496 	
5497 	/* SCIPsortPtrBool(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
5498 	#define SORTTPL_NAMEEXT     PtrBool
5499 	#define SORTTPL_KEYTYPE     void*
5500 	#define SORTTPL_FIELD1TYPE  SCIP_Bool
5501 	#define SORTTPL_PTRCOMP
5502 	#include "scip/sorttpl.c" /*lint !e451*/
5503 	
5504 	
5505 	/* SCIPsortPtrIntInt(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
5506 	#define SORTTPL_NAMEEXT     PtrIntInt
5507 	#define SORTTPL_KEYTYPE     void*
5508 	#define SORTTPL_FIELD1TYPE  int
5509 	#define SORTTPL_FIELD2TYPE  int
5510 	#define SORTTPL_PTRCOMP
5511 	#include "scip/sorttpl.c" /*lint !e451*/
5512 	
5513 	
5514 	/* SCIPsortPtrRealInt(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
5515 	#define SORTTPL_NAMEEXT     PtrRealInt
5516 	#define SORTTPL_KEYTYPE     void*
5517 	#define SORTTPL_FIELD1TYPE  SCIP_Real
5518 	#define SORTTPL_FIELD2TYPE  int
5519 	#define SORTTPL_PTRCOMP
5520 	#include "scip/sorttpl.c" /*lint !e451*/
5521 	
5522 	/* SCIPsortPtrRealRealInt(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
5523 	#define SORTTPL_NAMEEXT     PtrRealRealInt
5524 	#define SORTTPL_KEYTYPE     void*
5525 	#define SORTTPL_FIELD1TYPE  SCIP_Real
5526 	#define SORTTPL_FIELD2TYPE  SCIP_Real
5527 	#define SORTTPL_FIELD3TYPE  int
5528 	#define SORTTPL_PTRCOMP
5529 	#include "scip/sorttpl.c" /*lint !e451*/
5530 	
5531 	/* SCIPsortPtrRealRealBoolBool(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
5532 	#define SORTTPL_NAMEEXT     PtrRealRealBoolBool
5533 	#define SORTTPL_KEYTYPE     void*
5534 	#define SORTTPL_FIELD1TYPE  SCIP_Real
5535 	#define SORTTPL_FIELD2TYPE  SCIP_Real
5536 	#define SORTTPL_FIELD3TYPE  SCIP_Bool
5537 	#define SORTTPL_FIELD4TYPE  SCIP_Bool
5538 	#define SORTTPL_PTRCOMP
5539 	#include "scip/sorttpl.c" /*lint !e451*/
5540 	
5541 	/* SCIPsortPtrRealRealIntBool(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
5542 	#define SORTTPL_NAMEEXT     PtrRealRealIntBool
5543 	#define SORTTPL_KEYTYPE     void*
5544 	#define SORTTPL_FIELD1TYPE  SCIP_Real
5545 	#define SORTTPL_FIELD2TYPE  SCIP_Real
5546 	#define SORTTPL_FIELD3TYPE  int
5547 	#define SORTTPL_FIELD4TYPE  SCIP_Bool
5548 	#define SORTTPL_PTRCOMP
5549 	#include "scip/sorttpl.c" /*lint !e451*/
5550 	
5551 	/* SCIPsortPtrRealBool(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
5552 	#define SORTTPL_NAMEEXT     PtrRealBool
5553 	#define SORTTPL_KEYTYPE     void*
5554 	#define SORTTPL_FIELD1TYPE  SCIP_Real
5555 	#define SORTTPL_FIELD2TYPE  SCIP_Bool
5556 	#define SORTTPL_PTRCOMP
5557 	#include "scip/sorttpl.c" /*lint !e451*/
5558 	
5559 	
5560 	/* SCIPsortPtrPtrInt(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
5561 	#define SORTTPL_NAMEEXT     PtrPtrInt
5562 	#define SORTTPL_KEYTYPE     void*
5563 	#define SORTTPL_FIELD1TYPE  void*
5564 	#define SORTTPL_FIELD2TYPE  int
5565 	#define SORTTPL_PTRCOMP
5566 	#include "scip/sorttpl.c" /*lint !e451*/
5567 	
5568 	
5569 	/* SCIPsortPtrPtrReal(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
5570 	#define SORTTPL_NAMEEXT     PtrPtrReal
5571 	#define SORTTPL_KEYTYPE     void*
5572 	#define SORTTPL_FIELD1TYPE  void*
5573 	#define SORTTPL_FIELD2TYPE  SCIP_Real
5574 	#define SORTTPL_PTRCOMP
5575 	#include "scip/sorttpl.c" /*lint !e451*/
5576 	
5577 	
5578 	/* SCIPsortPtrRealIntInt(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
5579 	#define SORTTPL_NAMEEXT     PtrRealIntInt
5580 	#define SORTTPL_KEYTYPE     void*
5581 	#define SORTTPL_FIELD1TYPE  SCIP_Real
5582 	#define SORTTPL_FIELD2TYPE  int
5583 	#define SORTTPL_FIELD3TYPE  int
5584 	#define SORTTPL_PTRCOMP
5585 	#include "scip/sorttpl.c" /*lint !e451*/
5586 	
5587 	
5588 	/* SCIPsortPtrPtrIntInt(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
5589 	#define SORTTPL_NAMEEXT     PtrPtrIntInt
5590 	#define SORTTPL_KEYTYPE     void*
5591 	#define SORTTPL_FIELD1TYPE  void*
5592 	#define SORTTPL_FIELD2TYPE  int
5593 	#define SORTTPL_FIELD3TYPE  int
5594 	#define SORTTPL_PTRCOMP
5595 	#include "scip/sorttpl.c" /*lint !e451*/
5596 	
5597 	
5598 	/* SCIPsortPtrPtrRealInt(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
5599 	#define SORTTPL_NAMEEXT     PtrPtrRealInt
5600 	#define SORTTPL_KEYTYPE     void*
5601 	#define SORTTPL_FIELD1TYPE  void*
5602 	#define SORTTPL_FIELD2TYPE  SCIP_Real
5603 	#define SORTTPL_FIELD3TYPE  int
5604 	#define SORTTPL_PTRCOMP
5605 	#include "scip/sorttpl.c" /*lint !e451*/
5606 	
5607 	
5608 	/* SCIPsortPtrPtrRealBool(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
5609 	#define SORTTPL_NAMEEXT     PtrPtrRealBool
5610 	#define SORTTPL_KEYTYPE     void*
5611 	#define SORTTPL_FIELD1TYPE  void*
5612 	#define SORTTPL_FIELD2TYPE  SCIP_Real
5613 	#define SORTTPL_FIELD3TYPE  SCIP_Bool
5614 	#define SORTTPL_PTRCOMP
5615 	#include "scip/sorttpl.c" /*lint !e451*/
5616 	
5617 	
5618 	/* SCIPsortPtrPtrLongInt(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
5619 	#define SORTTPL_NAMEEXT     PtrPtrLongInt
5620 	#define SORTTPL_KEYTYPE     void*
5621 	#define SORTTPL_FIELD1TYPE  void*
5622 	#define SORTTPL_FIELD2TYPE  SCIP_Longint
5623 	#define SORTTPL_FIELD3TYPE  int
5624 	#define SORTTPL_PTRCOMP
5625 	#include "scip/sorttpl.c" /*lint !e451*/
5626 	
5627 	
5628 	/* SCIPsortPtrPtrLongIntInt(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
5629 	#define SORTTPL_NAMEEXT     PtrPtrLongIntInt
5630 	#define SORTTPL_KEYTYPE     void*
5631 	#define SORTTPL_FIELD1TYPE  void*
5632 	#define SORTTPL_FIELD2TYPE  SCIP_Longint
5633 	#define SORTTPL_FIELD3TYPE  int
5634 	#define SORTTPL_FIELD4TYPE  int
5635 	#define SORTTPL_PTRCOMP
5636 	#include "scip/sorttpl.c" /*lint !e451*/
5637 	
5638 	
5639 	/* SCIPsortReal(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
5640 	#define SORTTPL_NAMEEXT     Real
5641 	#define SORTTPL_KEYTYPE     SCIP_Real
5642 	#include "scip/sorttpl.c" /*lint !e451*/
5643 	
5644 	
5645 	/* SCIPsortRealBoolPtr(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
5646 	#define SORTTPL_NAMEEXT     RealBoolPtr
5647 	#define SORTTPL_KEYTYPE     SCIP_Real
5648 	#define SORTTPL_FIELD1TYPE  SCIP_Bool
5649 	#define SORTTPL_FIELD2TYPE  void*
5650 	#include "scip/sorttpl.c" /*lint !e451*/
5651 	
5652 	
5653 	/* SCIPsortRealPtr(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
5654 	#define SORTTPL_NAMEEXT     RealPtr
5655 	#define SORTTPL_KEYTYPE     SCIP_Real
5656 	#define SORTTPL_FIELD1TYPE  void*
5657 	#include "scip/sorttpl.c" /*lint !e451*/
5658 	
5659 	
5660 	/* SCIPsortRealInt(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
5661 	#define SORTTPL_NAMEEXT     RealInt
5662 	#define SORTTPL_KEYTYPE     SCIP_Real
5663 	#define SORTTPL_FIELD1TYPE  int
5664 	#include "scip/sorttpl.c" /*lint !e451*/
5665 	
5666 	
5667 	/* SCIPsortRealIntInt(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
5668 	#define SORTTPL_NAMEEXT     RealIntInt
5669 	#define SORTTPL_KEYTYPE     SCIP_Real
5670 	#define SORTTPL_FIELD1TYPE  int
5671 	#define SORTTPL_FIELD2TYPE  int
5672 	#include "scip/sorttpl.c" /*lint !e451*/
5673 	
5674 	
5675 	/* SCIPsortRealIntLong(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
5676 	#define SORTTPL_NAMEEXT     RealIntLong
5677 	#define SORTTPL_KEYTYPE     SCIP_Real
5678 	#define SORTTPL_FIELD1TYPE  int
5679 	#define SORTTPL_FIELD2TYPE  SCIP_Longint
5680 	#include "scip/sorttpl.c" /*lint !e451*/
5681 	
5682 	
5683 	/* SCIPsortRealIntPtr(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
5684 	#define SORTTPL_NAMEEXT     RealIntPtr
5685 	#define SORTTPL_KEYTYPE     SCIP_Real
5686 	#define SORTTPL_FIELD1TYPE  int
5687 	#define SORTTPL_FIELD2TYPE  void*
5688 	#include "scip/sorttpl.c" /*lint !e451*/
5689 	
5690 	
5691 	/* SCIPsortRealRealPtr(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
5692 	#define SORTTPL_NAMEEXT     RealRealPtr
5693 	#define SORTTPL_KEYTYPE     SCIP_Real
5694 	#define SORTTPL_FIELD1TYPE  SCIP_Real
5695 	#define SORTTPL_FIELD2TYPE  void*
5696 	#include "scip/sorttpl.c" /*lint !e451*/
5697 	
5698 	
5699 	/* SCIPsortRealLongRealInt(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
5700 	#define SORTTPL_NAMEEXT     RealLongRealInt
5701 	#define SORTTPL_KEYTYPE     SCIP_Real
5702 	#define SORTTPL_FIELD1TYPE  SCIP_Longint
5703 	#define SORTTPL_FIELD2TYPE  SCIP_Real
5704 	#define SORTTPL_FIELD3TYPE  int
5705 	#include "scip/sorttpl.c" /*lint !e451*/
5706 	
5707 	/* SCIPsortRealRealIntInt(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
5708 	#define SORTTPL_NAMEEXT     RealRealIntInt
5709 	#define SORTTPL_KEYTYPE     SCIP_Real
5710 	#define SORTTPL_FIELD1TYPE  SCIP_Real
5711 	#define SORTTPL_FIELD2TYPE  int
5712 	#define SORTTPL_FIELD3TYPE  int
5713 	#include "scip/sorttpl.c" /*lint !e451*/
5714 	
5715 	
5716 	/* SCIPsortRealRealRealInt(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
5717 	#define SORTTPL_NAMEEXT     RealRealRealInt
5718 	#define SORTTPL_KEYTYPE     SCIP_Real
5719 	#define SORTTPL_FIELD1TYPE  SCIP_Real
5720 	#define SORTTPL_FIELD2TYPE  SCIP_Real
5721 	#define SORTTPL_FIELD3TYPE  int
5722 	#include "scip/sorttpl.c" /*lint !e451*/
5723 	
5724 	
5725 	/* SCIPsortRealRealRealPtr(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
5726 	#define SORTTPL_NAMEEXT     RealRealRealPtr
5727 	#define SORTTPL_KEYTYPE     SCIP_Real
5728 	#define SORTTPL_FIELD1TYPE  SCIP_Real
5729 	#define SORTTPL_FIELD2TYPE  SCIP_Real
5730 	#define SORTTPL_FIELD3TYPE  void*
5731 	#include "scip/sorttpl.c" /*lint !e451*/
5732 	
5733 	
5734 	/* SCIPsortRealPtrPtrInt(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
5735 	#define SORTTPL_NAMEEXT     RealPtrPtrInt
5736 	#define SORTTPL_KEYTYPE     SCIP_Real
5737 	#define SORTTPL_FIELD1TYPE  void*
5738 	#define SORTTPL_FIELD2TYPE  void*
5739 	#define SORTTPL_FIELD3TYPE  int
5740 	#include "scip/sorttpl.c" /*lint !e451*/
5741 	
5742 	
5743 	/* SCIPsortRealPtrPtrIntInt(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
5744 	#define SORTTPL_NAMEEXT     RealPtrPtrIntInt
5745 	#define SORTTPL_KEYTYPE     SCIP_Real
5746 	#define SORTTPL_FIELD1TYPE  void*
5747 	#define SORTTPL_FIELD2TYPE  void*
5748 	#define SORTTPL_FIELD3TYPE  int
5749 	#define SORTTPL_FIELD4TYPE  int
5750 	#include "scip/sorttpl.c" /*lint !e451*/
5751 	
5752 	
5753 	/* SCIPsortRealRealRealBoolPtr(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
5754 	#define SORTTPL_NAMEEXT     RealRealRealBoolPtr
5755 	#define SORTTPL_KEYTYPE     SCIP_Real
5756 	#define SORTTPL_FIELD1TYPE  SCIP_Real
5757 	#define SORTTPL_FIELD2TYPE  SCIP_Real
5758 	#define SORTTPL_FIELD3TYPE  SCIP_Bool
5759 	#define SORTTPL_FIELD4TYPE  void*
5760 	#include "scip/sorttpl.c" /*lint !e451*/
5761 	
5762 	
5763 	/* SCIPsortRealRealRealBoolBoolPtr(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
5764 	#define SORTTPL_NAMEEXT     RealRealRealBoolBoolPtr
5765 	#define SORTTPL_KEYTYPE     SCIP_Real
5766 	#define SORTTPL_FIELD1TYPE  SCIP_Real
5767 	#define SORTTPL_FIELD2TYPE  SCIP_Real
5768 	#define SORTTPL_FIELD3TYPE  SCIP_Bool
5769 	#define SORTTPL_FIELD4TYPE  SCIP_Bool
5770 	#define SORTTPL_FIELD5TYPE  void*
5771 	#include "scip/sorttpl.c" /*lint !e451*/
5772 	
5773 	
5774 	/* SCIPsortInt(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
5775 	#define SORTTPL_NAMEEXT     Int
5776 	#define SORTTPL_KEYTYPE     int
5777 	#include "scip/sorttpl.c" /*lint !e451*/
5778 	
5779 	
5780 	/* SCIPsortIntInt(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
5781 	#define SORTTPL_NAMEEXT     IntInt
5782 	#define SORTTPL_KEYTYPE     int
5783 	#define SORTTPL_FIELD1TYPE  int
5784 	#include "scip/sorttpl.c" /*lint !e451*/
5785 	
5786 	
5787 	/* SCIPsortIntReal(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
5788 	#define SORTTPL_NAMEEXT     IntReal
5789 	#define SORTTPL_KEYTYPE     int
5790 	#define SORTTPL_FIELD1TYPE  SCIP_Real
5791 	#include "scip/sorttpl.c" /*lint !e451*/
5792 	
5793 	
5794 	/* SCIPsortIntPtr(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
5795 	#define SORTTPL_NAMEEXT     IntPtr
5796 	#define SORTTPL_KEYTYPE     int
5797 	#define SORTTPL_FIELD1TYPE  void*
5798 	#include "scip/sorttpl.c" /*lint !e451*/
5799 	
5800 	
5801 	/* SCIPsortIntIntInt(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
5802 	#define SORTTPL_NAMEEXT     IntIntInt
5803 	#define SORTTPL_KEYTYPE     int
5804 	#define SORTTPL_FIELD1TYPE  int
5805 	#define SORTTPL_FIELD2TYPE  int
5806 	#include "scip/sorttpl.c" /*lint !e451*/
5807 	
5808 	
5809 	/* SCIPsortIntIntLong(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
5810 	#define SORTTPL_NAMEEXT     IntIntLong
5811 	#define SORTTPL_KEYTYPE     int
5812 	#define SORTTPL_FIELD1TYPE  int
5813 	#define SORTTPL_FIELD2TYPE  SCIP_Longint
5814 	#include "scip/sorttpl.c" /*lint !e451*/
5815 	
5816 	/* SCIPsortIntRealLong(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
5817 	#define SORTTPL_NAMEEXT     IntRealLong
5818 	#define SORTTPL_KEYTYPE     int
5819 	#define SORTTPL_FIELD1TYPE  SCIP_Real
5820 	#define SORTTPL_FIELD2TYPE  SCIP_Longint
5821 	#include "scip/sorttpl.c" /*lint !e451*/
5822 	
5823 	
5824 	/* SCIPsortIntIntPtr(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
5825 	#define SORTTPL_NAMEEXT     IntIntPtr
5826 	#define SORTTPL_KEYTYPE     int
5827 	#define SORTTPL_FIELD1TYPE  int
5828 	#define SORTTPL_FIELD2TYPE  void*
5829 	#include "scip/sorttpl.c" /*lint !e451*/
5830 	
5831 	
5832 	/* SCIPsortIntIntReal(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
5833 	#define SORTTPL_NAMEEXT     IntIntReal
5834 	#define SORTTPL_KEYTYPE     int
5835 	#define SORTTPL_FIELD1TYPE  int
5836 	#define SORTTPL_FIELD2TYPE  SCIP_Real
5837 	#include "scip/sorttpl.c" /*lint !e451*/
5838 	
5839 	
5840 	/* SCIPsortIntPtrReal(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
5841 	#define SORTTPL_NAMEEXT     IntPtrReal
5842 	#define SORTTPL_KEYTYPE     int
5843 	#define SORTTPL_FIELD1TYPE  void*
5844 	#define SORTTPL_FIELD2TYPE  SCIP_Real
5845 	#include "scip/sorttpl.c" /*lint !e451*/
5846 	
5847 	
5848 	/* SCIPsortIntIntIntPtr(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
5849 	#define SORTTPL_NAMEEXT     IntIntIntPtr
5850 	#define SORTTPL_KEYTYPE     int
5851 	#define SORTTPL_FIELD1TYPE  int
5852 	#define SORTTPL_FIELD2TYPE  int
5853 	#define SORTTPL_FIELD3TYPE  void*
5854 	#include "scip/sorttpl.c" /*lint !e451*/
5855 	
5856 	/* SCIPsortIntIntIntReal(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
5857 	#define SORTTPL_NAMEEXT     IntIntIntReal
5858 	#define SORTTPL_KEYTYPE     int
5859 	#define SORTTPL_FIELD1TYPE  int
5860 	#define SORTTPL_FIELD2TYPE  int
5861 	#define SORTTPL_FIELD3TYPE  SCIP_Real
5862 	#include "scip/sorttpl.c" /*lint !e451*/
5863 	
5864 	/* SCIPsortIntPtrIntReal(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
5865 	#define SORTTPL_NAMEEXT     IntPtrIntReal
5866 	#define SORTTPL_KEYTYPE     int
5867 	#define SORTTPL_FIELD1TYPE  void*
5868 	#define SORTTPL_FIELD2TYPE  int
5869 	#define SORTTPL_FIELD3TYPE  SCIP_Real
5870 	#include "scip/sorttpl.c" /*lint !e451*/
5871 	
5872 	
5873 	/* SCIPsortLong(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
5874 	#define SORTTPL_NAMEEXT     Long
5875 	#define SORTTPL_KEYTYPE     SCIP_Longint
5876 	#include "scip/sorttpl.c" /*lint !e451*/
5877 	
5878 	
5879 	/* SCIPsortLongPtr(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
5880 	#define SORTTPL_NAMEEXT     LongPtr
5881 	#define SORTTPL_KEYTYPE     SCIP_Longint
5882 	#define SORTTPL_FIELD1TYPE  void*
5883 	#include "scip/sorttpl.c" /*lint !e451*/
5884 	
5885 	
5886 	/* SCIPsortLongPtrInt(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
5887 	#define SORTTPL_NAMEEXT     LongPtrInt
5888 	#define SORTTPL_KEYTYPE     SCIP_Longint
5889 	#define SORTTPL_FIELD1TYPE  void*
5890 	#define SORTTPL_FIELD2TYPE  int
5891 	#include "scip/sorttpl.c" /*lint !e451*/
5892 	
5893 	
5894 	/* SCIPsortLongPtrRealBool(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
5895 	#define SORTTPL_NAMEEXT     LongPtrRealBool
5896 	#define SORTTPL_KEYTYPE     SCIP_Longint
5897 	#define SORTTPL_FIELD1TYPE  void*
5898 	#define SORTTPL_FIELD2TYPE  SCIP_Real
5899 	#define SORTTPL_FIELD3TYPE  SCIP_Bool
5900 	#include "scip/sorttpl.c" /*lint !e451*/
5901 	
5902 	
5903 	/* SCIPsortLongPtrRealRealBool(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
5904 	#define SORTTPL_NAMEEXT     LongPtrRealRealBool
5905 	#define SORTTPL_KEYTYPE     SCIP_Longint
5906 	#define SORTTPL_FIELD1TYPE  void*
5907 	#define SORTTPL_FIELD2TYPE  SCIP_Real
5908 	#define SORTTPL_FIELD3TYPE  SCIP_Real
5909 	#define SORTTPL_FIELD4TYPE  SCIP_Bool
5910 	#include "scip/sorttpl.c" /*lint !e451*/
5911 	
5912 	
5913 	/* SCIPsortLongPtrRealRealIntBool(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
5914 	#define SORTTPL_NAMEEXT     LongPtrRealRealIntBool
5915 	#define SORTTPL_KEYTYPE     SCIP_Longint
5916 	#define SORTTPL_FIELD1TYPE  void*
5917 	#define SORTTPL_FIELD2TYPE  SCIP_Real
5918 	#define SORTTPL_FIELD3TYPE  SCIP_Real
5919 	#define SORTTPL_FIELD4TYPE  int
5920 	#define SORTTPL_FIELD5TYPE  SCIP_Bool
5921 	#include "scip/sorttpl.c" /*lint !e451*/
5922 	
5923 	
5924 	/* SCIPsortLongPtrPtrInt(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
5925 	#define SORTTPL_NAMEEXT     LongPtrPtrInt
5926 	#define SORTTPL_KEYTYPE     SCIP_Longint
5927 	#define SORTTPL_FIELD1TYPE  void*
5928 	#define SORTTPL_FIELD2TYPE  void*
5929 	#define SORTTPL_FIELD3TYPE  int
5930 	#include "scip/sorttpl.c" /*lint !e451*/
5931 	
5932 	
5933 	/* SCIPsortLongPtrPtrIntInt(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
5934 	#define SORTTPL_NAMEEXT     LongPtrPtrIntInt
5935 	#define SORTTPL_KEYTYPE     SCIP_Longint
5936 	#define SORTTPL_FIELD1TYPE  void*
5937 	#define SORTTPL_FIELD2TYPE  void*
5938 	#define SORTTPL_FIELD3TYPE  int
5939 	#define SORTTPL_FIELD4TYPE  int
5940 	#include "scip/sorttpl.c" /*lint !e451*/
5941 	
5942 	
5943 	/* SCIPsortLongPtrPtrBoolInt(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
5944 	#define SORTTPL_NAMEEXT     LongPtrPtrBoolInt
5945 	#define SORTTPL_KEYTYPE     SCIP_Longint
5946 	#define SORTTPL_FIELD1TYPE  void*
5947 	#define SORTTPL_FIELD2TYPE  void*
5948 	#define SORTTPL_FIELD3TYPE  SCIP_Bool
5949 	#define SORTTPL_FIELD4TYPE  int
5950 	#include "scip/sorttpl.c" /*lint !e451*/
5951 	
5952 	
5953 	/* SCIPsortPtrIntIntBoolBool(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
5954 	#define SORTTPL_NAMEEXT     PtrIntIntBoolBool
5955 	#define SORTTPL_KEYTYPE     void*
5956 	#define SORTTPL_FIELD1TYPE  int
5957 	#define SORTTPL_FIELD2TYPE  int
5958 	#define SORTTPL_FIELD3TYPE  SCIP_Bool
5959 	#define SORTTPL_FIELD4TYPE  SCIP_Bool
5960 	#define SORTTPL_PTRCOMP
5961 	#include "scip/sorttpl.c" /*lint !e451*/
5962 	
5963 	
5964 	/* SCIPsortIntPtrIntIntBoolBool(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
5965 	#define SORTTPL_NAMEEXT     IntPtrIntIntBoolBool
5966 	#define SORTTPL_KEYTYPE     int
5967 	#define SORTTPL_FIELD1TYPE  void*
5968 	#define SORTTPL_FIELD2TYPE  int
5969 	#define SORTTPL_FIELD3TYPE  int
5970 	#define SORTTPL_FIELD4TYPE  SCIP_Bool
5971 	#define SORTTPL_FIELD5TYPE  SCIP_Bool
5972 	#include "scip/sorttpl.c" /*lint !e451*/
5973 	
5974 	
5975 	/* now all downwards-sorting methods */
5976 	
5977 	
5978 	/** sort an indexed element set in non-increasing order, resulting in a permutation index array */
5979 	void SCIPsortDown(
5980 	   int*                  perm,               /**< pointer to store the resulting permutation */
5981 	   SCIP_DECL_SORTINDCOMP((*indcomp)),        /**< data element comparator */
5982 	   void*                 dataptr,            /**< pointer to data field that is given to the external compare method */
5983 	   int                   len                 /**< number of elements to be sorted (valid index range) */
5984 	   )
5985 	{
5986 	   int pos;
5987 	
5988 	   assert(indcomp != NULL);
5989 	   assert(len == 0 || perm != NULL);
5990 	
5991 	   /* create identity permutation */
5992 	   for( pos = 0; pos < len; ++pos )
5993 	      perm[pos] = pos;
5994 	
5995 	   SCIPsortDownInd(perm, indcomp, dataptr, len);
5996 	}
5997 	
5998 	
5999 	/* SCIPsortDownInd(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
6000 	#define SORTTPL_NAMEEXT     DownInd
6001 	#define SORTTPL_KEYTYPE     int
6002 	#define SORTTPL_INDCOMP
6003 	#define SORTTPL_BACKWARDS
6004 	#include "scip/sorttpl.c" /*lint !e451*/
6005 	
6006 	
6007 	/* SCIPsortDownPtr(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
6008 	#define SORTTPL_NAMEEXT     DownPtr
6009 	#define SORTTPL_KEYTYPE     void*
6010 	#define SORTTPL_PTRCOMP
6011 	#define SORTTPL_BACKWARDS
6012 	#include "scip/sorttpl.c" /*lint !e451*/
6013 	
6014 	
6015 	/* SCIPsortDownPtrPtr(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
6016 	#define SORTTPL_NAMEEXT     DownPtrPtr
6017 	#define SORTTPL_KEYTYPE     void*
6018 	#define SORTTPL_FIELD1TYPE  void*
6019 	#define SORTTPL_PTRCOMP
6020 	#define SORTTPL_BACKWARDS
6021 	#include "scip/sorttpl.c" /*lint !e451*/
6022 	
6023 	
6024 	/* SCIPsortDownPtrReal(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
6025 	#define SORTTPL_NAMEEXT     DownPtrReal
6026 	#define SORTTPL_KEYTYPE     void*
6027 	#define SORTTPL_FIELD1TYPE  SCIP_Real
6028 	#define SORTTPL_PTRCOMP
6029 	#define SORTTPL_BACKWARDS
6030 	#include "scip/sorttpl.c" /*lint !e451*/
6031 	
6032 	
6033 	/* SCIPsortDownPtrInt(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
6034 	#define SORTTPL_NAMEEXT     DownPtrInt
6035 	#define SORTTPL_KEYTYPE     void*
6036 	#define SORTTPL_FIELD1TYPE  int
6037 	#define SORTTPL_PTRCOMP
6038 	#define SORTTPL_BACKWARDS
6039 	#include "scip/sorttpl.c" /*lint !e451*/
6040 	
6041 	/* SCIPsortDownPtrBool(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
6042 	#define SORTTPL_NAMEEXT     DownPtrBool
6043 	#define SORTTPL_KEYTYPE     void*
6044 	#define SORTTPL_FIELD1TYPE  SCIP_Bool
6045 	#define SORTTPL_PTRCOMP
6046 	#define SORTTPL_BACKWARDS
6047 	#include "scip/sorttpl.c" /*lint !e451*/
6048 	
6049 	/* SCIPsortDownPtrIntInt(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
6050 	#define SORTTPL_NAMEEXT     DownPtrIntInt
6051 	#define SORTTPL_KEYTYPE     void*
6052 	#define SORTTPL_FIELD1TYPE  int
6053 	#define SORTTPL_FIELD2TYPE  int
6054 	#define SORTTPL_PTRCOMP
6055 	#define SORTTPL_BACKWARDS
6056 	#include "scip/sorttpl.c" /*lint !e451*/
6057 	
6058 	
6059 	/* SCIPsortDownPtrRealInt(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
6060 	#define SORTTPL_NAMEEXT     DownPtrRealInt
6061 	#define SORTTPL_KEYTYPE     void*
6062 	#define SORTTPL_FIELD1TYPE  SCIP_Real
6063 	#define SORTTPL_FIELD2TYPE  int
6064 	#define SORTTPL_PTRCOMP
6065 	#define SORTTPL_BACKWARDS
6066 	#include "scip/sorttpl.c" /*lint !e451*/
6067 	
6068 	
6069 	/* SCIPsortDownPtrRealBool(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
6070 	#define SORTTPL_NAMEEXT     DownPtrRealBool
6071 	#define SORTTPL_KEYTYPE     void*
6072 	#define SORTTPL_FIELD1TYPE  SCIP_Real
6073 	#define SORTTPL_FIELD2TYPE  SCIP_Bool
6074 	#define SORTTPL_PTRCOMP
6075 	#define SORTTPL_BACKWARDS
6076 	#include "scip/sorttpl.c" /*lint !e451*/
6077 	
6078 	
6079 	/* SCIPsortDownPtrPtrInt(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
6080 	#define SORTTPL_NAMEEXT     DownPtrPtrInt
6081 	#define SORTTPL_KEYTYPE     void*
6082 	#define SORTTPL_FIELD1TYPE  void*
6083 	#define SORTTPL_FIELD2TYPE  int
6084 	#define SORTTPL_PTRCOMP
6085 	#define SORTTPL_BACKWARDS
6086 	#include "scip/sorttpl.c" /*lint !e451*/
6087 	
6088 	
6089 	/* SCIPsortDownPtrPtrReal(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
6090 	#define SORTTPL_NAMEEXT     DownPtrPtrReal
6091 	#define SORTTPL_KEYTYPE     void*
6092 	#define SORTTPL_FIELD1TYPE  void*
6093 	#define SORTTPL_FIELD2TYPE  SCIP_Real
6094 	#define SORTTPL_PTRCOMP
6095 	#define SORTTPL_BACKWARDS
6096 	#include "scip/sorttpl.c" /*lint !e451*/
6097 	
6098 	
6099 	/* SCIPsortDownPtrRealIntInt(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
6100 	#define SORTTPL_NAMEEXT     DownPtrRealIntInt
6101 	#define SORTTPL_KEYTYPE     void*
6102 	#define SORTTPL_FIELD1TYPE  SCIP_Real
6103 	#define SORTTPL_FIELD2TYPE  int
6104 	#define SORTTPL_FIELD3TYPE  int
6105 	#define SORTTPL_PTRCOMP
6106 	#define SORTTPL_BACKWARDS
6107 	#include "scip/sorttpl.c" /*lint !e451*/
6108 	
6109 	
6110 	/* SCIPsortDownPtrPtrIntInt(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
6111 	#define SORTTPL_NAMEEXT     DownPtrPtrIntInt
6112 	#define SORTTPL_KEYTYPE     void*
6113 	#define SORTTPL_FIELD1TYPE  void*
6114 	#define SORTTPL_FIELD2TYPE  int
6115 	#define SORTTPL_FIELD3TYPE  int
6116 	#define SORTTPL_PTRCOMP
6117 	#define SORTTPL_BACKWARDS
6118 	#include "scip/sorttpl.c" /*lint !e451*/
6119 	
6120 	
6121 	/* SCIPsortDownPtrPtrRealInt(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
6122 	#define SORTTPL_NAMEEXT     DownPtrPtrRealInt
6123 	#define SORTTPL_KEYTYPE     void*
6124 	#define SORTTPL_FIELD1TYPE  void*
6125 	#define SORTTPL_FIELD2TYPE  SCIP_Real
6126 	#define SORTTPL_FIELD3TYPE  int
6127 	#define SORTTPL_PTRCOMP
6128 	#define SORTTPL_BACKWARDS
6129 	#include "scip/sorttpl.c" /*lint !e451*/
6130 	
6131 	
6132 	/* SCIPsortDownPtrPtrRealBool(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
6133 	#define SORTTPL_NAMEEXT     DownPtrPtrRealBool
6134 	#define SORTTPL_KEYTYPE     void*
6135 	#define SORTTPL_FIELD1TYPE  void*
6136 	#define SORTTPL_FIELD2TYPE  SCIP_Real
6137 	#define SORTTPL_FIELD3TYPE  SCIP_Bool
6138 	#define SORTTPL_PTRCOMP
6139 	#define SORTTPL_BACKWARDS
6140 	#include "scip/sorttpl.c" /*lint !e451*/
6141 	
6142 	
6143 	/* SCIPsortDownPtrPtrLongInt(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
6144 	#define SORTTPL_NAMEEXT     DownPtrPtrLongInt
6145 	#define SORTTPL_KEYTYPE     void*
6146 	#define SORTTPL_FIELD1TYPE  void*
6147 	#define SORTTPL_FIELD2TYPE  SCIP_Longint
6148 	#define SORTTPL_FIELD3TYPE  int
6149 	#define SORTTPL_PTRCOMP
6150 	#define SORTTPL_BACKWARDS
6151 	#include "scip/sorttpl.c" /*lint !e451*/
6152 	
6153 	
6154 	/* SCIPsortDownPtrPtrLongIntInt(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
6155 	#define SORTTPL_NAMEEXT     DownPtrPtrLongIntInt
6156 	#define SORTTPL_KEYTYPE     void*
6157 	#define SORTTPL_FIELD1TYPE  void*
6158 	#define SORTTPL_FIELD2TYPE  SCIP_Longint
6159 	#define SORTTPL_FIELD3TYPE  int
6160 	#define SORTTPL_FIELD4TYPE  int
6161 	#define SORTTPL_PTRCOMP
6162 	#define SORTTPL_BACKWARDS
6163 	#include "scip/sorttpl.c" /*lint !e451*/
6164 	
6165 	
6166 	/* SCIPsortDownReal(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
6167 	#define SORTTPL_NAMEEXT     DownReal
6168 	#define SORTTPL_KEYTYPE     SCIP_Real
6169 	#define SORTTPL_BACKWARDS
6170 	#include "scip/sorttpl.c" /*lint !e451*/
6171 	
6172 	
6173 	/* SCIPsortDownRealBoolPtr(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
6174 	#define SORTTPL_NAMEEXT     DownRealBoolPtr
6175 	#define SORTTPL_KEYTYPE     SCIP_Real
6176 	#define SORTTPL_FIELD1TYPE  SCIP_Bool
6177 	#define SORTTPL_FIELD2TYPE  void*
6178 	#define SORTTPL_BACKWARDS
6179 	#include "scip/sorttpl.c" /*lint !e451*/
6180 	
6181 	
6182 	/* SCIPsortDownRealPtr(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
6183 	#define SORTTPL_NAMEEXT     DownRealPtr
6184 	#define SORTTPL_KEYTYPE     SCIP_Real
6185 	#define SORTTPL_FIELD1TYPE  void*
6186 	#define SORTTPL_BACKWARDS
6187 	#include "scip/sorttpl.c" /*lint !e451*/
6188 	
6189 	
6190 	/* SCIPsortDownRealInt(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
6191 	#define SORTTPL_NAMEEXT     DownRealInt
6192 	#define SORTTPL_KEYTYPE     SCIP_Real
6193 	#define SORTTPL_FIELD1TYPE  int
6194 	#define SORTTPL_BACKWARDS
6195 	#include "scip/sorttpl.c" /*lint !e451*/
6196 	
6197 	/* SCIPsortDownRealIntInt(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
6198 	#define SORTTPL_NAMEEXT     DownRealIntInt
6199 	#define SORTTPL_KEYTYPE     SCIP_Real
6200 	#define SORTTPL_FIELD1TYPE  int
6201 	#define SORTTPL_FIELD2TYPE  int
6202 	#define SORTTPL_BACKWARDS
6203 	#include "scip/sorttpl.c" /*lint !e451*/
6204 	
6205 	/* SCIPsortDownRealIntLong(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
6206 	#define SORTTPL_NAMEEXT     DownRealIntLong
6207 	#define SORTTPL_KEYTYPE     SCIP_Real
6208 	#define SORTTPL_FIELD1TYPE  int
6209 	#define SORTTPL_FIELD2TYPE  SCIP_Longint
6210 	#define SORTTPL_BACKWARDS
6211 	#include "scip/sorttpl.c" /*lint !e451*/
6212 	
6213 	
6214 	/* SCIPsortDownRealIntPtr(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
6215 	#define SORTTPL_NAMEEXT     DownRealIntPtr
6216 	#define SORTTPL_KEYTYPE     SCIP_Real
6217 	#define SORTTPL_FIELD1TYPE  int
6218 	#define SORTTPL_FIELD2TYPE  void*
6219 	#define SORTTPL_BACKWARDS
6220 	#include "scip/sorttpl.c" /*lint !e451*/
6221 	
6222 	
6223 	/* SCIPsortDownRealPtrPtr(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
6224 	#define SORTTPL_NAMEEXT     DownRealPtrPtr
6225 	#define SORTTPL_KEYTYPE     SCIP_Real
6226 	#define SORTTPL_FIELD1TYPE  void*
6227 	#define SORTTPL_FIELD2TYPE  void*
6228 	#define SORTTPL_BACKWARDS
6229 	#include "scip/sorttpl.c" /*lint !e451*/
6230 	
6231 	/* SCIPsortDownRealRealInt(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
6232 	#define SORTTPL_NAMEEXT     DownRealRealInt
6233 	#define SORTTPL_KEYTYPE     SCIP_Real
6234 	#define SORTTPL_FIELD1TYPE  SCIP_Real
6235 	#define SORTTPL_FIELD2TYPE  int
6236 	#define SORTTPL_BACKWARDS
6237 	#include "scip/sorttpl.c" /*lint !e451*/
6238 	
6239 	/* SCIPsortDownRealRealPtr(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
6240 	#define SORTTPL_NAMEEXT     DownRealRealPtr
6241 	#define SORTTPL_KEYTYPE     SCIP_Real
6242 	#define SORTTPL_FIELD1TYPE  SCIP_Real
6243 	#define SORTTPL_FIELD2TYPE  void*
6244 	#define SORTTPL_BACKWARDS
6245 	#include "scip/sorttpl.c" /*lint !e451*/
6246 	
6247 	/* SCIPsortDownRealRealPtrPtr(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
6248 	#define SORTTPL_NAMEEXT     DownRealRealPtrPtr
6249 	#define SORTTPL_KEYTYPE     SCIP_Real
6250 	#define SORTTPL_FIELD1TYPE  SCIP_Real
6251 	#define SORTTPL_FIELD2TYPE  void*
6252 	#define SORTTPL_FIELD3TYPE  void*
6253 	#define SORTTPL_BACKWARDS
6254 	#include "scip/sorttpl.c" /*lint !e451*/
6255 	
6256 	
6257 	/* SCIPsortDownRealLongRealInt(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
6258 	#define SORTTPL_NAMEEXT     DownRealLongRealInt
6259 	#define SORTTPL_KEYTYPE     SCIP_Real
6260 	#define SORTTPL_FIELD1TYPE  SCIP_Longint
6261 	#define SORTTPL_FIELD2TYPE  SCIP_Real
6262 	#define SORTTPL_FIELD3TYPE  int
6263 	#define SORTTPL_BACKWARDS
6264 	#include "scip/sorttpl.c" /*lint !e451*/
6265 	
6266 	
6267 	/* SCIPsortDownRealRealIntInt(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
6268 	#define SORTTPL_NAMEEXT     DownRealRealIntInt
6269 	#define SORTTPL_KEYTYPE     SCIP_Real
6270 	#define SORTTPL_FIELD1TYPE  SCIP_Real
6271 	#define SORTTPL_FIELD2TYPE  int
6272 	#define SORTTPL_FIELD3TYPE  int
6273 	#define SORTTPL_BACKWARDS
6274 	#include "scip/sorttpl.c" /*lint !e451*/
6275 	
6276 	
6277 	/* SCIPsortDownRealRealRealInt(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
6278 	#define SORTTPL_NAMEEXT     DownRealRealRealInt
6279 	#define SORTTPL_KEYTYPE     SCIP_Real
6280 	#define SORTTPL_FIELD1TYPE  SCIP_Real
6281 	#define SORTTPL_FIELD2TYPE  SCIP_Real
6282 	#define SORTTPL_FIELD3TYPE  int
6283 	#define SORTTPL_BACKWARDS
6284 	#include "scip/sorttpl.c" /*lint !e451*/
6285 	
6286 	
6287 	/* SCIPsortDownRealRealRealPtr(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
6288 	#define SORTTPL_NAMEEXT     DownRealRealRealPtr
6289 	#define SORTTPL_KEYTYPE     SCIP_Real
6290 	#define SORTTPL_FIELD1TYPE  SCIP_Real
6291 	#define SORTTPL_FIELD2TYPE  SCIP_Real
6292 	#define SORTTPL_FIELD3TYPE  void*
6293 	#define SORTTPL_BACKWARDS
6294 	#include "scip/sorttpl.c" /*lint !e451*/
6295 	
6296 	
6297 	/* SCIPsortDownRealPtrPtrInt(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
6298 	#define SORTTPL_NAMEEXT     DownRealPtrPtrInt
6299 	#define SORTTPL_KEYTYPE     SCIP_Real
6300 	#define SORTTPL_FIELD1TYPE  void*
6301 	#define SORTTPL_FIELD2TYPE  void*
6302 	#define SORTTPL_FIELD3TYPE  int
6303 	#define SORTTPL_BACKWARDS
6304 	#include "scip/sorttpl.c" /*lint !e451*/
6305 	
6306 	/* SCIPsortDownRealPtrPtrIntInt(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
6307 	#define SORTTPL_NAMEEXT     DownRealPtrPtrIntInt
6308 	#define SORTTPL_KEYTYPE     SCIP_Real
6309 	#define SORTTPL_FIELD1TYPE  void*
6310 	#define SORTTPL_FIELD2TYPE  void*
6311 	#define SORTTPL_FIELD3TYPE  int
6312 	#define SORTTPL_FIELD4TYPE  int
6313 	#define SORTTPL_BACKWARDS
6314 	#include "scip/sorttpl.c" /*lint !e451*/
6315 	
6316 	
6317 	/* SCIPsortDownRealRealRealBoolPtr(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
6318 	#define SORTTPL_NAMEEXT     DownRealRealRealBoolPtr
6319 	#define SORTTPL_KEYTYPE     SCIP_Real
6320 	#define SORTTPL_FIELD1TYPE  SCIP_Real
6321 	#define SORTTPL_FIELD2TYPE  SCIP_Real
6322 	#define SORTTPL_FIELD3TYPE  SCIP_Bool
6323 	#define SORTTPL_FIELD4TYPE  void*
6324 	#define SORTTPL_BACKWARDS
6325 	#include "scip/sorttpl.c" /*lint !e451*/
6326 	
6327 	
6328 	/* SCIPsortDownRealRealRealBoolBoolPtr(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
6329 	#define SORTTPL_NAMEEXT     DownRealRealRealBoolBoolPtr
6330 	#define SORTTPL_KEYTYPE     SCIP_Real
6331 	#define SORTTPL_FIELD1TYPE  SCIP_Real
6332 	#define SORTTPL_FIELD2TYPE  SCIP_Real
6333 	#define SORTTPL_FIELD3TYPE  SCIP_Bool
6334 	#define SORTTPL_FIELD4TYPE  SCIP_Bool
6335 	#define SORTTPL_FIELD5TYPE  void*
6336 	#include "scip/sorttpl.c" /*lint !e451*/
6337 	
6338 	
6339 	/* SCIPsortDownInt(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
6340 	#define SORTTPL_NAMEEXT     DownInt
6341 	#define SORTTPL_KEYTYPE     int
6342 	#define SORTTPL_BACKWARDS
6343 	#include "scip/sorttpl.c" /*lint !e451*/
6344 	
6345 	
6346 	/* SCIPsortDownIntInt(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
6347 	#define SORTTPL_NAMEEXT     DownIntInt
6348 	#define SORTTPL_KEYTYPE     int
6349 	#define SORTTPL_FIELD1TYPE  int
6350 	#define SORTTPL_BACKWARDS
6351 	#include "scip/sorttpl.c" /*lint !e451*/
6352 	
6353 	
6354 	/* SCIPsortDownIntIntReal(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
6355 	#define SORTTPL_NAMEEXT     DownIntIntReal
6356 	#define SORTTPL_KEYTYPE     int
6357 	#define SORTTPL_FIELD1TYPE  int
6358 	#define SORTTPL_FIELD2TYPE  SCIP_Real
6359 	#define SORTTPL_BACKWARDS
6360 	#include "scip/sorttpl.c" /*lint !e451*/
6361 	
6362 	
6363 	/* SCIPsortDownIntReal(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
6364 	#define SORTTPL_NAMEEXT     DownIntReal
6365 	#define SORTTPL_KEYTYPE     int
6366 	#define SORTTPL_FIELD1TYPE  SCIP_Real
6367 	#define SORTTPL_BACKWARDS
6368 	#include "scip/sorttpl.c" /*lint !e451*/
6369 	
6370 	
6371 	/* SCIPsortDownIntPtr(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
6372 	#define SORTTPL_NAMEEXT     DownIntPtr
6373 	#define SORTTPL_KEYTYPE     int
6374 	#define SORTTPL_FIELD1TYPE  void*
6375 	#define SORTTPL_BACKWARDS
6376 	#include "scip/sorttpl.c" /*lint !e451*/
6377 	
6378 	
6379 	/* SCIPsortDownIntIntInt(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
6380 	#define SORTTPL_NAMEEXT     DownIntIntInt
6381 	#define SORTTPL_KEYTYPE     int
6382 	#define SORTTPL_FIELD1TYPE  int
6383 	#define SORTTPL_FIELD2TYPE  int
6384 	#define SORTTPL_BACKWARDS
6385 	#include "scip/sorttpl.c" /*lint !e451*/
6386 	
6387 	
6388 	/* SCIPsortDownIntIntLong(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
6389 	#define SORTTPL_NAMEEXT     DownIntIntLong
6390 	#define SORTTPL_KEYTYPE     int
6391 	#define SORTTPL_FIELD1TYPE  int
6392 	#define SORTTPL_FIELD2TYPE  SCIP_Longint
6393 	#define SORTTPL_BACKWARDS
6394 	#include "scip/sorttpl.c" /*lint !e451*/
6395 	
6396 	
6397 	/* SCIPsortDownIntIntPtr(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
6398 	#define SORTTPL_NAMEEXT     DownIntIntPtr
6399 	#define SORTTPL_KEYTYPE     int
6400 	#define SORTTPL_FIELD1TYPE  int
6401 	#define SORTTPL_FIELD2TYPE  void*
6402 	#define SORTTPL_BACKWARDS
6403 	#include "scip/sorttpl.c" /*lint !e451*/
6404 	
6405 	
6406 	/* SCIPsortDownIntIntIntPtr(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
6407 	#define SORTTPL_NAMEEXT     DownIntIntIntPtr
6408 	#define SORTTPL_KEYTYPE     int
6409 	#define SORTTPL_FIELD1TYPE  int
6410 	#define SORTTPL_FIELD2TYPE  int
6411 	#define SORTTPL_FIELD3TYPE  void*
6412 	#define SORTTPL_BACKWARDS
6413 	#include "scip/sorttpl.c" /*lint !e451*/
6414 	
6415 	
6416 	/* SCIPsortDownIntPtrIntReal(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
6417 	#define SORTTPL_NAMEEXT     DownIntPtrIntReal
6418 	#define SORTTPL_KEYTYPE     int
6419 	#define SORTTPL_FIELD1TYPE  void*
6420 	#define SORTTPL_FIELD2TYPE  int
6421 	#define SORTTPL_FIELD3TYPE  SCIP_Real
6422 	#define SORTTPL_BACKWARDS
6423 	#include "scip/sorttpl.c" /*lint !e451*/
6424 	
6425 	
6426 	/* SCIPsortDownLong(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
6427 	#define SORTTPL_NAMEEXT     DownLong
6428 	#define SORTTPL_KEYTYPE     SCIP_Longint
6429 	#define SORTTPL_BACKWARDS
6430 	#include "scip/sorttpl.c" /*lint !e451*/
6431 	
6432 	
6433 	/* SCIPsortDownLongPtr(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
6434 	#define SORTTPL_NAMEEXT     DownLongPtr
6435 	#define SORTTPL_KEYTYPE     SCIP_Longint
6436 	#define SORTTPL_FIELD1TYPE  void*
6437 	#define SORTTPL_BACKWARDS
6438 	#include "scip/sorttpl.c" /*lint !e451*/
6439 	
6440 	
6441 	/* SCIPsortDownLongPtrInt(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
6442 	#define SORTTPL_NAMEEXT     DownLongPtrInt
6443 	#define SORTTPL_KEYTYPE     SCIP_Longint
6444 	#define SORTTPL_FIELD1TYPE  void*
6445 	#define SORTTPL_FIELD2TYPE  int
6446 	#define SORTTPL_BACKWARDS
6447 	#include "scip/sorttpl.c" /*lint !e451*/
6448 	
6449 	
6450 	/* SCIPsortDownLongPtrRealBool(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
6451 	#define SORTTPL_NAMEEXT     DownLongPtrRealBool
6452 	#define SORTTPL_KEYTYPE     SCIP_Longint
6453 	#define SORTTPL_FIELD1TYPE  void*
6454 	#define SORTTPL_FIELD2TYPE  SCIP_Real
6455 	#define SORTTPL_FIELD3TYPE  SCIP_Bool
6456 	#define SORTTPL_BACKWARDS
6457 	#include "scip/sorttpl.c" /*lint !e451*/
6458 	
6459 	
6460 	/* SCIPsortDownLongPtrRealRealBool(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
6461 	#define SORTTPL_NAMEEXT     DownLongPtrRealRealBool
6462 	#define SORTTPL_KEYTYPE     SCIP_Longint
6463 	#define SORTTPL_FIELD1TYPE  void*
6464 	#define SORTTPL_FIELD2TYPE  SCIP_Real
6465 	#define SORTTPL_FIELD3TYPE  SCIP_Real
6466 	#define SORTTPL_FIELD4TYPE  SCIP_Bool
6467 	#define SORTTPL_BACKWARDS
6468 	#include "scip/sorttpl.c" /*lint !e451*/
6469 	
6470 	
6471 	/* SCIPsortLongPtrRealRealIntBool(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
6472 	#define SORTTPL_NAMEEXT     DownLongPtrRealRealIntBool
6473 	#define SORTTPL_KEYTYPE     SCIP_Longint
6474 	#define SORTTPL_FIELD1TYPE  void*
6475 	#define SORTTPL_FIELD2TYPE  SCIP_Real
6476 	#define SORTTPL_FIELD3TYPE  SCIP_Real
6477 	#define SORTTPL_FIELD4TYPE  int
6478 	#define SORTTPL_FIELD5TYPE  SCIP_Bool
6479 	#define SORTTPL_BACKWARDS
6480 	#include "scip/sorttpl.c" /*lint !e451*/
6481 	
6482 	
6483 	/* SCIPsortDownLongPtrPtrInt(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
6484 	#define SORTTPL_NAMEEXT     DownLongPtrPtrInt
6485 	#define SORTTPL_KEYTYPE     SCIP_Longint
6486 	#define SORTTPL_FIELD1TYPE  void*
6487 	#define SORTTPL_FIELD2TYPE  void*
6488 	#define SORTTPL_FIELD3TYPE  int
6489 	#define SORTTPL_BACKWARDS
6490 	#include "scip/sorttpl.c" /*lint !e451*/
6491 	
6492 	
6493 	/* SCIPsortDownLongPtrPtrIntInt(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
6494 	#define SORTTPL_NAMEEXT     DownLongPtrPtrIntInt
6495 	#define SORTTPL_KEYTYPE     SCIP_Longint
6496 	#define SORTTPL_FIELD1TYPE  void*
6497 	#define SORTTPL_FIELD2TYPE  void*
6498 	#define SORTTPL_FIELD3TYPE  int
6499 	#define SORTTPL_FIELD4TYPE  int
6500 	#define SORTTPL_BACKWARDS
6501 	#include "scip/sorttpl.c" /*lint !e451*/
6502 	
6503 	
6504 	/* SCIPsortDownLongPtrPtrBoolInt(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
6505 	#define SORTTPL_NAMEEXT     DownLongPtrPtrBoolInt
6506 	#define SORTTPL_KEYTYPE     SCIP_Longint
6507 	#define SORTTPL_FIELD1TYPE  void*
6508 	#define SORTTPL_FIELD2TYPE  void*
6509 	#define SORTTPL_FIELD3TYPE  SCIP_Bool
6510 	#define SORTTPL_FIELD4TYPE  int
6511 	#define SORTTPL_BACKWARDS
6512 	#include "scip/sorttpl.c" /*lint !e451*/
6513 	
6514 	
6515 	/* SCIPsortDownPtrIntIntBoolBool(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
6516 	#define SORTTPL_NAMEEXT     DownPtrIntIntBoolBool
6517 	#define SORTTPL_KEYTYPE     void*
6518 	#define SORTTPL_FIELD1TYPE  int
6519 	#define SORTTPL_FIELD2TYPE  int
6520 	#define SORTTPL_FIELD3TYPE  SCIP_Bool
6521 	#define SORTTPL_FIELD4TYPE  SCIP_Bool
6522 	#define SORTTPL_PTRCOMP
6523 	#define SORTTPL_BACKWARDS
6524 	#include "scip/sorttpl.c" /*lint !e451*/
6525 	
6526 	
6527 	/* SCIPsortDownIntPtrIntIntBoolBool(), SCIPsortedvecInsert...(), SCIPsortedvecDelPos...(), SCIPsortedvecFind...() via sort template */
6528 	#define SORTTPL_NAMEEXT     DownIntPtrIntIntBoolBool
6529 	#define SORTTPL_KEYTYPE     int
6530 	#define SORTTPL_FIELD1TYPE  void*
6531 	#define SORTTPL_FIELD2TYPE  int
6532 	#define SORTTPL_FIELD3TYPE  int
6533 	#define SORTTPL_FIELD4TYPE  SCIP_Bool
6534 	#define SORTTPL_FIELD5TYPE  SCIP_Bool
6535 	#define SORTTPL_BACKWARDS
6536 	#include "scip/sorttpl.c" /*lint !e451*/
6537 	
6538 	/*
6539 	 * Resulting activity
6540 	 */
6541 	
6542 	/** create a resource activity */
6543 	SCIP_RETCODE SCIPactivityCreate(
6544 	   SCIP_RESOURCEACTIVITY** activity,         /**< pointer to store the resource activity */
6545 	   SCIP_VAR*             var,                /**< start time variable of the activity */
6546 	   int                   duration,           /**< duration of the activity */
6547 	   int                   demand              /**< demand of the activity */
6548 	   )
6549 	{
6550 	   assert(activity != NULL);
6551 	
6552 	   SCIP_ALLOC( BMSallocMemory(activity) );
6553 	
6554 	   (*activity)->var = var;
6555 	   (*activity)->duration = duration;
6556 	   (*activity)->demand = demand;
6557 	
6558 	   return SCIP_OKAY;
6559 	}
6560 	
6561 	/** frees a resource activity */
6562 	void SCIPactivityFree(
6563 	   SCIP_RESOURCEACTIVITY** activity          /**< pointer to the resource activity */
6564 	   )
6565 	{
6566 	   assert(activity != NULL);
6567 	   assert(*activity != NULL);
6568 	
6569 	   BMSfreeMemory(activity);
6570 	}
6571 	
6572 	/* some simple variable functions implemented as defines */
6573 	
6574 	#ifndef NDEBUG
6575 	
6576 	/* In debug mode, the following methods are implemented as function calls to ensure
6577 	 * type validity.
6578 	 * In optimized mode, the methods are implemented as defines to improve performance.
6579 	 * However, we want to have them in the library anyways, so we have to undef the defines.
6580 	 */
6581 	
6582 	#undef SCIPactivityGetVar
6583 	#undef SCIPactivityGetDuration
6584 	#undef SCIPactivityGetDemand
6585 	#undef SCIPactivityGetEnergy
6586 	
6587 	/** returns the start time variable of the resource activity */
6588 	SCIP_VAR* SCIPactivityGetVar(
6589 	   SCIP_RESOURCEACTIVITY* activity           /**< resource activity */
6590 	   )
6591 	{
6592 	   assert(activity != NULL);
6593 	
6594 	   return activity->var;
6595 	}
6596 	
6597 	/** returns the duration of the resource activity */
6598 	int SCIPactivityGetDuration(
6599 	   SCIP_RESOURCEACTIVITY* activity           /**< resource activity */
6600 	   )
6601 	{
6602 	   assert(activity != NULL);
6603 	
6604 	   return activity->duration;
6605 	}
6606 	
6607 	/** returns the demand of the resource activity */
6608 	int SCIPactivityGetDemand(
6609 	   SCIP_RESOURCEACTIVITY* activity           /**< resource activity */
6610 	   )
6611 	{
6612 	   assert(activity != NULL);
6613 	
6614 	   return activity->demand;
6615 	}
6616 	
6617 	/** returns the energy of the resource activity */
6618 	int SCIPactivityGetEnergy(
6619 	   SCIP_RESOURCEACTIVITY* activity           /**< resource activity */
6620 	   )
6621 	{
6622 	   assert(activity != NULL);
6623 	
6624 	   return activity->duration * activity->demand ;
6625 	}
6626 	
6627 	#endif
6628 	
6629 	/*
6630 	 * Resource Profile
6631 	 */
6632 	
6633 	/** helper method to create a profile */
6634 	static
6635 	SCIP_RETCODE doProfileCreate(
6636 	   SCIP_PROFILE**        profile,            /**< pointer to store the resource profile */
6637 	   int                   capacity            /**< resource capacity */
6638 	   )
6639 	{
6640 	   SCIP_ALLOC( BMSallocMemory(profile) );
6641 	   BMSclearMemory(*profile);
6642 	
6643 	   (*profile)->arraysize = 10;
6644 	   SCIP_ALLOC( BMSallocMemoryArray(&(*profile)->timepoints, (*profile)->arraysize) );
6645 	   SCIP_ALLOC( BMSallocMemoryArray(&(*profile)->loads, (*profile)->arraysize) );
6646 	
6647 	   /* setup resource profile for use */
6648 	   (*profile)->ntimepoints = 1;
6649 	   (*profile)->timepoints[0] = 0;
6650 	   (*profile)->loads[0] = 0;
6651 	   (*profile)->capacity = capacity;
6652 	
6653 	   return SCIP_OKAY;
6654 	}
6655 	
6656 	/** creates resource profile */
6657 	SCIP_RETCODE SCIPprofileCreate(
6658 	   SCIP_PROFILE**        profile,            /**< pointer to store the resource profile */
6659 	   int                   capacity            /**< resource capacity */
6660 	   )
6661 	{
6662 	   assert(profile != NULL);
6663 	   assert(capacity > 0);
6664 	
6665 	   SCIP_CALL_FINALLY( doProfileCreate(profile, capacity), SCIPprofileFree(profile) );
6666 	
6667 	   return SCIP_OKAY;
6668 	}
6669 	
6670 	/** frees given resource profile */
6671 	void SCIPprofileFree(
6672 	   SCIP_PROFILE**        profile             /**< pointer to the resource profile */
6673 	   )
6674 	{
6675 	   assert(profile != NULL);
6676 	
6677 	   /* free resource profile */
6678 	   if( *profile != NULL )
6679 	   {
6680 	      BMSfreeMemoryArrayNull(&(*profile)->loads);
6681 	      BMSfreeMemoryArrayNull(&(*profile)->timepoints);
6682 	      BMSfreeMemory(profile);
6683 	   }
6684 	}
6685 	
6686 	/** output of the given resource profile */
6687 	void SCIPprofilePrint(
6688 	   SCIP_PROFILE*         profile,            /**< resource profile to output */
6689 	   SCIP_MESSAGEHDLR*     messagehdlr,        /**< message handler */
6690 	   FILE*                 file                /**< output file (or NULL for standard output) */
6691 	   )
6692 	{
6693 	   int t;
6694 	
6695 	   SCIPmessageFPrintInfo(messagehdlr, file, "Profile <%p> (capacity %d) --> ", (void*)profile, profile->capacity);
6696 	
6697 	   for( t = 0; t < profile->ntimepoints; ++t )
6698 	   {
6699 	      if( t == 0 )
6700 	         SCIPmessageFPrintInfo(messagehdlr, file, "%d:(%d,%d)", t, profile->timepoints[t], profile->loads[t]);
6701 	      else
6702 	         SCIPmessageFPrintInfo(messagehdlr, file, ", %d:(%d,%d)", t, profile->timepoints[t], profile->loads[t]);
6703 	   }
6704 	
6705 	   SCIPmessageFPrintInfo(messagehdlr, file,"\n");
6706 	}
6707 	
6708 	/** returns the capacity of the resource profile */
6709 	int SCIPprofileGetCapacity(
6710 	   SCIP_PROFILE*         profile             /**< resource profile to use */
6711 	   )
6712 	{
6713 	   assert(profile != NULL);
6714 	
6715 	   return profile->capacity;
6716 	}
6717 	
6718 	/** returns the number time points of the resource profile */
6719 	int SCIPprofileGetNTimepoints(
6720 	   SCIP_PROFILE*         profile             /**< resource profile to use */
6721 	   )
6722 	{
6723 	   assert(profile != NULL);
6724 	
6725 	   return profile->ntimepoints;
6726 	}
6727 	
6728 	/** returns the time points of the resource profile */
6729 	int* SCIPprofileGetTimepoints(
6730 	   SCIP_PROFILE*         profile             /**< resource profile to use */
6731 	   )
6732 	{
6733 	   assert(profile != NULL);
6734 	
6735 	   return profile->timepoints;
6736 	}
6737 	
6738 	/** returns the loads of the resource profile */
6739 	int* SCIPprofileGetLoads(
6740 	   SCIP_PROFILE*         profile             /**< resource profile to use */
6741 	   )
6742 	{
6743 	   assert(profile != NULL);
6744 	
6745 	   return profile->loads;
6746 	}
6747 	
6748 	/** returns the time point for given position of the resource profile */
6749 	int SCIPprofileGetTime(
6750 	   SCIP_PROFILE*         profile,            /**< resource profile to use */
6751 	   int                   pos                 /**< position */
6752 	   )
6753 	{
6754 	   assert(profile != NULL);
6755 	   assert(pos >= 0 && pos < profile->ntimepoints);
6756 	
6757 	   return profile->timepoints[pos];
6758 	}
6759 	
6760 	/** returns the loads of the resource profile at the given position */
6761 	int SCIPprofileGetLoad(
6762 	   SCIP_PROFILE*         profile,            /**< resource profile */
6763 	   int                   pos                 /**< position */
6764 	   )
6765 	{
6766 	   assert(profile != NULL);
6767 	   assert(pos >= 0 && pos < profile->ntimepoints);
6768 	
6769 	   return profile->loads[pos];
6770 	}
6771 	
6772 	/** returns if the given time point exists in the resource profile and stores the position of the given time point if it
6773 	 *  exists; otherwise the position of the next smaller existing time point is stored
6774 	 */
6775 	SCIP_Bool SCIPprofileFindLeft(
6776 	   SCIP_PROFILE*         profile,            /**< resource profile to search */
6777 	   int                   timepoint,          /**< time point to search for */
6778 	   int*                  pos                 /**< pointer to store the position */
6779 	   )
6780 	{
6781 	   assert(profile != NULL);
6782 	   assert(timepoint >= 0);
6783 	   assert(profile->ntimepoints > 0);
6784 	   assert(profile->timepoints[0] == 0);
6785 	
6786 	   /* find the position of time point in the time points array via binary search */
6787 	   if( SCIPsortedvecFindInt(profile->timepoints, timepoint, profile->ntimepoints, pos) )
6788 	      return TRUE;
6789 	
6790 	   assert(*pos > 0);
6791 	   (*pos)--;
6792 	
6793 	   return FALSE;
6794 	}
6795 	
6796 	/* ensures that resource profile arrays is big enough */
6797 	static
6798 	SCIP_RETCODE ensureProfileSize(
6799 	   SCIP_PROFILE*         profile,            /**< resource profile to insert the time point */
6800 	   int                   neededsize          /**< needed size */
6801 	   )
6802 	{
6803 	   assert(profile->arraysize > 0);
6804 	
6805 	   /* check whether the arrays are big enough */
6806 	   if( neededsize <= profile->arraysize )
6807 	      return SCIP_OKAY;
6808 	
6809 	   profile->arraysize *= 2;
6810 	
6811 	   SCIP_ALLOC( BMSreallocMemoryArray(&profile->timepoints, profile->arraysize) );
6812 	   SCIP_ALLOC( BMSreallocMemoryArray(&profile->loads, profile->arraysize) );
6813 	
6814 	   return SCIP_OKAY;
6815 	}
6816 	
6817 	/** inserts the given time point into the resource profile if it this time point does not exists yet; returns its
6818 	 *  position in the time point array
6819 	 */
6820 	static
6821 	SCIP_RETCODE profileInsertTimepoint(
6822 	   SCIP_PROFILE*         profile,            /**< resource profile to insert the time point */
6823 	   int                   timepoint,          /**< time point to insert */
6824 	   int*                  pos                 /**< pointer to store the insert position */
6825 	   )
6826 	{
6827 	   assert(profile != NULL);
6828 	   assert(timepoint >= 0);
6829 	   assert(profile->arraysize >= profile->ntimepoints);
6830 	
6831 	   /* get the position of the given time point in the resource profile array if it exists; otherwise the position of the
6832 	    * next smaller existing time point
6833 	    */
6834 	   if( !SCIPprofileFindLeft(profile, timepoint, pos) )
6835 	   {
6836 	      assert(*pos >= 0 && *pos < profile->ntimepoints);
6837 	      assert(timepoint >= profile->timepoints[*pos]);
6838 	
6839 	      /* ensure that the arrays are big enough */
6840 	      SCIP_CALL( ensureProfileSize(profile, profile->ntimepoints + 1) );
6841 	      assert(profile->arraysize > profile->ntimepoints);
6842 	
6843 	      /* insert new time point into the (sorted) resource profile */
6844 	      SCIPsortedvecInsertIntInt(profile->timepoints, profile->loads, timepoint, profile->loads[*pos],
6845 	         &profile->ntimepoints, pos);
6846 	   }
6847 	
6848 	#ifndef NDEBUG
6849 	   /* check if the time points are sorted */
6850 	   {
6851 	      int i;
6852 	      for( i = 1; i < profile->ntimepoints; ++i )
6853 	         assert(profile->timepoints[i-1] < profile->timepoints[i]);
6854 	   }
6855 	#endif
6856 	
6857 	   return SCIP_OKAY;
6858 	}
6859 	
6860 	/** updates the resource profile due to inserting of a core */
6861 	static
6862 	SCIP_RETCODE profileUpdate(
6863 	   SCIP_PROFILE*         profile,            /**< resource profile to update */
6864 	   int                   left,               /**< left side of core interval */
6865 	   int                   right,              /**< right side of core interval */
6866 	   int                   demand,             /**< demand of the core */
6867 	   int*                  pos,                /**< pointer to store the first position were it gets infeasible */
6868 	   SCIP_Bool*            infeasible          /**< pointer to store if the update is infeasible */
6869 	   )
6870 	{
6871 	   int startpos;
6872 	   int endpos;
6873 	   int i;
6874 	
6875 	   assert(profile != NULL);
6876 	   assert(profile->arraysize >= profile->ntimepoints);
6877 	   assert(left >= 0);
6878 	   assert(left < right);
6879 	   assert(infeasible != NULL);
6880 	
6881 	   (*infeasible) = FALSE;
6882 	   (*pos) = -1;
6883 	
6884 	   /* get position of the starttime in profile */
6885 	   SCIP_CALL( profileInsertTimepoint(profile, left, &startpos) );
6886 	   assert(profile->timepoints[startpos] == left);
6887 	
6888 	   /* get position of the endtime in profile */
6889 	   SCIP_CALL( profileInsertTimepoint(profile, right, &endpos) );
6890 	   assert(profile->timepoints[endpos] == right);
6891 	
6892 	   assert(startpos < endpos);
6893 	   assert(profile->arraysize >= profile->ntimepoints);
6894 	
6895 	   /* remove/add the given demand from the core */
6896 	   for( i = startpos; i < endpos; ++i )
6897 	   {
6898 	      profile->loads[i] += demand;
6899 	
6900 	      /* check if the core fits */
6901 	      if( profile->loads[i] > profile->capacity )
6902 	      {
6903 	         SCIPdebugMessage("core insertion detected infeasibility (pos %d)\n", i);
6904 	
6905 	         (*infeasible) = TRUE;
6906 	         (*pos) = i;
6907 	
6908 	         /* remove the partly inserted core since it does fit completely */
6909 	         for( ; i >= startpos; --i ) /*lint !e445*/
6910 	            profile->loads[i] -= demand;
6911 	
6912 	         break;
6913 	      }
6914 	   }
6915 	
6916 	   return SCIP_OKAY;
6917 	}
6918 	
6919 	/** insert a core into resource profile; if the core is non-empty the resource profile will be updated otherwise nothing
6920 	 *  happens
6921 	 */
6922 	SCIP_RETCODE SCIPprofileInsertCore(
6923 	   SCIP_PROFILE*         profile,            /**< resource profile */
6924 	   int                   left,               /**< left side of the core  */
6925 	   int                   right,              /**< right side of the core */
6926 	   int                   demand,             /**< demand of the core */
6927 	   int*                  pos,                /**< pointer to store the first position were it gets infeasible */
6928 	   SCIP_Bool*            infeasible          /**< pointer to store if the core does not fit due to capacity */
6929 	   )
6930 	{
6931 	   assert(profile != NULL);
6932 	   assert(left < right);
6933 	   assert(demand >= 0);
6934 	   assert(infeasible != NULL);
6935 	
6936 	   (*infeasible) = FALSE;
6937 	   (*pos) = -1;
6938 	
6939 	   /* insert core into the resource profile */
6940 	   SCIPdebugMessage("insert core [%d,%d] with demand %d\n", left, right, demand);
6941 	
6942 	   if( demand > 0 )
6943 	   {
6944 	      /* try to insert core into the resource profile */
6945 	      SCIP_CALL( profileUpdate(profile, left, right, demand, pos, infeasible) );
6946 	   }
6947 	
6948 	   return SCIP_OKAY;
6949 	}
6950 	
6951 	/** subtracts the demand from the resource profile during core time */
6952 	SCIP_RETCODE SCIPprofileDeleteCore(
6953 	   SCIP_PROFILE*         profile,            /**< resource profile to use */
6954 	   int                   left,               /**< left side of the core  */
6955 	   int                   right,              /**< right side of the core */
6956 	   int                   demand              /**< demand of the core */
6957 	   )
6958 	{
6959 	   SCIP_Bool infeasible;
6960 	   int pos;
6961 	
6962 	   assert(left < right);
6963 	#ifndef NDEBUG
6964 	   {
6965 	      /* check if the left and right time points of the core correspond to a time point in the resource profile; this
6966 	       * should be the case since we added the core before to the resource profile
6967 	       */
6968 	      assert(SCIPprofileFindLeft(profile, left, &pos));
6969 	      assert(SCIPprofileFindLeft(profile, right, &pos));
6970 	   }
6971 	#endif
6972 	
6973 	   /* remove the core from the resource profile */
6974 	   SCIPdebugMessage("delete core [%d,%d] with demand %d\n", left, right, demand);
6975 	
6976 	   SCIP_CALL( profileUpdate(profile, left, right, -demand, &pos, &infeasible) );
6977 	   assert(!infeasible);
6978 	
6979 	   return SCIP_OKAY; /*lint !e438*/
6980 	}
6981 	
6982 	/** returns TRUE if the core (given by its demand and during) can be inserted at the given time point; otherwise FALSE */
6983 	static
6984 	int profileFindFeasibleStart(
6985 	   SCIP_PROFILE*         profile,            /**< resource profile to use */
6986 	   int                   pos,                /**< pointer to store the position in the profile to start the serch */
6987 	   int                   lst,                /**< latest start time */
6988 	   int                   duration,           /**< duration of the core */
6989 	   int                   demand,             /**< demand of the core */
6990 	   SCIP_Bool*            infeasible          /**< pointer store if the corer cannot be inserted */
6991 	   )
6992 	{
6993 	   int remainingduration;
6994 	   int startpos;
6995 	
6996 	   assert(profile != NULL);
6997 	   assert(pos >= 0);
6998 	   assert(pos < profile->ntimepoints);
6999 	   assert(duration > 0);
7000 	   assert(demand > 0);
7001 	   assert(profile->loads[profile->ntimepoints-1] == 0);
7002 	
7003 	   remainingduration = duration;
7004 	   startpos = pos;
7005 	   (*infeasible) = FALSE;
7006 	
7007 	   if( profile->timepoints[startpos] > lst )
7008 	   {
7009 	      (*infeasible) = TRUE;
7010 	      return pos;
7011 	   }
7012 	
7013 	   while( pos < profile->ntimepoints - 1 )
7014 	   {
7015 	      if( profile->loads[pos] + demand > profile->capacity )
7016 	      {
7017 	         SCIPdebugMessage("profile <%p>: core does not fit at time point %d (pos %d)\n", (void*)profile, profile->timepoints[pos], pos);
7018 	         startpos = pos + 1;
7019 	         remainingduration = duration;
7020 	
7021 	         if( profile->timepoints[startpos] > lst )
7022 	         {
7023 	            (*infeasible) = TRUE;
7024 	            return pos;
7025 	         }
7026 	      }
7027 	      else
7028 	         remainingduration -= profile->timepoints[pos+1] - profile->timepoints[pos];
7029 	
7030 	      if( remainingduration <= 0 )
7031 	         break;
7032 	
7033 	      pos++;
7034 	   }
7035 	
7036 	   return startpos;
7037 	}
7038 	
7039 	/** return the earliest possible starting point within the time interval [lb,ub] for a given core (given by its demand
7040 	 *  and duration)
7041 	 */
7042 	int SCIPprofileGetEarliestFeasibleStart(
7043 	   SCIP_PROFILE*         profile,            /**< resource profile to use */
7044 	   int                   est,                /**< earliest starting time of the given core */
7045 	   int                   lst,                /**< latest starting time of the given core */
7046 	   int                   duration,           /**< duration of the core */
7047 	   int                   demand,             /**< demand of the core */
7048 	   SCIP_Bool*            infeasible          /**< pointer store if the corer cannot be inserted */
7049 	   )
7050 	{
7051 	   SCIP_Bool found;
7052 	   int pos;
7053 	
7054 	   assert(profile != NULL);
7055 	   assert(est >= 0);
7056 	   assert(est <= lst);
7057 	   assert(duration >= 0);
7058 	   assert(demand >= 0);
7059 	   assert(infeasible != NULL);
7060 	   assert(profile->ntimepoints > 0);
7061 	   assert(profile->loads[profile->ntimepoints-1] == 0);
7062 	
7063 	   SCIPdebugMessage("profile <%p>: find earliest start time (demad %d, duration %d) [%d,%d]\n", (void*)profile, demand, duration, est, lst);
7064 	
7065 	   if( duration == 0 || demand == 0 )
7066 	   {
7067 	      *infeasible = FALSE;
7068 	      return est;
7069 	   }
7070 	
7071 	   found = SCIPprofileFindLeft(profile, est, &pos);
7072 	   SCIPdebugMessage("profile <%p>: earliest start time does %s exist as time point (pos %d)\n", (void*)profile, found ? "" : "not", pos);
7073 	
7074 	   /* if the position is the last time point in the profile, the core can be inserted at its earliest start time */
7075 	   if( pos == profile->ntimepoints - 1 )
7076 	   {
7077 	      (*infeasible) = FALSE;
7078 	      return est;
7079 	   }
7080 	
7081 	   if( found )
7082 	   {
7083 	      /* if the start time matches a time point in the profile we can just search */
7084 	      assert(profile->timepoints[pos] == est);
7085 	      pos = profileFindFeasibleStart(profile, pos, lst, duration, demand, infeasible);
7086 	
7087 	      assert(pos < profile->ntimepoints);
7088 	      est = profile->timepoints[pos];
7089 	   }
7090 	   else if( profile->loads[pos] + demand > profile->capacity )
7091 	   {
7092 	      /* if the the time point left to the start time has not enough free capacity we can just search the profile
7093 	       * starting from the next time point
7094 	       */
7095 	      assert(profile->timepoints[pos] <= est);
7096 	      pos = profileFindFeasibleStart(profile, pos+1, lst, duration, demand, infeasible);
7097 	
7098 	      assert(pos < profile->ntimepoints);
7099 	      est = profile->timepoints[pos];
7100 	   }
7101 	   else
7102 	   {
7103 	      int remainingduration;
7104 	
7105 	      /* check if the core can be placed at its earliest start time */
7106 	
7107 	      assert(pos < profile->ntimepoints - 1);
7108 	
7109 	      remainingduration = duration - (profile->timepoints[pos+1] - est);
7110 	      SCIPdebugMessage("remaining duration %d\n", remainingduration);
7111 	
7112 	      if( remainingduration <= 0 )
7113 	         (*infeasible) = FALSE;
7114 	      else
7115 	      {
7116 	         pos = profileFindFeasibleStart(profile, pos+1, profile->timepoints[pos+1], remainingduration, demand, infeasible);
7117 	         SCIPdebugMessage("remaining duration can%s be processed\n", *infeasible ? "not" : "");
7118 	
7119 	         if( *infeasible )
7120 	         {
7121 	            pos = profileFindFeasibleStart(profile, pos+1, lst, duration, demand, infeasible);
7122 	
7123 	            assert(pos < profile->ntimepoints);
7124 	            est = profile->timepoints[pos];
7125 	         }
7126 	      }
7127 	   }
7128 	
7129 	   return est;
7130 	}
7131 	
7132 	/** returns TRUE if the core (given by its demand and during) can be inserted at the given time point; otherwise FALSE */
7133 	static
7134 	int profileFindDownFeasibleStart(
7135 	   SCIP_PROFILE*         profile,            /**< resource profile to use */
7136 	   int                   pos,                /**< pointer to store the position in the profile to start the search */
7137 	   int                   ect,                /**< earliest completion time */
7138 	   int                   duration,           /**< duration of the core */
7139 	   int                   demand,             /**< demand of the core */
7140 	   SCIP_Bool*            infeasible          /**< pointer store if the corer cannot be inserted */
7141 	   )
7142 	{
7143 	   int remainingduration;
7144 	   int endpos;
7145 	
7146 	   assert(profile != NULL);
7147 	   assert(pos >= 0);
7148 	   assert(pos < profile->ntimepoints);
7149 	   assert(duration > 0);
7150 	   assert(demand > 0);
7151 	   assert(profile->ntimepoints > 0);
7152 	   assert(profile->loads[profile->ntimepoints-1] == 0);
7153 	
7154 	   remainingduration = duration;
7155 	   endpos = pos;
7156 	   (*infeasible) = TRUE;
7157 	
7158 	   if( profile->timepoints[endpos] < ect - duration )
7159 	      return pos;
7160 	
7161 	   while( pos > 0 )
7162 	   {
7163 	      if( profile->loads[pos-1] + demand > profile->capacity )
7164 	      {
7165 	         SCIPdebugMessage("profile <%p>: core does not fit at time point %d (pos %d)\n", (void*)profile, profile->timepoints[pos-1], pos-1);
7166 	
7167 	         endpos = pos - 1;
7168 	         remainingduration = duration;
7169 	
7170 	         if( profile->timepoints[endpos] < ect - duration )
7171 	            return pos;
7172 	      }
7173 	      else
7174 	         remainingduration -= profile->timepoints[pos] - profile->timepoints[pos-1];
7175 	
7176 	      if( remainingduration <= 0 )
7177 	      {
7178 	         *infeasible = FALSE;
7179 	         break;
7180 	      }
7181 	
7182 	      pos--;
7183 	   }
7184 	
7185 	   return endpos;
7186 	}
7187 	
7188 	/** return the latest possible starting point within the time interval [lb,ub] for a given core (given by its demand and
7189 	 *  duration)
7190 	 */
7191 	int SCIPprofileGetLatestFeasibleStart(
7192 	   SCIP_PROFILE*         profile,            /**< resource profile to use */
7193 	   int                   est,                /**< earliest possible start point */
7194 	   int                   lst,                /**< latest possible start point */
7195 	   int                   duration,           /**< duration of the core */
7196 	   int                   demand,             /**< demand of the core */
7197 	   SCIP_Bool*            infeasible          /**< pointer store if the core cannot be inserted */
7198 	   )
7199 	{
7200 	   SCIP_Bool found;
7201 	   int ect;
7202 	   int lct;
7203 	   int pos;
7204 	
7205 	   assert(profile != NULL);
7206 	   assert(est >= 0);
7207 	   assert(est <= lst);
7208 	   assert(duration >= 0);
7209 	   assert(demand >= 0);
7210 	   assert(infeasible != NULL);
7211 	   assert(profile->ntimepoints > 0);
7212 	   assert(profile->loads[profile->ntimepoints-1] == 0);
7213 	
7214 	   if( duration == 0 || demand == 0 )
7215 	   {
7216 	      *infeasible = FALSE;
7217 	      return lst;
7218 	   }
7219 	
7220 	   ect = est + duration;
7221 	   lct = lst + duration;
7222 	
7223 	   found = SCIPprofileFindLeft(profile, lct, &pos);
7224 	   SCIPdebugMessage("profile <%p>: latest completion time %d does %s exist as time point (pos %d)\n", (void*)profile, lct, found ? "" : "not", pos);
7225 	
7226 	   if( found )
7227 	   {
7228 	      /* if the start time matches a time point in the profile we can just search */
7229 	      assert(profile->timepoints[pos] == lct);
7230 	      pos = profileFindDownFeasibleStart(profile, pos, ect, duration, demand, infeasible);
7231 	
7232 	      assert(pos < profile->ntimepoints && pos >= 0);
7233 	      lct = profile->timepoints[pos];
7234 	   }
7235 	   else if( profile->loads[pos] + demand > profile->capacity )
7236 	   {
7237 	      /* if the time point left to the start time has not enough free capacity we can just search the profile starting
7238 	       * from the next time point
7239 	       */
7240 	      assert(profile->timepoints[pos] < lct);
7241 	      pos = profileFindDownFeasibleStart(profile, pos, ect, duration, demand, infeasible);
7242 	
7243 	      assert(pos < profile->ntimepoints && pos >= 0);
7244 	      lct = profile->timepoints[pos];
7245 	   }
7246 	   else
7247 	   {
7248 	      int remainingduration;
7249 	
7250 	      /* check if the core can be placed at its latest start time */
7251 	      assert(profile->timepoints[pos] < lct);
7252 	
7253 	      remainingduration = duration - (lct - profile->timepoints[pos]);
7254 	
7255 	      if( remainingduration <= 0 )
7256 	         (*infeasible) = FALSE;
7257 	      else
7258 	      {
7259 	         pos = profileFindDownFeasibleStart(profile, pos, profile->timepoints[pos], remainingduration, demand, infeasible);
7260 	
7261 	         if( *infeasible )
7262 	         {
7263 	            pos = profileFindDownFeasibleStart(profile, pos, ect, duration, demand, infeasible);
7264 	
7265 	            assert(pos < profile->ntimepoints && pos >= 0);
7266 	            lct = profile->timepoints[pos];
7267 	         }
7268 	      }
7269 	   }
7270 	
7271 	   return lct - duration;
7272 	}
7273 	
7274 	/*
7275 	 * Directed graph
7276 	 */
7277 	
7278 	/** creates directed graph structure */
7279 	SCIP_RETCODE SCIPdigraphCreate(
7280 	   SCIP_DIGRAPH**        digraph,            /**< pointer to store the created directed graph */
7281 	   BMS_BLKMEM*           blkmem,             /**< block memory to store the data */
7282 	   int                   nnodes              /**< number of nodes */
7283 	   )
7284 	{
7285 	   assert(digraph != NULL);
7286 	   assert(blkmem != NULL);
7287 	   assert(nnodes > 0);
7288 	
7289 	   /* allocate memory for the graph and the arrays storing arcs and data */
7290 	   SCIP_ALLOC( BMSallocBlockMemory(blkmem, digraph) );
7291 	   SCIP_ALLOC( BMSallocClearBlockMemoryArray(blkmem, &(*digraph)->successors, nnodes) );
7292 	   SCIP_ALLOC( BMSallocClearBlockMemoryArray(blkmem, &(*digraph)->arcdata, nnodes) );
7293 	   SCIP_ALLOC( BMSallocClearBlockMemoryArray(blkmem, &(*digraph)->successorssize, nnodes) );
7294 	   SCIP_ALLOC( BMSallocClearBlockMemoryArray(blkmem, &(*digraph)->nsuccessors, nnodes) );
7295 	   SCIP_ALLOC( BMSallocClearBlockMemoryArray(blkmem, &(*digraph)->nodedata, nnodes) );
7296 	
7297 	   /* store number of nodes */
7298 	   (*digraph)->nnodes = nnodes;
7299 	
7300 	   /* at the beginning, no components are stored */
7301 	   (*digraph)->blkmem = blkmem;
7302 	   (*digraph)->ncomponents = 0;
7303 	   (*digraph)->componentstartsize = 0;
7304 	   (*digraph)->components = NULL;
7305 	   (*digraph)->componentstarts = NULL;
7306 	
7307 	   /* all nodes are initially considered as non-articulation points */
7308 	   (*digraph)->narticulations = -1;
7309 	   (*digraph)->articulations = NULL;
7310 	   (*digraph)->articulationscheck = FALSE;
7311 	
7312 	   return SCIP_OKAY;
7313 	}
7314 	
7315 	/** resize directed graph structure */
7316 	SCIP_RETCODE SCIPdigraphResize(
7317 	   SCIP_DIGRAPH*         digraph,            /**< directed graph */
7318 	   int                   nnodes              /**< new number of nodes */
7319 	   )
7320 	{
7321 	   int n;
7322 	   assert(digraph != NULL);
7323 	   assert(digraph->blkmem != NULL);
7324 	
7325 	   /* check if the digraph has already a proper size */
7326 	   if( nnodes <= digraph->nnodes )
7327 	      return SCIP_OKAY;
7328 	
7329 	   /* reallocate memory for increasing the arrays storing arcs and data */
7330 	   SCIP_ALLOC( BMSreallocBlockMemoryArray(digraph->blkmem, &digraph->successors, digraph->nnodes, nnodes) );
7331 	   SCIP_ALLOC( BMSreallocBlockMemoryArray(digraph->blkmem, &digraph->arcdata, digraph->nnodes, nnodes) );
7332 	   SCIP_ALLOC( BMSreallocBlockMemoryArray(digraph->blkmem, &digraph->successorssize, digraph->nnodes, nnodes) );
7333 	   SCIP_ALLOC( BMSreallocBlockMemoryArray(digraph->blkmem, &digraph->nsuccessors, digraph->nnodes, nnodes) );
7334 	   SCIP_ALLOC( BMSreallocBlockMemoryArray(digraph->blkmem, &digraph->nodedata, digraph->nnodes, nnodes) );
7335 	
7336 	   /* initialize the new node data structures */
7337 	   for( n = digraph->nnodes; n < nnodes; ++n )
7338 	   {
7339 	      digraph->nodedata[n] = NULL;
7340 	      digraph->arcdata[n] = NULL;
7341 	      digraph->successors[n] = NULL;
7342 	      digraph->successorssize[n] = 0;
7343 	      digraph->nsuccessors[n] = 0;
7344 	   }
7345 	
7346 	   /* store the new number of nodes */
7347 	   digraph->nnodes = nnodes;
7348 	
7349 	   return SCIP_OKAY;
7350 	}
7351 	
7352 	/** copies directed graph structure
7353 	 *
7354 	 *  @note The data in nodedata is copied verbatim. This possibly has to be adapted by the user.
7355 	 */
7356 	SCIP_RETCODE SCIPdigraphCopy(
7357 	   SCIP_DIGRAPH**        targetdigraph,      /**< pointer to store the copied directed graph */
7358 	   SCIP_DIGRAPH*         sourcedigraph,      /**< source directed graph */
7359 	   BMS_BLKMEM*           targetblkmem        /**< block memory to store the target block memory, or NULL to use the same
7360 	                                              *   the same block memory as used for the \p sourcedigraph */
7361 	   )
7362 	{
7363 	   int ncomponents;
7364 	   int nnodes;
7365 	   int i;
7366 	   SCIP_Bool articulationscheck;
7367 	
7368 	   assert(sourcedigraph != NULL);
7369 	   assert(targetdigraph != NULL);
7370 	
7371 	   /* use the source digraph block memory if not specified otherwise */
7372 	   if( targetblkmem == NULL )
7373 	      targetblkmem = sourcedigraph->blkmem;
7374 	
7375 	   assert(targetblkmem != NULL);
7376 	
7377 	   SCIP_ALLOC( BMSallocBlockMemory(targetblkmem, targetdigraph) );
7378 	
7379 	   nnodes = sourcedigraph->nnodes;
7380 	   ncomponents = sourcedigraph->ncomponents;
7381 	   articulationscheck = sourcedigraph->articulationscheck;
7382 	   (*targetdigraph)->nnodes = nnodes;
7383 	   (*targetdigraph)->ncomponents = ncomponents;
7384 	   (*targetdigraph)->blkmem = targetblkmem;
7385 	
7386 	   /* copy arcs and data */
7387 	   SCIP_ALLOC( BMSallocClearBlockMemoryArray(targetblkmem, &(*targetdigraph)->successors, nnodes) );
7388 	   SCIP_ALLOC( BMSallocClearBlockMemoryArray(targetblkmem, &(*targetdigraph)->arcdata, nnodes) );
7389 	   SCIP_ALLOC( BMSallocClearBlockMemoryArray(targetblkmem, &(*targetdigraph)->nodedata, nnodes) );
7390 	
7391 	   /* copy lists of successors and arc data */
7392 	   for( i = 0; i < nnodes; ++i )
7393 	   {
7394 	      if( sourcedigraph->nsuccessors[i] > 0 )
7395 	      {
7396 	         assert(sourcedigraph->successors[i] != NULL);
7397 	         assert(sourcedigraph->arcdata[i] != NULL);
7398 	
7399 	         SCIP_ALLOC( BMSduplicateBlockMemoryArray(targetblkmem, &((*targetdigraph)->successors[i]),
7400 	               sourcedigraph->successors[i], sourcedigraph->nsuccessors[i]) ); /*lint !e866*/
7401 	         SCIP_ALLOC( BMSduplicateBlockMemoryArray(targetblkmem, &((*targetdigraph)->arcdata[i]),
7402 	               sourcedigraph->arcdata[i], sourcedigraph->nsuccessors[i]) ); /*lint !e866*/
7403 	      }
7404 	      /* copy node data - careful if these are pointers to some information -> need to be copied by hand */
7405 	      (*targetdigraph)->nodedata[i] = sourcedigraph->nodedata[i];
7406 	   }
7407 	
7408 	   /* use nsuccessors as size to save memory */
7409 	   SCIP_ALLOC( BMSduplicateBlockMemoryArray(targetblkmem, &(*targetdigraph)->successorssize, sourcedigraph->nsuccessors, nnodes) );
7410 	   SCIP_ALLOC( BMSduplicateBlockMemoryArray(targetblkmem, &(*targetdigraph)->nsuccessors, sourcedigraph->nsuccessors, nnodes) );
7411 	
7412 	   /* copy component data */
7413 	   if( ncomponents > 0 )
7414 	   {
7415 	      SCIP_ALLOC( BMSduplicateBlockMemoryArray(targetblkmem, &(*targetdigraph)->components, sourcedigraph->components,
7416 	            sourcedigraph->componentstarts[ncomponents]) );
7417 	      SCIP_ALLOC( BMSduplicateBlockMemoryArray(targetblkmem, &(*targetdigraph)->componentstarts,
7418 	            sourcedigraph->componentstarts,ncomponents + 1) ); /*lint !e776*/
7419 	      (*targetdigraph)->componentstartsize = ncomponents + 1;
7420 	   }
7421 	   else
7422 	   {
7423 	      (*targetdigraph)->components = NULL;
7424 	      (*targetdigraph)->componentstarts = NULL;
7425 	      (*targetdigraph)->componentstartsize = 0;
7426 	   }
7427 	
7428 	   /* copy the articulation point information if it has been computed and is up-to-date */
7429 	   if( articulationscheck )
7430 	   {
7431 	      SCIP_ALLOC( BMSduplicateBlockMemoryArray(targetblkmem, &(*targetdigraph)->articulations, sourcedigraph->articulations, sourcedigraph->narticulations) );
7432 	      (*targetdigraph)->narticulations = sourcedigraph->narticulations;
7433 	      (*targetdigraph)->articulationscheck = TRUE;
7434 	   }
7435 	   else
7436 	   {
7437 	      (*targetdigraph)->narticulations = -1;
7438 	      (*targetdigraph)->articulations = NULL;
7439 	      (*targetdigraph)->articulationscheck = FALSE;
7440 	   }
7441 	
7442 	   return SCIP_OKAY;
7443 	}
7444 	
7445 	/** sets the sizes of the successor lists for the nodes in a directed graph and allocates memory for the lists */
7446 	SCIP_RETCODE SCIPdigraphSetSizes(
7447 	   SCIP_DIGRAPH*         digraph,            /**< directed graph */
7448 	   int*                  sizes               /**< sizes of the successor lists */
7449 	   )
7450 	{
7451 	   int i;
7452 	   BMS_BLKMEM* blkmem;
7453 	
7454 	   assert(digraph != NULL);
7455 	   assert(digraph->nnodes > 0);
7456 	   blkmem = digraph->blkmem;
7457 	
7458 	   for( i = 0; i < digraph->nnodes; ++i )
7459 	   {
7460 	      SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &digraph->successors[i], sizes[i]) ); /*lint !e866*/
7461 	      SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &digraph->arcdata[i], sizes[i]) ); /*lint !e866*/
7462 	      digraph->successorssize[i] = sizes[i];
7463 	      digraph->nsuccessors[i] = 0;
7464 	   }
7465 	
7466 	   return SCIP_OKAY;
7467 	}
7468 	
7469 	/** frees given directed graph structure */
7470 	void SCIPdigraphFree(
7471 	   SCIP_DIGRAPH**        digraph             /**< pointer to the directed graph */
7472 	   )
7473 	{
7474 	   int i;
7475 	   BMS_BLKMEM* blkmem;
7476 	   SCIP_DIGRAPH* digraphptr;
7477 	
7478 	   assert(digraph != NULL);
7479 	   assert(*digraph != NULL);
7480 	   assert((*digraph)->blkmem != NULL);
7481 	
7482 	   blkmem = (*digraph)->blkmem;
7483 	   digraphptr = *digraph;
7484 	
7485 	   /* free arrays storing the successor nodes and arc data */
7486 	   for( i = digraphptr->nnodes - 1; i >= 0; --i )
7487 	   {
7488 	      BMSfreeBlockMemoryArrayNull(blkmem, &digraphptr->successors[i], digraphptr->successorssize[i]);
7489 	      BMSfreeBlockMemoryArrayNull(blkmem, &digraphptr->arcdata[i], digraphptr->successorssize[i]);
7490 	   }
7491 	
7492 	   /* free components structure */
7493 	   SCIPdigraphFreeComponents(digraphptr);
7494 	   assert(digraphptr->ncomponents == 0);
7495 	   assert(digraphptr->componentstartsize == 0);
7496 	   assert(digraphptr->components == NULL);
7497 	   assert(digraphptr->componentstarts == NULL);
7498 	
7499 	   /* free the articulation points structure if it has been computed*/
7500 	   if( digraphptr->articulationscheck )
7501 	      BMSfreeBlockMemoryArray(blkmem, &digraphptr->articulations, digraphptr->narticulations);
7502 	
7503 	   /* free directed graph data structure */
7504 	   BMSfreeBlockMemoryArray(blkmem, &digraphptr->nodedata, digraphptr->nnodes);
7505 	   BMSfreeBlockMemoryArray(blkmem, &digraphptr->successorssize, digraphptr->nnodes);
7506 	   BMSfreeBlockMemoryArray(blkmem, &digraphptr->nsuccessors, digraphptr->nnodes);
7507 	   BMSfreeBlockMemoryArray(blkmem, &digraphptr->successors, digraphptr->nnodes);
7508 	   BMSfreeBlockMemoryArray(blkmem, &digraphptr->arcdata, digraphptr->nnodes);
7509 	
7510 	   BMSfreeBlockMemory(blkmem, digraph);
7511 	}
7512 	
7513 	#define STARTSUCCESSORSSIZE 5
7514 	
7515 	/** ensures that successors array of one node in a directed graph is big enough */
7516 	static
7517 	SCIP_RETCODE ensureSuccessorsSize(
7518 	   SCIP_DIGRAPH*         digraph,            /**< directed graph */
7519 	   int                   idx,                /**< index for which the size is ensured */
7520 	   int                   newsize             /**< needed size */
7521 	   )
7522 	{
7523 	   BMS_BLKMEM* blkmem;
7524 	
7525 	   assert(digraph != NULL);
7526 	   assert(digraph->blkmem != NULL);
7527 	   assert(idx >= 0);
7528 	   assert(idx < digraph->nnodes);
7529 	   assert(newsize > 0);
7530 	   assert(digraph->successorssize[idx] == 0 || digraph->successors[idx] != NULL);
7531 	   assert(digraph->successorssize[idx] == 0 || digraph->arcdata[idx] != NULL);
7532 	
7533 	   blkmem = digraph->blkmem;
7534 	
7535 	   /* check whether array is big enough, and realloc, if needed */
7536 	   if( newsize > digraph->successorssize[idx] )
7537 	   {
7538 	      if( digraph->successors[idx] == NULL )
7539 	      {
7540 	         assert(digraph->arcdata[idx] == NULL);
7541 	         digraph->successorssize[idx] = STARTSUCCESSORSSIZE;
7542 	         SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &digraph->successors[idx], digraph->successorssize[idx]) ); /*lint !e866*/
7543 	         SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &digraph->arcdata[idx], digraph->successorssize[idx]) ); /*lint !e866*/
7544 	      }
7545 	      else
7546 	      {
7547 	         newsize = MAX(newsize, 2 * digraph->successorssize[idx]);
7548 	         assert(digraph->arcdata[idx] != NULL);
7549 	         SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &digraph->successors[idx], digraph->successorssize[idx], newsize) ); /*lint !e866*/
7550 	         SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &digraph->arcdata[idx], digraph->successorssize[idx], newsize) ); /*lint !e866*/
7551 	         digraph->successorssize[idx] = newsize;
7552 	      }
7553 	   }
7554 	
7555 	   assert(newsize <= digraph->successorssize[idx]);
7556 	
7557 	   return SCIP_OKAY;
7558 	}
7559 	
7560 	/** add (directed) arc and a related data to the directed graph structure
7561 	 *
7562 	 *  @note if the arc is already contained, it is added a second time
7563 	 */
7564 	SCIP_RETCODE SCIPdigraphAddArc(
7565 	   SCIP_DIGRAPH*         digraph,            /**< directed graph */
7566 	   int                   startnode,          /**< start node of the arc */
7567 	   int                   endnode,            /**< start node of the arc */
7568 	   void*                 data                /**< data that should be stored for the arc; or NULL */
7569 	   )
7570 	{
7571 	   assert(digraph != NULL);
7572 	   assert(startnode >= 0);
7573 	   assert(endnode >= 0);
7574 	   assert(startnode < digraph->nnodes);
7575 	   assert(endnode < digraph->nnodes);
7576 	
7577 	   SCIP_CALL( ensureSuccessorsSize(digraph, startnode, digraph->nsuccessors[startnode] + 1) );
7578 	
7579 	   /* add arc */
7580 	   digraph->successors[startnode][digraph->nsuccessors[startnode]] = endnode;
7581 	   digraph->arcdata[startnode][digraph->nsuccessors[startnode]] = data;
7582 	   digraph->nsuccessors[startnode]++;
7583 	
7584 	   /* the articulation points are not up-to-date */
7585 	   digraph->articulationscheck = FALSE;
7586 	
7587 	   return SCIP_OKAY;
7588 	}
7589 	
7590 	/** add (directed) arc to the directed graph structure, if it is not contained, yet
7591 	 *
7592 	 * @note if there already exists an arc from startnode to endnode, the new arc is not added,
7593 	 *       even if its data is different
7594 	 */
7595 	SCIP_RETCODE SCIPdigraphAddArcSafe(
7596 	   SCIP_DIGRAPH*         digraph,            /**< directed graph */
7597 	   int                   startnode,          /**< start node of the arc */
7598 	   int                   endnode,            /**< start node of the arc */
7599 	   void*                 data                /**< data that should be stored for the arc; or NULL */
7600 	   )
7601 	{
7602 	   int nsuccessors;
7603 	   int i;
7604 	
7605 	   assert(digraph != NULL);
7606 	   assert(startnode >= 0);
7607 	   assert(endnode >= 0);
7608 	   assert(startnode < digraph->nnodes);
7609 	   assert(endnode < digraph->nnodes);
7610 	
7611 	   nsuccessors = digraph->nsuccessors[startnode];
7612 	
7613 	   /* search for the arc in existing arcs */
7614 	   for( i = 0; i < nsuccessors; ++i )
7615 	      if( digraph->successors[startnode][i] == endnode )
7616 	         return SCIP_OKAY;
7617 	
7618 	   SCIP_CALL( ensureSuccessorsSize(digraph, startnode, nsuccessors + 1) );
7619 	
7620 	   /* add arc */
7621 	   digraph->successors[startnode][nsuccessors] = endnode;
7622 	   digraph->arcdata[startnode][nsuccessors] = data;
7623 	   ++(digraph->nsuccessors[startnode]);
7624 	
7625 	   /* the articulation points are not up-to-date */
7626 	   digraph->articulationscheck = FALSE;
7627 	
7628 	   return SCIP_OKAY;
7629 	}
7630 	
7631 	/** sets the number of successors to a given value */
7632 	SCIP_RETCODE SCIPdigraphSetNSuccessors(
7633 	   SCIP_DIGRAPH*         digraph,            /**< directed graph */
7634 	   int                   node,               /**< node for which the number of successors has to be changed */
7635 	   int                   nsuccessors         /**< new number of successors */
7636 	   )
7637 	{
7638 	   assert(digraph != NULL);
7639 	   assert(node >= 0);
7640 	   assert(node < digraph->nnodes);
7641 	
7642 	   digraph->nsuccessors[node] = nsuccessors;
7643 	
7644 	   return SCIP_OKAY;
7645 	}
7646 	
7647 	/** returns the number of nodes of the given digraph */
7648 	int SCIPdigraphGetNNodes(
7649 	   SCIP_DIGRAPH*         digraph             /**< directed graph */
7650 	   )
7651 	{
7652 	   assert(digraph != NULL);
7653 	
7654 	   return digraph->nnodes;
7655 	}
7656 	
7657 	/** returns the node data, or NULL if no data exist */
7658 	void* SCIPdigraphGetNodeData(
7659 	   SCIP_DIGRAPH*         digraph,            /**< directed graph */
7660 	   int                   node                /**< node for which the node data is returned */
7661 	   )
7662 	{
7663 	   assert(digraph != NULL);
7664 	   assert(node >= 0);
7665 	   assert(node < digraph->nnodes);
7666 	
7667 	   return digraph->nodedata[node];
7668 	}
7669 	
7670 	/** sets the node data
7671 	 *
7672 	 *  @note The old user pointer is not freed. This has to be done by the user
7673 	 */
7674 	void SCIPdigraphSetNodeData(
7675 	   SCIP_DIGRAPH*         digraph,            /**< directed graph */
7676 	   void*                 dataptr,            /**< user node data pointer, or NULL */
7677 	   int                   node                /**< node for which the node data is returned */
7678 	   )
7679 	{
7680 	   assert(digraph != NULL);
7681 	   assert(node >= 0);
7682 	   assert(node < digraph->nnodes);
7683 	
7684 	   digraph->nodedata[node] = dataptr;
7685 	}
7686 	
7687 	/** returns the total number of arcs in the given digraph */
7688 	int SCIPdigraphGetNArcs(
7689 	   SCIP_DIGRAPH*         digraph             /**< directed graph */
7690 	   )
7691 	{
7692 	   int i;
7693 	   int narcs;
7694 	
7695 	   assert(digraph != NULL);
7696 	
7697 	   /* count number of arcs */
7698 	   narcs = 0;
7699 	   for( i = 0; i < digraph->nnodes; ++i )
7700 	      narcs += digraph->nsuccessors[i];
7701 	
7702 	   return narcs;
7703 	}
7704 	
7705 	/** returns the number of successor nodes of the given node */
7706 	int SCIPdigraphGetNSuccessors(
7707 	   SCIP_DIGRAPH*         digraph,            /**< directed graph */
7708 	   int                   node                /**< node for which the number of outgoing arcs is returned */
7709 	   )
7710 	{
7711 	   assert(digraph != NULL);
7712 	   assert(node >= 0);
7713 	   assert(node < digraph->nnodes);
7714 	   assert(digraph->nsuccessors[node] >= 0);
7715 	   assert(digraph->nsuccessors[node] <= digraph->successorssize[node]);
7716 	
7717 	   return digraph->nsuccessors[node];
7718 	}
7719 	
7720 	/** returns the array of indices of the successor nodes; this array must not be changed from outside */
7721 	int* SCIPdigraphGetSuccessors(
7722 	   SCIP_DIGRAPH*         digraph,            /**< directed graph */
7723 	   int                   node                /**< node for which the array of outgoing arcs is returned */
7724 	   )
7725 	{
7726 	   assert(digraph != NULL);
7727 	   assert(node >= 0);
7728 	   assert(node < digraph->nnodes);
7729 	   assert(digraph->nsuccessors[node] >= 0);
7730 	   assert(digraph->nsuccessors[node] <= digraph->successorssize[node]);
7731 	   assert((digraph->nsuccessors[node] == 0) || (digraph->successors[node] != NULL));
7732 	
7733 	   return digraph->successors[node];
7734 	}
7735 	
7736 	/** returns the array of data corresponding to the arcs originating at the given node, or NULL if no data exist; this
7737 	 *  array must not be changed from outside
7738 	 */
7739 	void** SCIPdigraphGetSuccessorsData(
7740 	   SCIP_DIGRAPH*         digraph,            /**< directed graph */
7741 	   int                   node                /**< node for which the data corresponding to the outgoing arcs is returned */
7742 	   )
7743 	{
7744 	   assert(digraph != NULL);
7745 	   assert(node >= 0);
7746 	   assert(node < digraph->nnodes);
7747 	   assert(digraph->nsuccessors[node] >= 0);
7748 	   assert(digraph->nsuccessors[node] <= digraph->successorssize[node]);
7749 	   assert(digraph->arcdata != NULL);
7750 	
7751 	   return digraph->arcdata[node];
7752 	}
7753 	
7754 	/** performs depth-first-search in the given directed graph from the given start node */
7755 	static
7756 	void depthFirstSearch(
7757 	   SCIP_DIGRAPH*         digraph,            /**< directed graph */
7758 	   int                   startnode,          /**< node to start the depth-first-search */
7759 	   SCIP_Bool*            visited,            /**< array to store for each node, whether it was already visited */
7760 	   int*                  dfsstack,           /**< array of size number of nodes to store the stack;
7761 	                                              *   only needed for performance reasons */
7762 	   int*                  stackadjvisited,    /**< array of size number of nodes to store the number of adjacent nodes already visited
7763 	                                              *   for each node on the stack; only needed for performance reasons */
7764 	   int*                  dfsnodes,           /**< array of nodes that can be reached starting at startnode, in reverse dfs order */
7765 	   int*                  ndfsnodes           /**< pointer to store number of nodes that can be reached starting at startnode */
7766 	   )
7767 	{
7768 	   int stackidx;
7769 	
7770 	   assert(digraph != NULL);
7771 	   assert(startnode >= 0);
7772 	   assert(startnode < digraph->nnodes);
7773 	   assert(visited != NULL);
7774 	   assert(visited[startnode] == FALSE);
7775 	   assert(dfsstack != NULL);
7776 	   assert(dfsnodes != NULL);
7777 	   assert(ndfsnodes != NULL);
7778 	
7779 	   /* put start node on the stack */
7780 	   dfsstack[0] = startnode;
7781 	   stackadjvisited[0] = 0;
7782 	   stackidx = 0;
7783 	
7784 	   while( stackidx >= 0 )
7785 	   {
7786 	      int currnode;
7787 	      int sadv;
7788 	
7789 	      /* get next node from stack */
7790 	      currnode = dfsstack[stackidx];
7791 	
7792 	      sadv = stackadjvisited[stackidx];
7793 	      assert( 0 <= sadv && sadv <= digraph->nsuccessors[currnode] );
7794 	
7795 	      /* mark current node as visited */
7796 	      assert( visited[currnode] == (sadv > 0) );
7797 	      visited[currnode] = TRUE;
7798 	
7799 	      /* iterate through the successor list until we reach unhandled node */
7800 	      while( sadv < digraph->nsuccessors[currnode] && visited[digraph->successors[currnode][sadv]] )
7801 	         ++sadv;
7802 	
7803 	      /* the current node was completely handled, remove it from stack */
7804 	      if( sadv == digraph->nsuccessors[currnode] )
7805 	      {
7806 	         --stackidx;
7807 	
7808 	         /* store node in the sorted nodes array */
7809 	         dfsnodes[(*ndfsnodes)++] = currnode;
7810 	      }
7811 	      /* handle next unhandled successor node */
7812 	      else
7813 	      {
7814 	         assert( ! visited[digraph->successors[currnode][sadv]] );
7815 	
7816 	         /* store current stackadjvisted index */
7817 	         stackadjvisited[stackidx] = sadv + 1;
7818 	
7819 	         /* put the successor node onto the stack */
7820 	         ++stackidx;
7821 	         dfsstack[stackidx] = digraph->successors[currnode][sadv];
7822 	         stackadjvisited[stackidx] = 0;
7823 	         assert( stackidx < digraph->nnodes );
7824 	      }
7825 	   }
7826 	}
7827 	
7828 	/** checks for articulation points in a given directed graph through a recursive depth-first-search.
7829 	 *  starts from a given start node and keeps track of the nodes' discovery time in search for back edges.
7830 	 *
7831 	 *  @note an articulation point is a node whose removal disconnects a connected graph or increases
7832 	 *  the number of connected components in a disconnected graph
7833 	 */
7834 	static
7835 	void findArticulationPointsUtil(
7836 	   SCIP_DIGRAPH*         digraph,            /**< directed graph */
7837 	   int                   startnode,          /**< node to start the depth-first-search */
7838 	   SCIP_Bool*            visited,            /**< array to store for each node, whether it was already visited */
7839 	   int*                  tdisc,              /**< array of size number of nodes to store each node's discovery time */
7840 	   int*                  mindisc,            /**< array of size number of nodes to store the discovery time of the earliest discovered vertex
7841 	                                              *   to which startnode (or any node in the subtree rooted at it) is having a back edge */
7842 	   int*                  parent,             /**< array to store the parent of each node in the DFS tree */
7843 	   SCIP_Bool*            articulationflag,   /**< array to mark whether a node is identified as an articulation point */
7844 	   int                   time                /**< current discovery time in the DFS */
7845 	   )
7846 	{
7847 	   int n;
7848 	   int nchildren = 0;
7849 	   int nsucc;
7850 	   int* succnodes;
7851 	
7852 	   assert(digraph != NULL);
7853 	   assert(startnode >= 0);
7854 	   assert(startnode < digraph->nnodes);
7855 	   assert(visited != NULL);
7856 	   assert(visited[startnode] == FALSE);
7857 	   assert(tdisc != NULL);
7858 	   assert(mindisc != NULL);
7859 	   assert(parent != NULL);
7860 	   assert(articulationflag != NULL);
7861 	   assert(time >= 0);
7862 	
7863 	   nsucc = (int) SCIPdigraphGetNSuccessors(digraph, startnode);
7864 	   succnodes = (int*) SCIPdigraphGetSuccessors(digraph, startnode);
7865 	   visited[startnode] = TRUE;
7866 	   tdisc[startnode] = time + 1;
7867 	   mindisc[startnode] = time + 1;
7868 	
7869 	   /* process all the adjacent nodes to startnode */
7870 	   for( n = 0; n < nsucc; ++n)
7871 	   {
7872 	      if( !visited[succnodes[n]] )
7873 	      {
7874 	         parent[succnodes[n]] = startnode;
7875 	         ++nchildren;
7876 	         findArticulationPointsUtil(digraph, succnodes[n], visited, tdisc, mindisc, parent, articulationflag, time + 1);
7877 	         /* updated the mindisc of startnode when the DFS concludes for node n*/
7878 	         mindisc[startnode] = MIN(mindisc[startnode], mindisc[succnodes[n]]);
7879 	
7880 	         /* the root is an articulation point if it has more than 2 children*/
7881 	         if( parent[startnode] == -1 && nchildren > 1 )
7882 	            articulationflag[startnode] = TRUE;
7883 	         /* a vertex startnode is an articulation point if it is not the root and
7884 	          * there is no back edge from the subtree rooted at child n to any of the ancestors of startnode */
7885 	         if( parent[startnode] > -1 && mindisc[succnodes[n]] >= tdisc[startnode] )
7886 	            articulationflag[startnode] = TRUE;
7887 	      }
7888 	      else
7889 	      {
7890 	         if( parent[startnode] != succnodes[n] )
7891 	            mindisc[startnode] = MIN(mindisc[startnode], tdisc[succnodes[n]]);
7892 	      }
7893 	   }
7894 	
7895 	   if( articulationflag[startnode] )
7896 	      ++digraph->narticulations;
7897 	}
7898 	
7899 	/** identifies the articulation points in a given directed graph
7900 	 *  uses the helper recursive function findArticulationPointsUtil
7901 	 */
7902 	SCIP_RETCODE SCIPdigraphGetArticulationPoints(
7903 	   SCIP_DIGRAPH*         digraph,            /**< directed graph */
7904 	   int**                 articulations,      /**< array to store the sorted node indices of the computed articulation points, or NULL */
7905 	   int*                  narticulations      /**< number of the computed articulation points, or NULL */
7906 	   )
7907 	{
7908 	   SCIP_RETCODE retcode = SCIP_OKAY;
7909 	   BMS_BLKMEM* blkmem;
7910 	   SCIP_Bool* visited = NULL;
7911 	   SCIP_Bool* articulationflag = NULL;
7912 	   int* tdisc = NULL;
7913 	   int* mindisc = NULL;
7914 	   int* parent = NULL;
7915 	   int n;
7916 	   int articulationidx = 0;
7917 	   int time = 0;
7918 	
7919 	   assert(digraph != NULL);
7920 	   assert(digraph->nnodes > 0);
7921 	
7922 	   /* Only perform the computation if the articulation points are NOT up-to-date */
7923 	   if( !digraph->articulationscheck )
7924 	   {
7925 	      SCIP_ALLOC_TERMINATE( retcode, BMSallocMemoryArray(&visited, digraph->nnodes), TERMINATE );
7926 	      SCIP_ALLOC_TERMINATE( retcode, BMSallocMemoryArray(&tdisc, digraph->nnodes), TERMINATE );
7927 	      SCIP_ALLOC_TERMINATE( retcode, BMSallocMemoryArray(&mindisc, digraph->nnodes), TERMINATE );
7928 	      SCIP_ALLOC_TERMINATE( retcode, BMSallocMemoryArray(&parent, digraph->nnodes), TERMINATE );
7929 	      SCIP_ALLOC_TERMINATE( retcode, BMSallocMemoryArray(&articulationflag, digraph->nnodes), TERMINATE );
7930 	
7931 	      assert(digraph->blkmem != NULL);
7932 	      blkmem = digraph->blkmem;
7933 	
7934 	      if( digraph->narticulations >= 0 ) /* case: articulations have already been computed but not up-to-date */
7935 	         BMSfreeBlockMemoryArray(blkmem, &digraph->articulations, digraph->narticulations);
7936 	
7937 	      /* Initialize the no. of articulation points ahead of the recursive computation */
7938 	      digraph->narticulations = 0;
7939 	
7940 	      for( n = 0; n < digraph->nnodes; ++n )
7941 	      {
7942 	         visited[n] = FALSE;
7943 	         parent[n] = -1;
7944 	         articulationflag[n] = FALSE;
7945 	      }
7946 	
7947 	      /* the function is called on every unvisited node in the graph to cover the disconnected graph case */
7948 	      for( n = 0; n < digraph->nnodes; ++n )
7949 	      {
7950 	         if( !visited[n] )
7951 	            findArticulationPointsUtil(digraph, n, visited, tdisc, mindisc, parent, articulationflag, time);
7952 	      }
7953 	
7954 	      /* allocation of the block memory for the node indices of the articulation points*/
7955 	      SCIP_ALLOC_TERMINATE( retcode, BMSallocBlockMemoryArray(blkmem, &digraph->articulations, digraph->narticulations), TERMINATE );
7956 	
7957 	      for( n = 0; n < digraph->nnodes; ++n )
7958 	      {
7959 	         if( articulationflag[n] )
7960 	         {
7961 	            digraph->articulations[articulationidx] = n;
7962 	            ++articulationidx;
7963 	         }
7964 	      }
7965 	   }
7966 	
7967 	   if( articulations != NULL )
7968 	      (*articulations) = digraph->articulations;
7969 	   if( narticulations != NULL )
7970 	      (*narticulations) = digraph->narticulations;
7971 	
7972 	   /* the articulation points are now up-to-date */
7973 	   digraph->articulationscheck = TRUE;
7974 	
7975 	/* cppcheck-suppress unusedLabel */
7976 	TERMINATE:
7977 	   BMSfreeMemoryArrayNull(&articulationflag);
7978 	   BMSfreeMemoryArrayNull(&parent);
7979 	   BMSfreeMemoryArrayNull(&mindisc);
7980 	   BMSfreeMemoryArrayNull(&tdisc);
7981 	   BMSfreeMemoryArrayNull(&visited);
7982 	
7983 	   return retcode;
7984 	}
7985 	
7986 	/** Compute undirected connected components on the given graph.
7987 	 *
7988 	 *  @note For each arc, its reverse is added, so the graph does not need to be the directed representation of an
7989 	 *        undirected graph.
7990 	 */
7991 	SCIP_RETCODE SCIPdigraphComputeUndirectedComponents(
7992 	   SCIP_DIGRAPH*         digraph,            /**< directed graph */
7993 	   int                   minsize,            /**< all components with less nodes are ignored */
7994 	   int*                  components,         /**< array with as many slots as there are nodes in the directed graph
7995 	                                              *   to store for each node the component to which it belongs
7996 	                                              *   (components are numbered 0 to ncomponents - 1); or NULL, if components
7997 	                                              *   are accessed one-by-one using SCIPdigraphGetComponent() */
7998 	   int*                  ncomponents         /**< pointer to store the number of components; or NULL, if the
7999 	                                              *   number of components is accessed by SCIPdigraphGetNComponents() */
8000 	   )
8001 	{
8002 	   BMS_BLKMEM* blkmem;
8003 	   SCIP_Bool* visited;
8004 	   int* ndirectedsuccessors;
8005 	   int* stackadjvisited;
8006 	   int* dfsstack;
8007 	   int ndfsnodes;
8008 	   int compstart;
8009 	   int v;
8010 	   int i;
8011 	   int j;
8012 	
8013 	   SCIP_RETCODE retcode = SCIP_OKAY;
8014 	
8015 	   assert(digraph != NULL);
8016 	   assert(digraph->nnodes > 0);
8017 	   assert(digraph->blkmem != NULL);
8018 	
8019 	   blkmem = digraph->blkmem;
8020 	
8021 	   /* first free the old components */
8022 	   if( digraph->ncomponents > 0 )
8023 	   {
8024 	      SCIPdigraphFreeComponents(digraph);
8025 	   }
8026 	
8027 	   digraph->ncomponents = 0;
8028 	   digraph->componentstartsize = 10;
8029 	
8030 	   /* storage to hold components is stored in block memory */
8031 	   SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &digraph->components, digraph->nnodes) );
8032 	   SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &digraph->componentstarts, digraph->componentstartsize) );
8033 	
8034 	   /* allocate temporary arrays */
8035 	   SCIP_ALLOC_TERMINATE( retcode, BMSallocClearMemoryArray(&visited, digraph->nnodes), TERMINATE );
8036 	   SCIP_ALLOC_TERMINATE( retcode, BMSallocMemoryArray(&dfsstack, digraph->nnodes), TERMINATE );
8037 	   SCIP_ALLOC_TERMINATE( retcode, BMSallocMemoryArray(&stackadjvisited, digraph->nnodes), TERMINATE );
8038 	   SCIP_ALLOC_TERMINATE( retcode, BMSallocMemoryArray(&ndirectedsuccessors, digraph->nnodes), TERMINATE );
8039 	
8040 	   digraph->componentstarts[0] = 0;
8041 	
8042 	   /* store the number of directed arcs per node */
8043 	   BMScopyMemoryArray(ndirectedsuccessors, digraph->nsuccessors, digraph->nnodes);
8044 	
8045 	   /* add reverse arcs to the graph */
8046 	   for( i = digraph->nnodes - 1; i >= 0; --i )
8047 	   {
8048 	      for( j = 0; j < ndirectedsuccessors[i]; ++j )
8049 	      {
8050 	         SCIP_CALL_TERMINATE( retcode, SCIPdigraphAddArc(digraph, digraph->successors[i][j], i, NULL), TERMINATE );
8051 	      }
8052 	   }
8053 	
8054 	   for( v = 0; v < digraph->nnodes; ++v )
8055 	   {
8056 	      if( visited[v] )
8057 	         continue;
8058 	
8059 	      compstart = digraph->componentstarts[digraph->ncomponents];
8060 	      ndfsnodes = 0;
8061 	      depthFirstSearch(digraph, v, visited, dfsstack, stackadjvisited,
8062 	         &digraph->components[compstart], &ndfsnodes);
8063 	
8064 	      /* forget about this component if it is too small */
8065 	      if( ndfsnodes >= minsize )
8066 	      {
8067 	         digraph->ncomponents++;
8068 	
8069 	         /* enlarge componentstartsize array, if needed */
8070 	         if( digraph->ncomponents >= digraph->componentstartsize )
8071 	         {
8072 	            int newsize;
8073 	
8074 	            newsize = 2 * digraph->componentstartsize;
8075 	            assert(digraph->ncomponents < newsize);
8076 	
8077 	            SCIP_ALLOC_TERMINATE( retcode, BMSreallocBlockMemoryArray(blkmem, &digraph->componentstarts, digraph->componentstartsize, newsize), TERMINATE );
8078 	            digraph->componentstartsize = newsize;
8079 	         }
8080 	         digraph->componentstarts[digraph->ncomponents] = compstart + ndfsnodes;
8081 	
8082 	         /* store component number for contained nodes if array was given */
8083 	         if( components != NULL )
8084 	         {
8085 	            for( i = digraph->componentstarts[digraph->ncomponents] - 1; i >= compstart; --i )
8086 	            {
8087 	               components[digraph->components[i]] = digraph->ncomponents - 1;
8088 	            }
8089 	         }
8090 	      }
8091 	   }
8092 	
8093 	   /* restore the number of directed arcs per node */
8094 	   BMScopyMemoryArray(digraph->nsuccessors, ndirectedsuccessors, digraph->nnodes);
8095 	   BMSclearMemoryArray(visited, digraph->nnodes);
8096 	
8097 	   /* return number of components, if the pointer was given */
8098 	   if( ncomponents != NULL )
8099 	      (*ncomponents) = digraph->ncomponents;
8100 	
8101 	TERMINATE:
8102 	   if( retcode != SCIP_OKAY )
8103 	   {
8104 	      SCIPdigraphFreeComponents(digraph);
8105 	   }
8106 	   BMSfreeMemoryArrayNull(&ndirectedsuccessors);
8107 	   BMSfreeMemoryArrayNull(&stackadjvisited);
8108 	   BMSfreeMemoryArrayNull(&dfsstack);
8109 	   BMSfreeMemoryArrayNull(&visited);
8110 	
8111 	   return retcode;
8112 	}
8113 	
8114 	/** Performs an (almost) topological sort on the undirected components of the given directed graph. The undirected
8115 	 *  components should be computed before using SCIPdigraphComputeUndirectedComponents().
8116 	 *
8117 	 *  @note In general a topological sort is not unique.  Note, that there might be directed cycles, that are randomly
8118 	 *        broken, which is the reason for having only almost topologically sorted arrays.
8119 	 */
8120 	SCIP_RETCODE SCIPdigraphTopoSortComponents(
8121 	   SCIP_DIGRAPH*         digraph             /**< directed graph */
8122 	   )
8123 	{
8124 	   SCIP_Bool* visited = NULL;
8125 	   int* comps;
8126 	   int* compstarts;
8127 	   int* stackadjvisited = NULL;
8128 	   int* dfsstack = NULL;
8129 	   int* dfsnodes = NULL;
8130 	   int ndfsnodes;
8131 	   int ncomps;
8132 	   int i;
8133 	   int j;
8134 	   int k;
8135 	   int endidx;
8136 	   SCIP_RETCODE retcode = SCIP_OKAY;
8137 	
8138 	   assert(digraph != NULL);
8139 	
8140 	   ncomps = digraph->ncomponents;
8141 	   comps = digraph->components;
8142 	   compstarts = digraph->componentstarts;
8143 	
8144 	   SCIP_ALLOC_TERMINATE( retcode, BMSallocClearMemoryArray(&visited, digraph->nnodes), TERMINATE );
8145 	   SCIP_ALLOC_TERMINATE( retcode, BMSallocMemoryArray(&dfsnodes, digraph->nnodes), TERMINATE );
8146 	   SCIP_ALLOC_TERMINATE( retcode, BMSallocMemoryArray(&dfsstack, digraph->nnodes), TERMINATE );
8147 	   SCIP_ALLOC_TERMINATE( retcode, BMSallocMemoryArray(&stackadjvisited, digraph->nnodes), TERMINATE );
8148 	
8149 	   /* sort the components (almost) topologically */
8150 	   for( i = 0; i < ncomps; ++i )
8151 	   {
8152 	      endidx = compstarts[i+1] - 1;
8153 	      ndfsnodes = 0;
8154 	      for( j = compstarts[i]; j < compstarts[i+1]; ++j )
8155 	      {
8156 	         if( visited[comps[j]] )
8157 	            continue;
8158 	
8159 	         /* perform depth first search, nodes visited in this call are appended to the list dfsnodes in reverse
8160 	          * dfs order, after the nodes already contained;
8161 	          * so at every point in time, the nodes in dfsnode are in reverse (almost) topological order
8162 	          */
8163 	         depthFirstSearch(digraph, comps[j], visited, dfsstack, stackadjvisited, dfsnodes, &ndfsnodes);
8164 	      }
8165 	      assert(endidx - ndfsnodes == compstarts[i] - 1);
8166 	
8167 	      /* copy reverse (almost) topologically sorted array of nodes reached by the dfs searches;
8168 	       * reverse their order to get an (almost) topologically sort
8169 	       */
8170 	      for( k = 0; k < ndfsnodes; ++k )
8171 	      {
8172 	         digraph->components[endidx - k] = dfsnodes[k];
8173 	      }
8174 	   }
8175 	
8176 	TERMINATE:
8177 	   BMSfreeMemoryArrayNull(&stackadjvisited);
8178 	   BMSfreeMemoryArrayNull(&dfsstack);
8179 	   BMSfreeMemoryArrayNull(&dfsnodes);
8180 	   BMSfreeMemoryArrayNull(&visited);
8181 	
8182 	   return retcode;
8183 	}
8184 	
8185 	/** returns the number of previously computed undirected components for the given directed graph */
8186 	int SCIPdigraphGetNComponents(
8187 	   SCIP_DIGRAPH*         digraph             /**< directed graph */
8188 	   )
8189 	{
8190 	   assert(digraph != NULL);
8191 	   assert(digraph->componentstartsize > 0); /* components should have been computed */
8192 	
8193 	   return digraph->ncomponents;
8194 	}
8195 	
8196 	/** Returns the previously computed undirected component of the given number for the given directed graph.
8197 	 *  If the components were sorted using SCIPdigraphTopoSortComponents(), the component is (almost) topologically sorted.
8198 	 */
8199 	void SCIPdigraphGetComponent(
8200 	   SCIP_DIGRAPH*         digraph,            /**< directed graph */
8201 	   int                   compidx,            /**< number of the component to return */
8202 	   int**                 nodes,              /**< pointer to store the nodes in the component; or NULL, if not needed */
8203 	   int*                  nnodes              /**< pointer to store the number of nodes in the component;
8204 	                                              *   or NULL, if not needed */
8205 	   )
8206 	{
8207 	   assert(digraph != NULL);
8208 	   assert(compidx >= 0);
8209 	   assert(compidx < digraph->ncomponents);
8210 	   assert(nodes != NULL || nnodes != NULL);
8211 	
8212 	   if( nodes != NULL )
8213 	      (*nodes) = &(digraph->components[digraph->componentstarts[compidx]]);
8214 	   if( nnodes != NULL )
8215 	      (*nnodes) = digraph->componentstarts[compidx + 1] - digraph->componentstarts[compidx];
8216 	}
8217 	
8218 	/* Performs Tarjan's algorithm for a given directed graph to obtain the strongly connected components
8219 	 * which are reachable from a given node.
8220 	 */
8221 	static
8222 	void tarjan(
8223 	   SCIP_DIGRAPH*         digraph,            /**< directed graph */
8224 	   int                   v,                  /**< node to start the algorithm */
8225 	   int*                  lowlink,            /**< array to store lowlink values */
8226 	   int*                  dfsidx,             /**< array to store dfs indices */
8227 	   int*                  stack,              /**< array to store a stack */
8228 	   int*                  stacksize,          /**< pointer to store the size of the stack */
8229 	   SCIP_Bool*            unprocessed,        /**< array to store which node is unprocessed yet */
8230 	   SCIP_Bool*            nodeinstack,        /**< array to store which nodes are in the stack */
8231 	   int*                  maxdfs,             /**< pointer to store index for DFS */
8232 	   int*                  strongcomponents,   /**< array to store for each node the strongly connected
8233 	                                              *   component to which it belongs (components are
8234 	                                              *   numbered 0 to nstrongcomponents - 1); */
8235 	   int*                  nstrongcomponents,  /**< pointer to store the number of computed components so far */
8236 	   int*                  strongcompstartidx, /**< array to store the start index of the computed components */
8237 	   int*                  nstorednodes        /**< pointer to store the number of already stored nodes */
8238 	   )
8239 	{
8240 	   int i;
8241 	
8242 	   assert(digraph != NULL);
8243 	   assert(v >= 0);
8244 	   assert(v < digraph->nnodes);
8245 	   assert(lowlink != NULL);
8246 	   assert(dfsidx != NULL);
8247 	   assert(stack != NULL);
8248 	   assert(stacksize != NULL);
8249 	   assert(*stacksize >= 0);
8250 	   assert(*stacksize < digraph->nnodes);
8251 	   assert(unprocessed != NULL);
8252 	   assert(nodeinstack != NULL);
8253 	   assert(maxdfs != NULL);
8254 	   assert(strongcomponents != NULL);
8255 	   assert(nstrongcomponents != NULL);
8256 	   assert(strongcompstartidx != NULL);
8257 	   assert(nstorednodes != NULL);
8258 	   assert(*nstorednodes >= 0 && *nstorednodes < digraph->nnodes);
8259 	
8260 	   dfsidx[v] = *maxdfs;
8261 	   lowlink[v] = *maxdfs;
8262 	   *maxdfs += 1;
8263 	
8264 	   /* add v to the stack */
8265 	   stack[*stacksize] = v;
8266 	   *stacksize += 1;
8267 	   nodeinstack[v] = TRUE;
8268 	
8269 	   /* mark v as processed */
8270 	   unprocessed[v] = FALSE;
8271 	
8272 	   for( i = 0; i < digraph->nsuccessors[v]; ++i )
8273 	   {
8274 	      int w;
8275 	
8276 	      /* edge (v,w) */
8277 	      w = digraph->successors[v][i];
8278 	
8279 	      if( unprocessed[w] )
8280 	      {
8281 	         tarjan(digraph, w, lowlink, dfsidx, stack, stacksize, unprocessed, nodeinstack, maxdfs, strongcomponents,
8282 	               nstrongcomponents, strongcompstartidx, nstorednodes);
8283 	
8284 	         assert(lowlink[v] >= 0 && lowlink[v] < digraph->nnodes);
8285 	         assert(lowlink[w] >= 0 && lowlink[w] < digraph->nnodes);
8286 	
8287 	         /* update lowlink */
8288 	         lowlink[v] = MIN(lowlink[v], lowlink[w]);
8289 	      }
8290 	      else if( nodeinstack[w] )
8291 	      {
8292 	         assert(lowlink[v] >= 0 && lowlink[v] < digraph->nnodes);
8293 	         assert(dfsidx[w] >= 0 && dfsidx[w] < digraph->nnodes);
8294 	
8295 	         /* update lowlink */
8296 	         lowlink[v] = MIN(lowlink[v], dfsidx[w]);
8297 	      }
8298 	   }
8299 	
8300 	   /* found a root of a strong component */
8301 	   if( lowlink[v] == dfsidx[v] )
8302 	   {
8303 	      int w;
8304 	
8305 	      strongcompstartidx[*nstrongcomponents] = *nstorednodes;
8306 	      *nstrongcomponents += 1;
8307 	
8308 	      do
8309 	      {
8310 	         assert(*stacksize > 0);
8311 	
8312 	         /* stack.pop() */
8313 	         w = stack[*stacksize - 1];
8314 	         *stacksize -= 1;
8315 	         nodeinstack[w] = FALSE;
8316 	
8317 	         /* store the node in the corresponding component */
8318 	         strongcomponents[*nstorednodes] = w;
8319 	         *nstorednodes += 1;
8320 	      }
8321 	      while( v != w );
8322 	   }
8323 	}
8324 	
8325 	/** Computes all strongly connected components of an undirected connected component with Tarjan's Algorithm.
8326 	 *  The resulting strongly connected components are sorted topologically (starting from the end of the
8327 	 *  strongcomponents array).
8328 	 *
8329 	 *  @note In general a topological sort of the strongly connected components is not unique.
8330 	 */
8331 	SCIP_RETCODE SCIPdigraphComputeDirectedComponents(
8332 	   SCIP_DIGRAPH*         digraph,            /**< directed graph */
8333 	   int                   compidx,            /**< number of the undirected connected component */
8334 	   int*                  strongcomponents,   /**< array to store the strongly connected components
8335 	                                              *   (length >= size of the component) */
8336 	   int*                  strongcompstartidx, /**< array to store the start indices of the strongly connected
8337 	                                              *   components (length >= size of the component) */
8338 	   int*                  nstrongcomponents   /**< pointer to store the number of strongly connected
8339 	                                              *   components */
8340 	   )
8341 	{
8342 	   int* lowlink;
(1) Event var_decl: Declaring variable "dfsidx" without initializer.
Also see events: [uninit_use_in_call]
8343 	   int* dfsidx;
8344 	   int* stack;
8345 	   int stacksize;
8346 	   SCIP_Bool* unprocessed;
8347 	   SCIP_Bool* nodeinstack;
8348 	   int maxdfs;
8349 	   int nstorednodes;
8350 	   int i;
8351 	   SCIP_RETCODE retcode;
8352 	
8353 	   assert(digraph != NULL);
8354 	   assert(compidx >= 0);
8355 	   assert(compidx < digraph->ncomponents);
8356 	   assert(strongcomponents != NULL);
8357 	   assert(strongcompstartidx != NULL);
8358 	   assert(nstrongcomponents != NULL);
8359 	
8360 	   retcode = SCIP_OKAY;
8361 	
(2) Event cond_true: Condition "NULL == (lowlink = BMSallocMemoryArray_call((size_t)(ptrdiff_t)digraph->nnodes, 4UL /* sizeof (*lowlink) */, "/sapmnt/home1/d029903/my_work/SCIPSoPlex_coverity/scipoptsuite-8.0.1/scip/src/scip/misc.c", 8362))", taking true branch.
(3) Event goto: Jumping to label "TERMINATE".
8362 	   SCIP_ALLOC_TERMINATE( retcode, BMSallocMemoryArray(&lowlink, digraph->nnodes), TERMINATE );
8363 	   SCIP_ALLOC_TERMINATE( retcode, BMSallocMemoryArray(&dfsidx, digraph->nnodes), TERMINATE );
8364 	   SCIP_ALLOC_TERMINATE( retcode, BMSallocMemoryArray(&stack, digraph->nnodes), TERMINATE );
8365 	   SCIP_ALLOC_TERMINATE( retcode, BMSallocMemoryArray(&unprocessed, digraph->nnodes), TERMINATE );
8366 	   SCIP_ALLOC_TERMINATE( retcode, BMSallocMemoryArray(&nodeinstack, digraph->nnodes), TERMINATE );
8367 	
8368 	   for( i = 0; i < digraph->nnodes; ++i )
8369 	   {
8370 	      lowlink[i] = -1;
8371 	      dfsidx[i] = -1;
8372 	      stack[i] = -1;
8373 	      unprocessed[i] = TRUE;
8374 	      nodeinstack[i] = FALSE;
8375 	   }
8376 	
8377 	   nstorednodes = 0;
8378 	   stacksize = 0;
8379 	   maxdfs = 0;
8380 	   *nstrongcomponents = 0;
8381 	
8382 	   /* iterate over all nodes in the undirected connected component */
8383 	   for( i = digraph->componentstarts[compidx]; i < digraph->componentstarts[compidx + 1]; ++i )
8384 	   {
8385 	      int v;
8386 	
8387 	      v = digraph->components[i];
8388 	      assert(v >= 0 && v < digraph->nnodes);
8389 	
8390 	      /* call Tarjan's algorithm for unprocessed nodes */
8391 	      if( unprocessed[v] )
8392 	      {
8393 	         SCIPdebugMessage("apply Tarjan's algorithm for node %d\n", v);
8394 	         tarjan(digraph, v, lowlink, dfsidx, stack, &stacksize, unprocessed, nodeinstack, &maxdfs,
8395 	               strongcomponents, nstrongcomponents, strongcompstartidx, &nstorednodes);
8396 	      }
8397 	   }
8398 	
8399 	   /* we should have stored as many nodes as in the undirected connected component */
8400 	   assert(nstorednodes == digraph->componentstarts[compidx + 1] - digraph->componentstarts[compidx]);
8401 	
8402 	   /* to simplify the iteration over all strongly connected components */
8403 	   assert(*nstrongcomponents < digraph->nnodes + 1);
8404 	   strongcompstartidx[*nstrongcomponents] = nstorednodes;
8405 	
8406 	   assert(retcode == SCIP_OKAY);
8407 	
(4) Event label: Reached label "TERMINATE".
8408 	TERMINATE:
8409 	   BMSfreeMemoryArrayNull(&lowlink);
(5) Event uninit_use_in_call: Using uninitialized value "*((void **)&dfsidx)" when calling "BMSfreeMemoryNull_call". [details]
Also see events: [var_decl]
8410 	   BMSfreeMemoryArrayNull(&dfsidx);
8411 	   BMSfreeMemoryArrayNull(&stack);
8412 	   BMSfreeMemoryArrayNull(&unprocessed);
8413 	   BMSfreeMemoryArrayNull(&nodeinstack);
8414 	
8415 	   return retcode;
8416 	}
8417 	
8418 	/** frees the component information for the given directed graph */
8419 	void SCIPdigraphFreeComponents(
8420 	   SCIP_DIGRAPH*         digraph             /**< directed graph */
8421 	   )
8422 	{
8423 	   BMS_BLKMEM* blkmem;
8424 	
8425 	   assert(digraph != NULL);
8426 	   assert(digraph->blkmem != NULL);
8427 	
8428 	   blkmem = digraph->blkmem;
8429 	
8430 	   /* free components structure */
8431 	   if( digraph->componentstartsize > 0 )
8432 	   {
8433 	      BMSfreeBlockMemoryArray(blkmem, &digraph->componentstarts, digraph->componentstartsize);
8434 	      BMSfreeBlockMemoryArray(blkmem, &digraph->components, digraph->nnodes);
8435 	      digraph->components = NULL;
8436 	      digraph->componentstarts = NULL;
8437 	      digraph->ncomponents = 0;
8438 	      digraph->componentstartsize = 0;
8439 	   }
8440 	#ifndef NDEBUG
8441 	   else
8442 	   {
8443 	      assert(digraph->components == NULL);
8444 	      assert(digraph->componentstarts == NULL);
8445 	      assert(digraph->ncomponents == 0);
8446 	   }
8447 	#endif
8448 	}
8449 	
8450 	/** output of the given directed graph via the given message handler */
8451 	void SCIPdigraphPrint(
8452 	   SCIP_DIGRAPH*         digraph,            /**< directed graph */
8453 	   SCIP_MESSAGEHDLR*     messagehdlr,        /**< message handler */
8454 	   FILE*                 file                /**< output file (or NULL for standard output) */
8455 	   )
8456 	{
8457 	   int n;
8458 	
8459 	   for( n = 0; n < digraph->nnodes; ++n )
8460 	   {
8461 	      int* successors;
8462 	      int nsuccessors;
8463 	      int m;
8464 	
8465 	      nsuccessors = digraph->nsuccessors[n];
8466 	      successors = digraph->successors[n];
8467 	
8468 	      SCIPmessageFPrintInfo(messagehdlr, file, "node %d --> ", n);
8469 	
8470 	      for( m = 0; m < nsuccessors ; ++m )
8471 	      {
8472 	         if( m == 0 )
8473 	         {
8474 	            SCIPmessageFPrintInfo(messagehdlr, file, "%d", successors[m]);
8475 	         }
8476 	         else
8477 	         {
8478 	            SCIPmessageFPrintInfo(messagehdlr, file, ", %d", successors[m]);
8479 	         }
8480 	      }
8481 	      SCIPmessageFPrintInfo(messagehdlr, file, "\n");
8482 	   }
8483 	}
8484 	
8485 	/** prints the given directed graph structure in GML format into the given file */
8486 	void SCIPdigraphPrintGml(
8487 	   SCIP_DIGRAPH*         digraph,            /**< directed graph */
8488 	   FILE*                 file                /**< file to write to */
8489 	   )
8490 	{
8491 	   int n;
8492 	
8493 	   /* write GML format opening */
8494 	   SCIPgmlWriteOpening(file, TRUE);
8495 	
8496 	   /* write all nodes of the graph */
8497 	   for( n = 0; n < digraph->nnodes; ++n )
8498 	   {
8499 	      char label[SCIP_MAXSTRLEN];
8500 	
8501 	      (void)SCIPsnprintf(label, SCIP_MAXSTRLEN, "%d", n);
8502 	      SCIPgmlWriteNode(file, (unsigned int)n, label, "circle", NULL, NULL);
8503 	   }
8504 	
8505 	   /* write all edges */
8506 	   for( n = 0; n < digraph->nnodes; ++n )
8507 	   {
8508 	      int* successors;
8509 	      int nsuccessors;
8510 	      int m;
8511 	
8512 	      nsuccessors = digraph->nsuccessors[n];
8513 	      successors = digraph->successors[n];
8514 	
8515 	      for( m = 0; m < nsuccessors; ++m )
8516 	      {
8517 	         SCIPgmlWriteArc(file, (unsigned int)n, (unsigned int)successors[m], NULL, NULL);
8518 	      }
8519 	   }
8520 	   /* write GML format closing */
8521 	   SCIPgmlWriteClosing(file);
8522 	}
8523 	
8524 	/** output of the given directed graph via the given message handler */
8525 	void SCIPdigraphPrintComponents(
8526 	   SCIP_DIGRAPH*         digraph,            /**< directed graph */
8527 	   SCIP_MESSAGEHDLR*     messagehdlr,        /**< message handler */
8528 	   FILE*                 file                /**< output file (or NULL for standard output) */
8529 	   )
8530 	{
8531 	   int c;
8532 	   int i;
8533 	
8534 	   for( c = 0; c < digraph->ncomponents; ++c )
8535 	   {
8536 	      int start = digraph->componentstarts[c];
8537 	      int end =  digraph->componentstarts[c+1];
8538 	
8539 	      SCIPmessageFPrintInfo(messagehdlr, file, "Components %d --> ", c);
8540 	
8541 	      for( i = start; i < end; ++i )
8542 	      {
8543 	         if( i == start )
8544 	         {
8545 	            SCIPmessageFPrintInfo(messagehdlr, file, "%d", digraph->components[i]);
8546 	         }
8547 	         else
8548 	         {
8549 	            SCIPmessageFPrintInfo(messagehdlr, file, ", %d", digraph->components[i]);
8550 	         }
8551 	      }
8552 	      SCIPmessageFPrintInfo(messagehdlr, file, "\n");
8553 	   }
8554 	}
8555 	
8556 	/*
8557 	 * Binary tree
8558 	 */
8559 	
8560 	/** creates a node for a binary tree */
8561 	static
8562 	SCIP_RETCODE btnodeCreateEmpty(
8563 	   SCIP_BT*              tree,               /**< binary tree */
8564 	   SCIP_BTNODE**         node                /**< pointer to store the created node */
8565 	   )
8566 	{
8567 	   SCIP_ALLOC( BMSallocBlockMemory(tree->blkmem, node) );
8568 	
8569 	   (*node)->parent = NULL;
8570 	   (*node)->left = NULL;
8571 	   (*node)->right = NULL;
8572 	   (*node)->dataptr = NULL;
8573 	
8574 	   return SCIP_OKAY;
8575 	}
8576 	
8577 	/** creates a tree node with (optinal) user data */
8578 	SCIP_RETCODE SCIPbtnodeCreate(
8579 	   SCIP_BT*              tree,               /**< binary tree */
8580 	   SCIP_BTNODE**         node,               /**< pointer to store the created node */
8581 	   void*                 dataptr             /**< user node data pointer, or NULL */
8582 	   )
8583 	{
8584 	   assert(tree != NULL);
8585 	   assert(node != NULL);
8586 	
8587 	   SCIP_CALL( btnodeCreateEmpty(tree, node) );
8588 	
8589 	   assert((*node)->parent == NULL);
8590 	   assert((*node)->left == NULL);
8591 	   assert((*node)->right == NULL);
8592 	
8593 	   /* initialize user data */
8594 	   (*node)->dataptr = dataptr;
8595 	
8596 	   return SCIP_OKAY;
8597 	}
8598 	
8599 	/** frees a tree leaf */
8600 	static
8601 	void btnodeFreeLeaf(
8602 	   SCIP_BT*              tree,               /**< binary tree */
8603 	   SCIP_BTNODE**         node                /**< pointer to node which has to be freed */
8604 	   )
8605 	{
8606 	   assert(tree != NULL);
8607 	   assert(node != NULL);
8608 	   assert(*node != NULL);
8609 	
8610 	   assert((*node)->left == NULL);
8611 	   assert((*node)->right == NULL);
8612 	
8613 	#if 0
8614 	   /* remove reference from parent node */
8615 	   if( (*node)->parent != NULL )
8616 	   {
8617 	      assert(*node != NULL);
8618 	
8619 	      assert((*node)->parent->left == *node || ((*node)->parent->right == *node));
8620 	
8621 	      if( (*node)->parent->left == *node )
8622 	      {
8623 	         (*node)->parent->left = NULL;
8624 	      }
8625 	      else
8626 	      {
8627 	         assert((*node)->parent->right == *node);
8628 	         (*node)->parent->right = NULL;
8629 	      }
8630 	   }
8631 	#endif
8632 	
8633 	   assert(*node != NULL);
8634 	   BMSfreeBlockMemory(tree->blkmem, node);
8635 	   assert(*node == NULL);
8636 	}
8637 	
8638 	/** frees the node including the rooted subtree
8639 	 *
8640 	 *  @note The user pointer (object) is not freed. If needed, it has to be done by the user.
8641 	 */
8642 	void SCIPbtnodeFree(
8643 	   SCIP_BT*              tree,               /**< binary tree */
8644 	   SCIP_BTNODE**         node                /**< node to be freed */
8645 	   )
8646 	{
8647 	   assert(tree != NULL);
8648 	   assert(node != NULL);
8649 	   assert(*node != NULL);
8650 	
8651 	   if( (*node)->left != NULL )
8652 	   {
8653 	      SCIPbtnodeFree(tree, &(*node)->left);
8654 	      assert((*node)->left == NULL);
8655 	   }
8656 	
8657 	   if( (*node)->right != NULL )
8658 	   {
8659 	      SCIPbtnodeFree(tree, &(*node)->right);
8660 	      assert((*node)->right == NULL);
8661 	   }
8662 	
8663 	   btnodeFreeLeaf(tree, node);
8664 	   assert(*node == NULL);
8665 	}
8666 	
8667 	/* some simple variable functions implemented as defines */
8668 	
8669 	/* In debug mode, the following methods are implemented as function calls to ensure
8670 	 * type validity.
8671 	 * In optimized mode, the methods are implemented as defines to improve performance.
8672 	 * However, we want to have them in the library anyways, so we have to undef the defines.
8673 	 */
8674 	
8675 	#undef SCIPbtnodeGetData
8676 	#undef SCIPbtnodeGetKey
8677 	#undef SCIPbtnodeGetParent
8678 	#undef SCIPbtnodeGetLeftchild
8679 	#undef SCIPbtnodeGetRightchild
8680 	#undef SCIPbtnodeGetSibling
8681 	#undef SCIPbtnodeIsRoot
8682 	#undef SCIPbtnodeIsLeaf
8683 	#undef SCIPbtnodeIsLeftchild
8684 	#undef SCIPbtnodeIsRightchild
8685 	
8686 	/** returns the user data pointer stored in that node */
8687 	void* SCIPbtnodeGetData(
8688 	   SCIP_BTNODE*          node                /**< node */
8689 	   )
8690 	{
8691 	   assert(node != NULL);
8692 	
8693 	   return node->dataptr;
8694 	}
8695 	
8696 	/** returns the parent which can be NULL if the given node is the root */
8697 	SCIP_BTNODE* SCIPbtnodeGetParent(
8698 	   SCIP_BTNODE*          node                /**< node */
8699 	   )
8700 	{
8701 	   assert(node != NULL);
8702 	
8703 	   return node->parent;
8704 	}
8705 	
8706 	/** returns left child which can be NULL if the given node is a leaf */
8707 	SCIP_BTNODE* SCIPbtnodeGetLeftchild(
8708 	   SCIP_BTNODE*          node                /**< node */
8709 	   )
8710 	{
8711 	   assert(node != NULL);
8712 	
8713 	   return node->left;
8714 	}
8715 	
8716 	/** returns right child which can be NULL if the given node is a leaf */
8717 	SCIP_BTNODE* SCIPbtnodeGetRightchild(
8718 	   SCIP_BTNODE*          node                /**< node */
8719 	   )
8720 	{
8721 	   assert(node != NULL);
8722 	
8723 	   return node->right;
8724 	}
8725 	
8726 	/** returns the sibling of the node or NULL if does not exist */
8727 	SCIP_BTNODE* SCIPbtnodeGetSibling(
8728 	   SCIP_BTNODE*          node                /**< node */
8729 	   )
8730 	{
8731 	   SCIP_BTNODE* parent;
8732 	
8733 	   parent = SCIPbtnodeGetParent(node);
8734 	
8735 	   if( parent == NULL )
8736 	      return NULL;
8737 	
8738 	   if( SCIPbtnodeGetLeftchild(parent) == node )
8739 	      return SCIPbtnodeGetRightchild(parent);
8740 	
8741 	   assert(SCIPbtnodeGetRightchild(parent) == node);
8742 	
8743 	   return SCIPbtnodeGetLeftchild(parent);
8744 	}
8745 	
8746 	/** returns whether the node is a root node */
8747 	SCIP_Bool SCIPbtnodeIsRoot(
8748 	   SCIP_BTNODE*          node                /**< node */
8749 	   )
8750 	{
8751 	   assert(node != NULL);
8752 	
8753 	   return (node->parent == NULL);
8754 	}
8755 	
8756 	/** returns whether the node is a leaf */
8757 	SCIP_Bool SCIPbtnodeIsLeaf(
8758 	   SCIP_BTNODE*          node                /**< node */
8759 	   )
8760 	{
8761 	   assert(node != NULL);
8762 	
8763 	   return (node->left == NULL && node->right == NULL);
8764 	}
8765 	
8766 	/** returns TRUE if the given node is left child */
8767 	SCIP_Bool SCIPbtnodeIsLeftchild(
8768 	   SCIP_BTNODE*          node                /**< node */
8769 	   )
8770 	{
8771 	   SCIP_BTNODE* parent;
8772 	
8773 	   if( SCIPbtnodeIsRoot(node) )
8774 	      return FALSE;
8775 	
8776 	   parent = SCIPbtnodeGetParent(node);
8777 	
8778 	   if( SCIPbtnodeGetLeftchild(parent) == node )
8779 	      return TRUE;
8780 	
8781 	   return FALSE;
8782 	}
8783 	
8784 	/** returns TRUE if the given node is right child */
8785 	SCIP_Bool SCIPbtnodeIsRightchild(
8786 	   SCIP_BTNODE*          node                /**< node */
8787 	   )
8788 	{
8789 	   SCIP_BTNODE* parent;
8790 	
8791 	   if( SCIPbtnodeIsRoot(node) )
8792 	      return FALSE;
8793 	
8794 	   parent = SCIPbtnodeGetParent(node);
8795 	
8796 	   if( SCIPbtnodeGetRightchild(parent) == node )
8797 	      return TRUE;
8798 	
8799 	   return FALSE;
8800 	}
8801 	
8802 	/** sets the give node data
8803 	 *
8804 	 *  @note The old user pointer is not freed.
8805 	 */
8806 	void SCIPbtnodeSetData(
8807 	   SCIP_BTNODE*          node,               /**< node */
8808 	   void*                 dataptr             /**< node user data pointer */
8809 	   )
8810 	{
8811 	   assert(node != NULL);
8812 	
8813 	   node->dataptr = dataptr;
8814 	}
8815 	
8816 	/** sets parent node
8817 	 *
8818 	 *  @note The old parent including the rooted subtree is not delete.
8819 	 */
8820 	void SCIPbtnodeSetParent(
8821 	   SCIP_BTNODE*          node,               /**< node */
8822 	   SCIP_BTNODE*          parent              /**< new parent node, or NULL */
8823 	   )
8824 	{
8825 	   assert(node != NULL);
8826 	
8827 	   node->parent = parent;
8828 	}
8829 	
8830 	/** sets left child
8831 	 *
8832 	 *  @note The old left child including the rooted subtree is not delete.
8833 	 */
8834 	void SCIPbtnodeSetLeftchild(
8835 	   SCIP_BTNODE*          node,               /**< node */
8836 	   SCIP_BTNODE*          left                /**< new left child, or NULL */
8837 	   )
8838 	{
8839 	   assert(node != NULL);
8840 	
8841 	   node->left = left;
8842 	}
8843 	
8844 	/** sets right child
8845 	 *
8846 	 *  @note The old right child including the rooted subtree is not delete.
8847 	 */
8848 	void SCIPbtnodeSetRightchild(
8849 	   SCIP_BTNODE*          node,               /**< node */
8850 	   SCIP_BTNODE*          right               /**< new right child, or NULL */
8851 	   )
8852 	{
8853 	   assert(node != NULL);
8854 	
8855 	   node->right = right;
8856 	}
8857 	
8858 	/** creates an binary tree */
8859 	SCIP_RETCODE SCIPbtCreate(
8860 	   SCIP_BT**             tree,               /**< pointer to store the created binary tree */
8861 	   BMS_BLKMEM*           blkmem              /**< block memory used to createnode */
8862 	   )
8863 	{
8864 	   assert(tree != NULL);
8865 	   assert(blkmem != NULL);
8866 	
8867 	   SCIP_ALLOC( BMSallocBlockMemory(blkmem, tree) );
8868 	   (*tree)->blkmem = blkmem;
8869 	   (*tree)->root = NULL;
8870 	
8871 	   return SCIP_OKAY;
8872 	}
8873 	
8874 	/** frees binary tree
8875 	 *
8876 	 *  @note The user pointers (object) of the nodes are not freed. If needed, it has to be done by the user.
8877 	 */
8878 	void SCIPbtFree(
8879 	   SCIP_BT**             tree                /**< pointer to binary tree */
8880 	   )
8881 	{
8882 	   assert(tree != NULL);
8883 	
8884 	   if( (*tree)->root != NULL )
8885 	   {
8886 	      SCIPbtnodeFree(*tree, &((*tree)->root));
8887 	   }
8888 	
8889 	   BMSfreeBlockMemory((*tree)->blkmem, tree);
8890 	}
8891 	
8892 	/** prints the rooted subtree of the given binary tree node in GML format into the given file */
8893 	static
8894 	void btPrintSubtree(
8895 	   SCIP_BTNODE*          node,               /**< binary tree node */
8896 	   FILE*                 file,               /**< file to write to */
8897 	   int*                  nnodes              /**< pointer to count the number of nodes */
8898 	   )
8899 	{
8900 	   SCIP_BTNODE* left;
8901 	   SCIP_BTNODE* right;
8902 	   char label[SCIP_MAXSTRLEN];
8903 	
8904 	   assert(node != NULL);
8905 	
8906 	   (*nnodes)++;
8907 	   (void)SCIPsnprintf(label, SCIP_MAXSTRLEN, "%d", *nnodes);
8908 	
8909 	   SCIPgmlWriteNode(file, (unsigned int)(size_t)node, label, "circle", NULL, NULL);
8910 	
8911 	   left = SCIPbtnodeGetLeftchild(node);
8912 	   right = SCIPbtnodeGetRightchild(node);
8913 	
8914 	   if( left != NULL )
8915 	   {
8916 	      btPrintSubtree(left, file, nnodes);
8917 	
8918 	      SCIPgmlWriteArc(file, (unsigned int)(size_t)node, (unsigned int)(size_t)left, NULL, NULL);
8919 	   }
8920 	
8921 	   if( right != NULL )
8922 	   {
8923 	      btPrintSubtree(right, file, nnodes);
8924 	
8925 	      SCIPgmlWriteArc(file, (unsigned int)(size_t)node, (unsigned int)(size_t)right, NULL, NULL);
8926 	   }
8927 	}
8928 	
8929 	/** prints the binary tree in GML format into the given file */
8930 	void SCIPbtPrintGml(
8931 	   SCIP_BT*              tree,               /**< binary tree */
8932 	   FILE*                 file                /**< file to write to */
8933 	   )
8934 	{
8935 	   /* write GML opening */
8936 	   SCIPgmlWriteOpening(file, TRUE);
8937 	
8938 	   if( !SCIPbtIsEmpty(tree) )
8939 	   {
8940 	      SCIP_BTNODE* root;
8941 	      int nnodes;
8942 	
8943 	      root = SCIPbtGetRoot(tree);
8944 	      assert(root != NULL);
8945 	
8946 	      nnodes = 0;
8947 	
8948 	      btPrintSubtree(root, file, &nnodes);
8949 	   }
8950 	
8951 	   /* write GML closing */
8952 	   SCIPgmlWriteClosing(file);
8953 	}
8954 	
8955 	/* some simple variable functions implemented as defines */
8956 	#undef SCIPbtIsEmpty
8957 	#undef SCIPbtGetRoot
8958 	
8959 	/** returns whether the binary tree is empty (has no nodes) */
8960 	SCIP_Bool SCIPbtIsEmpty(
8961 	   SCIP_BT*              tree                /**< binary tree */
8962 	   )
8963 	{
8964 	   assert(tree != NULL);
8965 	
8966 	   return (tree->root == NULL);
8967 	}
8968 	
8969 	/** returns the the root node of the binary or NULL if the binary tree is empty */
8970 	SCIP_BTNODE* SCIPbtGetRoot(
8971 	   SCIP_BT*              tree                /**< tree to be evaluated */
8972 	   )
8973 	{
8974 	   assert(tree != NULL);
8975 	
8976 	   return tree->root;
8977 	}
8978 	
8979 	/** sets root node
8980 	 *
8981 	 *  @note The old root including the rooted subtree is not delete.
8982 	 */
8983 	void SCIPbtSetRoot(
8984 	   SCIP_BT*              tree,               /**< tree to be evaluated */
8985 	   SCIP_BTNODE*          root                /**< new root, or NULL */
8986 	   )
8987 	{
8988 	   assert(tree != NULL);
8989 	
8990 	   tree->root = root;
8991 	}
8992 	
8993 	
8994 	/*
8995 	 * Numerical methods
8996 	 */
8997 	
8998 	/** returns the machine epsilon: the smallest number eps > 0, for which 1.0 + eps > 1.0 */
8999 	SCIP_Real SCIPcalcMachineEpsilon(
9000 	   void
9001 	   )
9002 	{
9003 	   SCIP_Real eps;
9004 	   SCIP_Real lasteps;
9005 	   SCIP_Real one;
9006 	   SCIP_Real onepluseps;
9007 	
9008 	   one = 1.0;
9009 	   eps = 1.0;
9010 	   do
9011 	   {
9012 	      lasteps = eps;
9013 	      eps /= 2.0;
9014 	      onepluseps = one + eps;
9015 	   }
9016 	   while( onepluseps > one );
9017 	
9018 	   return lasteps;
9019 	}
9020 	
9021 	/** calculates the greatest common divisor of the two given values */
9022 	SCIP_Longint SCIPcalcGreComDiv(
9023 	   SCIP_Longint          val1,               /**< first value of greatest common devisor calculation */
9024 	   SCIP_Longint          val2                /**< second value of greatest common devisor calculation */
9025 	   )
9026 	{
9027 	   int t;
9028 	
9029 	   assert(val1 > 0);
9030 	   assert(val2 > 0);
9031 	
9032 	   t = 0;
9033 	   /* if val1 is even, divide it by 2 */
9034 	   while( !(val1 & 1) )
9035 	   {
9036 	      val1 >>= 1; /*lint !e704*/
9037 	
9038 	      /* if val2 is even too, divide it by 2 and increase t(=number of e) */
9039 	      if( !(val2 & 1) )
9040 	      {
9041 	         val2 >>= 1; /*lint !e704*/
9042 	         ++t;
9043 	      }
9044 	      /* only val1 can be odd */
9045 	      else
9046 	      {
9047 	         /* while val1 is even, divide it by 2 */
9048 	         while( !(val1 & 1) )
9049 	            val1 >>= 1; /*lint !e704*/
9050 	
9051 	         break;
9052 	      }
9053 	   }
9054 	
9055 	   /* while val2 is even, divide it by 2 */
9056 	   while( !(val2 & 1) )
9057 	      val2 >>= 1; /*lint !e704*/
9058 	
9059 	   /* the following if/else condition is only to make sure that we do not overflow when adding up both values before
9060 	    * dividing them by 4 in the following while loop
9061 	    */
9062 	   if( t == 0 )
9063 	   {
9064 	      if( val1 > val2 )
9065 	      {
9066 	         val1 -= val2;
9067 	
9068 	         /* divide val1 by 2 as long as possible  */
9069 	         while( !(val1 & 1) )
9070 	            val1 >>= 1;   /*lint !e704*/
9071 	      }
9072 	      else if( val1 < val2 )
9073 	      {
9074 	         val2 -= val1;
9075 	
9076 	         /* divide val2 by 2 as long as possible  */
9077 	         while( !(val2 & 1) )
9078 	            val2 >>= 1;   /*lint !e704*/
9079 	      }
9080 	   }
9081 	
9082 	   /* val1 and val2 are odd */
9083 	   while( val1 != val2 )
9084 	   {
9085 	      if( val1 > val2 )
9086 	      {
9087 	         /* we can stop if one value reached one */
9088 	         if( val2 == 1 )
9089 	            return (val2 << t);  /*lint !e647 !e703*/
9090 	
9091 	         /* if ((val1 xor val2) and 2) = 2, then gcd(val1, val2) = gcd((val1 + val2)/4, val2),
9092 	          * and otherwise                        gcd(val1, val2) = gcd((val1 − val2)/4, val2)
9093 	          */
9094 	         if( ((val1 ^ val2) & 2) == 2 )
9095 	            val1 += val2;
9096 	         else
9097 	            val1 -= val2;
9098 	
9099 	         assert((val1 & 3) == 0);
9100 	         val1 >>= 2;   /*lint !e704*/
9101 	
9102 	         /* if val1 is still even, divide it by 2  */
9103 	         while( !(val1 & 1) )
9104 	            val1 >>= 1;   /*lint !e704*/
9105 	      }
9106 	      else
9107 	      {
9108 	         /* we can stop if one value reached one */
9109 	         if( val1 == 1 )
9110 	            return (val1 << t);  /*lint !e647 !e703*/
9111 	
9112 	         /* if ((val2 xor val1) and 2) = 2, then gcd(val2, val1) = gcd((val2 + val1)/4, val1),
9113 	          * and otherwise                        gcd(val2, val1) = gcd((val2 − val1)/4, val1)
9114 	          */
9115 	         if( ((val2 ^ val1) & 2) == 2 )
9116 	            val2 += val1;
9117 	         else
9118 	            val2 -= val1;
9119 	
9120 	         assert((val2 & 3) == 0);
9121 	         val2 >>= 2;   /*lint !e704*/
9122 	
9123 	         /* if val2 is still even, divide it by 2  */
9124 	         while( !(val2 & 1) )
9125 	            val2 >>= 1;   /*lint !e704*/
9126 	      }
9127 	   }
9128 	
9129 	   return (val1 << t);  /*lint !e703*/
9130 	}
9131 	
9132 	
9133 	/* for the MS compiler, the function nextafter is named _nextafter */
9134 	#if defined(_MSC_VER) && !defined(NO_NEXTAFTER)
9135 	#define nextafter(x,y) _nextafter(x,y)
9136 	#endif
9137 	
9138 	/* on systems where the function nextafter is not defined, we provide an implementation from Sun */
9139 	#ifdef NO_NEXTAFTER
9140 	/* The following implementation of the routine nextafter() comes with the following license:
9141 	 *
9142 	 * ====================================================
9143 	 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
9144 	 *
9145 	 * Developed at SunSoft, a Sun Microsystems, Inc. business.
9146 	 * Permission to use, copy, modify, and distribute this
9147 	 * software is freely granted, provided that this notice
9148 	 * is preserved.
9149 	 * ====================================================
9150 	 */
9151 	
9152 	#define __HI(x) *(1+(int*)&x)
9153 	#define __LO(x) *(int*)&x
9154 	#define __HIp(x) *(1+(int*)x)
9155 	#define __LOp(x) *(int*)x
9156 	
9157 	static
9158 	double nextafter(double x, double y)
9159 	{
9160 	   int hx;
9161 	   int hy;
9162 	   int ix;
9163 	   int iy;
9164 	   unsigned lx;
9165 	   unsigned ly;
9166 	
9167 	   /* cppcheck-suppress invalidPointerCast */
9168 	   hx = __HI(x);     /* high word of x */
9169 	   /* cppcheck-suppress invalidPointerCast */
9170 	   lx = __LO(x);     /* low  word of x */
9171 	   /* cppcheck-suppress invalidPointerCast */
9172 	   hy = __HI(y);     /* high word of y */
9173 	   /* cppcheck-suppress invalidPointerCast */
9174 	   ly = __LO(y);     /* low  word of y */
9175 	   ix = hx&0x7fffffff;     /* |x| */
9176 	   iy = hy&0x7fffffff;     /* |y| */
9177 	
9178 	   if( ((ix>=0x7ff00000) && ((ix-0x7ff00000)|lx) != 0 ) ||   /* x is nan */
9179 	      ( (iy>=0x7ff00000) && ((iy-0x7ff00000)|ly) != 0 ))     /* y is nan */
9180 	      return x + y;
9181 	
9182 	   /* x == y, return x */
9183 	   if( x == y )
9184 	      return x;
9185 	
9186 	   /* x == 0 */
9187 	   if( (ix|lx) == 0 )
9188 	   {
9189 	      /* return +-minsubnormal */
9190 	      /* cppcheck-suppress invalidPointerCast */
9191 	      __HI(x) = hy&0x80000000;
9192 	      /* cppcheck-suppress invalidPointerCast */
9193 	      __LO(x) = 1;
9194 	      y = x * x;
9195 	      if ( y == x )
9196 	         return y;
9197 	      else
9198 	         return x;  /* raise underflow flag */
9199 	   }
9200 	   /* x > 0 */
9201 	   if( hx >= 0 )
9202 	   {
9203 	      /* x > y, x -= ulp */
9204 	      if( hx > hy || ((hx == hy) && (lx > ly)) )
9205 	      {
9206 	         if ( lx == 0 )
9207 	            hx -= 1;
9208 	         lx -= 1;
9209 	      }
9210 	      else
9211 	      {
9212 	         /* x < y, x += ulp */
9213 	         lx += 1;
9214 	         if ( lx == 0 )
9215 	            hx += 1;
9216 	      }
9217 	   }
9218 	   else
9219 	   {
9220 	      /* x < 0 */
9221 	      if( hy >= 0 || hx > hy || ((hx == hy) && (lx > ly)) )
9222 	      {
9223 	         /* x < y, x -= ulp */
9224 	         if ( lx == 0 )
9225 	            hx -= 1;
9226 	         lx -= 1;
9227 	      }
9228 	      else
9229 	      {
9230 	         /* x > y, x += ulp */
9231 	         lx += 1;
9232 	         if( lx == 0 )
9233 	            hx += 1;
9234 	      }
9235 	   }
9236 	   hy = hx&0x7ff00000;
9237 	   /* overflow  */
9238 	   if( hy >= 0x7ff00000 )
9239 	      return x + x;
9240 	   if( hy < 0x00100000 )
9241 	   {
9242 	      /* underflow */
9243 	      y = x*x;
9244 	      if( y != x )
9245 	      {
9246 	         /* raise underflow flag */
9247 	         /* cppcheck-suppress invalidPointerCast */
9248 	         __HI(y) = hx;
9249 	         /* cppcheck-suppress invalidPointerCast */
9250 	         __LO(y) = lx;
9251 	         return y;
9252 	      }
9253 	   }
9254 	
9255 	   /* cppcheck-suppress invalidPointerCast */
9256 	   __HI(x) = hx;
9257 	   /* cppcheck-suppress invalidPointerCast */
9258 	   __LO(x) = lx;
9259 	   return x;
9260 	}
9261 	#endif
9262 	
9263 	
9264 	/** returns the next representable value of from in the direction of to */
9265 	SCIP_Real SCIPnextafter(
9266 	   SCIP_Real             from,               /**< value from which the next representable value should be returned */
9267 	   SCIP_Real             to                  /**< direction in which the next representable value should be returned */
9268 	   )
9269 	{
9270 	   return nextafter(from, to);
9271 	}
9272 	
9273 	/** calculates the smallest common multiple of the two given values */
9274 	SCIP_Longint SCIPcalcSmaComMul(
9275 	   SCIP_Longint          val1,               /**< first value of smallest common multiple calculation */
9276 	   SCIP_Longint          val2                /**< second value of smallest common multiple calculation */
9277 	   )
9278 	{
9279 	   SCIP_Longint gcd;
9280 	
9281 	   assert(val1 > 0);
9282 	   assert(val2 > 0);
9283 	
9284 	   gcd = SCIPcalcGreComDiv(val1, val2);
9285 	
9286 	   return val1/gcd * val2;
9287 	}
9288 	
9289 	static const SCIP_Real simplednoms[] = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0,
9290 	                                   17.0, 18.0, 19.0, 25.0, -1.0};
9291 	
9292 	/** converts a real number into a (approximate) rational representation, and returns TRUE iff the conversion was
9293 	 *  successful
9294 	 */
9295 	SCIP_Bool SCIPrealToRational(
9296 	   SCIP_Real             val,                /**< real value r to convert into rational number */
9297 	   SCIP_Real             mindelta,           /**< minimal allowed difference r - q of real r and rational q = n/d */
9298 	   SCIP_Real             maxdelta,           /**< maximal allowed difference r - q of real r and rational q = n/d */
9299 	   SCIP_Longint          maxdnom,            /**< maximal denominator allowed */
9300 	   SCIP_Longint*         nominator,          /**< pointer to store the nominator n of the rational number */
9301 	   SCIP_Longint*         denominator         /**< pointer to store the denominator d of the rational number */
9302 	   )
9303 	{
9304 	   SCIP_Real a;
9305 	   SCIP_Real b;
9306 	   SCIP_Real g0;
9307 	   SCIP_Real g1;
9308 	   SCIP_Real gx;
9309 	   SCIP_Real h0;
9310 	   SCIP_Real h1;
9311 	   SCIP_Real hx;
9312 	   SCIP_Real delta0;
9313 	   SCIP_Real delta1;
9314 	   SCIP_Real epsilon;
9315 	   int i;
9316 	
9317 	   assert(mindelta < 0.0);
9318 	   assert(maxdelta > 0.0);
9319 	   assert(nominator != NULL);
9320 	   assert(denominator != NULL);
9321 	
9322 	   if( REALABS(val) >= ((SCIP_Real)SCIP_LONGINT_MAX) / maxdnom )
9323 	      return FALSE;
9324 	
9325 	   /* try the simple denominators first: each value of the simpledenoms table multiplied by powers of 10
9326 	    * is tried as denominator
9327 	    */
9328 	   for( i = 0; simplednoms[i] > 0.0; ++i )
9329 	   {
9330 	      SCIP_Real nom;
9331 	      SCIP_Real dnom;
9332 	      SCIP_Real ratval0;
9333 	      SCIP_Real ratval1;
9334 	
9335 	      /* try powers of 10 (including 10^0) */
9336 	      dnom = simplednoms[i];
9337 	      while( dnom <= maxdnom )
9338 	      {
9339 	         nom = floor(val * dnom);
9340 	         ratval0 = nom/dnom;
9341 	         ratval1 = (nom+1.0)/dnom;
9342 	         if( mindelta <= val - ratval0 && val - ratval1 <= maxdelta )
9343 	         {
9344 	            if( val - ratval0 <= maxdelta )
9345 	            {
9346 	               *nominator = (SCIP_Longint)nom;
9347 	               *denominator = (SCIP_Longint)dnom;
9348 	               return TRUE;
9349 	            }
9350 	            if( mindelta <= val - ratval1 )
9351 	            {
9352 	               *nominator = (SCIP_Longint)(nom+1.0);
9353 	               *denominator = (SCIP_Longint)dnom;
9354 	               return TRUE;
9355 	            }
9356 	         }
9357 	         dnom *= 10.0;
9358 	      }
9359 	   }
9360 	
9361 	   /* the simple denominators didn't work: calculate rational representation with arbitrary denominator */
9362 	   epsilon = MIN(-mindelta, maxdelta)/2.0;
9363 	
9364 	   b = val;
9365 	   a = EPSFLOOR(b, epsilon);
9366 	   g0 = a;
9367 	   h0 = 1.0;
9368 	   g1 = 1.0;
9369 	   h1 = 0.0;
9370 	   delta0 = val - g0/h0;
9371 	   delta1 = (delta0 < 0.0 ? val - (g0-1.0)/h0 : val - (g0+1.0)/h0);
9372 	
9373 	   while( (delta0 < mindelta || delta0 > maxdelta) && (delta1 < mindelta || delta1 > maxdelta) )
9374 	   {
9375 	      assert(EPSGT(b, a, epsilon));
9376 	      assert(h0 >= 0.0);
9377 	      assert(h1 >= 0.0);
9378 	
9379 	      b = 1.0 / (b - a);
9380 	      a = EPSFLOOR(b, epsilon);
9381 	
9382 	      assert(a >= 0.0);
9383 	      gx = g0;
9384 	      hx = h0;
9385 	
9386 	      g0 = a * g0 + g1;
9387 	      h0 = a * h0 + h1;
9388 	
9389 	      g1 = gx;
9390 	      h1 = hx;
9391 	
9392 	      if( h0 > maxdnom )
9393 	         return FALSE;
9394 	
9395 	      delta0 = val - g0/h0;
9396 	      delta1 = (delta0 < 0.0 ? val - (g0-1.0)/h0 : val - (g0+1.0)/h0);
9397 	   }
9398 	
9399 	   if( REALABS(g0) > (SCIP_Real)(SCIP_LONGINT_MAX >> 4) || h0 > (SCIP_Real)(SCIP_LONGINT_MAX >> 4) )
9400 	      return FALSE;
9401 	
9402 	   assert(h0 > 0.5);
9403 	
9404 	   if( delta0 < mindelta )
9405 	   {
9406 	      assert(mindelta <= delta1 && delta1 <= maxdelta);
9407 	      *nominator = (SCIP_Longint)(g0 - 1.0);
9408 	      *denominator = (SCIP_Longint)h0;
9409 	   }
9410 	   else if( delta0 > maxdelta )
9411 	   {
9412 	      assert(mindelta <= delta1 && delta1 <= maxdelta);
9413 	      *nominator = (SCIP_Longint)(g0 + 1.0);
9414 	      *denominator = (SCIP_Longint)h0;
9415 	   }
9416 	   else
9417 	   {
9418 	      *nominator = (SCIP_Longint)g0;
9419 	      *denominator = (SCIP_Longint)h0;
9420 	   }
9421 	   assert(*denominator >= 1);
9422 	   assert(val - (SCIP_Real)(*nominator)/(SCIP_Real)(*denominator) >= mindelta);
9423 	   assert(val - (SCIP_Real)(*nominator)/(SCIP_Real)(*denominator) <= maxdelta);
9424 	
9425 	   return TRUE;
9426 	}
9427 	
9428 	/** checks, whether the given scalar scales the given value to an integral number with error in the given bounds */
9429 	static
9430 	SCIP_Bool isIntegralScalar(
9431 	   SCIP_Real             val,                /**< value that should be scaled to an integral value */
9432 	   SCIP_Real             scalar,             /**< scalar that should be tried */
9433 	   SCIP_Real             mindelta,           /**< minimal relative allowed difference of scaled coefficient s*c and integral i */
9434 	   SCIP_Real             maxdelta            /**< maximal relative allowed difference of scaled coefficient s*c and integral i */
9435 	   )
9436 	{
9437 	   SCIP_Real sval;
9438 	   SCIP_Real downval;
9439 	   SCIP_Real upval;
9440 	
9441 	   assert(mindelta <= 0.0);
9442 	   assert(maxdelta >= 0.0);
9443 	
9444 	   sval = val * scalar;
9445 	   downval = floor(sval);
9446 	   upval = ceil(sval);
9447 	
9448 	   return (SCIPrelDiff(sval, downval) <= maxdelta || SCIPrelDiff(sval, upval) >= mindelta);
9449 	}
9450 	
9451 	/** additional scalars that are tried in integrality scaling */
9452 	static const SCIP_Real scalars[] = {3.0, 5.0, 7.0, 9.0, 11.0, 13.0, 15.0, 17.0, 19.0};
9453 	static const int nscalars = 9;
9454 	
9455 	/** tries to find a value, such that all given values, if scaled with this value become integral in relative allowed
9456 	 *  difference in between mindelta and maxdelta
9457 	 */
9458 	SCIP_RETCODE SCIPcalcIntegralScalar(
9459 	   SCIP_Real*            vals,               /**< values to scale */
9460 	   int                   nvals,              /**< number of values to scale */
9461 	   SCIP_Real             mindelta,           /**< minimal relative allowed difference of scaled coefficient s*c and integral i */
9462 	   SCIP_Real             maxdelta,           /**< maximal relative allowed difference of scaled coefficient s*c and integral i */
9463 	   SCIP_Longint          maxdnom,            /**< maximal denominator allowed in rational numbers */
9464 	   SCIP_Real             maxscale,           /**< maximal allowed scalar */
9465 	   SCIP_Real*            intscalar,          /**< pointer to store scalar that would make the coefficients integral, or NULL */
9466 	   SCIP_Bool*            success             /**< stores whether returned value is valid */
9467 	   )
9468 	{
9469 	   SCIP_Real bestscalar;
9470 	   SCIP_Longint gcd;
9471 	   SCIP_Longint scm;
9472 	   SCIP_Longint nominator;
9473 	   SCIP_Longint denominator;
9474 	   SCIP_Real val;
9475 	   SCIP_Real minval;
9476 	   SCIP_Real absval;
9477 	   SCIP_Real scaleval;
9478 	   SCIP_Bool scalable;
9479 	   SCIP_Bool rational;
9480 	   int c;
9481 	   int s;
9482 	   int i;
9483 	
9484 	   assert(vals != NULL);
9485 	   assert(nvals >= 0);
9486 	   assert(maxdnom >= 1);
9487 	   assert(mindelta < 0.0);
9488 	   assert(maxdelta > 0.0);
9489 	   assert(success != NULL);
9490 	
9491 	   SCIPdebugMessage("trying to find rational representation for given values\n");
9492 	
9493 	   if( intscalar != NULL )
9494 	      *intscalar = SCIP_INVALID;
9495 	   *success = FALSE;
9496 	
9497 	   /* get minimal absolute non-zero value */
9498 	   minval = SCIP_REAL_MAX;
9499 	   for( c = 0; c < nvals; ++c )
9500 	   {
9501 	      val = vals[c];
9502 	      if( val < mindelta || val > maxdelta )
9503 	      {
9504 	         absval = REALABS(val);
9505 	         minval = MIN(minval, absval);
9506 	      }
9507 	   }
9508 	
9509 	   if( minval == SCIP_REAL_MAX ) /*lint !e777*/
9510 	   {
9511 	      /* all coefficients are zero (inside tolerances) */
9512 	      if( intscalar != NULL )
9513 	         *intscalar = 1.0;
9514 	      *success = TRUE;
9515 	      SCIPdebugMessage(" -> all values are zero (inside tolerances)\n");
9516 	
9517 	      return SCIP_OKAY;
9518 	   }
9519 	   assert(minval > MIN(-mindelta, maxdelta));
9520 	
9521 	   bestscalar = SCIP_INVALID;
9522 	
9523 	   for( i = 0; i < 2; ++i )
9524 	   {
9525 	      scalable = TRUE;
9526 	
9527 	      /* try, if values can be made integral multiplying them with the reciprocal of the smallest value and a power of 2 */
9528 	      if( i == 0 )
9529 		 scaleval = 1.0/minval;
9530 	      /* try, if values can be made integral by multiplying them by a power of 2 */
9531 	      else
9532 		 scaleval = 1.0;
9533 	
9534 	      for( c = 0; c < nvals && scalable; ++c )
9535 	      {
9536 		 /* check, if the value can be scaled with a simple scalar */
9537 		 val = vals[c];
9538 		 if( val == 0.0 ) /* zeros are allowed in the vals array */
9539 		    continue;
9540 	
9541 		 absval = REALABS(val);
9542 		 while( scaleval <= maxscale
9543 		    && (absval * scaleval < 0.5 || !isIntegralScalar(val, scaleval, mindelta, maxdelta)) )
9544 		 {
9545 		    for( s = 0; s < nscalars; ++s )
9546 		    {
9547 		       if( isIntegralScalar(val, scaleval * scalars[s], mindelta, maxdelta) )
9548 		       {
9549 			  scaleval *= scalars[s];
9550 			  break;
9551 		       }
9552 		    }
9553 		    if( s >= nscalars )
9554 		       scaleval *= 2.0;
9555 		 }
9556 		 scalable = (scaleval <= maxscale);
9557 		 SCIPdebugMessage(" -> val=%g, scaleval=%g, val*scaleval=%g, scalable=%u\n",
9558 		    val, scaleval, val*scaleval, scalable);
9559 	      }
9560 	      if( scalable )
9561 	      {
9562 		 /* make values integral by dividing them by the smallest value (and multiplying them with a power of 2) */
9563 		 assert(scaleval <= maxscale);
9564 	
9565 		 /* check if we found a better scaling value */
9566 		 if( scaleval < bestscalar )
9567 		    bestscalar = scaleval;
9568 	
9569 		 SCIPdebugMessage(" -> integrality could be achieved by scaling with %g\n", scaleval);
9570 	
9571 		 /* if the scalar is still the reciprocal of the minimal value, all coeffcients are the same and we do not get a better scalar */
9572 		 if( i == 0 && EPSEQ(scaleval, 1.0/minval, SCIP_DEFAULT_EPSILON) )
9573 		 {
9574 		    if( intscalar != NULL )
9575 		       *intscalar = bestscalar;
9576 		    *success = TRUE;
9577 	
9578 		    return SCIP_OKAY;
9579 		 }
9580 	      }
9581 	   }
9582 	
9583 	   /* convert each value into a rational number, calculate the greatest common divisor of the nominators
9584 	    * and the smallest common multiple of the denominators
9585 	    */
9586 	   gcd = 1;
9587 	   scm = 1;
9588 	   rational = TRUE;
9589 	
9590 	   /* first value (to initialize gcd) */
9591 	   for( c = 0; c < nvals && rational; ++c )
9592 	   {
9593 	      val = vals[c];
9594 	      if( val == 0.0 ) /* zeros are allowed in the vals array */
9595 	         continue;
9596 	
9597 	      rational = SCIPrealToRational(val, mindelta, maxdelta, maxdnom, &nominator, &denominator);
9598 	      if( rational && nominator != 0 )
9599 	      {
9600 	         assert(denominator > 0);
9601 	         gcd = ABS(nominator);
9602 	         scm = denominator;
9603 	         rational = ((SCIP_Real)scm/(SCIP_Real)gcd <= maxscale);
9604 	         SCIPdebugMessage(" -> c=%d first rational: val: %g == %" SCIP_LONGINT_FORMAT "/%" SCIP_LONGINT_FORMAT ", gcd=%" SCIP_LONGINT_FORMAT ", scm=%" SCIP_LONGINT_FORMAT ", rational=%u\n",
9605 	            c, val, nominator, denominator, gcd, scm, rational);
9606 	         break;
9607 	      }
9608 	   }
9609 	
9610 	   /* remaining values */
9611 	   for( ++c; c < nvals && rational; ++c )
9612 	   {
9613 	      val = vals[c];
9614 	      if( val == 0.0 ) /* zeros are allowed in the vals array */
9615 	         continue;
9616 	
9617 	      rational = SCIPrealToRational(val, mindelta, maxdelta, maxdnom, &nominator, &denominator);
9618 	      if( rational && nominator != 0 )
9619 	      {
9620 	         assert(denominator > 0);
9621 	         gcd = SCIPcalcGreComDiv(gcd, ABS(nominator));
9622 	         scm *= denominator / SCIPcalcGreComDiv(scm, denominator);
9623 	         rational = ((SCIP_Real)scm/(SCIP_Real)gcd <= maxscale);
9624 	         SCIPdebugMessage(" -> c=%d next rational : val: %g == %" SCIP_LONGINT_FORMAT "/%" SCIP_LONGINT_FORMAT ", gcd=%" SCIP_LONGINT_FORMAT ", scm=%" SCIP_LONGINT_FORMAT ", rational=%u\n",
9625 	            c, val, nominator, denominator, gcd, scm, rational);
9626 	      }
9627 	      else
9628 	      {
9629 	         SCIPdebugMessage(" -> failed to convert %g into a rational representation\n", val);
9630 	      }
9631 	   }
9632 	
9633 	   if( rational )
9634 	   {
9635 	      /* make values integral by multiplying them with the smallest common multiple of the denominators */
9636 	      assert((SCIP_Real)scm/(SCIP_Real)gcd <= maxscale);
9637 	
9638 	      /* check if we found a better scaling value */
9639 	      if( (SCIP_Real)scm/(SCIP_Real)gcd < bestscalar )
9640 		 bestscalar = (SCIP_Real)scm/(SCIP_Real)gcd;
9641 	
9642 	      SCIPdebugMessage(" -> integrality could be achieved by scaling with %g (rational:%" SCIP_LONGINT_FORMAT "/%" SCIP_LONGINT_FORMAT ")\n",
9643 	         (SCIP_Real)scm/(SCIP_Real)gcd, scm, gcd);
9644 	   }
9645 	
9646 	   if( bestscalar < SCIP_INVALID )
9647 	   {
9648 	      if( intscalar != NULL )
9649 	         *intscalar = bestscalar;
9650 	      *success = TRUE;
9651 	
9652 	      SCIPdebugMessage(" -> smallest value to achieve integrality is %g \n", bestscalar);
9653 	   }
9654 	
9655 	   return SCIP_OKAY;
9656 	}
9657 	
9658 	/* Inform compiler that this code accesses the floating-point environment, so that
9659 	 * certain optimizations should be omitted (http://www.cplusplus.com/reference/cfenv/FENV_ACCESS/).
9660 	 * Not supported by Clang (gives warning) and GCC (silently), at the moment.
9661 	 */
9662 	#if defined(__INTEL_COMPILER) || defined(_MSC_VER)
9663 	#pragma fenv_access (on)
9664 	#elif defined __GNUC__
9665 	#pragma STDC FENV_ACCESS ON
9666 	#endif
9667 	
9668 	/** given a (usually very small) interval, tries to find a rational number with simple denominator (i.e. a small
9669 	 *  number, probably multiplied with powers of 10) out of this interval; returns TRUE iff a valid rational
9670 	 *  number inside the interval was found
9671 	 */
9672 	SCIP_Bool SCIPfindSimpleRational(
9673 	   SCIP_Real             lb,                 /**< lower bound of the interval */
9674 	   SCIP_Real             ub,                 /**< upper bound of the interval */
9675 	   SCIP_Longint          maxdnom,            /**< maximal denominator allowed for resulting rational number */
9676 	   SCIP_Longint*         nominator,          /**< pointer to store the nominator n of the rational number */
9677 	   SCIP_Longint*         denominator         /**< pointer to store the denominator d of the rational number */
9678 	   )
9679 	{
9680 	   SCIP_Real center;
9681 	   SCIP_Real delta;
9682 	
9683 	   assert(lb <= ub);
9684 	
9685 	   center = 0.5*(lb+ub);
9686 	
9687 	   /* in order to compute a rational number that is exactly within the bounds (as the user expects),
9688 	    * we computed the allowed delta with downward rounding, if available
9689 	    */
9690 	   if( SCIPintervalHasRoundingControl() )
9691 	   {
9692 	      SCIP_ROUNDMODE roundmode;
9693 	
9694 	      roundmode = SCIPintervalGetRoundingMode();
9695 	      SCIPintervalSetRoundingModeDownwards();
9696 	
9697 	      delta = 0.5*(ub-lb);
9698 	
9699 	      SCIPintervalSetRoundingMode(roundmode);
9700 	   }
9701 	   else
9702 	   {
9703 	      delta = 0.5*(ub-lb);
9704 	   }
9705 	
9706 	   return SCIPrealToRational(center, -delta, +delta, maxdnom, nominator, denominator);
9707 	}
9708 	
9709 	#if defined(__INTEL_COMPILER) || defined(_MSC_VER)
9710 	#pragma fenv_access (off)
9711 	#elif defined __GNUC__
9712 	#pragma STDC FENV_ACCESS OFF
9713 	#endif
9714 	
9715 	/** given a (usually very small) interval, selects a value inside this interval; it is tried to select a rational number
9716 	 *  with simple denominator (i.e. a small number, probably multiplied with powers of 10);
9717 	 *  if no valid rational number inside the interval was found, selects the central value of the interval
9718 	 */
9719 	SCIP_Real SCIPselectSimpleValue(
9720 	   SCIP_Real             lb,                 /**< lower bound of the interval */
9721 	   SCIP_Real             ub,                 /**< upper bound of the interval */
9722 	   SCIP_Longint          maxdnom             /**< maximal denominator allowed for resulting rational number */
9723 	   )
9724 	{
9725 	   SCIP_Real val;
9726 	
9727 	   val = 0.5*(lb+ub);
9728 	   if( lb < ub )
9729 	   {
9730 	      SCIP_Longint nominator;
9731 	      SCIP_Longint denominator;
9732 	      SCIP_Bool success;
9733 	
9734 	      /* try to find a "simple" rational number inside the interval */
9735 	      SCIPdebugMessage("simple rational in [%.9f,%.9f]:", lb, ub);
9736 	      success = SCIPfindSimpleRational(lb, ub, maxdnom, &nominator, &denominator);
9737 	      if( success )
9738 	      {
9739 	         val = (SCIP_Real)nominator/(SCIP_Real)denominator;
9740 	         SCIPdebugPrintf(" %" SCIP_LONGINT_FORMAT "/%" SCIP_LONGINT_FORMAT " == %.9f\n", nominator, denominator, val);
9741 	
9742 	         if( val - lb < 0.0 || val - ub > 0.0 )
9743 	         {
9744 	            SCIPdebugPrintf(" value is out of interval bounds by %g -> failed\n", MAX(lb-val, val-ub));
9745 	            val = 0.5*(lb+ub);
9746 	         }
9747 	      }
9748 	      else
9749 	      {
9750 	         SCIPdebugPrintf(" failed\n");
9751 	      }
9752 	   }
9753 	
9754 	   return val;
9755 	}
9756 	
9757 	/** Performs the Newton Procedure from a given starting point to compute a root of the given function with
9758 	 *  specified precision and maximum number of iterations. If the procedure fails, SCIP_INVALID is returned.
9759 	 */
9760 	SCIP_Real SCIPcalcRootNewton(
9761 	   SCIP_DECL_NEWTONEVAL((*function)),        /**< pointer to function for which roots are computed */
9762 	   SCIP_DECL_NEWTONEVAL((*derivative)),      /**< pointer to derivative of above function */
9763 	   SCIP_Real*            params,             /**< parameters needed for function (can be NULL) */
9764 	   int                   nparams,            /**< number of parameters (can be 0) */
9765 	   SCIP_Real             x,                  /**< starting point */
9766 	   SCIP_Real             eps,                /**< tolerance */
9767 	   int                   k                   /**< iteration limit */
9768 	   )
9769 	{
9770 	   SCIP_Real result = x;
9771 	   int iteration = 0;
9772 	
9773 	   assert(function != NULL);
9774 	   assert(derivative != NULL);
9775 	   assert(params != NULL || nparams == 0);
9776 	   assert(eps > 0.0);
9777 	   assert(k >= 0);
9778 	   assert(x != SCIP_INVALID); /*lint !e777*/
9779 	
9780 	   while( iteration < k )
9781 	   {
9782 	      SCIP_Real deriv = derivative(result, params, nparams);
9783 	
9784 	      /* if we arrive at a stationary point, the procedure is aborted */
9785 	      if( REALABS(deriv) <= eps || deriv == SCIP_INVALID ) /*lint !e777*/
9786 	         return SCIP_INVALID;
9787 	
9788 	      result = result - function(result, params, nparams) / deriv;
9789 	
9790 	      /* if new point is within eps-range of 0, we are done */
9791 	      if( REALABS(function(result, params, nparams)) <= eps )
9792 	         break;
9793 	
9794 	      ++iteration;
9795 	   }
9796 	
9797 	   if( k == iteration )
9798 	      return SCIP_INVALID;
9799 	   else
9800 	      return result;
9801 	}
9802 	
9803 	
9804 	/*
9805 	 * Random Numbers
9806 	 */
9807 	
9808 	#if defined(NO_RAND_R) || defined(_WIN32) || defined(_WIN64)
9809 	
9810 	#define SCIP_RAND_MAX 32767
9811 	/** returns a random number between 0 and SCIP_RAND_MAX */
9812 	static
9813 	int getRand(
9814 	   unsigned int*         seedp               /**< pointer to seed value */
9815 	   )
9816 	{
9817 	   SCIP_Longint nextseed;
9818 	
9819 	   assert(seedp != NULL);
9820 	
9821 	   nextseed = (*seedp) * (SCIP_Longint)1103515245 + 12345;
9822 	   *seedp = (unsigned int)nextseed;
9823 	
9824 	   return (int)((unsigned int)(nextseed/(2*(SCIP_RAND_MAX+1))) % (SCIP_RAND_MAX+1));
9825 	}
9826 	
9827 	#else
9828 	
9829 	#define SCIP_RAND_MAX RAND_MAX
9830 	
9831 	/** returns a random number between 0 and SCIP_RAND_MAX */
9832 	static
9833 	int getRand(
9834 	   unsigned int*         seedp               /**< pointer to seed value */
9835 	   )
9836 	{
9837 	   return rand_r(seedp);
9838 	}
9839 	
9840 	#endif
9841 	
9842 	/** returns a random integer between minrandval and maxrandval */
9843 	static
9844 	int getRandomInt(
9845 	   int                   minrandval,         /**< minimal value to return */
9846 	   int                   maxrandval,         /**< maximal value to return */
9847 	   unsigned int*         seedp               /**< pointer to seed value */
9848 	   )
9849 	{
9850 	   SCIP_Real randnumber;
9851 	
9852 	   randnumber = (SCIP_Real)getRand(seedp)/(SCIP_RAND_MAX+1.0);
9853 	   assert(randnumber >= 0.0);
9854 	   assert(randnumber < 1.0);
9855 	
9856 	   /* we multiply minrandval and maxrandval separately by randnumber in order to avoid overflow if they are more than INT_MAX
9857 	    * apart
9858 	    */
9859 	   return (int) (minrandval*(1.0 - randnumber) + maxrandval*randnumber + randnumber);
9860 	}
9861 	
9862 	/** returns a random real between minrandval and maxrandval */
9863 	static
9864 	SCIP_Real getRandomReal(
9865 	   SCIP_Real             minrandval,         /**< minimal value to return */
9866 	   SCIP_Real             maxrandval,         /**< maximal value to return */
9867 	   unsigned int*         seedp               /**< pointer to seed value */
9868 	   )
9869 	{
9870 	   SCIP_Real randnumber;
9871 	
9872 	   randnumber = (SCIP_Real)getRand(seedp)/(SCIP_Real)SCIP_RAND_MAX;
9873 	   assert(randnumber >= 0.0);
9874 	   assert(randnumber <= 1.0);
9875 	
9876 	   /* we multiply minrandval and maxrandval separately by randnumber in order to avoid overflow if they are more than
9877 	    * SCIP_REAL_MAX apart
9878 	    */
9879 	   return minrandval*(1.0 - randnumber) + maxrandval*randnumber;
9880 	}
9881 	
9882 	/** returns a random integer between minrandval and maxrandval
9883 	 *
9884 	 *  @deprecated Please use SCIPrandomGetInt() to request a random integer.
9885 	 */
9886 	int SCIPgetRandomInt(
9887 	   int                   minrandval,         /**< minimal value to return */
9888 	   int                   maxrandval,         /**< maximal value to return */
9889 	   unsigned int*         seedp               /**< pointer to seed value */
9890 	   )
9891 	{
9892 	   return getRandomInt(minrandval, maxrandval, seedp);
9893 	}
9894 	
9895 	/** returns a random real between minrandval and maxrandval
9896 	 *
9897 	 *  @deprecated Please use SCIPrandomGetReal() to request a random real.
9898 	 */
9899 	SCIP_Real SCIPgetRandomReal(
9900 	   SCIP_Real             minrandval,         /**< minimal value to return */
9901 	   SCIP_Real             maxrandval,         /**< maximal value to return */
9902 	   unsigned int*         seedp               /**< pointer to seed value */
9903 	   )
9904 	{
9905 	   return getRandomReal(minrandval, maxrandval, seedp);
9906 	}
9907 	
9908 	
9909 	/* initial seeds for KISS random number generator */
9910 	#define DEFAULT_SEED UINT32_C(123456789)
9911 	#define DEFAULT_XOR  UINT32_C(362436000)
9912 	#define DEFAULT_MWC  UINT32_C(521288629)
9913 	#define DEFAULT_CST  UINT32_C(7654321)
9914 	
9915 	
9916 	/** initializes a random number generator with a given start seed */
9917 	void SCIPrandomSetSeed(
9918 	   SCIP_RANDNUMGEN*      randnumgen,         /**< random number generator */
9919 	   unsigned int          initseed            /**< initial random seed */
9920 	   )
9921 	{
9922 	   assert(randnumgen != NULL);
9923 	
9924 	   /* use MAX() to avoid zero after over flowing */
9925 	   randnumgen->seed = MAX(SCIPhashTwo(DEFAULT_SEED, initseed), 1u);
9926 	   randnumgen->xor_seed = MAX(SCIPhashTwo(DEFAULT_XOR, initseed), 1u);
9927 	   randnumgen->mwc_seed = MAX(SCIPhashTwo(DEFAULT_MWC, initseed), 1u);
9928 	   randnumgen->cst_seed = SCIPhashTwo(DEFAULT_CST, initseed);
9929 	
9930 	   assert(randnumgen->seed > 0);
9931 	   assert(randnumgen->xor_seed > 0);
9932 	   assert(randnumgen->mwc_seed > 0);
9933 	}
9934 	
9935 	/** returns a random number between 0 and UINT32_MAX
9936 	 *
9937 	 *  implementation of KISS random number generator developed by George Marsaglia.
9938 	 *  KISS is combination of three different random number generators:
9939 	 *   - Linear congruential generator
9940 	 *   - Xorshift
9941 	 *   - Lag-1 Multiply-with-carry
9942 	 *
9943 	 *  KISS has a period of 2^123 and passes all statistical test part of BigCrush-Test of TestU01 [1].
9944 	 *
9945 	 *  [1] http://dl.acm.org/citation.cfm?doid=1268776.1268777
9946 	 */
9947 	static
9948 	uint32_t randomGetRand(
9949 	   SCIP_RANDNUMGEN*      randnumgen          /**< random number generator */
9950 	   )
9951 	{
9952 	   uint64_t t;
9953 	
9954 	   /* linear congruential */
9955 	   randnumgen->seed = (uint32_t) (randnumgen->seed * UINT64_C(1103515245) + UINT64_C(12345));
9956 	
9957 	   /* Xorshift */
9958 	   randnumgen->xor_seed ^= (randnumgen->xor_seed << 13);
9959 	   randnumgen->xor_seed ^= (randnumgen->xor_seed >> 17);
9960 	   randnumgen->xor_seed ^= (randnumgen->xor_seed << 5);
9961 	
9962 	   /* Multiply-with-carry */
9963 	   t = UINT64_C(698769069) * randnumgen->mwc_seed + randnumgen->cst_seed;
9964 	   randnumgen->cst_seed = (uint32_t) (t >> 32);
9965 	   randnumgen->mwc_seed = (uint32_t) t;
9966 	
9967 	   return randnumgen->seed + randnumgen->xor_seed + randnumgen->mwc_seed;
9968 	}
9969 	
9970 	/** creates and initializes a random number generator */
9971 	SCIP_RETCODE SCIPrandomCreate(
9972 	   SCIP_RANDNUMGEN**     randnumgen,         /**< random number generator */
9973 	   BMS_BLKMEM*           blkmem,             /**< block memory */
9974 	   unsigned int          initialseed         /**< initial random seed */
9975 	   )
9976 	{
9977 	   assert(randnumgen != NULL);
9978 	
9979 	   SCIP_ALLOC( BMSallocBlockMemory(blkmem, randnumgen) );
9980 	
9981 	   SCIPrandomSetSeed((*randnumgen), initialseed);
9982 	
9983 	   return SCIP_OKAY;
9984 	}
9985 	
9986 	/** frees a random number generator */
9987 	void SCIPrandomFree(
9988 	   SCIP_RANDNUMGEN**     randnumgen,         /**< random number generator */
9989 	   BMS_BLKMEM*           blkmem              /**< block memory */
9990 	   )
9991 	{
9992 	   assert(randnumgen != NULL);
9993 	   assert((*randnumgen) != NULL);
9994 	
9995 	   BMSfreeBlockMemory(blkmem, randnumgen);
9996 	
9997 	   return;
9998 	}
9999 	
10000	
10001	
10002	/** returns a random integer between minrandval and maxrandval */
10003	int SCIPrandomGetInt(
10004	   SCIP_RANDNUMGEN*      randnumgen,         /**< random number generator */
10005	   int                   minrandval,         /**< minimal value to return */
10006	   int                   maxrandval          /**< maximal value to return */
10007	   )
10008	{
10009	   SCIP_Real randnumber;
10010	   SCIP_Longint zeromax;
10011	
10012	   randnumber = (SCIP_Real)randomGetRand(randnumgen)/(UINT32_MAX+1.0);
10013	   assert(randnumber >= 0.0);
10014	   assert(randnumber < 1.0);
10015	
10016	   /* we need to shift the range to the non-negative integers to handle negative integer values correctly.
10017	    * we use a long integer to avoid overflows.
10018	    */
10019	   zeromax = (SCIP_Longint)maxrandval - (SCIP_Longint)minrandval + 1;
10020	
10021	   return (int) ((SCIP_Longint)(zeromax * randnumber) + (SCIP_Longint)minrandval);
10022	}
10023	
10024	/** returns a random real between minrandval and maxrandval */
10025	SCIP_Real SCIPrandomGetReal(
10026	   SCIP_RANDNUMGEN*      randnumgen,         /**< random number generator */
10027	   SCIP_Real             minrandval,         /**< minimal value to return */
10028	   SCIP_Real             maxrandval          /**< maximal value to return */
10029	   )
10030	{
10031	   SCIP_Real randnumber;
10032	
10033	   randnumber = (SCIP_Real)randomGetRand(randnumgen)/(SCIP_Real)UINT32_MAX;
10034	   assert(randnumber >= 0.0);
10035	   assert(randnumber <= 1.0);
10036	
10037	   /* we multiply minrandval and maxrandval separately by randnumber in order to avoid overflow if they are more than
10038	    * SCIP_REAL_MAX apart
10039	    */
10040	   return minrandval*(1.0 - randnumber) + maxrandval*randnumber;
10041	}
10042	
10043	/** randomly shuffles parts of an integer array using the Fisher-Yates algorithm */
10044	void SCIPrandomPermuteIntArray(
10045	   SCIP_RANDNUMGEN*      randnumgen,         /**< random number generator */
10046	   int*                  array,              /**< array to be shuffled */
10047	   int                   begin,              /**< first included index that should be subject to shuffling
10048	                                              *   (0 for first array entry)
10049	                                              */
10050	   int                   end                 /**< first excluded index that should not be subject to shuffling
10051	                                              *   (array size for last array entry)
10052	                                              */
10053	   )
10054	{
10055	   int tmp;
10056	   int i;
10057	
10058	   /* loop backwards through all elements and always swap the current last element to a random position */
10059	   while( end > begin+1 )
10060	   {
10061	      --end;
10062	
10063	      /* get a random position into which the last entry should be shuffled */
10064	      i = SCIPrandomGetInt(randnumgen, begin, end);
10065	
10066	      /* swap the last element and the random element */
10067	      tmp = array[i];
10068	      array[i] = array[end];
10069	      array[end] = tmp;
10070	   }
10071	}
10072	
10073	/** randomly shuffles parts of an array using the Fisher-Yates algorithm */
10074	void SCIPrandomPermuteArray(
10075	   SCIP_RANDNUMGEN*      randnumgen,         /**< random number generator */
10076	   void**                array,              /**< array to be shuffled */
10077	   int                   begin,              /**< first included index that should be subject to shuffling
10078	                                              *   (0 for first array entry)
10079	                                              */
10080	   int                   end                 /**< first excluded index that should not be subject to shuffling
10081	                                              *   (array size for last array entry)
10082	                                              */
10083	   )
10084	{
10085	   void* tmp;
10086	   int i;
10087	
10088	   /* loop backwards through all elements and always swap the current last element to a random position */
10089	   while( end > begin+1 )
10090	   {
10091	      end--;
10092	
10093	      /* get a random position into which the last entry should be shuffled */
10094	      i = SCIPrandomGetInt(randnumgen, begin, end);
10095	
10096	      /* swap the last element and the random element */
10097	      tmp = array[i];
10098	      array[i] = array[end];
10099	      array[end] = tmp;
10100	   }
10101	}
10102	
10103	/** draws a random subset of disjoint elements from a given set of disjoint elements;
10104	 *  this implementation is suited for the case that nsubelems is considerably smaller then nelems
10105	 */
10106	SCIP_RETCODE SCIPrandomGetSubset(
10107	   SCIP_RANDNUMGEN*      randnumgen,         /**< random number generator */
10108	   void**                set,                /**< original set, from which elements should be drawn */
10109	   int                   nelems,             /**< number of elements in original set */
10110	   void**                subset,             /**< subset in which drawn elements should be stored */
10111	   int                   nsubelems           /**< number of elements that should be drawn and stored */
10112	   )
10113	{
10114	   int i;
10115	   int j;
10116	
10117	   /* if both sets are of equal size, we just copy the array */
10118	   if( nelems == nsubelems)
10119	   {
10120	      BMScopyMemoryArray(subset,set,nelems);
10121	      return SCIP_OKAY;
10122	   }
10123	
10124	   /* abort, if size of subset is too big */
10125	   if( nsubelems > nelems )
10126	   {
10127	      SCIPerrorMessage("Cannot create %d-elementary subset of %d-elementary set.\n", nsubelems, nelems);
10128	      return SCIP_INVALIDDATA;
10129	   }
10130	#ifndef NDEBUG
10131	   for( i = 0; i < nsubelems; i++ )
10132	      for( j = 0; j < i; j++ )
10133	         assert(set[i] != set[j]);
10134	#endif
10135	
10136	   /* draw each element individually */
10137	   i = 0;
10138	   while( i < nsubelems )
10139	   {
10140	      int r;
10141	
10142	      r = SCIPrandomGetInt(randnumgen, 0, nelems-1);
10143	      subset[i] = set[r];
10144	
10145	      /* if we get an element that we already had, we will draw again */
10146	      for( j = 0; j < i; j++ )
10147	      {
10148	         if( subset[i] == subset[j] )
10149	         {
10150	            --i;
10151	            break;
10152	         }
10153	      }
10154	      ++i;
10155	   }
10156	   return SCIP_OKAY;
10157	}
10158	
10159	/*
10160	 * Additional math functions
10161	 */
10162	
10163	/** calculates a binomial coefficient n over m, choose m elements out of n, maximal value will be 33 over 16 (because
10164	 *  the n=33 is the last line in the Pascal's triangle where each entry fits in a 4 byte value), an error occurs due to
10165	 *  big numbers or an negative value m (and m < n) and -1 will be returned
10166	 */
10167	SCIP_Longint SCIPcalcBinomCoef(
10168	   int                   n,                  /**< number of different elements */
10169	   int                   m                   /**< number to choose out of the above */
10170	   )
10171	{
10172	   if( m == 0 || m >= n )
10173	      return 1;
10174	
10175	   if( m < 0 )
10176	      return -1;
10177	
10178	   /* symmetry of the binomial coefficient, choose smaller m */
10179	   if( m > n/2 )
10180	      m = n - m;
10181	
10182	   /* trivial case m == 1 */
10183	   if( m == 1 )
10184	      return n;
10185	
10186	   /* simple case m == 2 */
10187	   if( m == 2 )
10188	   {
10189	      if( ((SCIP_Real)SCIP_LONGINT_MAX) / n >= (n-1) * 2 ) /*lint !e790*/
10190	         return ((SCIP_Longint)n*(n-1)/2); /*lint !e647*/
10191	      else
10192	         return -1;
10193	   }
10194	
10195	   /* abort on to big numbers */
10196	   if( m > 16 || n > 33 )
10197	      return -1;
10198	
10199	   /* simple case m == 3 */
10200	   if( m == 3 )
10201	      return (n*(n-1)*(n-2)/6); /*lint !e647*/
10202	   else
10203	   {
10204	      /* first half of Pascal's triangle numbers(without the symmetric part) backwards from (33,16) over (32,16),
10205	       * (33,15), (32,15),(31,15, (30,15), (33,14) to (8,4) (rest is calculated directly)
10206	       *
10207	       * due to this order we can extract the right binomial coefficient by (16-m)^2+(16-m)+(33-n)
10208	       */
10209	      static const SCIP_Longint binoms[182] = {
10210	         1166803110, 601080390, 1037158320, 565722720, 300540195, 155117520, 818809200, 471435600, 265182525, 145422675,
10211	         77558760, 40116600, 573166440, 347373600, 206253075, 119759850, 67863915, 37442160, 20058300, 10400600,
10212	         354817320, 225792840, 141120525, 86493225, 51895935, 30421755, 17383860, 9657700, 5200300, 2704156, 193536720,
10213	         129024480, 84672315, 54627300, 34597290, 21474180, 13037895, 7726160, 4457400, 2496144, 1352078, 705432,
10214	         92561040, 64512240, 44352165, 30045015, 20030010, 13123110, 8436285, 5311735, 3268760, 1961256, 1144066,
10215	         646646, 352716, 184756, 38567100, 28048800, 20160075, 14307150, 10015005, 6906900, 4686825, 3124550, 2042975,
10216	         1307504, 817190, 497420, 293930, 167960, 92378, 48620, 13884156, 10518300, 7888725, 5852925, 4292145, 3108105,
10217	         2220075, 1562275, 1081575, 735471, 490314, 319770, 203490, 125970, 75582, 43758, 24310, 12870, 4272048, 3365856,
10218	         2629575, 2035800, 1560780, 1184040, 888030, 657800, 480700, 346104, 245157, 170544, 116280, 77520, 50388, 31824,
10219	         19448, 11440, 6435, 3432, 1107568, 906192, 736281, 593775, 475020, 376740, 296010, 230230, 177100, 134596,
10220	         100947, 74613, 54264, 38760, 27132, 18564, 12376, 8008, 5005, 3003, 1716, 924, 237336, 201376, 169911, 142506,
10221	         118755, 98280, 80730, 65780, 53130, 42504, 33649, 26334, 20349, 15504, 11628, 8568, 6188, 4368, 3003, 2002,
10222	         1287, 792, 462, 252, 40920, 35960, 31465, 27405, 23751, 20475, 17550, 14950, 12650, 10626, 8855, 7315, 5985,
10223	         4845, 3876, 3060, 2380, 1820, 1365, 1001, 715, 495, 330, 210, 126, 70};
10224	
10225	      /* m can at most be 16 */
10226	      const int t = 16-m;
10227	      assert(t >= 0);
10228	      assert(n <= 33);
10229	
10230	      /* binoms array hast exactly 182 elements */
10231	      assert(t*(t+1)+(33-n) < 182);
10232	
10233	      return binoms[t*(t+1)+(33-n)]; /*lint !e662 !e661*/
10234	   }
10235	}
10236	
10237	#ifndef NDEBUG
10238	/** calculates hash for floating-point number by using Fibonacci hashing */
10239	#if defined(__GNUC__) && __GNUC__ * 100 + __GNUC_MINOR__ * 10 >= 490 && !defined(__INTEL_COMPILER)
10240	__attribute__((no_sanitize_undefined))
10241	#endif
10242	unsigned int SCIPcalcFibHash(
10243	   SCIP_Real             v                   /**< number to hash */
10244	   )
10245	{
10246	   if( v >= 0 )
10247	      return ((unsigned long long)(v * 2654435769)) % UINT_MAX;
10248	   return ((unsigned long long)(-v * 683565275)) % UINT_MAX;
10249	}
10250	#endif
10251	
10252	/** negates a number */
10253	SCIP_Real SCIPnegateReal(
10254	   SCIP_Real             x                   /**< value to negate */
10255	   )
10256	{
10257	   return -x;
10258	}
10259	
10260	/*
10261	 * Permutations / Shuffling
10262	 */
10263	
10264	/** swaps two ints */
10265	void SCIPswapInts(
10266	   int*                  value1,             /**< pointer to first integer */
10267	   int*                  value2              /**< pointer to second integer */
10268	   )
10269	{
10270	   int tmp;
10271	
10272	   tmp = *value1;
10273	   *value1 = *value2;
10274	   *value2 = tmp;
10275	}
10276	
10277	/** swaps two real values */
10278	void SCIPswapReals(
10279	   SCIP_Real*            value1,             /**< pointer to first real value */
10280	   SCIP_Real*            value2              /**< pointer to second real value */
10281	   )
10282	{
10283	   SCIP_Real tmp;
10284	
10285	   tmp = *value1;
10286	   *value1 = *value2;
10287	   *value2 = tmp;
10288	}
10289	
10290	/** swaps the addresses of two pointers */
10291	void SCIPswapPointers(
10292	   void**                pointer1,           /**< first pointer */
10293	   void**                pointer2            /**< second pointer */
10294	   )
10295	{
10296	   void* tmp;
10297	
10298	   tmp = *pointer1;
10299	   *pointer1 = *pointer2;
10300	   *pointer2 = tmp;
10301	}
10302	
10303	/** randomly shuffles parts of an integer array using the Fisher-Yates algorithm
10304	 *
10305	 *  @deprecated Please use SCIPrandomPermuteIntArray()
10306	 */
10307	void SCIPpermuteIntArray(
10308	   int*                  array,              /**< array to be shuffled */
10309	   int                   begin,              /**< first included index that should be subject to shuffling
10310	                                              *   (0 for first array entry)
10311	                                              */
10312	   int                   end,                /**< first excluded index that should not be subject to shuffling
10313	                                              *   (array size for last array entry)
10314	                                              */
10315	   unsigned int*         randseed            /**< seed value for the random generator */
10316	   )
10317	{
10318	   int tmp;
10319	   int i;
10320	
10321	   /* loop backwards through all elements and always swap the current last element to a random position */
10322	   while( end > begin+1 )
10323	   {
10324	      --end;
10325	
10326	      /* get a random position into which the last entry should be shuffled */
10327	      i = getRandomInt(begin, end, randseed);
10328	
10329	      /* swap the last element and the random element */
10330	      tmp = array[i];
10331	      array[i] = array[end];
10332	      array[end] = tmp;
10333	   }
10334	}
10335	
10336	
10337	/** randomly shuffles parts of an array using the Fisher-Yates algorithm
10338	 *
10339	 *  @deprecated Please use SCIPrandomPermuteArray()
10340	 */
10341	void SCIPpermuteArray(
10342	   void**                array,              /**< array to be shuffled */
10343	   int                   begin,              /**< first included index that should be subject to shuffling
10344	                                              *   (0 for first array entry)
10345	                                              */
10346	   int                   end,                /**< first excluded index that should not be subject to shuffling
10347	                                              *   (array size for last array entry)
10348	                                              */
10349	   unsigned int*         randseed            /**< seed value for the random generator */
10350	   )
10351	{
10352	   void* tmp;
10353	   int i;
10354	
10355	   /* loop backwards through all elements and always swap the current last element to a random position */
10356	   while( end > begin+1 )
10357	   {
10358	      end--;
10359	
10360	      /* get a random position into which the last entry should be shuffled */
10361	      i = getRandomInt(begin, end, randseed);
10362	
10363	      /* swap the last element and the random element */
10364	      tmp = array[i];
10365	      array[i] = array[end];
10366	      array[end] = tmp;
10367	   }
10368	}
10369	
10370	/** draws a random subset of disjoint elements from a given set of disjoint elements;
10371	 *  this implementation is suited for the case that nsubelems is considerably smaller then nelems
10372	 *
10373	 *  @deprecated Please use SCIPrandomGetSubset()
10374	 */
10375	SCIP_RETCODE SCIPgetRandomSubset(
10376	   void**                set,                /**< original set, from which elements should be drawn */
10377	   int                   nelems,             /**< number of elements in original set */
10378	   void**                subset,             /**< subset in which drawn elements should be stored */
10379	   int                   nsubelems,          /**< number of elements that should be drawn and stored */
10380	   unsigned int          randseed            /**< seed value for random generator */
10381	   )
10382	{
10383	   int i;
10384	   int j;
10385	
10386	   /* if both sets are of equal size, we just copy the array */
10387	   if( nelems == nsubelems)
10388	   {
10389	      BMScopyMemoryArray(subset,set,nelems);
10390	      return SCIP_OKAY;
10391	   }
10392	
10393	   /* abort, if size of subset is too big */
10394	   if( nsubelems > nelems )
10395	   {
10396	      SCIPerrorMessage("Cannot create %d-elementary subset of %d-elementary set.\n", nsubelems, nelems);
10397	      return SCIP_INVALIDDATA;
10398	   }
10399	#ifndef NDEBUG
10400	   for( i = 0; i < nsubelems; i++ )
10401	      for( j = 0; j < i; j++ )
10402	         assert(set[i] != set[j]);
10403	#endif
10404	
10405	   /* draw each element individually */
10406	   i = 0;
10407	   while( i < nsubelems )
10408	   {
10409	      int r;
10410	
10411	      r = getRandomInt(0, nelems-1, &randseed);
10412	      subset[i] = set[r];
10413	
10414	      /* if we get an element that we already had, we will draw again */
10415	      for( j = 0; j < i; j++ )
10416	      {
10417	         if( subset[i] == subset[j] )
10418	         {
10419	            --i;
10420	            break;
10421	         }
10422	      }
10423	      ++i;
10424	   }
10425	   return SCIP_OKAY;
10426	}
10427	
10428	
10429	/*
10430	 * Arrays
10431	 */
10432	
10433	/** computes set intersection (duplicates removed) of two integer arrays that are ordered ascendingly
10434	 *
10435	 * @deprecated Switch to SCIPcomputeArraysIntersectionInt().
10436	 */
10437	SCIP_RETCODE SCIPcomputeArraysIntersection(
10438	   int*                  array1,             /**< first array (in ascending order) */
10439	   int                   narray1,            /**< number of entries of first array */
10440	   int*                  array2,             /**< second array (in ascending order) */
10441	   int                   narray2,            /**< number of entries of second array */
10442	   int*                  intersectarray,     /**< intersection of array1 and array2
10443	                                              *   (note: it is possible to use array1 for this input argument) */
10444	   int*                  nintersectarray     /**< pointer to store number of entries of intersection array
10445	                                              *   (note: it is possible to use narray1 for this input argument) */
10446	   )
10447	{
10448	   SCIPcomputeArraysIntersectionInt(array1, narray1, array2, narray2, intersectarray, nintersectarray);
10449	
10450	   return SCIP_OKAY;
10451	}
10452	
10453	/** computes set intersection (duplicates removed) of two integer arrays that are ordered ascendingly */
10454	void SCIPcomputeArraysIntersectionInt(
10455	   int*                  array1,             /**< first array (in ascending order) */
10456	   int                   narray1,            /**< number of entries of first array */
10457	   int*                  array2,             /**< second array (in ascending order) */
10458	   int                   narray2,            /**< number of entries of second array */
10459	   int*                  intersectarray,     /**< intersection of array1 and array2
10460	                                              *   (note: it is possible to use array1 for this input argument) */
10461	   int*                  nintersectarray     /**< pointer to store number of entries of intersection array
10462	                                              *   (note: it is possible to use narray1 for this input argument) */
10463	   )
10464	{
10465	   int cnt = 0;
10466	   int k = 0;
10467	   int v1;
10468	   int v2;
10469	
10470	   assert( array1 != NULL );
10471	   assert( array2 != NULL );
10472	   assert( intersectarray != NULL );
10473	   assert( nintersectarray != NULL );
10474	
10475	   /* determine intersection of array1 and array2 */
10476	   for (v1 = 0; v1 < narray1; ++v1)
10477	   {
10478	      assert( v1 == 0 || array1[v1] >= array1[v1-1] );
10479	
10480	      /* skip duplicate entries */
10481	      if ( v1+1 < narray1 && array1[v1] == array1[v1+1])
10482	         continue;
10483	
10484	      for (v2 = k; v2 < narray2; ++v2)
10485	      {
10486	         assert( v2 == 0 || array2[v2] >= array2[v2-1] );
10487	
10488	         if ( array2[v2] > array1[v1] )
10489	         {
10490	            k = v2;
10491	            break;
10492	         }
10493	         else if ( array2[v2] == array1[v1] )
10494	         {
10495	            intersectarray[cnt++] = array2[v2];
10496	            k = v2 + 1;
10497	            break;
10498	         }
10499	      }
10500	   }
10501	
10502	   /* store size of intersection array */
10503	   *nintersectarray = cnt;
10504	}
10505	
10506	/** computes set intersection (duplicates removed) of two void-pointer arrays that are ordered ascendingly */
10507	void SCIPcomputeArraysIntersectionPtr(
10508	   void**                array1,             /**< pointer to first data array */
10509	   int                   narray1,            /**< number of entries of first array */
10510	   void**                array2,             /**< pointer to second data array */
10511	   int                   narray2,            /**< number of entries of second array */
10512	   SCIP_DECL_SORTPTRCOMP((*ptrcomp)),        /**< data element comparator */
10513	   void**                intersectarray,     /**< intersection of array1 and array2
10514	                                              *   (note: it is possible to use array1 for this input argument) */
10515	   int*                  nintersectarray     /**<  pointer to store number of entries of intersection array
10516	                                              *   (note: it is possible to use narray1 for this input argument) */
10517	   )
10518	{
10519	   int cnt = 0;
10520	   int k = 0;
10521	   int v1;
10522	   int v2;
10523	
10524	   assert( array1 != NULL );
10525	   assert( array2 != NULL );
10526	   assert( ptrcomp != NULL );
10527	   assert( intersectarray != NULL );
10528	   assert( nintersectarray != NULL );
10529	
10530	   /* determine intersection of array1 and array2 */
10531	   for( v1 = 0; v1 < narray1; ++v1 )
10532	   {
10533	      assert( v1 == 0 || (*ptrcomp)(array1[v1], array1[v1-1]) >= 0 );
10534	
10535	      /* skip duplicate entries */
10536	      if( v1+1 < narray1 && array1[v1] == array1[v1+1] )
10537	         continue;
10538	
10539	      for( v2 = k; v2 < narray2; ++v2 )
10540	      {
10541	         assert( v2 == 0 || (*ptrcomp)(array2[v2], array2[v2-1]) > 0 || array2[v2] == array2[v2-1] );
10542	
10543	         if( (*ptrcomp)(array2[v2], array1[v1]) > 0 )
10544	         {
10545	            k = v2;
10546	            break;
10547	         }
10548	
10549	         if( array2[v2] == array1[v1] )
10550	         {
10551	            intersectarray[cnt++] = array2[v2];
10552	            k = v2 + 1;
10553	            break;
10554	         }
10555	      }
10556	   }
10557	
10558	   /* store size of intersection array */
10559	   *nintersectarray = cnt;
10560	}
10561	
10562	
10563	/** computes set difference (duplicates removed) of two integer arrays that are ordered ascendingly
10564	 *
10565	 * @deprecated Switch to SCIPcomputeArraysSetminusInt().
10566	 */
10567	SCIP_RETCODE SCIPcomputeArraysSetminus(
10568	   int*                  array1,             /**< first array (in ascending order) */
10569	   int                   narray1,            /**< number of entries of first array */
10570	   int*                  array2,             /**< second array (in ascending order) */
10571	   int                   narray2,            /**< number of entries of second array */
10572	   int*                  setminusarray,      /**< array to store entries of array1 that are not an entry of array2
10573	                                              *   (note: it is possible to use array1 for this input argument) */
10574	   int*                  nsetminusarray      /**< pointer to store number of entries of setminus array
10575	                                              *   (note: it is possible to use narray1 for this input argument) */
10576	   )
10577	{
10578	   SCIPcomputeArraysSetminusInt(array1, narray1, array2, narray2, setminusarray, nsetminusarray);
10579	
10580	   return SCIP_OKAY;
10581	}
10582	
10583	/** computes set difference (duplicates removed) of two integer arrays that are ordered ascendingly */
10584	void SCIPcomputeArraysSetminusInt(
10585	   int*                  array1,             /**< first array (in ascending order) */
10586	   int                   narray1,            /**< number of entries of first array */
10587	   int*                  array2,             /**< second array (in ascending order) */
10588	   int                   narray2,            /**< number of entries of second array */
10589	   int*                  setminusarray,      /**< array to store entries of array1 that are not an entry of array2
10590	                                              *   (note: it is possible to use array1 for this input argument) */
10591	   int*                  nsetminusarray      /**< pointer to store number of entries of setminus array
10592	                                              *   (note: it is possible to use narray1 for this input argument) */
10593	   )
10594	{
10595	   int cnt = 0;
10596	   int v1 = 0;
10597	   int v2 = 0;
10598	
10599	   assert( array1 != NULL );
10600	   assert( array2 != NULL );
10601	   assert( setminusarray != NULL );
10602	   assert( nsetminusarray != NULL );
10603	
10604	   while ( v1 < narray1 )
10605	   {
10606	      int entry1;
10607	
10608	      assert( v1 == 0 || array1[v1] >= array1[v1-1] );
10609	
10610	      /* skip duplicate entries */
10611	      while ( v1 + 1 < narray1 && array1[v1] == array1[v1 + 1] )
10612	         ++v1;
10613	
10614	      entry1 = array1[v1];
10615	
10616	      while ( v2 < narray2 && array2[v2] < entry1 )
10617	         ++v2;
10618	
10619	      if ( v2 >= narray2 || entry1 < array2[v2] )
10620	         setminusarray[cnt++] = entry1;
10621	      ++v1;
10622	   }
10623	
10624	   /* store size of setminus array */
10625	   *nsetminusarray = cnt;
10626	}
10627	
10628	
10629	/*
10630	 * Strings
10631	 */
10632	
10633	
10634	/** copies characters from 'src' to 'dest', copying is stopped when either the 'stop' character is reached or after
10635	 *  'cnt' characters have been copied, whichever comes first.
10636	 *
10637	 *  @note undefined behavior on overlapping arrays
10638	 */
10639	int SCIPmemccpy(
10640	   char*                 dest,               /**< destination pointer to copy to */
10641	   const char*           src,                /**< source pointer to copy from */
10642	   char                  stop,               /**< character when found stop copying */
10643	   unsigned int          cnt                 /**< maximal number of characters to copy */
10644	   )
10645	{
10646	   if( dest == NULL || src == NULL || cnt == 0 )
10647	      return -1;
10648	   else
10649	   {
10650	      char* destination = dest;
10651	
10652	      while( cnt-- && (*destination++ = *src++) != stop ); /*lint !e722*/
10653	
10654	      return (int)(destination - dest);
10655	   }
10656	}
10657	
10658	/** prints an error message containing of the given string followed by a string describing the current system error
10659	 *
10660	 *  Prefers to use the strerror_r method, which is threadsafe. On systems where this method does not exist,
10661	 *  NO_STRERROR_R should be defined (see INSTALL). In this case, strerror is used which is not guaranteed to be
10662	 *  threadsafe (on SUN-systems, it actually is).
10663	 */
10664	void SCIPprintSysError(
10665	   const char*           message             /**< first part of the error message, e.g. the filename */
10666	   )
10667	{
10668	#ifdef NO_STRERROR_R
10669	   SCIPmessagePrintError("%s: %s\n", message, strerror(errno));
10670	#else
10671	   char buf[SCIP_MAXSTRLEN];
10672	
10673	#if defined(_WIN32) || defined(_WIN64)
10674	   /* strerror_s returns 0 on success; the string is \0 terminated. */
10675	   if ( strerror_s(buf, SCIP_MAXSTRLEN, errno) != 0 )
10676	      SCIPmessagePrintError("Unknown error number %d or error message too long.\n", errno);
10677	   SCIPmessagePrintError("%s: %s\n", message, buf);
10678	#elif (_POSIX_C_SOURCE >= 200112L || __DARWIN_C_LEVEL > 200112L || _XOPEN_SOURCE >= 600) && ! defined(_GNU_SOURCE)
10679	   /* We are in the POSIX/XSI case, where strerror_r returns 0 on success; \0 termination is unclear. */
10680	   if ( strerror_r(errno, buf, SCIP_MAXSTRLEN) != 0 )
10681	      SCIPmessagePrintError("Unknown error number %d.\n", errno);
10682	   buf[SCIP_MAXSTRLEN - 1] = '\0';
10683	   SCIPmessagePrintError("%s: %s\n", message, buf);
10684	#else
10685	   /* We are in the GNU case, where strerror_r returns a pointer to the error string. This string is possibly stored
10686	    * in buf and is always \0 terminated.
10687	    * However, if compiling on one system and executing on another system, we might actually call a different
10688	    * variant of the strerror_r function than we had at compile time.
10689	    */
10690	   char* errordescr;
10691	   *buf = '\0';
10692	   errordescr = strerror_r(errno, buf, SCIP_MAXSTRLEN);
10693	   if( *buf != '\0' )
10694	   {
10695	      /* strerror_r wrote into buf */
10696	      SCIPmessagePrintError("%s: %s\n", message, buf);
10697	   }
10698	   else if( errordescr != NULL )
10699	   {
10700	      /* strerror_r returned something non-NULL */
10701	      SCIPmessagePrintError("%s: %s\n", message, errordescr);
10702	   }
10703	   else
10704	   {
10705	      /* strerror_r did return NULL and did not write into buf */
10706	      SCIPmessagePrintError("Could not obtain description for error %d.\n", errno);
10707	   }
10708	#endif
10709	#endif
10710	}
10711	
10712	/** extracts tokens from strings - wrapper method for strtok_r() */
10713	char* SCIPstrtok(
10714	   char*                 s,                  /**< string to parse */
10715	   const char*           delim,              /**< delimiters for parsing */
10716	   char**                ptrptr              /**< pointer to working char pointer - must stay the same while parsing */
10717	   )
10718	{
10719	#ifdef SCIP_NO_STRTOK_R
10720	   return strtok(s, delim);
10721	#else
10722	   return strtok_r(s, delim, ptrptr);
10723	#endif
10724	}
10725	
10726	/** translates the given string into a string where symbols ", ', and spaces are escaped with a \ prefix */
10727	void SCIPescapeString(
10728	   char*                 t,                  /**< target buffer to store escaped string */
10729	   int                   bufsize,            /**< size of buffer t */
10730	   const char*           s                   /**< string to transform into escaped string */
10731	   )
10732	{
10733	   int len;
10734	   int i;
10735	   int p;
10736	
10737	   assert(t != NULL);
10738	   assert(bufsize > 0);
10739	
10740	   len = (int)strlen(s);
10741	   for( p = 0, i = 0; i <= len && p < bufsize; ++i, ++p )
10742	   {
10743	      if( s[i] == ' ' || s[i] == '"' || s[i] == '\'' )
10744	      {
10745	         t[p] = '\\';
10746	         p++;
10747	      }
10748	      if( p < bufsize )
10749	         t[p] = s[i];
10750	   }
10751	   t[bufsize-1] = '\0';
10752	}
10753	
10754	/* safe version of snprintf */
10755	int SCIPsnprintf(
10756	   char*                 t,                  /**< target string */
10757	   int                   len,                /**< length of the string to copy */
10758	   const char*           s,                  /**< source string */
10759	   ...                                       /**< further parameters */
10760	   )
10761	{
10762	   va_list ap;
10763	   int n;
10764	
10765	   assert(t != NULL);
10766	   assert(len > 0);
10767	
10768	   va_start(ap, s); /*lint !e826*/
10769	
10770	#if defined(_WIN32) || defined(_WIN64)
10771	   n = _vsnprintf(t, (size_t) len, s, ap);
10772	#else
10773	   n = vsnprintf(t, (size_t) len, s, ap); /*lint !e571*/
10774	#endif
10775	   va_end(ap);
10776	
10777	   if( n < 0 || n >= len )
10778	   {
10779	#ifndef NDEBUG
10780	      if( n < 0 )
10781	      {
10782	         SCIPerrorMessage("vsnprintf returned %d\n",n);
10783	      }
10784	#endif
10785	      t[len-1] = '\0';
10786	      n = len-1;
10787	   }
10788	   return n;
10789	}
10790	
10791	/** safe version of strncpy
10792	 *
10793	 *  Copies string in s to t using at most @a size-1 nonzero characters (strncpy copies size characters). It always adds
10794	 *  a terminating zero char. Does not pad the remaining string with zero characters (unlike strncpy). Returns the number
10795	 *  of copied nonzero characters, if the length of s is at most size - 1, and returns size otherwise. Thus, the original
10796	 *  string was truncated if the return value is size.
10797	 */
10798	int SCIPstrncpy(
10799	   char*                 t,                  /**< target string */
10800	   const char*           s,                  /**< source string */
10801	   int                   size                /**< maximal size of t */
10802	   )
10803	{
10804	   int n;
10805	
10806	   if( size <= 0 )
10807	      return 0;
10808	
10809	   /* decrease size by 1 to create space for terminating zero char */
10810	   --size;
10811	   for( n = 0; n < size && *s != '\0'; n++ )
10812	      *(t++) = *(s++);
10813	   *t = '\0';
10814	
10815	   if( *s != '\0' )
10816	      ++n;
10817	
10818	   return n;
10819	}
10820	
10821	/** extract the next token as a integer value if it is one; in case no value is parsed the endptr is set to @p str
10822	 *
10823	 *  @return Returns TRUE if a value could be extracted, otherwise FALSE
10824	 */
10825	SCIP_Bool SCIPstrToIntValue(
10826	   const char*           str,                /**< string to search */
10827	   int*                  value,              /**< pointer to store the parsed value */
10828	   char**                endptr              /**< pointer to store the final string position if successfully parsed, otherwise @p str */
10829	   )
10830	{
10831	   assert(str != NULL);
10832	   assert(value != NULL);
10833	   assert(endptr != NULL);
10834	
10835	   /* init errno to detect possible errors */
10836	   errno = 0;
10837	
10838	   *value = (int) strtol(str, endptr, 10);
10839	
10840	   if( *endptr != str && *endptr != NULL )
10841	   {
10842	      SCIPdebugMessage("parsed integer value <%d>\n", *value);
10843	      return TRUE;
10844	   }
10845	   *endptr = (char*)str;
10846	
10847	   SCIPdebugMessage("failed parsing integer value <%s>\n", str);
10848	
10849	   return FALSE;
10850	}
10851	
10852	/** extract the next token as a double value if it is one; in case no value is parsed the endptr is set to @p str
10853	 *
10854	 *  @return Returns TRUE if a value could be extracted, otherwise FALSE
10855	 */
10856	SCIP_Bool SCIPstrToRealValue(
10857	   const char*           str,                /**< string to search */
10858	   SCIP_Real*            value,              /**< pointer to store the parsed value */
10859	   char**                endptr              /**< pointer to store the final string position if successfully parsed, otherwise @p str */
10860	   )
10861	{
10862	   assert(str != NULL);
10863	   assert(value != NULL);
10864	   assert(endptr != NULL);
10865	
10866	   /* init errno to detect possible errors */
10867	   errno = 0;
10868	
10869	   *value = strtod(str, endptr);
10870	
10871	   if( *endptr != str && *endptr != NULL )
10872	   {
10873	      SCIPdebugMessage("parsed real value <%g>\n", *value);
10874	      return TRUE;
10875	   }
10876	   *endptr = (char*)str;
10877	
10878	   SCIPdebugMessage("failed parsing real value <%s>\n", str);
10879	
10880	   return FALSE;
10881	}
10882	
10883	/** copies the first size characters between a start and end character of str into token, if no error occurred endptr
10884	 *  will point to the position after the read part, otherwise it will point to @p str
10885	 */
10886	void SCIPstrCopySection(
10887	   const char*           str,                /**< string to search */
10888	   char                  startchar,          /**< character which defines the beginning */
10889	   char                  endchar,            /**< character which defines the ending */
10890	   char*                 token,              /**< string to store the copy */
10891	   int                   size,               /**< size of the token char array */
10892	   char**                endptr              /**< pointer to store the final string position if successfully parsed, otherwise @p str */
10893	   )
10894	{
10895	   const char* copystr;
10896	   int nchars;
10897	
10898	   assert(str != NULL);
10899	   assert(token != NULL);
10900	   assert(size > 0);
10901	   assert(endptr != NULL);
10902	
10903	   nchars = 0;
10904	
10905	   copystr = str;
10906	
10907	   /* find starting character */
10908	   while( *str != '\0' && *str != startchar )
10909	      ++str;
10910	
10911	   /* did not find start character */
10912	   if( *str == '\0' )
10913	   {
10914	      *endptr = (char*)copystr;
10915	      return;
10916	   }
10917	
10918	   /* skip start character */
10919	   ++str;
10920	
10921	   /* copy string */
10922	   while( *str != '\0' && *str != endchar && nchars < size-1 )
10923	   {
10924	      assert(nchars < SCIP_MAXSTRLEN);
10925	      token[nchars] = *str;
10926	      nchars++;
10927	      ++str;
10928	   }
10929	
10930	   /* add end to token */
10931	   token[nchars] = '\0';
10932	
10933	   /* if section was longer than size, we want to reach the end of the parsing section anyway */
10934	   if( nchars == (size-1) )
10935	      while( *str != '\0' && *str != endchar )
10936	         ++str;
10937	
10938	   /* did not find end character */
10939	   if( *str == '\0' )
10940	   {
10941	      *endptr = (char*)copystr;
10942	      return;
10943	   }
10944	
10945	   /* skip end character */
10946	   ++str;
10947	
10948	   SCIPdebugMessage("parsed section <%s>\n", token);
10949	
10950	   *endptr = (char*) str;
10951	}
10952	
10953	/*
10954	 * File methods
10955	 */
10956	
10957	/** returns, whether the given file exists */
10958	SCIP_Bool SCIPfileExists(
10959	   const char*           filename            /**< file name */
10960	   )
10961	{
10962	   FILE* f;
10963	
10964	   f = fopen(filename, "r");
10965	   if( f == NULL )
10966	      return FALSE;
10967	
10968	   fclose(f);
10969	
10970	   return TRUE;
10971	}
10972	
10973	/** splits filename into path, name, and extension */
10974	void SCIPsplitFilename(
10975	   char*                 filename,           /**< filename to split; is destroyed (but not freed) during process */
10976	   char**                path,               /**< pointer to store path, or NULL if not needed */
10977	   char**                name,               /**< pointer to store name, or NULL if not needed */
10978	   char**                extension,          /**< pointer to store extension, or NULL if not needed */
10979	   char**                compression         /**< pointer to store compression extension, or NULL if not needed */
10980	   )
10981	{
10982	   char* lastslash;
10983	   char* lastbackslash;
10984	   char* lastdot;
10985	
10986	   assert(filename != NULL);
10987	
10988	   if( path != NULL )
10989	      *path = NULL;
10990	   if( name != NULL )
10991	      *name = NULL;
10992	   if( extension != NULL )
10993	      *extension = NULL;
10994	   if( compression != NULL )
10995	      *compression = NULL;
10996	
10997	   /* treat both slashes '/' and '\' as directory delimiters */
10998	   lastslash = strrchr(filename, '/');
10999	   lastbackslash = strrchr(filename, '\\');
11000	   lastslash = MAX(lastslash, lastbackslash); /*lint !e613*/
11001	   lastdot = strrchr(filename, '.');
11002	   if( lastslash != NULL && lastdot != NULL && lastdot < lastslash ) /* is the last dot belonging to the path? */
11003	      lastdot = NULL;
11004	
11005	   /* detect known compression extensions */
11006	#ifdef SCIP_WITH_ZLIB
11007	   if( lastdot != NULL )
11008	   {
11009	      char* compext;
11010	
11011	      compext = lastdot+1;
11012	      if( strcmp(compext, "gz") == 0
11013	        || strcmp(compext, "z") == 0
11014	        || strcmp(compext, "Z") == 0 )
11015	      {
11016	         if( compression != NULL )
11017	            *compression = compext;
11018	         *lastdot = '\0';
11019	      }
11020	
11021	      /* find again the last dot in the filename without compression extension */
11022	      lastdot = strrchr(filename, '.');
11023	      if( lastslash != NULL && lastdot != NULL && lastdot < lastslash ) /* is the last dot belonging to the path? */
11024	         lastdot = NULL;
11025	   }
11026	#endif
11027	
11028	   if( lastslash == NULL )
11029	   {
11030	      if( name != NULL )
11031	         *name = filename;
11032	   }
11033	   else
11034	   {
11035	      if( path != NULL )
11036	         *path = filename;
11037	      if( name != NULL )
11038	         *name = lastslash+1;
11039	      *lastslash = '\0';
11040	   }
11041	
11042	   if( lastdot != NULL )
11043	   {
11044	      if( extension != NULL )
11045	         *extension = lastdot+1;
11046	      *lastdot = '\0';
11047	   }
11048	}
11049	
11050	/*
11051	 * simple functions implemented as defines
11052	 */
11053	
11054	/* In debug mode, the following methods are implemented as function calls to ensure
11055	 * type validity.
11056	 * In optimized mode, the methods are implemented as defines to improve performance.
11057	 * However, we want to have them in the library anyways, so we have to undef the defines.
11058	 */
11059	
11060	#undef SCIPrelDiff
11061	
11062	/** returns the relative difference: (val1-val2)/max(|val1|,|val2|,1.0) */
11063	SCIP_Real SCIPrelDiff(
11064	   SCIP_Real             val1,               /**< first value to be compared */
11065	   SCIP_Real             val2                /**< second value to be compared */
11066	   )
11067	{
11068	   SCIP_Real absval1;
11069	   SCIP_Real absval2;
11070	   SCIP_Real quot;
11071	
11072	   absval1 = REALABS(val1);
11073	   absval2 = REALABS(val2);
11074	   quot = MAX3(1.0, absval1, absval2);
11075	
11076	   return (val1-val2)/quot;
11077	}
11078	
11079	
11080	/** computes the gap from the primal and the dual bound */
11081	SCIP_Real SCIPcomputeGap(
11082	   SCIP_Real             eps,                /**< the value treated as zero */
11083	   SCIP_Real             inf,                /**< the value treated as infinity */
11084	   SCIP_Real             primalbound,        /**< the primal bound */
11085	   SCIP_Real             dualbound           /**< the dual bound */
11086	   )
11087	{
11088	   if( EPSEQ(primalbound, dualbound, eps) )
11089	      return 0.0;
11090	   else
11091	   {
11092	      SCIP_Real absdual = REALABS(dualbound);
11093	      SCIP_Real absprimal = REALABS(primalbound);
11094	
11095	      if( EPSZ(dualbound, eps) || EPSZ(primalbound, eps) || absprimal >= inf || absdual >= inf ||
11096	         primalbound * dualbound < 0.0 )
11097	         return inf;
11098	      else
11099	         return REALABS((primalbound - dualbound)/MIN(absdual, absprimal));
11100	   }
11101	}
11102	
11103	/*
11104	 * disjoint set (union-find) data structure
11105	 */
11106	
11107	/** creates a disjoint set (union find) structure \p djset for \p ncomponents many components (of size one) */
11108	SCIP_RETCODE SCIPdisjointsetCreate(
11109	   SCIP_DISJOINTSET**    djset,              /**< disjoint set (union find) data structure */
11110	   BMS_BLKMEM*           blkmem,             /**< block memory */
11111	   int                   ncomponents         /**< number of components */
11112	   )
11113	{
11114	   assert(djset != NULL);
11115	   assert(blkmem != NULL);
11116	
11117	   /* allocate the necessary memory */
11118	   assert(ncomponents > 0);
11119	   SCIP_ALLOC( BMSallocBlockMemory(blkmem, djset) );
11120	   SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &((*djset)->parents), ncomponents) );
11121	   SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &((*djset)->sizes), ncomponents) );
11122	   (*djset)->size = ncomponents;
11123	
11124	   /* clear the data structure */
11125	   SCIPdisjointsetClear(*djset);
11126	
11127	   return SCIP_OKAY;
11128	}
11129	
11130	/** clears the disjoint set (union find) structure \p djset */
11131	void SCIPdisjointsetClear(
11132	   SCIP_DISJOINTSET*     djset               /**< disjoint set (union find) data structure */
11133	   )
11134	{
11135	   int i;
11136	
11137	   djset->componentcount = djset->size;
11138	
11139	   /* reset all components to be unconnected */
11140	   for( i = 0; i < djset->componentcount; i++ )
11141	   {
11142	      djset->parents[i] = i;
11143	      djset->sizes[i] = 1;
11144	   }
11145	}
11146	
11147	/** finds and returns the component identifier of this \p element */
11148	int SCIPdisjointsetFind(
11149	   SCIP_DISJOINTSET*     djset,              /**< disjoint set (union find) data structure */
11150	   int                   element             /**< element to be found */
11151	   )
11152	{
11153	   int newelement;
11154	   int root = element;
11155	   int* parents = djset->parents;
11156	
11157	   /* find root of this element */
11158	   while( root != parents[root] )
11159	   {
11160	      root = parents[root];
11161	   }
11162	
11163	   /* compress the path to make future queries faster */
11164	   while( element != root )
11165	   {
11166	      newelement = parents[element];
11167	      parents[element] = root;
11168	      element = newelement;
11169	   }
11170	
11171	   return root;
11172	}
11173	
11174	/** merges the components containing the elements \p p and \p q */
11175	void SCIPdisjointsetUnion(
11176	   SCIP_DISJOINTSET*     djset,              /**< disjoint set (union find) data structure */
11177	   int                   p,                  /**< first element */
11178	   int                   q,                  /**< second element */
11179	   SCIP_Bool             forcerepofp         /**< force representative of p to be new representative */
11180	   )
11181	{
11182	   int idp;
11183	   int idq;
11184	   int* sizes;
11185	   int* parents;
11186	
11187	   assert(djset != NULL);
11188	   assert(0 <= p);
11189	   assert(0 <= q);
11190	   assert(djset->size > p);
11191	   assert(djset->size > q);
11192	
11193	   idp = SCIPdisjointsetFind(djset, p);
11194	   idq = SCIPdisjointsetFind(djset, q);
11195	
11196	   /* if p and q lie in the same component, there is nothing to be done */
11197	   if( idp == idq )
11198	      return;
11199	
11200	   sizes = djset->sizes;
11201	   parents = djset->parents;
11202	
11203	   if( forcerepofp )
11204	   {
11205	      parents[idq] = idp;
11206	      sizes[idp] += sizes[idq];
11207	   }
11208	   else
11209	   {
11210	      if( sizes[idp] < sizes[idq] )
11211	      {
11212	         parents[idp] = idq;
11213	         sizes[idq] += sizes[idp];
11214	      }
11215	      else
11216	      {
11217	         parents[idq] = idp;
11218	         sizes[idp] += sizes[idq];
11219	      }
11220	   }
11221	   /* one less component */
11222	   djset->componentcount--;
11223	}
11224	
11225	/** frees the disjoint set (union find) data structure */
11226	void SCIPdisjointsetFree(
11227	   SCIP_DISJOINTSET**    djset,              /**< pointer to disjoint set (union find) data structure */
11228	   BMS_BLKMEM*           blkmem              /**< block memory */
11229	   )
11230	{
11231	   SCIP_DISJOINTSET* dsptr;
11232	
11233	   assert(djset != NULL);
11234	   assert(*djset != NULL);
11235	
11236	   dsptr = *djset;
11237	
11238	   BMSfreeBlockMemoryArray(blkmem, &dsptr->sizes, dsptr->size);
11239	   BMSfreeBlockMemoryArray(blkmem, &dsptr->parents, dsptr->size);
11240	
11241	   BMSfreeBlockMemory(blkmem, djset);
11242	}
11243	
11244	/** returns the number of independent components in this disjoint set (union find) data structure */
11245	int SCIPdisjointsetGetComponentCount(
11246	   SCIP_DISJOINTSET*     djset               /**< disjoint set (union find) data structure */
11247	   )
11248	{
11249	   assert(djset != NULL);
11250	
11251	   return djset->componentcount;
11252	}
11253	
11254	/** returns the size (number of nodes) of this disjoint set (union find) data structure */
11255	int SCIPdisjointsetGetSize(
11256	   SCIP_DISJOINTSET*     djset               /**< disjoint set (union find) data structure */
11257	   )
11258	{
11259	   assert(djset != NULL);
11260	
11261	   return djset->size;
11262	}
11263	
11264	/** checks whether a given string t appears at the beginning of the string s (up to spaces at beginning) */
11265	SCIP_Bool SCIPstrAtStart(
11266	   const char*           s,                  /**< string to search in */
11267	   const char*           t,                  /**< string to search for */
11268	   size_t                tlen                /**< length of t */
11269	   )
11270	{
11271	   int idxctr = 0;
11272	
11273	   assert(s != NULL);
11274	   assert(t != NULL);
11275	
11276	   /* skip whitespace at beginning */
11277	   while( idxctr < SCIP_MAXSTRLEN && isspace((unsigned char)s[idxctr]) )
11278	      ++idxctr;
11279	   if( strncmp(&s[idxctr], t, tlen) == 0 )
11280	      return TRUE;
11281	   return FALSE;
11282	}
11283