Scippy

SCIP

Solving Constraint Integer Programs

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