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