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