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