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 sparse solution */
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 !e776*/
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 !e776*/
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 !e776*/
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 !e776*/
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 data */
5335  SCIP_ALLOC( BMSallocMemory(digraph) );
5336  SCIP_ALLOC( BMSallocClearMemoryArray(&(*digraph)->successors, nnodes) );
5337  SCIP_ALLOC( BMSallocClearMemoryArray(&(*digraph)->arcdata, nnodes) );
5338  SCIP_ALLOC( BMSallocClearMemoryArray(&(*digraph)->successorssize, nnodes) );
5339  SCIP_ALLOC( BMSallocClearMemoryArray(&(*digraph)->nsuccessors, nnodes) );
5340  SCIP_ALLOC( BMSallocClearMemoryArray(&(*digraph)->nodedata, nnodes) );
5341 
5342  /* store number of nodes */
5343  (*digraph)->nnodes = nnodes;
5344 
5345  /* at the beginning, no components are stored */
5346  (*digraph)->ncomponents = 0;
5347  (*digraph)->componentstartsize = 0;
5348  (*digraph)->components = NULL;
5349  (*digraph)->componentstarts = NULL;
5350 
5351  return SCIP_OKAY;
5352 }
5353 
5354 /** resize directed graph structure */
5356  SCIP_DIGRAPH* digraph, /**< directed graph */
5357  int nnodes /**< new number of nodes */
5358  )
5359 {
5360  int n;
5361 
5362  /* check if the digraph has already a proper size */
5363  if( nnodes <= digraph->nnodes )
5364  return SCIP_OKAY;
5365 
5366  /* reallocate memory for increasing the arrays storing arcs and data */
5367  SCIP_ALLOC( BMSreallocMemoryArray(&digraph->successors, nnodes) );
5368  SCIP_ALLOC( BMSreallocMemoryArray(&digraph->arcdata, nnodes) );
5369  SCIP_ALLOC( BMSreallocMemoryArray(&digraph->successorssize, nnodes) );
5370  SCIP_ALLOC( BMSreallocMemoryArray(&digraph->nsuccessors, nnodes) );
5371  SCIP_ALLOC( BMSreallocMemoryArray(&digraph->nodedata, nnodes) );
5372 
5373  /* initialize the new node data structures */
5374  for( n = digraph->nnodes; n < nnodes; ++n )
5375  {
5376  digraph->nodedata[n] = NULL;
5377  digraph->successorssize[n] = 0;
5378  digraph->nsuccessors[n] = 0;
5379  }
5380 
5381  /* store the new number of nodes */
5382  digraph->nnodes = nnodes;
5383 
5384  return SCIP_OKAY;
5385 }
5386 
5387 /** copies directed graph structure
5388  *
5389  * @note The data in nodedata is copied verbatim. This possibly has to be adapted by the user.
5390  */
5392  SCIP_DIGRAPH** targetdigraph, /**< pointer to store the copied directed graph */
5393  SCIP_DIGRAPH* sourcedigraph /**< source directed graph */
5394  )
5395 {
5396  int ncomponents;
5397  int nnodes;
5398  int i;
5399 
5400  SCIP_ALLOC( BMSallocMemory(targetdigraph) );
5401 
5402  nnodes = sourcedigraph->nnodes;
5403  ncomponents = sourcedigraph->ncomponents;
5404  (*targetdigraph)->nnodes = nnodes;
5405  (*targetdigraph)->ncomponents = ncomponents;
5406 
5407  /* copy arcs and data */
5408  SCIP_ALLOC( BMSallocClearMemoryArray(&(*targetdigraph)->successors, nnodes) );
5409  SCIP_ALLOC( BMSallocClearMemoryArray(&(*targetdigraph)->arcdata, nnodes) );
5410  SCIP_ALLOC( BMSallocClearMemoryArray(&(*targetdigraph)->nodedata, nnodes) );
5411 
5412  /* copy lists of successors and arc data */
5413  for( i = 0; i < nnodes; ++i )
5414  {
5415  if( sourcedigraph->nsuccessors[i] > 0 )
5416  {
5417  assert(sourcedigraph->successors[i] != NULL);
5418  assert(sourcedigraph->arcdata[i] != NULL);
5419  SCIP_ALLOC( BMSduplicateMemoryArray(&((*targetdigraph)->successors[i]),
5420  sourcedigraph->successors[i], sourcedigraph->nsuccessors[i]) ); /*lint !e866*/
5421  SCIP_ALLOC( BMSduplicateMemoryArray(&((*targetdigraph)->arcdata[i]),
5422  sourcedigraph->arcdata[i], sourcedigraph->nsuccessors[i]) ); /*lint !e866*/
5423  }
5424  /* copy node data - careful if these are pointers to some information -> need to be copied by hand */
5425  (*targetdigraph)->nodedata[i] = sourcedigraph->nodedata[i];
5426  }
5427  SCIP_ALLOC( BMSduplicateMemoryArray(&(*targetdigraph)->successorssize, sourcedigraph->nsuccessors, nnodes) );
5428  SCIP_ALLOC( BMSduplicateMemoryArray(&(*targetdigraph)->nsuccessors, sourcedigraph->nsuccessors, nnodes) );
5429 
5430  /* copy component data */
5431  if( ncomponents > 0 )
5432  {
5433  SCIP_ALLOC( BMSduplicateMemoryArray(&(*targetdigraph)->components, sourcedigraph->components,
5434  sourcedigraph->componentstarts[ncomponents]) );
5435  SCIP_ALLOC( BMSduplicateMemoryArray(&(*targetdigraph)->componentstarts,
5436  sourcedigraph->componentstarts,ncomponents + 1) ); /*lint !e776*/
5437  (*targetdigraph)->componentstartsize = ncomponents + 1;
5438  }
5439  else
5440  {
5441  (*targetdigraph)->components = NULL;
5442  (*targetdigraph)->componentstarts = NULL;
5443  (*targetdigraph)->componentstartsize = 0;
5444  }
5445 
5446  return SCIP_OKAY;
5447 }
5448 
5449 /** sets the sizes of the successor lists for the nodes in a directed graph and allocates memory for the lists */
5451  SCIP_DIGRAPH* digraph, /**< directed graph */
5452  int* sizes /**< sizes of the successor lists */
5453  )
5454 {
5455  int i;
5456 
5457  assert(digraph != NULL);
5458  assert(digraph->nnodes > 0);
5459 
5460  for( i = 0; i < digraph->nnodes; ++i )
5461  {
5462  SCIP_ALLOC( BMSallocMemoryArray(&digraph->successors[i], sizes[i]) ); /*lint !e866*/
5463  SCIP_ALLOC( BMSallocMemoryArray(&digraph->arcdata[i], sizes[i]) ); /*lint !e866*/
5464  digraph->successorssize[i] = sizes[i];
5465  digraph->nsuccessors[i] = 0;
5466  }
5467 
5468  return SCIP_OKAY;
5469 }
5470 
5471 /** frees given directed graph structure */
5473  SCIP_DIGRAPH** digraph /**< pointer to the directed graph */
5474  )
5475 {
5476  int i;
5477 
5478  assert(digraph != NULL);
5479  assert(*digraph != NULL);
5480 
5481  /* free arrays storing the successor nodes and arc data */
5482  for( i = (*digraph)->nnodes - 1; i >= 0; --i )
5483  {
5484  BMSfreeMemoryArrayNull(&(*digraph)->successors[i]);
5485  BMSfreeMemoryArrayNull(&(*digraph)->arcdata[i]);
5486  }
5487 
5488  /* free components structure */
5489  SCIPdigraphFreeComponents(*digraph);
5490  assert((*digraph)->ncomponents == 0);
5491  assert((*digraph)->componentstartsize == 0);
5492  assert((*digraph)->components == NULL);
5493  assert((*digraph)->componentstarts == NULL);
5494 
5495  /* free directed graph data structure */
5496  BMSfreeMemoryArray(&(*digraph)->nodedata);
5497  BMSfreeMemoryArray(&(*digraph)->successorssize);
5498  BMSfreeMemoryArray(&(*digraph)->nsuccessors);
5499  BMSfreeMemoryArray(&(*digraph)->successors);
5500  BMSfreeMemoryArray(&(*digraph)->arcdata);
5501 
5502  BMSfreeMemory(digraph);
5503 }
5504 
5505 #define STARTSUCCESSORSSIZE 5
5506 
5507 /* ensures that successors array of one node in a directed graph is big enough */
5508 static
5510  SCIP_DIGRAPH* digraph, /**< directed graph */
5511  int idx, /**< index for which the size is ensured */
5512  int newsize /**< needed size */
5513  )
5514 {
5515  assert(digraph != NULL);
5516  assert(idx >= 0);
5517  assert(idx < digraph->nnodes);
5518  assert(newsize > 0);
5519 
5520  /* check whether array is big enough, and realloc, if needed */
5521  if( newsize > digraph->successorssize[idx] )
5522  {
5523  if( digraph->successorssize[idx] == 0 )
5524  {
5525  digraph->successorssize[idx] = STARTSUCCESSORSSIZE;
5526  SCIP_ALLOC( BMSallocMemoryArray(&digraph->successors[idx], digraph->successorssize[idx]) ); /*lint !e866*/
5527  SCIP_ALLOC( BMSallocMemoryArray(&digraph->arcdata[idx], digraph->successorssize[idx]) ); /*lint !e866*/
5528  }
5529  else
5530  {
5531  digraph->successorssize[idx] = 2 * digraph->successorssize[idx];
5532  SCIP_ALLOC( BMSreallocMemoryArray(&digraph->successors[idx], digraph->successorssize[idx]) ); /*lint !e866*/
5533  SCIP_ALLOC( BMSreallocMemoryArray(&digraph->arcdata[idx], digraph->successorssize[idx]) ); /*lint !e866*/
5534  }
5535  }
5536 
5537  return SCIP_OKAY;
5538 }
5539 
5540 /** add (directed) arc and a related data to the directed graph structure
5541  *
5542  * @note if the arc is already contained, it is added a second time
5543  */
5545  SCIP_DIGRAPH* digraph, /**< directed graph */
5546  int startnode, /**< start node of the arc */
5547  int endnode, /**< start node of the arc */
5548  void* data /**< data that should be stored for the arc; or NULL */
5549  )
5550 {
5551  assert(digraph != NULL);
5552  assert(startnode >= 0);
5553  assert(endnode >= 0);
5554  assert(startnode < digraph->nnodes);
5555  assert(endnode < digraph->nnodes);
5556 
5557  SCIP_CALL( ensureSuccessorsSize(digraph, startnode, digraph->nsuccessors[startnode] + 1) );
5558 
5559  /* add arc */
5560  digraph->successors[startnode][digraph->nsuccessors[startnode]] = endnode;
5561  digraph->arcdata[startnode][digraph->nsuccessors[startnode]] = data;
5562  digraph->nsuccessors[startnode]++;
5563 
5564  return SCIP_OKAY;
5565 }
5566 
5567 /** add (directed) arc to the directed graph structure, if it is not contained, yet
5568  *
5569  * @note if there already exists an arc from startnode to endnode, the new arc is not added,
5570  * even if its data is different
5571  */
5573  SCIP_DIGRAPH* digraph, /**< directed graph */
5574  int startnode, /**< start node of the arc */
5575  int endnode, /**< start node of the arc */
5576  void* data /**< data that should be stored for the arc; or NULL */
5577  )
5578 {
5579  int nsuccessors;
5580  int i;
5581 
5582  assert(digraph != NULL);
5583  assert(startnode >= 0);
5584  assert(endnode >= 0);
5585  assert(startnode < digraph->nnodes);
5586  assert(endnode < digraph->nnodes);
5587 
5588  nsuccessors = digraph->nsuccessors[startnode];
5589 
5590  /* search for the arc in existing arcs */
5591  for( i = 0; i < nsuccessors; ++i )
5592  if( digraph->successors[startnode][i] == endnode )
5593  return SCIP_OKAY;
5594 
5595  SCIP_CALL( ensureSuccessorsSize(digraph, startnode, nsuccessors + 1) );
5596 
5597  /* add arc */
5598  digraph->successors[startnode][nsuccessors] = endnode;
5599  digraph->arcdata[startnode][nsuccessors] = data;
5600  ++(digraph->nsuccessors[startnode]);
5601 
5602  return SCIP_OKAY;
5603 }
5604 
5605 /** returns the number of nodes of the given digraph */
5607  SCIP_DIGRAPH* digraph /**< directed graph */
5608  )
5609 {
5610  assert(digraph != NULL);
5611 
5612  return digraph->nnodes;
5613 }
5614 
5615 /** returns the node data, or NULL if no data exist */
5617  SCIP_DIGRAPH* digraph, /**< directed graph */
5618  int node /**< node for which the node data is returned */
5619  )
5620 {
5621  assert(digraph != NULL);
5622  assert(node >= 0);
5623  assert(node < digraph->nnodes);
5624 
5625  return digraph->nodedata[node];
5626 }
5627 
5628 /** sets the node data
5629  *
5630  * @note The old user pointer is not freed. This has to be done by the user
5631  */
5633  SCIP_DIGRAPH* digraph, /**< directed graph */
5634  void* dataptr, /**< user node data pointer, or NULL */
5635  int node /**< node for which the node data is returned */
5636  )
5637 {
5638  assert(digraph != NULL);
5639  assert(node >= 0);
5640  assert(node < digraph->nnodes);
5641 
5642  digraph->nodedata[node] = dataptr;
5643 }
5644 
5645 /** returns the total number of arcs in the given digraph */
5647  SCIP_DIGRAPH* digraph /**< directed graph */
5648  )
5649 {
5650  int i;
5651  int narcs;
5652 
5653  assert(digraph != NULL);
5654 
5655  /* count number of arcs */
5656  narcs = 0;
5657  for( i = 0; i < digraph->nnodes; ++i )
5658  narcs += digraph->nsuccessors[i];
5659 
5660  return narcs;
5661 }
5662 
5663 /** returns the number of successor nodes of the given node */
5665  SCIP_DIGRAPH* digraph, /**< directed graph */
5666  int node /**< node for which the number of outgoing arcs is returned */
5667  )
5668 {
5669  assert(digraph != NULL);
5670  assert(node >= 0);
5671  assert(node < digraph->nnodes);
5672  assert(digraph->nsuccessors[node] >= 0);
5673  assert(digraph->nsuccessors[node] <= digraph->successorssize[node]);
5674 
5675  return digraph->nsuccessors[node];
5676 }
5677 
5678 /** returns the array of indices of the successor nodes; this array must not be changed from outside */
5680  SCIP_DIGRAPH* digraph, /**< directed graph */
5681  int node /**< node for which the array of outgoing arcs is returned */
5682  )
5683 {
5684  assert(digraph != NULL);
5685  assert(node >= 0);
5686  assert(node < digraph->nnodes);
5687  assert(digraph->nsuccessors[node] >= 0);
5688  assert(digraph->nsuccessors[node] <= digraph->successorssize[node]);
5689  assert((digraph->nsuccessors[node] == 0) || (digraph->successors[node] != NULL));
5690 
5691  return digraph->successors[node];
5692 }
5693 
5694 /** returns the array of data corresponding to the arcs originating at the given node, or NULL if no data exist; this
5695  * array must not be changed from outside
5696  */
5698  SCIP_DIGRAPH* digraph, /**< directed graph */
5699  int node /**< node for which the data corresponding to the outgoing arcs is returned */
5700  )
5701 {
5702  assert(digraph != NULL);
5703  assert(node >= 0);
5704  assert(node < digraph->nnodes);
5705  assert(digraph->nsuccessors[node] >= 0);
5706  assert(digraph->nsuccessors[node] <= digraph->successorssize[node]);
5707  assert(digraph->arcdata != NULL);
5708 
5709  return digraph->arcdata[node];
5710 }
5711 
5712 /** performs depth-first-search in the given directed graph from the given start node */
5713 static
5715  SCIP_DIGRAPH* digraph, /**< directed graph */
5716  int startnode, /**< node to start the depth-first-search */
5717  SCIP_Bool* visited, /**< array to store for each node, whether it was already visited */
5718  int* dfsstack, /**< array of size number of nodes to store the stack;
5719  * only needed for performance reasons */
5720  int* stackadjvisited, /**< array of size number of nodes to store the number of adjacent nodes already visited
5721  * for each node on the stack; only needed for performance reasons */
5722  int* dfsnodes, /**< array of nodes that can be reached starting at startnode, in reverse dfs order */
5723  int* ndfsnodes /**< pointer to store number of nodes that can be reached starting at startnode */
5724  )
5725 {
5726  int stacksize;
5727  int currnode;
5728 
5729  assert(digraph != NULL);
5730  assert(startnode >= 0);
5731  assert(startnode < digraph->nnodes);
5732  assert(visited != NULL);
5733  assert(visited[startnode] == FALSE);
5734  assert(dfsstack != NULL);
5735  assert(dfsnodes != NULL);
5736  assert(ndfsnodes != NULL);
5737 
5738  /* put start node on the stack */
5739  dfsstack[0] = startnode;
5740  stackadjvisited[0] = 0;
5741  stacksize = 1;
5742 
5743  while( stacksize > 0 )
5744  {
5745  /* get next node from stack */
5746  currnode = dfsstack[stacksize - 1];
5747 
5748  /* mark current node as visited */
5749  assert(visited[currnode] == (stackadjvisited[stacksize - 1] > 0));
5750  visited[currnode] = TRUE;
5751 
5752  /* iterate through the successor list until we reach unhandled node */
5753  while( stackadjvisited[stacksize - 1] < digraph->nsuccessors[currnode]
5754  && visited[digraph->successors[currnode][stackadjvisited[stacksize - 1]]] )
5755  {
5756  stackadjvisited[stacksize - 1]++;
5757  }
5758 
5759  /* the current node was completely handled, remove it from stack */
5760  if( stackadjvisited[stacksize - 1] == digraph->nsuccessors[currnode] )
5761  {
5762  stacksize--;
5763 
5764  /* store node in the sorted nodes array */
5765  dfsnodes[(*ndfsnodes)] = currnode;
5766  (*ndfsnodes)++;
5767  }
5768  /* handle next unhandled successor node */
5769  else
5770  {
5771  assert(!visited[digraph->successors[currnode][stackadjvisited[stacksize - 1]]]);
5772 
5773  /* put the successor node onto the stack */
5774  dfsstack[stacksize] = digraph->successors[currnode][stackadjvisited[stacksize - 1]];
5775  stackadjvisited[stacksize] = 0;
5776  stackadjvisited[stacksize - 1]++;
5777  stacksize++;
5778  assert(stacksize <= digraph->nnodes);
5779  }
5780  }
5781 }
5782 
5783 /** Compute undirected connected components on the given graph.
5784  *
5785  * @note For each arc, its reverse is added, so the graph does not need to be the directed representation of an
5786  * undirected graph.
5787  */
5789  SCIP_DIGRAPH* digraph, /**< directed graph */
5790  int minsize, /**< all components with less nodes are ignored */
5791  int* components, /**< array with as many slots as there are nodes in the directed graph
5792  * to store for each node the component to which it belongs
5793  * (components are numbered 0 to ncomponents - 1); or NULL, if components
5794  * are accessed one-by-one using SCIPdigraphGetComponent() */
5795  int* ncomponents /**< pointer to store the number of components; or NULL, if the
5796  * number of components is accessed by SCIPdigraphGetNComponents() */
5797  )
5798 {
5799  SCIP_Bool* visited;
5800  int* ndirectedsuccessors;
5801  int* stackadjvisited;
5802  int* dfsstack;
5803  int ndfsnodes;
5804  int compstart;
5805  int v;
5806  int i;
5807  int j;
5808 
5809  assert(digraph != NULL);
5810  assert(digraph->nnodes > 0);
5811 
5812  /* first free the old components */
5813  if( digraph->ncomponents > 0 )
5814  {
5815  SCIPdigraphFreeComponents(digraph);
5816  }
5817 
5818  digraph->ncomponents = 0;
5819  digraph->componentstartsize = 10;
5820 
5821  SCIP_ALLOC( BMSallocClearMemoryArray(&visited, digraph->nnodes) );
5822  SCIP_ALLOC( BMSallocMemoryArray(&digraph->components, digraph->nnodes) );
5824  SCIP_ALLOC( BMSallocMemoryArray(&dfsstack, digraph->nnodes) );
5825  SCIP_ALLOC( BMSallocMemoryArray(&stackadjvisited, digraph->nnodes) );
5826  SCIP_ALLOC( BMSallocMemoryArray(&ndirectedsuccessors, digraph->nnodes) );
5827 
5828  digraph->componentstarts[0] = 0;
5829 
5830  /* store the number of directed arcs per node */
5831  BMScopyMemoryArray(ndirectedsuccessors, digraph->nsuccessors, digraph->nnodes);
5832 
5833  /* add reverse arcs to the graph */
5834  for( i = digraph->nnodes - 1; i >= 0; --i )
5835  {
5836  for( j = 0; j < ndirectedsuccessors[i]; ++j )
5837  {
5838  SCIP_CALL( SCIPdigraphAddArc(digraph, digraph->successors[i][j], i, NULL) );
5839  }
5840  }
5841 
5842  for( v = 0; v < digraph->nnodes; ++v )
5843  {
5844  if( visited[v] )
5845  continue;
5846 
5847  compstart = digraph->componentstarts[digraph->ncomponents];
5848  ndfsnodes = 0;
5849  depthFirstSearch(digraph, v, visited, dfsstack, stackadjvisited,
5850  &digraph->components[compstart], &ndfsnodes);
5851 
5852  /* forget about this component if it is too small */
5853  if( ndfsnodes >= minsize )
5854  {
5855  digraph->ncomponents++;
5856 
5857  /* enlarge componentstartsize array, if needed */
5858  if( digraph->ncomponents >= digraph->componentstartsize )
5859  {
5860  digraph->componentstartsize = 2 * digraph->componentstartsize;
5861  assert(digraph->ncomponents < digraph->componentstartsize);
5862 
5864  }
5865  digraph->componentstarts[digraph->ncomponents] = compstart + ndfsnodes;
5866 
5867  /* store component number for contained nodes if array was given */
5868  if( components != NULL )
5869  {
5870  for( i = digraph->componentstarts[digraph->ncomponents] - 1; i >= compstart; --i )
5871  {
5872  components[digraph->components[i]] = digraph->ncomponents - 1;
5873  }
5874  }
5875  }
5876  }
5877 
5878  /* restore the number of directed arcs per node */
5879  BMScopyMemoryArray(digraph->nsuccessors, ndirectedsuccessors, digraph->nnodes);
5880  BMSclearMemoryArray(visited, digraph->nnodes);
5881 
5882  /* return number of components, if the pointer was given */
5883  if( ncomponents != NULL )
5884  (*ncomponents) = digraph->ncomponents;
5885 
5886  BMSfreeMemoryArray(&ndirectedsuccessors);
5887  BMSfreeMemoryArray(&stackadjvisited);
5888  BMSfreeMemoryArray(&dfsstack);
5889  BMSfreeMemoryArray(&visited);
5890 
5891  return SCIP_OKAY;
5892 }
5893 
5894 /** Performes an (almost) topological sort on the undirected components of the given directed graph. The undirected
5895  * components should be computed before using SCIPdigraphComputeUndirectedComponents().
5896  *
5897  * @note In general a topological sort is not unique. Note, that there might be directed cycles, that are randomly
5898  * broken, which is the reason for having only almost topologically sorted arrays.
5899  */
5901  SCIP_DIGRAPH* digraph /**< directed graph */
5902  )
5903 {
5904  SCIP_Bool* visited;
5905  int* comps;
5906  int* compstarts;
5907  int* stackadjvisited;
5908  int* dfsstack;
5909  int* dfsnodes;
5910  int ndfsnodes;
5911  int ncomps;
5912  int i;
5913  int j;
5914  int k;
5915  int endidx;
5916 
5917  assert(digraph != NULL);
5918 
5919  ncomps = digraph->ncomponents;
5920  comps = digraph->components;
5921  compstarts = digraph->componentstarts;
5922 
5923  SCIP_ALLOC( BMSallocClearMemoryArray(&visited, digraph->nnodes) );
5924  SCIP_ALLOC( BMSallocMemoryArray(&dfsnodes, digraph->nnodes) );
5925  SCIP_ALLOC( BMSallocMemoryArray(&dfsstack, digraph->nnodes) );
5926  SCIP_ALLOC( BMSallocMemoryArray(&stackadjvisited, digraph->nnodes) );
5927 
5928  /* sort the components (almost) topologically */
5929  for( i = 0; i < ncomps; ++i )
5930  {
5931  endidx = compstarts[i+1] - 1;
5932  ndfsnodes = 0;
5933  for( j = compstarts[i]; j < compstarts[i+1]; ++j )
5934  {
5935  if( visited[comps[j]] )
5936  continue;
5937 
5938  /* perform depth first search, nodes visited in this call are appended to the list dfsnodes in reverse
5939  * dfs order, after the nodes already contained;
5940  * so at every point in time, the nodes in dfsnode are in reverse (almost) topological order
5941  */
5942  depthFirstSearch(digraph, comps[j], visited, dfsstack, stackadjvisited, dfsnodes, &ndfsnodes);
5943  }
5944  assert(endidx - ndfsnodes == compstarts[i] - 1);
5945 
5946  /* copy reverse (almost) topologically sorted array of nodes reached by the dfs searches;
5947  * reverse their order to get an (almost) topologically sort
5948  */
5949  for( k = 0; k < ndfsnodes; ++k )
5950  {
5951  digraph->components[endidx - k] = dfsnodes[k];
5952  }
5953  }
5954 
5955  BMSfreeMemoryArray(&stackadjvisited);
5956  BMSfreeMemoryArray(&dfsstack);
5957  BMSfreeMemoryArray(&dfsnodes);
5958  BMSfreeMemoryArray(&visited);
5959 
5960  return SCIP_OKAY;
5961 }
5962 
5963 /** returns the number of previously computed undirected components for the given directed graph */
5965  SCIP_DIGRAPH* digraph /**< directed graph */
5966  )
5967 {
5968  assert(digraph != NULL);
5969  assert(digraph->componentstartsize > 0); /* components should have been computed */
5970 
5971  return digraph->ncomponents;
5972 }
5973 
5974 /** Returns the previously computed undirected component of the given number for the given directed graph.
5975  * If the components were sorted using SCIPdigraphTopoSortComponents(), the component is (almost) topologically sorted.
5976  */
5978  SCIP_DIGRAPH* digraph, /**< directed graph */
5979  int compidx, /**< number of the component to return */
5980  int** nodes, /**< pointer to store the nodes in the component; or NULL, if not needed */
5981  int* nnodes /**< pointer to store the number of nodes in the component;
5982  * or NULL, if not needed */
5983  )
5984 {
5985  assert(digraph != NULL);
5986  assert(compidx >= 0);
5987  assert(compidx < digraph->ncomponents);
5988  assert(nodes != NULL || nnodes != NULL);
5989 
5990  if( nodes != NULL )
5991  (*nodes) = &(digraph->components[digraph->componentstarts[compidx]]);
5992  if( nnodes != NULL )
5993  (*nnodes) = digraph->componentstarts[compidx + 1] - digraph->componentstarts[compidx];
5994 }
5995 
5996 /** frees the component information for the given directed graph */
5998  SCIP_DIGRAPH* digraph /**< directed graph */
5999  )
6000 {
6001  assert(digraph != NULL);
6002 
6003  /* free components structure */
6004  if( digraph->componentstartsize > 0 )
6005  {
6007  BMSfreeMemoryArray(&digraph->components);
6008  digraph->components = NULL;
6009  digraph->componentstarts = NULL;
6010  digraph->ncomponents = 0;
6011  digraph->componentstartsize = 0;
6012  }
6013 #ifndef NDEBUG
6014  else
6015  {
6016  assert(digraph->components == NULL);
6017  assert(digraph->componentstarts == NULL);
6018  assert(digraph->ncomponents == 0);
6019  }
6020 #endif
6021 }
6022 
6023 /** output of the given directed graph via the given message handler */
6025  SCIP_DIGRAPH* digraph, /**< directed graph */
6026  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
6027  FILE* file /**< output file (or NULL for standard output) */
6028  )
6029 {
6030  int n;
6031 
6032  for( n = 0; n < digraph->nnodes; ++n )
6033  {
6034  int* successors;
6035  int nsuccessors;
6036  int m;
6037 
6038  nsuccessors = digraph->nsuccessors[n];
6039  successors = digraph->successors[n];
6040 
6041  SCIPmessageFPrintInfo(messagehdlr, file, "node %d --> ", n);
6042 
6043  for( m = 0; m < nsuccessors ; ++m )
6044  {
6045  if( m == 0 )
6046  {
6047  SCIPmessageFPrintInfo(messagehdlr, file, "%d", successors[m]);
6048  }
6049  else
6050  {
6051  SCIPmessageFPrintInfo(messagehdlr, file, ", %d", successors[m]);
6052  }
6053  }
6054  SCIPmessageFPrintInfo(messagehdlr, file, "\n");
6055  }
6056 }
6057 
6058 /** prints the given directed graph structure in GML format into the given file */
6060  SCIP_DIGRAPH* digraph, /**< directed graph */
6061  FILE* file /**< file to write to */
6062  )
6063 {
6064  int n;
6065 
6066  /* write GML format opening */
6067  SCIPgmlWriteOpening(file, TRUE);
6068 
6069  /* write all nodes of the graph */
6070  for( n = 0; n < digraph->nnodes; ++n )
6071  {
6072  char label[SCIP_MAXSTRLEN];
6073 
6074  (void)SCIPsnprintf(label, SCIP_MAXSTRLEN, "%d", n);
6075  SCIPgmlWriteNode(file, (unsigned int)n, label, "circle", NULL, NULL);
6076  }
6077 
6078  /* write all edges */
6079  for( n = 0; n < digraph->nnodes; ++n )
6080  {
6081  int* successors;
6082  int nsuccessors;
6083  int m;
6084 
6085  nsuccessors = digraph->nsuccessors[n];
6086  successors = digraph->successors[n];
6087 
6088  for( m = 0; m < nsuccessors; ++m )
6089  {
6090  SCIPgmlWriteArc(file, (unsigned int)n, (unsigned int)successors[m], NULL, NULL);
6091  }
6092  }
6093  /* write GML format closing */
6094  SCIPgmlWriteClosing(file);
6095 }
6096 
6097 /** output of the given directed graph via the given message handler */
6099  SCIP_DIGRAPH* digraph, /**< directed graph */
6100  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
6101  FILE* file /**< output file (or NULL for standard output) */
6102  )
6103 {
6104  int c;
6105  int i;
6106 
6107  for( c = 0; c < digraph->ncomponents; ++c )
6108  {
6109  int start = digraph->componentstarts[c];
6110  int end = digraph->componentstarts[c+1];
6111 
6112  SCIPmessageFPrintInfo(messagehdlr, file, "Components %d --> ", c);
6113 
6114  for( i = start; i < end; ++i )
6115  {
6116  if( i == start )
6117  {
6118  SCIPmessageFPrintInfo(messagehdlr, file, "%d", digraph->components[i]);
6119  }
6120  else
6121  {
6122  SCIPmessageFPrintInfo(messagehdlr, file, ", %d", digraph->components[i]);
6123  }
6124  }
6125  SCIPmessageFPrintInfo(messagehdlr, file, "\n");
6126  }
6127 }
6128 
6129 /*
6130  * Binary tree
6131  */
6132 
6133 /** creates a node for a binary tree */
6134 static
6136  SCIP_BT* tree, /**< binary tree */
6137  SCIP_BTNODE** node /**< pointer to store the created node */
6138  )
6139 {
6140  SCIP_ALLOC( BMSallocBlockMemory(tree->blkmem, node) );
6141 
6142  (*node)->parent = NULL;
6143  (*node)->left = NULL;
6144  (*node)->right = NULL;
6145  (*node)->dataptr = NULL;
6146 
6147  return SCIP_OKAY;
6148 }
6149 
6150 /** creates a tree node with (optinal) user data */
6152  SCIP_BT* tree, /**< binary tree */
6153  SCIP_BTNODE** node, /**< pointer to store the created node */
6154  void* dataptr /**< user node data pointer, or NULL */
6155  )
6156 {
6157  assert(tree != NULL);
6158  assert(node != NULL);
6159 
6160  SCIP_CALL( btnodeCreateEmpty(tree, node) );
6161 
6162  assert((*node)->parent == NULL);
6163  assert((*node)->left == NULL);
6164  assert((*node)->right == NULL);
6165 
6166  /* initialize user data */
6167  (*node)->dataptr = dataptr;
6168 
6169  return SCIP_OKAY;
6170 }
6171 
6172 /** frees a tree leaf */
6173 static
6175  SCIP_BT* tree, /**< binary tree */
6176  SCIP_BTNODE** node /**< pointer to node which has to be freed */
6177  )
6178 {
6179  assert(tree != NULL);
6180  assert(node != NULL);
6181  assert(*node != NULL);
6182 
6183  assert((*node)->left == NULL);
6184  assert((*node)->right == NULL);
6185 
6186 #if 0
6187  /* remove reference from parent node */
6188  if( (*node)->parent != NULL )
6189  {
6190  assert(*node != NULL);
6191 
6192  assert((*node)->parent->left == *node || ((*node)->parent->right == *node));
6193 
6194  if( (*node)->parent->left == *node )
6195  {
6196  (*node)->parent->left = NULL;
6197  }
6198  else
6199  {
6200  assert((*node)->parent->right == *node);
6201  (*node)->parent->right = NULL;
6202  }
6203  }
6204 #endif
6205 
6206  assert(*node != NULL);
6207  BMSfreeBlockMemory(tree->blkmem, node);
6208  assert(*node == NULL);
6209 }
6210 
6211 /** frees the node including the rooted subtree
6212  *
6213  * @note The user pointer (object) is not freed. If needed, it has to be done by the user.
6214  */
6216  SCIP_BT* tree, /**< binary tree */
6217  SCIP_BTNODE** node /**< node to be freed */
6218  )
6219 {
6220  assert(tree != NULL);
6221  assert(node != NULL);
6222  assert(*node != NULL);
6223 
6224  if( (*node)->left != NULL )
6225  {
6226  SCIPbtnodeFree(tree, &(*node)->left);
6227  assert((*node)->left == NULL);
6228  }
6229 
6230  if( (*node)->right != NULL )
6231  {
6232  SCIPbtnodeFree(tree, &(*node)->right);
6233  assert((*node)->right == NULL);
6234  }
6235 
6236  btnodeFreeLeaf(tree, node);
6237  assert(*node == NULL);
6238 }
6239 
6240 /* some simple variable functions implemented as defines */
6241 
6242 /* In debug mode, the following methods are implemented as function calls to ensure
6243  * type validity.
6244  * In optimized mode, the methods are implemented as defines to improve performance.
6245  * However, we want to have them in the library anyways, so we have to undef the defines.
6246  */
6247 
6248 #undef SCIPbtnodeGetData
6249 #undef SCIPbtnodeGetKey
6250 #undef SCIPbtnodeGetParent
6251 #undef SCIPbtnodeGetLeftchild
6252 #undef SCIPbtnodeGetRightchild
6253 #undef SCIPbtnodeGetSibling
6254 #undef SCIPbtnodeIsRoot
6255 #undef SCIPbtnodeIsLeaf
6256 #undef SCIPbtnodeIsLeftchild
6257 #undef SCIPbtnodeIsRightchild
6258 
6259 /** returns the user data pointer stored in that node */
6261  SCIP_BTNODE* node /**< node */
6262  )
6263 {
6264  assert(node != NULL);
6265 
6266  return node->dataptr;
6267 }
6268 
6269 /** returns the parent which can be NULL if the given node is the root */
6271  SCIP_BTNODE* node /**< node */
6272  )
6273 {
6274  assert(node != NULL);
6275 
6276  return node->parent;
6277 }
6278 
6279 /** returns left child which can be NULL if the given node is a leaf */
6281  SCIP_BTNODE* node /**< node */
6282  )
6283 {
6284  assert(node != NULL);
6285 
6286  return node->left;
6287 }
6288 
6289 /** returns right child which can be NULL if the given node is a leaf */
6291  SCIP_BTNODE* node /**< node */
6292  )
6293 {
6294  assert(node != NULL);
6295 
6296  return node->right;
6297 }
6298 
6299 /** returns the sibling of the node or NULL if does not exist */
6301  SCIP_BTNODE* node /**< node */
6302  )
6303 {
6304  SCIP_BTNODE* parent;
6305 
6306  parent = SCIPbtnodeGetParent(node);
6307 
6308  if( parent == NULL )
6309  return NULL;
6310 
6311  if( SCIPbtnodeGetLeftchild(parent) == node )
6312  return SCIPbtnodeGetRightchild(parent);
6313 
6314  assert(SCIPbtnodeGetRightchild(parent) == node);
6315 
6316  return SCIPbtnodeGetLeftchild(parent);
6317 }
6318 
6319 /** returns whether the node is a root node */
6321  SCIP_BTNODE* node /**< node */
6322  )
6323 {
6324  assert(node != NULL);
6325 
6326  return (node->parent == NULL);
6327 }
6328 
6329 /** returns whether the node is a leaf */
6331  SCIP_BTNODE* node /**< node */
6332  )
6333 {
6334  assert(node != NULL);
6335 
6336  return (node->left == NULL && node->right == NULL);
6337 }
6338 
6339 /** returns TRUE if the given node is left child */
6341  SCIP_BTNODE* node /**< node */
6342  )
6343 {
6344  SCIP_BTNODE* parent;
6345 
6346  if( SCIPbtnodeIsRoot(node) )
6347  return FALSE;
6348 
6349  parent = SCIPbtnodeGetParent(node);
6350 
6351  if( SCIPbtnodeGetLeftchild(parent) == node )
6352  return TRUE;
6353 
6354  return FALSE;
6355 }
6356 
6357 /** returns TRUE if the given node is right child */
6359  SCIP_BTNODE* node /**< node */
6360  )
6361 {
6362  SCIP_BTNODE* parent;
6363 
6364  if( SCIPbtnodeIsRoot(node) )
6365  return FALSE;
6366 
6367  parent = SCIPbtnodeGetParent(node);
6368 
6369  if( SCIPbtnodeGetRightchild(parent) == node )
6370  return TRUE;
6371 
6372  return FALSE;
6373 }
6374 
6375 /** sets the give node data
6376  *
6377  * @note The old user pointer is not freed.
6378  */
6380  SCIP_BTNODE* node, /**< node */
6381  void* dataptr /**< node user data pointer */
6382  )
6383 {
6384  assert(node != NULL);
6385 
6386  node->dataptr = dataptr;
6387 }
6388 
6389 /** sets parent node
6390  *
6391  * @note The old parent including the rooted subtree is not delete.
6392  */
6394  SCIP_BTNODE* node, /**< node */
6395  SCIP_BTNODE* parent /**< new parent node, or NULL */
6396  )
6397 {
6398  assert(node != NULL);
6399 
6400  node->parent = parent;
6401 }
6402 
6403 /** sets left child
6404  *
6405  * @note The old left child including the rooted subtree is not delete.
6406  */
6408  SCIP_BTNODE* node, /**< node */
6409  SCIP_BTNODE* left /**< new left child, or NULL */
6410  )
6411 {
6412  assert(node != NULL);
6413 
6414  node->left = left;
6415 }
6416 
6417 /** sets right child
6418  *
6419  * @note The old right child including the rooted subtree is not delete.
6420  */
6422  SCIP_BTNODE* node, /**< node */
6423  SCIP_BTNODE* right /**< new right child, or NULL */
6424  )
6425 {
6426  assert(node != NULL);
6427 
6428  node->right = right;
6429 }
6430 
6431 /** creates an binary tree */
6433  SCIP_BT** tree, /**< pointer to store the created binary tree */
6434  BMS_BLKMEM* blkmem /**< block memory used to createnode */
6435  )
6436 {
6437  assert(tree != NULL);
6438  assert(blkmem != NULL);
6439 
6440  SCIP_ALLOC( BMSallocMemory(tree) );
6441  (*tree)->blkmem = blkmem;
6442  (*tree)->root = NULL;
6443 
6444  return SCIP_OKAY;
6445 }
6446 
6447 /** frees binary tree
6448  *
6449  * @note The user pointers (object) of the nodes are not freed. If needed, it has to be done by the user.
6450  */
6452  SCIP_BT** tree /**< pointer to binary tree */
6453  )
6454 {
6455  assert(tree != NULL);
6456 
6457  if( (*tree)->root != NULL )
6458  {
6459  SCIPbtnodeFree(*tree, &((*tree)->root));
6460  }
6461 
6462  BMSfreeMemory(tree);
6463 }
6464 
6465 /** prints the rooted subtree of the given binary tree node in GML format into the given file */
6466 static
6468  SCIP_BTNODE* node, /**< binary tree node */
6469  FILE* file, /**< file to write to */
6470  int* nnodes /**< pointer to count the number of nodes */
6471  )
6472 {
6473  SCIP_BTNODE* left;
6474  SCIP_BTNODE* right;
6475  char label[SCIP_MAXSTRLEN];
6476 
6477  assert(node != NULL);
6478 
6479  (*nnodes)++;
6480  (void)SCIPsnprintf(label, SCIP_MAXSTRLEN, "%d", *nnodes);
6481 
6482  SCIPgmlWriteNode(file, (unsigned int)(size_t)node, label, "circle", NULL, NULL);
6483 
6484  left = SCIPbtnodeGetLeftchild(node);
6485  right = SCIPbtnodeGetRightchild(node);
6486 
6487  if( left != NULL )
6488  {
6489  btPrintSubtree(left, file, nnodes);
6490 
6491  SCIPgmlWriteArc(file, (unsigned int)(size_t)node, (unsigned int)(size_t)left, NULL, NULL);
6492  }
6493 
6494  if( right != NULL )
6495  {
6496  btPrintSubtree(right, file, nnodes);
6497 
6498  SCIPgmlWriteArc(file, (unsigned int)(size_t)node, (unsigned int)(size_t)right, NULL, NULL);
6499  }
6500 }
6501 
6502 /** prints the binary tree in GML format into the given file */
6504  SCIP_BT* tree, /**< binary tree */
6505  FILE* file /**< file to write to */
6506  )
6507 {
6508  /* write GML opening */
6509  SCIPgmlWriteOpening(file, TRUE);
6510 
6511  if( !SCIPbtIsEmpty(tree) )
6512  {
6513  SCIP_BTNODE* root;
6514  int nnodes;
6515 
6516  root = SCIPbtGetRoot(tree);
6517  assert(root != NULL);
6518 
6519  nnodes = 0;
6520 
6521  btPrintSubtree(root, file, &nnodes);
6522  }
6523 
6524  /* write GML closing */
6525  SCIPgmlWriteClosing(file);
6526 }
6527 
6528 /* some simple variable functions implemented as defines */
6529 #undef SCIPbtIsEmpty
6530 #undef SCIPbtGetRoot
6531 
6532 /** returns whether the binary tree is empty (has no nodes) */
6534  SCIP_BT* tree /**< binary tree */
6535  )
6536 {
6537  assert(tree != NULL);
6538 
6539  return (tree->root == NULL);
6540 }
6541 
6542 /** returns the the root node of the binary or NULL if the binary tree is empty */
6544  SCIP_BT* tree /**< tree to be evaluated */
6545  )
6546 {
6547  assert(tree != NULL);
6548 
6549  return tree->root;
6550 }
6551 
6552 /** sets root node
6553  *
6554  * @note The old root including the rooted subtree is not delete.
6555  */
6557  SCIP_BT* tree, /**< tree to be evaluated */
6558  SCIP_BTNODE* root /**< new root, or NULL */
6559  )
6560 {
6561  assert(tree != NULL);
6562 
6563  tree->root = root;
6564 }
6565 
6566 
6567 /*
6568  * Numerical methods
6569  */
6570 
6571 /** returns the machine epsilon: the smallest number eps > 0, for which 1.0 + eps > 1.0 */
6573  void
6574  )
6575 {
6576  SCIP_Real eps;
6577  SCIP_Real lasteps;
6578  SCIP_Real one;
6579  SCIP_Real onepluseps;
6580 
6581  one = 1.0;
6582  eps = 1.0;
6583  do
6584  {
6585  lasteps = eps;
6586  eps /= 2.0;
6587  onepluseps = one + eps;
6588  }
6589  while( onepluseps > one );
6590 
6591  return lasteps;
6592 }
6593 
6594 /** calculates the greatest common divisor of the two given values */
6596  SCIP_Longint val1, /**< first value of greatest common devisor calculation */
6597  SCIP_Longint val2 /**< second value of greatest common devisor calculation */
6598  )
6599 {
6600  int t;
6601 
6602  assert(val1 > 0);
6603  assert(val2 > 0);
6604 
6605  t = 0;
6606  /* if val1 is even, divide it by 2 */
6607  while( !(val1 & 1) )
6608  {
6609  val1 >>= 1; /*lint !e704*/
6610 
6611  /* if val2 is even too, divide it by 2 and increase t(=number of e) */
6612  if( !(val2 & 1) )
6613  {
6614  val2 >>= 1; /*lint !e704*/
6615  ++t;
6616  }
6617  /* only val1 can be odd */
6618  else
6619  {
6620  /* while val1 is even, divide it by 2 */
6621  while( !(val1 & 1) )
6622  val1 >>= 1; /*lint !e704*/
6623 
6624  break;
6625  }
6626  }
6627 
6628  /* while val2 is even, divide it by 2 */
6629  while( !(val2 & 1) )
6630  val2 >>= 1; /*lint !e704*/
6631 
6632  /* the following if/else condition is only to make sure that we do not overflow when adding up both values before
6633  * dividing them by 4 in the following while loop
6634  */
6635  if( t == 0 )
6636  {
6637  if( val1 > val2 )
6638  {
6639  val1 -= val2;
6640 
6641  /* divide val1 by 2 as long as possible */
6642  while( !(val1 & 1) )
6643  val1 >>= 1; /*lint !e704*/
6644  }
6645  else if( val1 < val2 )
6646  {
6647  val2 -= val1;
6648 
6649  /* divide val2 by 2 as long as possible */
6650  while( !(val2 & 1) )
6651  val2 >>= 1; /*lint !e704*/
6652  }
6653  }
6654 
6655  /* val1 and val2 are odd */
6656  while( val1 != val2 )
6657  {
6658  if( val1 > val2 )
6659  {
6660  /* we can stop if one value reached one */
6661  if( val2 == 1 )
6662  return (1 << t); /*lint !e647 !e701*/
6663 
6664  /* if ((val1 xor val2) and 2) = 2, then gcd(val1, val2) = gcd((val1 + val2)/4, val2),
6665  * and otherwise gcd(val1, val2) = gcd((val1 − val2)/4, val2)
6666  */
6667  if( ((val1 ^ val2) & 2) == 2 )
6668  val1 += val2;
6669  else
6670  val1 -= val2;
6671 
6672  assert((val1 & 3) == 0);
6673  val1 >>= 2; /*lint !e704*/
6674 
6675  /* if val1 is still even, divide it by 2 */
6676  while( !(val1 & 1) )
6677  val1 >>= 1; /*lint !e704*/
6678  }
6679  else
6680  {
6681  /* we can stop if one value reached one */
6682  if( val1 == 1 )
6683  return (1 << t); /*lint !e647 !e701*/
6684 
6685  /* if ((val2 xor val1) and 2) = 2, then gcd(val2, val1) = gcd((val2 + val1)/4, val1),
6686  * and otherwise gcd(val2, val1) = gcd((val2 − val1)/4, val1)
6687  */
6688  if( ((val2 ^ val1) & 2) == 2 )
6689  val2 += val1;
6690  else
6691  val2 -= val1;
6692 
6693  assert((val2 & 3) == 0);
6694  val2 >>= 2; /*lint !e704*/
6695 
6696  /* if val2 is still even, divide it by 2 */
6697  while( !(val2 & 1) )
6698  val2 >>= 1; /*lint !e704*/
6699  }
6700  }
6701 
6702  return (val1 << t); /*lint !e703*/
6703 }
6704 
6705 /** calculates the smallest common multiple of the two given values */
6707  SCIP_Longint val1, /**< first value of smallest common multiple calculation */
6708  SCIP_Longint val2 /**< second value of smallest common multiple calculation */
6709  )
6710 {
6711  SCIP_Longint gcd;
6712 
6713  assert(val1 > 0);
6714  assert(val2 > 0);
6715 
6716  gcd = SCIPcalcGreComDiv(val1, val2);
6717 
6718  return val1/gcd * val2;
6719 }
6720 
6721 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,
6722  17.0, 18.0, 19.0, 25.0, -1.0};
6723 
6724 /** converts a real number into a (approximate) rational representation, and returns TRUE iff the conversion was
6725  * successful
6726  */
6728  SCIP_Real val, /**< real value r to convert into rational number */
6729  SCIP_Real mindelta, /**< minimal allowed difference r - q of real r and rational q = n/d */
6730  SCIP_Real maxdelta, /**< maximal allowed difference r - q of real r and rational q = n/d */
6731  SCIP_Longint maxdnom, /**< maximal denominator allowed */
6732  SCIP_Longint* nominator, /**< pointer to store the nominator n of the rational number */
6733  SCIP_Longint* denominator /**< pointer to store the denominator d of the rational number */
6734  )
6735 {
6736  SCIP_Real a;
6737  SCIP_Real b;
6738  SCIP_Real g0;
6739  SCIP_Real g1;
6740  SCIP_Real gx;
6741  SCIP_Real h0;
6742  SCIP_Real h1;
6743  SCIP_Real hx;
6744  SCIP_Real delta0;
6745  SCIP_Real delta1;
6746  SCIP_Real epsilon;
6747  int i;
6748 
6749  assert(mindelta < 0.0);
6750  assert(maxdelta > 0.0);
6751  assert(nominator != NULL);
6752  assert(denominator != NULL);
6753 
6754  /* try the simple denominators first: each value of the simpledenoms table multiplied by powers of 10
6755  * is tried as denominator
6756  */
6757  for( i = 0; simplednoms[i] > 0.0; ++i )
6758  {
6759  SCIP_Real nom;
6760  SCIP_Real dnom;
6761  SCIP_Real ratval0;
6762  SCIP_Real ratval1;
6763 
6764  /* try powers of 10 (including 10^0) */
6765  dnom = simplednoms[i];
6766  while( dnom <= maxdnom )
6767  {
6768  nom = floor(val * dnom);
6769  ratval0 = nom/dnom;
6770  ratval1 = (nom+1.0)/dnom;
6771  if( mindelta <= val - ratval0 && val - ratval1 <= maxdelta )
6772  {
6773  if( val - ratval0 <= maxdelta )
6774  {
6775  *nominator = (SCIP_Longint)nom;
6776  *denominator = (SCIP_Longint)dnom;
6777  return TRUE;
6778  }
6779  if( mindelta <= val - ratval1 )
6780  {
6781  *nominator = (SCIP_Longint)(nom+1.0);
6782  *denominator = (SCIP_Longint)dnom;
6783  return TRUE;
6784  }
6785  }
6786  dnom *= 10.0;
6787  }
6788  }
6789 
6790  /* the simple denominators didn't work: calculate rational representation with arbitrary denominator */
6791  epsilon = MIN(-mindelta, maxdelta)/2.0;
6792 
6793  b = val;
6794  a = EPSFLOOR(b, epsilon);
6795  g0 = a;
6796  h0 = 1.0;
6797  g1 = 1.0;
6798  h1 = 0.0;
6799  delta0 = val - g0/h0;
6800  delta1 = (delta0 < 0.0 ? val - (g0-1.0)/h0 : val - (g0+1.0)/h0);
6801 
6802  while( (delta0 < mindelta || delta0 > maxdelta) && (delta1 < mindelta || delta1 > maxdelta) )
6803  {
6804  assert(EPSGT(b, a, epsilon));
6805  assert(h0 >= 0.0);
6806  assert(h1 >= 0.0);
6807 
6808  b = 1.0 / (b - a);
6809  a = EPSFLOOR(b, epsilon);
6810 
6811  assert(a >= 0.0);
6812  gx = g0;
6813  hx = h0;
6814 
6815  g0 = a * g0 + g1;
6816  h0 = a * h0 + h1;
6817 
6818  g1 = gx;
6819  h1 = hx;
6820 
6821  if( h0 > maxdnom )
6822  return FALSE;
6823 
6824  delta0 = val - g0/h0;
6825  delta1 = (delta0 < 0.0 ? val - (g0-1.0)/h0 : val - (g0+1.0)/h0);
6826  }
6827 
6828  if( REALABS(g0) > (SCIP_LONGINT_MAX >> 4) || h0 > (SCIP_LONGINT_MAX >> 4) )
6829  return FALSE;
6830 
6831  assert(h0 > 0.5);
6832 
6833  if( delta0 < mindelta )
6834  {
6835  assert(mindelta <= delta1 && delta1 <= maxdelta);
6836  *nominator = (SCIP_Longint)(g0 - 1.0);
6837  *denominator = (SCIP_Longint)h0;
6838  }
6839  else if( delta0 > maxdelta )
6840  {
6841  assert(mindelta <= delta1 && delta1 <= maxdelta);
6842  *nominator = (SCIP_Longint)(g0 + 1.0);
6843  *denominator = (SCIP_Longint)h0;
6844  }
6845  else
6846  {
6847  *nominator = (SCIP_Longint)g0;
6848  *denominator = (SCIP_Longint)h0;
6849  }
6850  assert(*denominator >= 1);
6851  assert(val - (SCIP_Real)(*nominator)/(SCIP_Real)(*denominator) >= mindelta);
6852  assert(val - (SCIP_Real)(*nominator)/(SCIP_Real)(*denominator) <= maxdelta);
6853 
6854  return TRUE;
6855 }
6856 
6857 /** checks, whether the given scalar scales the given value to an integral number with error in the given bounds */
6858 static
6860  SCIP_Real val, /**< value that should be scaled to an integral value */
6861  SCIP_Real scalar, /**< scalar that should be tried */
6862  SCIP_Real mindelta, /**< minimal relative allowed difference of scaled coefficient s*c and integral i */
6863  SCIP_Real maxdelta /**< maximal relative allowed difference of scaled coefficient s*c and integral i */
6864  )
6865 {
6866  SCIP_Real sval;
6867  SCIP_Real downval;
6868  SCIP_Real upval;
6869 
6870  assert(mindelta <= 0.0);
6871  assert(maxdelta >= 0.0);
6872 
6873  sval = val * scalar;
6874  downval = floor(sval);
6875  upval = ceil(sval);
6876 
6877  return (SCIPrelDiff(sval, downval) <= maxdelta || SCIPrelDiff(sval, upval) >= mindelta);
6878 }
6879 
6880 /** additional scalars that are tried in integrality scaling */
6881 static const SCIP_Real scalars[] = {3.0, 5.0, 7.0, 9.0, 11.0, 13.0, 15.0, 17.0, 19.0};
6882 static const int nscalars = 9;
6883 
6884 /** tries to find a value, such that all given values, if scaled with this value become integral in relative allowed
6885  * difference in between mindelta and maxdelta
6886  */
6888  SCIP_Real* vals, /**< values to scale */
6889  int nvals, /**< number of values to scale */
6890  SCIP_Real mindelta, /**< minimal relative allowed difference of scaled coefficient s*c and integral i */
6891  SCIP_Real maxdelta, /**< maximal relative allowed difference of scaled coefficient s*c and integral i */
6892  SCIP_Longint maxdnom, /**< maximal denominator allowed in rational numbers */
6893  SCIP_Real maxscale, /**< maximal allowed scalar */
6894  SCIP_Real* intscalar, /**< pointer to store scalar that would make the coefficients integral, or NULL */
6895  SCIP_Bool* success /**< stores whether returned value is valid */
6896  )
6897 {
6898  SCIP_Real bestscalar;
6899  SCIP_Longint gcd;
6900  SCIP_Longint scm;
6901  SCIP_Longint nominator;
6902  SCIP_Longint denominator;
6903  SCIP_Real val;
6904  SCIP_Real minval;
6905  SCIP_Real absval;
6906  SCIP_Real scaleval;
6907  SCIP_Bool scalable;
6908  SCIP_Bool rational;
6909  int c;
6910  int s;
6911  int i;
6912 
6913  assert(vals != NULL);
6914  assert(nvals >= 0);
6915  assert(maxdnom >= 1);
6916  assert(mindelta < 0.0);
6917  assert(maxdelta > 0.0);
6918  assert(success != NULL);
6919 
6920  SCIPdebugMessage("trying to find rational representation for given values\n");
6921 
6922  if( intscalar != NULL )
6923  *intscalar = SCIP_INVALID;
6924  *success = FALSE;
6925 
6926  /* get minimal absolute non-zero value */
6927  minval = SCIP_REAL_MAX;
6928  for( c = 0; c < nvals; ++c )
6929  {
6930  val = vals[c];
6931  if( val < mindelta || val > maxdelta )
6932  {
6933  absval = REALABS(val);
6934  minval = MIN(minval, absval);
6935  }
6936  }
6937 
6938  if( minval == SCIP_REAL_MAX ) /*lint !e777*/
6939  {
6940  /* all coefficients are zero (inside tolerances) */
6941  if( intscalar != NULL )
6942  *intscalar = 1.0;
6943  *success = TRUE;
6944  SCIPdebugMessage(" -> all values are zero (inside tolerances)\n");
6945 
6946  return SCIP_OKAY;
6947  }
6948  assert(minval > MIN(-mindelta, maxdelta));
6949 
6950  bestscalar = SCIP_INVALID;
6951 
6952  for( i = 0; i < 2; ++i )
6953  {
6954  scalable = TRUE;
6955 
6956  /* try, if values can be made integral multiplying them with the reciprocal of the smallest value and a power of 2 */
6957  if( i == 0 )
6958  scaleval = 1.0/minval;
6959  /* try, if values can be made integral by multiplying them by a power of 2 */
6960  else
6961  scaleval = 1.0;
6962 
6963  for( c = 0; c < nvals && scalable; ++c )
6964  {
6965  /* check, if the value can be scaled with a simple scalar */
6966  val = vals[c];
6967  if( val == 0.0 ) /* zeros are allowed in the vals array */
6968  continue;
6969 
6970  absval = REALABS(val);
6971  while( scaleval <= maxscale
6972  && (absval * scaleval < 0.5 || !isIntegralScalar(val, scaleval, mindelta, maxdelta)) )
6973  {
6974  for( s = 0; s < nscalars; ++s )
6975  {
6976  if( isIntegralScalar(val, scaleval * scalars[s], mindelta, maxdelta) )
6977  {
6978  scaleval *= scalars[s];
6979  break;
6980  }
6981  }
6982  if( s >= nscalars )
6983  scaleval *= 2.0;
6984  }
6985  scalable = (scaleval <= maxscale);
6986  SCIPdebugMessage(" -> val=%g, scaleval=%g, val*scaleval=%g, scalable=%u\n",
6987  val, scaleval, val*scaleval, scalable);
6988  }
6989  if( scalable )
6990  {
6991  /* make values integral by dividing them by the smallest value (and multiplying them with a power of 2) */
6992  assert(scaleval <= maxscale);
6993 
6994  /* check if we found a better scaling value */
6995  if( scaleval < bestscalar )
6996  bestscalar = scaleval;
6997 
6998  SCIPdebugMessage(" -> integrality could be achieved by scaling with %g\n", scaleval);
6999 
7000  /* if the scalar is still the reciprocal of the minimal value, all coeffcients are the same and we do not get a better scalar */
7001  if( i == 0 && EPSEQ(scaleval, 1.0/minval, SCIP_DEFAULT_EPSILON) )
7002  {
7003  if( intscalar != NULL )
7004  *intscalar = bestscalar;
7005  *success = TRUE;
7006 
7007  return SCIP_OKAY;
7008  }
7009  }
7010  }
7011 
7012  /* convert each value into a rational number, calculate the greatest common divisor of the nominators
7013  * and the smallest common multiple of the denominators
7014  */
7015  gcd = 1;
7016  scm = 1;
7017  rational = TRUE;
7018 
7019  /* first value (to initialize gcd) */
7020  for( c = 0; c < nvals && rational; ++c )
7021  {
7022  val = vals[c];
7023  if( val == 0.0 ) /* zeros are allowed in the vals array */
7024  continue;
7025 
7026  rational = SCIPrealToRational(val, mindelta, maxdelta, maxdnom, &nominator, &denominator);
7027  if( rational && nominator != 0 )
7028  {
7029  assert(denominator > 0);
7030  gcd = ABS(nominator);
7031  scm = denominator;
7032  rational = ((SCIP_Real)scm/(SCIP_Real)gcd <= maxscale);
7033  SCIPdebugMessage(" -> c=%d first rational: val: %g == %"SCIP_LONGINT_FORMAT"/%"SCIP_LONGINT_FORMAT", gcd=%"SCIP_LONGINT_FORMAT", scm=%"SCIP_LONGINT_FORMAT", rational=%u\n",
7034  c, val, nominator, denominator, gcd, scm, rational);
7035  break;
7036  }
7037  }
7038 
7039  /* remaining values */
7040  for( ++c; c < nvals && rational; ++c )
7041  {
7042  val = vals[c];
7043  if( val == 0.0 ) /* zeros are allowed in the vals array */
7044  continue;
7045 
7046  rational = SCIPrealToRational(val, mindelta, maxdelta, maxdnom, &nominator, &denominator);
7047  if( rational && nominator != 0 )
7048  {
7049  assert(denominator > 0);
7050  gcd = SCIPcalcGreComDiv(gcd, ABS(nominator));
7051  scm *= denominator / SCIPcalcGreComDiv(scm, denominator);
7052  rational = ((SCIP_Real)scm/(SCIP_Real)gcd <= maxscale);
7053  SCIPdebugMessage(" -> c=%d next rational : val: %g == %"SCIP_LONGINT_FORMAT"/%"SCIP_LONGINT_FORMAT", gcd=%"SCIP_LONGINT_FORMAT", scm=%"SCIP_LONGINT_FORMAT", rational=%u\n",
7054  c, val, nominator, denominator, gcd, scm, rational);
7055  }
7056  else
7057  {
7058  SCIPdebugMessage(" -> failed to convert %g into a rational representation\n", val);
7059  }
7060  }
7061 
7062  if( rational )
7063  {
7064  /* make values integral by multiplying them with the smallest common multiple of the denominators */
7065  assert((SCIP_Real)scm/(SCIP_Real)gcd <= maxscale);
7066 
7067  /* check if we found a better scaling value */
7068  if( (SCIP_Real)scm/(SCIP_Real)gcd < bestscalar )
7069  bestscalar = (SCIP_Real)scm/(SCIP_Real)gcd;
7070 
7071  SCIPdebugMessage(" -> integrality could be achieved by scaling with %g (rational:%"SCIP_LONGINT_FORMAT"/%"SCIP_LONGINT_FORMAT")\n",
7072  (SCIP_Real)scm/(SCIP_Real)gcd, scm, gcd);
7073  }
7074 
7075  if( bestscalar < SCIP_INVALID )
7076  {
7077  if( intscalar != NULL )
7078  *intscalar = bestscalar;
7079  *success = TRUE;
7080 
7081  SCIPdebugMessage(" -> smallest value to achieve integrality is %g \n", bestscalar);
7082  }
7083 
7084  return SCIP_OKAY;
7085 }
7086 
7087 /** given a (usually very small) interval, tries to find a rational number with simple denominator (i.e. a small
7088  * number, probably multiplied with powers of 10) out of this interval; returns TRUE iff a valid rational
7089  * number inside the interval was found
7090  */
7092  SCIP_Real lb, /**< lower bound of the interval */
7093  SCIP_Real ub, /**< upper bound of the interval */
7094  SCIP_Longint maxdnom, /**< maximal denominator allowed for resulting rational number */
7095  SCIP_Longint* nominator, /**< pointer to store the nominator n of the rational number */
7096  SCIP_Longint* denominator /**< pointer to store the denominator d of the rational number */
7097  )
7098 {
7099  SCIP_Real center;
7100  SCIP_Real delta;
7101 
7102  assert(lb <= ub);
7103 
7104  center = 0.5*(lb+ub);
7105 
7106  /* in order to compute a rational number that is exactly within the bounds (as the user expects),
7107  * we computed the allowed delta with downward rounding, if available
7108  */
7110  {
7111  SCIP_ROUNDMODE roundmode;
7112 
7113  roundmode = SCIPintervalGetRoundingMode();
7115 
7116  delta = 0.5*(ub-lb);
7117 
7118  SCIPintervalSetRoundingMode(roundmode);
7119  }
7120  else
7121  {
7122  delta = 0.5*(ub-lb);
7123  }
7124 
7125  return SCIPrealToRational(center, -delta, +delta, maxdnom, nominator, denominator);
7126 }
7127 
7128 /** given a (usually very small) interval, selects a value inside this interval; it is tried to select a rational number
7129  * with simple denominator (i.e. a small number, probably multiplied with powers of 10);
7130  * if no valid rational number inside the interval was found, selects the central value of the interval
7131  */
7133  SCIP_Real lb, /**< lower bound of the interval */
7134  SCIP_Real ub, /**< upper bound of the interval */
7135  SCIP_Longint maxdnom /**< maximal denominator allowed for resulting rational number */
7136  )
7137 {
7138  SCIP_Real val;
7139 
7140  val = 0.5*(lb+ub);
7141  if( lb < ub )
7142  {
7143  SCIP_Longint nominator;
7144  SCIP_Longint denominator;
7145  SCIP_Bool success;
7146 
7147  /* try to find a "simple" rational number inside the interval */
7148  SCIPdebugMessage("simple rational in [%.9f,%.9f]:", lb, ub);
7149  success = SCIPfindSimpleRational(lb, ub, maxdnom, &nominator, &denominator);
7150  if( success )
7151  {
7152  val = (SCIP_Real)nominator/(SCIP_Real)denominator;
7153  SCIPdebugPrintf(" %"SCIP_LONGINT_FORMAT"/%"SCIP_LONGINT_FORMAT" == %.9f\n", nominator, denominator, val);
7154 
7155  if( val - lb < 0.0 || val - ub > 0.0 )
7156  {
7157  SCIPdebugPrintf(" value is out of interval bounds by %g -> failed\n", MAX(lb-val, val-ub));
7158  val = 0.5*(lb+ub);
7159  }
7160  }
7161  else
7162  {
7163  SCIPdebugPrintf(" failed\n");
7164  }
7165  }
7166 
7167  return val;
7168 }
7169 
7170 
7171 
7172 
7173 /*
7174  * Random Numbers
7175  */
7176 
7177 #ifdef NO_RAND_R
7178 
7179 #define SCIP_RAND_MAX 32767
7180 /** returns a random number between 0 and SCIP_RAND_MAX */
7181 static
7182 int getRand(
7183  unsigned int* seedp /**< pointer to seed value */
7184  )
7185 {
7186  SCIP_Longint nextseed;
7187 
7188  assert(seedp != NULL);
7189 
7190  nextseed = (*seedp) * 1103515245 + 12345;
7191  *seedp = (unsigned int)nextseed;
7192 
7193  return (int)((unsigned int)(nextseed/(2*(SCIP_RAND_MAX+1))) % (SCIP_RAND_MAX+1));
7194 }
7195 
7196 #else
7197 
7198 #define SCIP_RAND_MAX RAND_MAX
7199 
7200 /** returns a random number between 0 and SCIP_RAND_MAX */
7201 static
7203  unsigned int* seedp /**< pointer to seed value */
7204  )
7205 {
7206  return rand_r(seedp);
7207 }
7208 
7209 #endif
7210 
7211 /** returns a random integer between minrandval and maxrandval */
7213  int minrandval, /**< minimal value to return */
7214  int maxrandval, /**< maximal value to return */
7215  unsigned int* seedp /**< pointer to seed value */
7216  )
7217 {
7218  SCIP_Real randnumber;
7219 
7220  randnumber = (SCIP_Real)getRand(seedp)/(SCIP_RAND_MAX+1.0);
7221  assert(randnumber >= 0.0);
7222  assert(randnumber < 1.0);
7223 
7224  /* we multiply minrandval and maxrandval separately by randnumber in order to avoid overflow if they are more than INT_MAX
7225  * apart
7226  */
7227  return (int) (minrandval*(1.0 - randnumber) + maxrandval*randnumber + randnumber);
7228 }
7229 
7230 /** returns a random real between minrandval and maxrandval */
7232  SCIP_Real minrandval, /**< minimal value to return */
7233  SCIP_Real maxrandval, /**< maximal value to return */
7234  unsigned int* seedp /**< pointer to seed value */
7235  )
7236 {
7237  SCIP_Real randnumber;
7238 
7239  randnumber = (SCIP_Real)getRand(seedp)/(SCIP_Real)SCIP_RAND_MAX;
7240  assert(randnumber >= 0.0);
7241  assert(randnumber <= 1.0);
7242 
7243  /* we multiply minrandval and maxrandval separately by randnumber in order to avoid overflow if they are more than
7244  * SCIP_REAL_MAX apart
7245  */
7246  return minrandval*(1.0 - randnumber) + maxrandval*randnumber;
7247 }
7248 
7249 
7250 /*
7251  * Additional math functions
7252  */
7253 
7254 /** calculates a binomial coefficient n over m, choose m elements out of n, maximal value will be 33 over 16 (because
7255  * 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
7256  * big numbers or an negative value m (and m < n) and -1 will be returned
7257  */
7259  int n, /**< number of different elements */
7260  int m /**< number to choose out of the above */
7261  )
7262 {
7263  if( m == 0 || m >= n )
7264  return 1;
7265 
7266  if( m < 0 )
7267  return -1;
7268 
7269  /* symmetry of the binomial coefficient, choose smaller m */
7270  if( m > n/2 )
7271  m = n - m;
7272 
7273  /* trivial case m == 1 */
7274  if( m == 1 )
7275  return n;
7276 
7277  /* simple case m == 2 */
7278  if( m == 2 )
7279  {
7280  if( ((SCIP_Real)SCIP_LONGINT_MAX) / n >= (n-1) * 2 ) /*lint !e790*/
7281  return (n*(n-1)/2); /*lint !e647*/
7282  else
7283  return -1;
7284  }
7285 
7286  /* abort on to big numbers */
7287  if( m > 16 || n > 33 )
7288  return -1;
7289 
7290  /* simple case m == 3 */
7291  if( m == 3 )
7292  return (n*(n-1)*(n-2)/6); /*lint !e647*/
7293  else
7294  {
7295  /* first half of Pascal's triangle numbers(without the symmetric part) backwards from (33,16) over (32,16),
7296  * (33,15), (32,15),(31,15, (30,15), (33,14) to (8,4) (rest is calculated directly)
7297  *
7298  * due to this order we can extract the right binomial coefficient by (16-m)^2+(16-m)+(33-n)
7299  */
7300  static const SCIP_Longint binoms[182] = {
7301  1166803110, 601080390, 1037158320, 565722720, 300540195, 155117520, 818809200, 471435600, 265182525, 145422675,
7302  77558760, 40116600, 573166440, 347373600, 206253075, 119759850, 67863915, 37442160, 20058300, 10400600,
7303  354817320, 225792840, 141120525, 86493225, 51895935, 30421755, 17383860, 9657700, 5200300, 2704156, 193536720,
7304  129024480, 84672315, 54627300, 34597290, 21474180, 13037895, 7726160, 4457400, 2496144, 1352078, 705432,
7305  92561040, 64512240, 44352165, 30045015, 20030010, 13123110, 8436285, 5311735, 3268760, 1961256, 1144066,
7306  646646, 352716, 184756, 38567100, 28048800, 20160075, 14307150, 10015005, 6906900, 4686825, 3124550, 2042975,
7307  1307504, 817190, 497420, 293930, 167960, 92378, 48620, 13884156, 10518300, 7888725, 5852925, 4292145, 3108105,
7308  2220075, 1562275, 1081575, 735471, 490314, 319770, 203490, 125970, 75582, 43758, 24310, 12870, 4272048, 3365856,
7309  2629575, 2035800, 1560780, 1184040, 888030, 657800, 480700, 346104, 245157, 170544, 116280, 77520, 50388, 31824,
7310  19448, 11440, 6435, 3432, 1107568, 906192, 736281, 593775, 475020, 376740, 296010, 230230, 177100, 134596,
7311  100947, 74613, 54264, 38760, 27132, 18564, 12376, 8008, 5005, 3003, 1716, 924, 237336, 201376, 169911, 142506,
7312  118755, 98280, 80730, 65780, 53130, 42504, 33649, 26334, 20349, 15504, 11628, 8568, 6188, 4368, 3003, 2002,
7313  1287, 792, 462, 252, 40920, 35960, 31465, 27405, 23751, 20475, 17550, 14950, 12650, 10626, 8855, 7315, 5985,
7314  4845, 3876, 3060, 2380, 1820, 1365, 1001, 715, 495, 330, 210, 126, 70};
7315 
7316  /* m can at most be 16 */
7317  const int t = 16-m;
7318  assert(t >= 0);
7319  assert(n <= 33);
7320 
7321  /* binoms array hast exactly 182 elements */
7322  assert(t*(t+1)+(33-n) < 182);
7323 
7324  return binoms[t*(t+1)+(33-n)]; /*lint !e662 !e661*/
7325  }
7326 }
7327 
7328 /** negates a number */
7330  SCIP_Real x /**< value to negate */
7331  )
7332 {
7333  return -x;
7334 }
7335 
7336 /*
7337  * Permutations / Shuffling
7338  */
7339 
7340 /** swaps two ints */
7342  int* value1, /**< pointer to first integer */
7343  int* value2 /**< pointer ti second integer */
7344  )
7345 {
7346  int tmp;
7347 
7348  tmp = *value1;
7349  *value1 = *value2;
7350  *value2 = tmp;
7351 }
7352 
7353 /** swaps the addresses of two pointers */
7355  void** pointer1, /**< first pointer */
7356  void** pointer2 /**< second pointer */
7357  )
7358 {
7359  void* tmp;
7360 
7361  tmp = *pointer1;
7362  *pointer1 = *pointer2;
7363  *pointer2 = tmp;
7364 }
7365 
7366 /** randomly shuffles parts of an integer array using the Fisher-Yates algorithm */
7368  int* array, /**< array to be shuffled */
7369  int begin, /**< first index that should be subject to shuffling (0 for whole array) */
7370  int end, /**< last index that should be subject to shuffling (array size for whole
7371  * array)
7372  */
7373  unsigned int* randseed /**< seed value for the random generator */
7374  )
7375 {
7376  int tmp;
7377  int i;
7378 
7379  /* loop backwards through all elements and always swap the current last element to a random position */
7380  while( end > begin+1 )
7381  {
7382  --end;
7383 
7384  /* get a random position into which the last entry should be shuffled */
7385  i = SCIPgetRandomInt(begin, end, randseed);
7386 
7387  /* swap the last element and the random element */
7388  tmp = array[i];
7389  array[i] = array[end];
7390  array[end] = tmp;
7391  }
7392 }
7393 
7394 
7395 /** randomly shuffles parts of an array using the Fisher-Yates algorithm */
7397  void** array, /**< array to be shuffled */
7398  int begin, /**< first index that should be subject to shuffling (0 for whole array) */
7399  int end, /**< last index that should be subject to shuffling (array size for whole
7400  * array)
7401  */
7402  unsigned int* randseed /**< seed value for the random generator */
7403  )
7404 {
7405  void* tmp;
7406  int i;
7407 
7408  /* loop backwards through all elements and always swap the current last element to a random position */
7409  while( end > begin+1 )
7410  {
7411  end--;
7412 
7413  /* get a random position into which the last entry should be shuffled */
7414  i = SCIPgetRandomInt(begin, end, randseed);
7415 
7416  /* swap the last element and the random element */
7417  tmp = array[i];
7418  array[i] = array[end];
7419  array[end] = tmp;
7420  }
7421 }
7422 
7423 /** draws a random subset of disjoint elements from a given set of disjoint elements;
7424  * this implementation is suited for the case that nsubelems is considerably smaller then nelems
7425  */
7427  void** set, /**< original set, from which elements should be drawn */
7428  int nelems, /**< number of elements in original set */
7429  void** subset, /**< subset in which drawn elements should be stored */
7430  int nsubelems, /**< number of elements that should be drawn and stored */
7431  unsigned int randseed /**< seed value for random generator */
7432  )
7433 {
7434  int i;
7435  int j;
7436 
7437  /* if both sets are of equal size, we just copy the array */
7438  if( nelems == nsubelems)
7439  {
7440  BMScopyMemoryArray(subset,set,nelems);
7441  return SCIP_OKAY;
7442  }
7443 
7444  /* abort, if size of subset is too big */
7445  if( nsubelems > nelems )
7446  {
7447  SCIPerrorMessage("Cannot create %d-elementary subset of %d-elementary set.\n", nsubelems, nelems);
7448  return SCIP_INVALIDDATA;
7449  }
7450 #ifndef NDEBUG
7451  for( i = 0; i < nsubelems; i++ )
7452  for( j = 0; j < i; j++ )
7453  assert(set[i] != set[j]);
7454 #endif
7455 
7456  /* draw each element individually */
7457  i = 0;
7458  while( i < nsubelems )
7459  {
7460  int r;
7461 
7462  r = SCIPgetRandomInt(0, nelems-1, &randseed);
7463  subset[i] = set[r];
7464 
7465  /* if we get an element that we already had, we will draw again */
7466  for( j = 0; j < i; j++ )
7467  {
7468  if( subset[i] == subset[j] )
7469  {
7470  --i;
7471  break;
7472  }
7473  }
7474  ++i;
7475  }
7476  return SCIP_OKAY;
7477 }
7478 
7479 
7480 
7481 /*
7482  * Strings
7483  */
7484 
7485 
7486 /** copies characters from 'src' to 'dest', copying is stopped when either the 'stop' character is reached or after
7487  * 'cnt' characters have been copied, whichever comes first.
7488  *
7489  * @note undefined behaviuor on overlapping arrays
7490  */
7492  char* dest, /**< destination pointer to copy to */
7493  const char* src, /**< source pointer to copy to */
7494  char stop, /**< character when found stop copying */
7495  unsigned int cnt /**< maximal number of characters to copy too */
7496  )
7497 {
7498  if( dest == NULL || src == NULL || cnt == 0 )
7499  return -1;
7500  else
7501  {
7502  char* destination = dest;
7503 
7504  while( cnt-- && (*destination++ = *src++) != stop ); /*lint !e722*/
7505 
7506  return (destination - dest);
7507  }
7508 }
7509 
7510 /** prints an error message containing of the given string followed by a string describing the current system error;
7511  * prefers to use the strerror_r method, which is threadsafe; on systems where this method does not exist,
7512  * NO_STRERROR_R should be defined (see INSTALL), in this case, strerror is used which is not guaranteed to be
7513  * threadsafe (on SUN-systems, it actually is)
7514  */
7516  const char* message /**< first part of the error message, e.g. the filename */
7517  )
7518 {
7519 #ifdef NO_STRERROR_R
7520  char* buf;
7521  buf = strerror(errno);
7522 #else
7523  char buf[SCIP_MAXSTRLEN];
7524 
7525 #if defined(_WIN32) || defined(_WIN64)
7526  (void) strerror_s(buf, SCIP_MAXSTRLEN, errno);
7527 #else
7528  (void) strerror_r(errno, buf, SCIP_MAXSTRLEN);
7529 #endif
7530 
7531  buf[SCIP_MAXSTRLEN - 1] = '\0';
7532 #endif
7533  SCIPmessagePrintError("%s: %s\n", message, buf);
7534 }
7535 
7536 /** extracts tokens from strings - wrapper method for strtok_r() */
7538  char* s, /**< string to parse */
7539  const char* delim, /**< delimiters for parsing */
7540  char** ptrptr /**< pointer to working char pointer - must stay the same while parsing */
7541  )
7542 {
7543 #ifdef NO_STRTOK_R
7544  return strtok(s, delim);
7545 #else
7546  return strtok_r(s, delim, ptrptr);
7547 #endif
7548 }
7549 
7550 /** translates the given string into a string where symbols ", ', and spaces are escaped with a \ prefix */
7552  char* t, /**< target buffer to store escaped string */
7553  int bufsize, /**< size of buffer t */
7554  const char* s /**< string to transform into escaped string */
7555  )
7556 {
7557  int len;
7558  int i;
7559  int p;
7560 
7561  assert(t != NULL);
7562  assert(bufsize > 0);
7563 
7564  len = (int)strlen(s);
7565  for( p = 0, i = 0; i <= len && p < bufsize; ++i, ++p )
7566  {
7567  if( s[i] == ' ' || s[i] == '"' || s[i] == '\'' )
7568  {
7569  t[p] = '\\';
7570  p++;
7571  }
7572  if( p < bufsize )
7573  t[p] = s[i];
7574  }
7575  t[bufsize-1] = '\0';
7576 }
7577 
7578 /* safe version of snprintf */
7580  char* t, /**< target string */
7581  int len, /**< length of the string to copy */
7582  const char* s, /**< source string */
7583  ... /**< further parameters */
7584  )
7585 {
7586  va_list ap;
7587  int n;
7588 
7589  assert(t != NULL);
7590  assert(len > 0);
7591 
7592  va_start(ap, s); /*lint !e826*/
7593 
7594 #if defined(_WIN32) || defined(_WIN64)
7595  n = _vsnprintf(t, (size_t) len, s, ap);
7596 #else
7597  n = vsnprintf(t, (size_t) len, s, ap); /*lint !e571*/
7598 #endif
7599  va_end(ap);
7600 
7601  if( n < 0 || n >= len )
7602  {
7603 #ifndef NDEBUG
7604  if( n < 0 )
7605  {
7606  SCIPerrorMessage("vsnprintf returned %d\n",n);
7607  }
7608 #endif
7609  t[len-1] = '\0';
7610  n = len-1;
7611  }
7612  return n;
7613 }
7614 
7615 /** 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
7616  *
7617  * @return Returns TRUE if a value could be extracted, otherwise FALSE
7618  */
7620  const char* str, /**< string to search */
7621  int* value, /**< pointer to store the parsed value */
7622  char** endptr /**< pointer to store the final string position if successfully parsed, otherwise @p str */
7623  )
7624 {
7625  assert(str != NULL);
7626  assert(value != NULL);
7627  assert(endptr != NULL);
7628 
7629  /* init errno to detect possible errors */
7630  errno = 0;
7631 
7632  *value = (int) strtol(str, endptr, 10);
7633 
7634  if( *endptr != str && *endptr != NULL )
7635  {
7636  SCIPdebugMessage("parsed integer value <%d>\n", *value);
7637  return TRUE;
7638  }
7639  *endptr = (char*)str;
7640 
7641  SCIPdebugMessage("failed parsing integer value <%s>\n", str);
7642 
7643  return FALSE;
7644 }
7645 
7646 /** 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
7647  *
7648  * @return Returns TRUE if a value could be extracted, otherwise FALSE
7649  */
7651  const char* str, /**< string to search */
7652  SCIP_Real* value, /**< pointer to store the parsed value */
7653  char** endptr /**< pointer to store the final string position if successfully parsed, otherwise @p str */
7654  )
7655 {
7656  assert(str != NULL);
7657  assert(value != NULL);
7658  assert(endptr != NULL);
7659 
7660  /* init errno to detect possible errors */
7661  errno = 0;
7662 
7663  *value = strtod(str, endptr);
7664 
7665  if( *endptr != str && *endptr != NULL )
7666  {
7667  SCIPdebugMessage("parsed real value <%g>\n", *value);
7668  return TRUE;
7669  }
7670  *endptr = (char*)str;
7671 
7672  SCIPdebugMessage("failed parsing real value <%s>\n", str);
7673 
7674  return FALSE;
7675 }
7676 
7677 /** copies the first size characters between a start and end character of str into token, if no error occured endptr
7678  * will point to the position after the read part, otherwise it will point to @p str
7679  */
7681  const char* str, /**< string to search */
7682  char startchar, /**< character which defines the beginning */
7683  char endchar, /**< character which defines the ending */
7684  char* token, /**< string to store the copy */
7685  int size, /**< size of the token char array */
7686  char** endptr /**< pointer to store the final string position if successfully parsed, otherwise @p str */
7687  )
7688 {
7689  const char* copystr;
7690  int nchars;
7691 
7692  assert(str != NULL);
7693  assert(token != NULL);
7694  assert(size > 0);
7695  assert(endptr != NULL);
7696 
7697  nchars = 0;
7698 
7699  copystr = str;
7700 
7701  /* find starting character */
7702  while( *str != '\0' && *str != startchar )
7703  ++str;
7704 
7705  /* did not find start character */
7706  if( *str == '\0' )
7707  {
7708  *endptr = (char*)copystr;
7709  return;
7710  }
7711 
7712  /* skip start character */
7713  ++str;
7714 
7715  /* copy string */
7716  while( *str != '\0' && *str != endchar && nchars < size-1 )
7717  {
7718  assert(nchars < SCIP_MAXSTRLEN);
7719  token[nchars] = *str;
7720  nchars++;
7721  ++str;
7722  }
7723 
7724  /* add end to token */
7725  token[nchars] = '\0';
7726 
7727  /* if section was longer than size, we want to reach the end of the parsing section anyway */
7728  if( nchars == (size-1) )
7729  while( *str != '\0' && *str != endchar )
7730  ++str;
7731 
7732  /* did not find end character */
7733  if( *str == '\0' )
7734  {
7735  *endptr = (char*)copystr;
7736  return;
7737  }
7738 
7739  /* skip end character */
7740  ++str;
7741 
7742  SCIPdebugMessage("parsed section <%s>\n", token);
7743 
7744  *endptr = (char*) str;
7745 }
7746 
7747 /*
7748  * File methods
7749  */
7750 
7751 /** returns, whether the given file exists */
7753  const char* filename /**< file name */
7754  )
7755 {
7756  FILE* f;
7757 
7758  f = fopen(filename, "r");
7759  if( f == NULL )
7760  return FALSE;
7761 
7762  fclose(f);
7763 
7764  return TRUE;
7765 }
7766 
7767 /** splits filename into path, name, and extension */
7769  char* filename, /**< filename to split; is destroyed (but not freed) during process */
7770  char** path, /**< pointer to store path, or NULL if not needed */
7771  char** name, /**< pointer to store name, or NULL if not needed */
7772  char** extension, /**< pointer to store extension, or NULL if not needed */
7773  char** compression /**< pointer to store compression extension, or NULL if not needed */
7774  )
7775 {
7776  char* lastslash;
7777  char* lastbackslash;
7778  char* lastdot;
7779 
7780  assert(filename != NULL);
7781 
7782  if( path != NULL )
7783  *path = NULL;
7784  if( name != NULL )
7785  *name = NULL;
7786  if( extension != NULL )
7787  *extension = NULL;
7788  if( compression != NULL )
7789  *compression = NULL;
7790 
7791  /* treat both slashes '/' and '\' as directory delimiters */
7792  lastslash = strrchr(filename, '/');
7793  lastbackslash = strrchr(filename, '\\');
7794  lastslash = MAX(lastslash, lastbackslash); /*lint !e613*/
7795  lastdot = strrchr(filename, '.');
7796  if( lastslash != NULL && lastdot != NULL && lastdot < lastslash ) /* is the last dot belonging to the path? */
7797  lastdot = NULL;
7798 
7799  /* detect known compression extensions */
7800 #ifdef WITH_ZLIB
7801  if( lastdot != NULL )
7802  {
7803  char* compext;
7804 
7805  compext = lastdot+1;
7806  if( strcmp(compext, "gz") == 0
7807  || strcmp(compext, "z") == 0
7808  || strcmp(compext, "Z") == 0 )
7809  {
7810  if( compression != NULL )
7811  *compression = compext;
7812  *lastdot = '\0';
7813  }
7814 
7815  /* find again the last dot in the filename without compression extension */
7816  lastdot = strrchr(filename, '.');
7817  if( lastslash != NULL && lastdot != NULL && lastdot < lastslash ) /* is the last dot belonging to the path? */
7818  lastdot = NULL;
7819  }
7820 #endif
7821 
7822  if( lastslash == NULL )
7823  {
7824  if( name != NULL )
7825  *name = filename;
7826  }
7827  else
7828  {
7829  if( path != NULL )
7830  *path = filename;
7831  if( name != NULL )
7832  *name = lastslash+1;
7833  *lastslash = '\0';
7834  }
7835 
7836  if( lastdot != NULL )
7837  {
7838  if( extension != NULL )
7839  *extension = lastdot+1;
7840  *lastdot = '\0';
7841  }
7842 }
7843 
7844 
7845 
7846 
7847 /*
7848  * simple functions implemented as defines
7849  */
7850 
7851 /* In debug mode, the following methods are implemented as function calls to ensure
7852  * type validity.
7853  * In optimized mode, the methods are implemented as defines to improve performance.
7854  * However, we want to have them in the library anyways, so we have to undef the defines.
7855  */
7856 
7857 #undef SCIPrelDiff
7858 
7859 /** returns the relative difference: (val1-val2)/max(|val1|,|val2|,1.0) */
7861  SCIP_Real val1, /**< first value to be compared */
7862  SCIP_Real val2 /**< second value to be compared */
7863  )
7864 {
7865  SCIP_Real absval1;
7866  SCIP_Real absval2;
7867  SCIP_Real quot;
7868 
7869  absval1 = REALABS(val1);
7870  absval2 = REALABS(val2);
7871  quot = MAX3(1.0, absval1, absval2);
7872 
7873  return (val1-val2)/quot;
7874 }
void SCIPpermuteArray(void **array, int begin, int end, unsigned int *randseed)
Definition: misc.c:7396
SCIP_BTNODE * parent
Definition: struct_misc.h:188
SCIP_RETCODE SCIPbtnodeCreate(SCIP_BT *tree, SCIP_BTNODE **node, void *dataptr)
Definition: misc.c:6151
static void * hashtablelistRetrieve(SCIP_HASHTABLELIST *hashtablelist, SCIP_DECL_HASHGETKEY((*hashgetkey)), SCIP_DECL_HASHKEYEQ((*hashkeyeq)), SCIP_DECL_HASHKEYVAL((*hashkeyval)), void *userptr, unsigned int keyval, void *key)
Definition: misc.c:1055
int SCIPrealarrayGetMaxIdx(SCIP_REALARRAY *realarray)
Definition: misc.c:2528
int SCIPpqueueNElems(SCIP_PQUEUE *pqueue)
Definition: misc.c:880
void SCIPbtnodeFree(SCIP_BT *tree, SCIP_BTNODE **node)
Definition: misc.c:6215
SCIP_Real * vals
Definition: struct_misc.h:112
BMS_BLKMEM * blkmem
Definition: struct_misc.h:85
#define BMSfreeBlockMemoryArrayNull(mem, ptr, num)
Definition: memory.h:424
int SCIPmemccpy(char *dest, const char *src, char stop, unsigned int cnt)
Definition: misc.c:7491
void *** arcdata
Definition: struct_misc.h:174
#define BMSfreeMemoryArrayNull(ptr)
Definition: memory.h:122
SCIP_HASHMAPLIST ** lists
Definition: struct_misc.h:104
static void * hashmaplistGetImage(SCIP_HASHMAPLIST *hashmaplist, void *origin)
Definition: misc.c:1780
static const int nscalars
Definition: misc.c:6882
void SCIPsparseSolGetFirstSol(SCIP_SPARSESOL *sparsesol, SCIP_Longint *sol, int nvars)
Definition: misc.c:425
void * SCIPhashmapListGetOrigin(SCIP_HASHMAPLIST *hashmaplist)
Definition: misc.c:2114
SCIP_BTNODE * SCIPbtnodeGetSibling(SCIP_BTNODE *node)
Definition: misc.c:6300
SCIP_RETCODE SCIPprofileDeleteCore(SCIP_PROFILE *profile, int left, int right, int demand)
Definition: misc.c:4998
void * SCIPbtnodeGetData(SCIP_BTNODE *node)
Definition: misc.c:6260
void SCIPsortInd(int *indarray, SCIP_DECL_SORTINDCOMP((*indcomp)), void *dataptr, int len)
SCIP_RETCODE SCIPhashtableInsert(SCIP_HASHTABLE *hashtable, void *element)
Definition: misc.c:1374
BMS_BLKMEM * blkmem
Definition: struct_misc.h:198
void SCIPdigraphFreeComponents(SCIP_DIGRAPH *digraph)
Definition: misc.c:5997
static SCIP_RETCODE hashmaplistAppend(SCIP_HASHMAPLIST **hashmaplist, BMS_BLKMEM *blkmem, void *origin, void *image)
Definition: misc.c:1701
SCIP_RETCODE SCIPintarrayIncVal(SCIP_INTARRAY *intarray, int arraygrowinit, SCIP_Real arraygrowfac, int idx, int incval)
Definition: misc.c:2870
#define SCIP_MAXSTRLEN
Definition: def.h:196
void ** nodedata
Definition: struct_misc.h:175
void SCIPgmlWriteArc(FILE *file, unsigned int source, unsigned int target, const char *label, const char *color)
Definition: misc.c:244
SCIP_Longint nelements
Definition: struct_misc.h:89
SCIP_RETCODE SCIPdigraphComputeUndirectedComponents(SCIP_DIGRAPH *digraph, int minsize, int *components, int *ncomponents)
Definition: misc.c:5788
#define NULL
Definition: lpi_spx.cpp:129
int SCIPintarrayGetMinIdx(SCIP_INTARRAY *intarray)
Definition: misc.c:2882
SCIP_RETCODE SCIPrealarrayCreate(SCIP_REALARRAY **realarray, BMS_BLKMEM *blkmem)
Definition: misc.c:2166
static SCIP_RETCODE btnodeCreateEmpty(SCIP_BT *tree, SCIP_BTNODE **node)
Definition: misc.c:6135
SCIP_RETCODE SCIPintarrayCopy(SCIP_INTARRAY **intarray, BMS_BLKMEM *blkmem, SCIP_INTARRAY *sourceintarray)
Definition: misc.c:2558
SCIP_Bool SCIPboolarrayGetVal(SCIP_BOOLARRAY *boolarray, int idx)
Definition: misc.c:3149
int * SCIPdigraphGetSuccessors(SCIP_DIGRAPH *digraph, int node)
Definition: misc.c:5679
static SCIP_RETCODE ensureSuccessorsSize(SCIP_DIGRAPH *digraph, int idx, int newsize)
Definition: misc.c:5509
int firstfree
Definition: struct_misc.h:49
SCIP_RETCODE SCIPqueueInsert(SCIP_QUEUE *queue, void *elem)
Definition: misc.c:595
static void hashmaplistFree(SCIP_HASHMAPLIST **hashmaplist, BMS_BLKMEM *blkmem)
Definition: misc.c:1731
void SCIPgmlWriteNode(FILE *file, unsigned int id, const char *label, const char *nodetype, const char *fillcolor, const char *bordercolor)
Definition: misc.c:102
void SCIPsplitFilename(char *filename, char **path, char **name, char **extension, char **compression)
Definition: misc.c:7768
SCIP_Bool SCIPsparseSolGetNextSol(SCIP_SPARSESOL *sparsesol, SCIP_Longint *sol, int nvars)
Definition: misc.c:448
int SCIPprofileGetTime(SCIP_PROFILE *profile, int pos)
Definition: misc.c:4795
int SCIPintarrayGetVal(SCIP_INTARRAY *intarray, int idx)
Definition: misc.c:2781
void * SCIPhashmapListGetImage(SCIP_HASHMAPLIST *hashmaplist)
Definition: misc.c:2124
int * componentstarts
Definition: struct_misc.h:179
void SCIPgmlWriteClosing(FILE *file)
Definition: misc.c:304
static int calcGrowSize(int initsize, SCIP_Real growfac, int num)
Definition: misc.c:46
void SCIPswapPointers(void **pointer1, void **pointer2)
Definition: misc.c:7354
void SCIPbtnodeSetRightchild(SCIP_BTNODE *node, SCIP_BTNODE *right)
Definition: misc.c:6421
SCIP_Longint SCIPcalcBinomCoef(int n, int m)
Definition: misc.c:7258
void SCIPintervalSetRoundingMode(SCIP_ROUNDMODE roundmode)
#define SCIP_HASHTABLE_MAXSIZE
Definition: misc.c:1165
#define SCIP_RAND_MAX
Definition: misc.c:7198
void * SCIPptrarrayGetVal(SCIP_PTRARRAY *ptrarray, int idx)
Definition: misc.c:3502
#define FALSE
Definition: def.h:52
#define GMLNODEWIDTH
Definition: misc.c:92
SCIP_RETCODE SCIPhashmapCreate(SCIP_HASHMAP **hashmap, BMS_BLKMEM *blkmem, int mapsize)
Definition: misc.c:1864
#define EPSEQ(x, y, eps)
Definition: def.h:147
int SCIPboolarrayGetMaxIdx(SCIP_BOOLARRAY *boolarray)
Definition: misc.c:3248
SCIP_Real SCIPrelDiff(SCIP_Real val1, SCIP_Real val2)
Definition: misc.c:7860
int SCIPprofileGetEarliestFeasibleStart(SCIP_PROFILE *profile, int est, int lst, int duration, int demand, SCIP_Bool *infeasible)
Definition: misc.c:5088
SCIP_HASHMAPLIST * SCIPhashmapGetList(SCIP_HASHMAP *hashmap, int listindex)
Definition: misc.c:2088
miscellaneous datastructures
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition: misc.c:7579
#define TRUE
Definition: def.h:51
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:53
SCIP_RETCODE SCIPdigraphSetSizes(SCIP_DIGRAPH *digraph, int *sizes)
Definition: misc.c:5450
void SCIPdigraphPrintComponents(SCIP_DIGRAPH *digraph, SCIP_MESSAGEHDLR *messagehdlr, FILE *file)
Definition: misc.c:6098
SCIP_VAR * SCIPactivityGetVar(SCIP_RESOURCEACTIVITY *activity)
Definition: misc.c:4649
SCIP_RETCODE SCIPptrarrayExtend(SCIP_PTRARRAY *ptrarray, int arraygrowinit, SCIP_Real arraygrowfac, int minidx, int maxidx)
Definition: misc.c:3316
void * SCIPpqueueFirst(SCIP_PQUEUE *pqueue)
Definition: misc.c:866
SCIP_RETCODE SCIPboolarrayCopy(SCIP_BOOLARRAY **boolarray, BMS_BLKMEM *blkmem, SCIP_BOOLARRAY *sourceboolarray)
Definition: misc.c:2923
void SCIPhashtableClear(SCIP_HASHTABLE *hashtable)
Definition: misc.c:1349
#define BMSallocMemoryArray(ptr, num)
Definition: memory.h:76
int SCIPdigraphGetNComponents(SCIP_DIGRAPH *digraph)
Definition: misc.c:5964
SCIP_Bool SCIPstrToIntValue(const char *str, int *value, char **endptr)
Definition: misc.c:7619
void SCIPpqueueFree(SCIP_PQUEUE **pqueue)
Definition: misc.c:777
SCIP_RETCODE SCIPprofileInsertCore(SCIP_PROFILE *profile, int left, int right, int demand, int *pos, SCIP_Bool *infeasible)
Definition: misc.c:4968
#define SCIPdebugMessage
Definition: pub_message.h:77
SCIP_Real SCIPselectSimpleValue(SCIP_Real lb, SCIP_Real ub, SCIP_Longint maxdnom)
Definition: misc.c:7132
void SCIPdigraphGetComponent(SCIP_DIGRAPH *digraph, int compidx, int **nodes, int *nnodes)
Definition: misc.c:5977
SCIP_VAR ** vars
Definition: struct_misc.h:38
static SCIP_RETCODE hashtablelistAppend(SCIP_HASHTABLELIST **hashtablelist, BMS_BLKMEM *blkmem, void *element)
Definition: misc.c:978
SCIP_Bool SCIPhashmapIsEmpty(SCIP_HASHMAP *hashmap)
Definition: misc.c:2048
void * SCIPhashmapGetImage(SCIP_HASHMAP *hashmap, void *origin)
Definition: misc.c:1923
#define SCIP_LONGINT_MAX
Definition: def.h:108
int SCIPptrarrayGetMinIdx(SCIP_PTRARRAY *ptrarray)
Definition: misc.c:3591
SCIP_Bool SCIPqueueIsEmpty(SCIP_QUEUE *queue)
Definition: misc.c:691
#define BMSfreeMemory(ptr)
Definition: memory.h:117
SCIP_Real SCIPnegateReal(SCIP_Real x)
Definition: misc.c:7329
void SCIPsortDown(int *perm, SCIP_DECL_SORTINDCOMP((*indcomp)), void *dataptr, int len)
Definition: misc.c:4095
template functions for sorting
#define SCIP_HASHTABLE_GROW_FACTOR
Definition: misc.c:1167
int SCIPprofileGetLoad(SCIP_PROFILE *profile, int pos)
Definition: misc.c:4807
void * dataptr
Definition: struct_misc.h:191
SCIP_RETCODE SCIPdigraphTopoSortComponents(SCIP_DIGRAPH *digraph)
Definition: misc.c:5900
int SCIPrealarrayGetMinIdx(SCIP_REALARRAY *realarray)
Definition: misc.c:2518
SCIP_Bool SCIPbtnodeIsRoot(SCIP_BTNODE *node)
Definition: misc.c:6320
SCIP_RETCODE SCIPhashtableCreate(SCIP_HASHTABLE **hashtable, BMS_BLKMEM *blkmem, int tablesize, SCIP_DECL_HASHGETKEY((*hashgetkey)), SCIP_DECL_HASHKEYEQ((*hashkeyeq)), SCIP_DECL_HASHKEYVAL((*hashkeyval)), void *userptr)
Definition: misc.c:1287
static SCIP_RETCODE hashtableResize(SCIP_HASHTABLE *hashtable)
Definition: misc.c:1171
SCIP_RETCODE SCIPboolarraySetVal(SCIP_BOOLARRAY *boolarray, int arraygrowinit, SCIP_Real arraygrowfac, int idx, SCIP_Bool val)
Definition: misc.c:3170
static SCIP_HASHMAPLIST * hashmaplistFind(SCIP_HASHMAPLIST *hashmaplist, void *origin)
Definition: misc.c:1763
#define SCIP_DEFAULT_EPSILON
Definition: def.h:129
BMS_BLKMEM * blkmem
Definition: struct_misc.h:103
SCIP_Bool SCIPhashmapExists(SCIP_HASHMAP *hashmap, void *origin)
Definition: misc.c:1966
void * userptr
Definition: struct_misc.h:88
SCIP_BTNODE * root
Definition: struct_misc.h:197
SCIP_Bool SCIPfileExists(const char *filename)
Definition: misc.c:7752
void SCIPqueueClear(SCIP_QUEUE *queue)
Definition: misc.c:584
int SCIPdigraphGetNNodes(SCIP_DIGRAPH *digraph)
Definition: misc.c:5606
int SCIPprofileGetCapacity(SCIP_PROFILE *profile)
Definition: misc.c:4755
SCIP_RETCODE SCIPintarrayFree(SCIP_INTARRAY **intarray)
Definition: misc.c:2581
int ** successors
Definition: struct_misc.h:173
SCIP_Bool SCIPrealToRational(SCIP_Real val, SCIP_Real mindelta, SCIP_Real maxdelta, SCIP_Longint maxdnom, SCIP_Longint *nominator, SCIP_Longint *denominator)
Definition: misc.c:6727
SCIP_RETCODE SCIPdigraphCreate(SCIP_DIGRAPH **digraph, int nnodes)
Definition: misc.c:5326
void SCIPsortedvecInsertIntInt(int *intarray1, int *intarray2, int keyval, int field1val, int *len, int *pos)
SCIP_RETCODE SCIPrealarrayIncVal(SCIP_REALARRAY *realarray, int arraygrowinit, SCIP_Real arraygrowfac, int idx, SCIP_Real incval)
Definition: misc.c:2500
void ** slots
Definition: struct_misc.h:67
SCIP_RETCODE SCIPactivityCreate(SCIP_RESOURCEACTIVITY **activity, SCIP_VAR *var, int duration, int demand)
Definition: misc.c:4604
int SCIPhashmapListGetNEntries(SCIP_HASHMAPLIST *hashmaplist)
Definition: misc.c:2101
void SCIPsortDownInd(int *indarray, SCIP_DECL_SORTINDCOMP((*indcomp)), void *dataptr, int len)
void * SCIPhashtableRetrieveNext(SCIP_HASHTABLE *hashtable, SCIP_HASHTABLELIST **hashtablelist, void *key)
Definition: misc.c:1463
int SCIPhashmapGetNLists(SCIP_HASHMAP *hashmap)
Definition: misc.c:2078
static SCIP_Bool hashtablelistRemove(SCIP_HASHTABLELIST **hashtablelist, BMS_BLKMEM *blkmem, void *element)
Definition: misc.c:1138
static void * hashtablelistRetrieveNext(SCIP_HASHTABLELIST **hashtablelist, SCIP_DECL_HASHGETKEY((*hashgetkey)), SCIP_DECL_HASHKEYEQ((*hashkeyeq)), SCIP_DECL_HASHKEYVAL((*hashkeyval)), void *userptr, unsigned int keyval, void *key)
Definition: misc.c:1105
BMS_BLKMEM * blkmem
Definition: struct_misc.h:111
BMS_BLKMEM * blkmem
Definition: struct_misc.h:122
#define BMSduplicateBlockMemoryArray(mem, ptr, source, num)
Definition: memory.h:414
SCIP_RETCODE SCIPrealarrayCopy(SCIP_REALARRAY **realarray, BMS_BLKMEM *blkmem, SCIP_REALARRAY *sourcerealarray)
Definition: misc.c:2186
SCIP_Longint * SCIPsparseSolGetLbs(SCIP_SPARSESOL *sparsesol)
Definition: misc.c:405
int SCIPqueueNElems(SCIP_QUEUE *queue)
Definition: misc.c:704
SCIP_BTNODE * left
Definition: struct_misc.h:189
#define BMSfreeMemoryArray(ptr)
Definition: memory.h:120
SCIP_BTNODE * SCIPbtnodeGetParent(SCIP_BTNODE *node)
Definition: misc.c:6270
#define GMLNODEHEIGTH
Definition: misc.c:93
void SCIPmessagePrintError(const char *formatstr,...)
Definition: message.c:775
#define SCIPerrorMessage
Definition: pub_message.h:45
void SCIPhashmapPrintStatistics(SCIP_HASHMAP *hashmap, SCIP_MESSAGEHDLR *messagehdlr)
Definition: misc.c:2005
int SCIPactivityGetEnergy(SCIP_RESOURCEACTIVITY *activity)
Definition: misc.c:4679
interval arithmetics for provable bounds
#define SCIPdebugPrintf
Definition: pub_message.h:80
int SCIPhashmapGetNEntries(SCIP_HASHMAP *hashmap)
Definition: misc.c:2063
#define GMLNODETYPE
Definition: misc.c:95
void SCIPbtnodeSetLeftchild(SCIP_BTNODE *node, SCIP_BTNODE *left)
Definition: misc.c:6407
SCIP_RETCODE SCIPboolarrayCreate(SCIP_BOOLARRAY **boolarray, BMS_BLKMEM *blkmem)
Definition: misc.c:2903
void * SCIPdigraphGetNodeData(SCIP_DIGRAPH *digraph, int node)
Definition: misc.c:5616
int * timepoints
Definition: struct_misc.h:163
int SCIPcalcHashtableSize(int minsize)
Definition: misc.c:964
#define BMSmoveMemoryArray(ptr, source, num)
Definition: memory.h:106
SCIP_Real SCIPrealarrayGetVal(SCIP_REALARRAY *realarray, int idx)
Definition: misc.c:2410
void SCIPdigraphSetNodeData(SCIP_DIGRAPH *digraph, void *dataptr, int node)
Definition: misc.c:5632
void SCIPescapeString(char *t, int bufsize, const char *s)
Definition: misc.c:7551
int SCIPintarrayGetMaxIdx(SCIP_INTARRAY *intarray)
Definition: misc.c:2892
void SCIPstrCopySection(const char *str, char startchar, char endchar, char *token, int size, char **endptr)
Definition: misc.c:7680
SCIP_Real sizefac
Definition: struct_misc.h:65
static int profileFindFeasibleStart(SCIP_PROFILE *profile, int pos, int lst, int duration, int demand, SCIP_Bool *infeasible)
Definition: misc.c:5030
void SCIPhashmapFree(SCIP_HASHMAP **hashmap)
Definition: misc.c:1882
void SCIPdigraphPrint(SCIP_DIGRAPH *digraph, SCIP_MESSAGEHDLR *messagehdlr, FILE *file)
Definition: misc.c:6024
static SCIP_HASHTABLELIST * hashtablelistFind(SCIP_HASHTABLELIST *hashtablelist, SCIP_DECL_HASHGETKEY((*hashgetkey)), SCIP_DECL_HASHKEYEQ((*hashkeyeq)), SCIP_DECL_HASHKEYVAL((*hashkeyval)), void *userptr, unsigned int keyval, void *key)
Definition: misc.c:1024
void ** SCIPdigraphGetSuccessorsDatas(SCIP_DIGRAPH *digraph, int node)
Definition: misc.c:5697
internal miscellaneous methods
SCIP_RETCODE SCIPboolarrayClear(SCIP_BOOLARRAY *boolarray)
Definition: misc.c:3118
SCIP_HASHTABLELIST * next
Definition: struct_misc.h:76
SCIP_Longint * lbvalues
Definition: struct_misc.h:39
#define REALABS(x)
Definition: def.h:146
void SCIPactivityFree(SCIP_RESOURCEACTIVITY **activity)
Definition: misc.c:4623
void SCIPgmlWriteEdge(FILE *file, unsigned int source, unsigned int target, const char *label, const char *color)
Definition: misc.c:200
int SCIPptrarrayGetMaxIdx(SCIP_PTRARRAY *ptrarray)
Definition: misc.c:3601
#define SCIP_CALL(x)
Definition: def.h:258
#define PQ_LEFTCHILD(p)
Definition: misc.c:729
#define GMLNODEFILLCOLOR
Definition: misc.c:96
static SCIP_RETCODE profileUpdate(SCIP_PROFILE *profile, int left, int right, int demand, int *pos, SCIP_Bool *infeasible)
Definition: misc.c:4908
void SCIPmessagePrintInfo(SCIP_MESSAGEHDLR *messagehdlr, const char *formatstr,...)
Definition: message.c:578
void SCIPhashtableRemoveAll(SCIP_HASHTABLE *hashtable)
Definition: misc.c:1560
SCIP_RETCODE SCIPhashtableRemove(SCIP_HASHTABLE *hashtable, void *element)
Definition: misc.c:1526
SCIP_DECL_HASHGETKEY(SCIPhashGetKeyStandard)
Definition: misc.c:1674
SCIP_RETCODE SCIPintarraySetVal(SCIP_INTARRAY *intarray, int arraygrowinit, SCIP_Real arraygrowfac, int idx, int val)
Definition: misc.c:2802
SCIP_RETCODE SCIPprofileCreate(SCIP_PROFILE **profile, int capacity)
Definition: misc.c:4695
static SCIP_RETCODE ensureProfileSize(SCIP_PROFILE *profile, int neededsize)
Definition: misc.c:4844
void SCIPqueueFree(SCIP_QUEUE **queue)
Definition: misc.c:573
SCIP_RETCODE SCIPdigraphAddArc(SCIP_DIGRAPH *digraph, int startnode, int endnode, void *data)
Definition: misc.c:5544
SCIP_Bool SCIPbtnodeIsRightchild(SCIP_BTNODE *node)
Definition: misc.c:6358
void * SCIPpqueueRemove(SCIP_PQUEUE *pqueue)
Definition: misc.c:825
SCIP_Bool SCIPsortedvecFindInt(int *intarray, int val, int len, int *pos)
SCIP_DECL_HASHKEYVAL(SCIPhashKeyValString)
Definition: misc.c:1655
SCIP_BTNODE * SCIPbtGetRoot(SCIP_BT *tree)
Definition: misc.c:6543
#define BMSduplicateMemoryArray(ptr, source, num)
Definition: memory.h:111
SCIP_RETCODE SCIPgetRandomSubset(void **set, int nelems, void **subset, int nsubelems, unsigned int randseed)
Definition: misc.c:7426
#define BMSfreeBlockMemory(mem, ptr)
Definition: memory.h:417
static int getRand(unsigned int *seedp)
Definition: misc.c:7202
SCIP_Bool * vals
Definition: struct_misc.h:134
static SCIP_RETCODE pqueueResize(SCIP_PQUEUE *pqueue, int minsize)
Definition: misc.c:735
int * components
Definition: struct_misc.h:178
void SCIPhashtablePrintStatistics(SCIP_HASHTABLE *hashtable, SCIP_MESSAGEHDLR *messagehdlr)
Definition: misc.c:1601
SCIP_DECL_SORTPTRCOMP(SCIPsortCompInt)
Definition: misc.c:3616
#define PQ_PARENT(q)
Definition: misc.c:728
SCIP_BTNODE * SCIPbtnodeGetRightchild(SCIP_BTNODE *node)
Definition: misc.c:6290
public data structures and miscellaneous methods
SCIP_RETCODE SCIPdigraphAddArcSafe(SCIP_DIGRAPH *digraph, int startnode, int endnode, void *data)
Definition: misc.c:5572
static const int primetablesize
Definition: misc.c:961
int SCIPdigraphGetNSuccessors(SCIP_DIGRAPH *digraph, int node)
Definition: misc.c:5664
#define SCIP_Bool
Definition: def.h:49
static SCIP_RETCODE hashmaplistRemove(SCIP_HASHMAPLIST **hashmaplist, BMS_BLKMEM *blkmem, void *origin)
Definition: misc.c:1826
#define GMLFONTSIZE
Definition: misc.c:94
#define BMSallocBlockMemoryArray(mem, ptr, num)
Definition: memory.h:386
SCIP_Longint * SCIPsparseSolGetUbs(SCIP_SPARSESOL *sparsesol)
Definition: misc.c:415
void SCIPprintSysError(const char *message)
Definition: misc.c:7515
SCIP_RETCODE SCIPsparseSolCreate(SCIP_SPARSESOL **sparsesol, SCIP_VAR **vars, int nvars, SCIP_Bool cleared)
Definition: misc.c:319
SCIP_RETCODE SCIPhashmapRemoveAll(SCIP_HASHMAP *hashmap)
Definition: misc.c:2144
void ** slots
Definition: struct_misc.h:48
SCIP_Bool SCIPprofileFindLeft(SCIP_PROFILE *profile, int timepoint, int *pos)
Definition: misc.c:4821
SCIP_RETCODE SCIPrealarrayFree(SCIP_REALARRAY **realarray)
Definition: misc.c:2210
SCIP_RETCODE SCIPdigraphResize(SCIP_DIGRAPH *digraph, int nnodes)
Definition: misc.c:5355
static const SCIP_Real simplednoms[]
Definition: misc.c:6721
#define MAX(x, y)
Definition: tclique_def.h:75
SCIP_Bool SCIPstrToRealValue(const char *str, SCIP_Real *value, char **endptr)
Definition: misc.c:7650
int SCIPdigraphGetNArcs(SCIP_DIGRAPH *digraph)
Definition: misc.c:5646
void SCIPbtFree(SCIP_BT **tree)
Definition: misc.c:6451
SCIP_RETCODE SCIPhashtableSafeInsert(SCIP_HASHTABLE *hashtable, void *element)
Definition: misc.c:1415
SCIP_Bool SCIPbtnodeIsLeftchild(SCIP_BTNODE *node)
Definition: misc.c:6340
SCIP_Bool SCIPintervalHasRoundingControl(void)
int SCIPboolarrayGetMinIdx(SCIP_BOOLARRAY *boolarray)
Definition: misc.c:3238
int * successorssize
Definition: struct_misc.h:176
void ** SCIPpqueueElems(SCIP_PQUEUE *pqueue)
Definition: misc.c:891
#define BMScopyMemoryArray(ptr, source, num)
Definition: memory.h:102
void SCIPprofilePrint(SCIP_PROFILE *profile, SCIP_MESSAGEHDLR *messagehdlr, FILE *file)
Definition: misc.c:4733
void SCIPgmlWriteNodeWeight(FILE *file, unsigned int id, const char *label, const char *nodetype, const char *fillcolor, const char *bordercolor, SCIP_Real weight)
Definition: misc.c:150
SCIP_Bool SCIPfindSimpleRational(SCIP_Real lb, SCIP_Real ub, SCIP_Longint maxdnom, SCIP_Longint *nominator, SCIP_Longint *denominator)
Definition: misc.c:7091
void * SCIPhashtableRetrieve(SCIP_HASHTABLE *hashtable, void *key)
Definition: misc.c:1434
SCIP_Longint * ubvalues
Definition: struct_misc.h:40
static SCIP_Bool isIntegralScalar(SCIP_Real val, SCIP_Real scalar, SCIP_Real mindelta, SCIP_Real maxdelta)
Definition: misc.c:6859
int * SCIPprofileGetTimepoints(SCIP_PROFILE *profile)
Definition: misc.c:4775
static void hashtablelistFree(SCIP_HASHTABLELIST **hashtablelist, BMS_BLKMEM *blkmem)
Definition: misc.c:1000
SCIP_VAR ** SCIPsparseSolGetVars(SCIP_SPARSESOL *sparsesol)
Definition: misc.c:385
int * SCIPprofileGetLoads(SCIP_PROFILE *profile)
Definition: misc.c:4785
static void depthFirstSearch(SCIP_DIGRAPH *digraph, int startnode, SCIP_Bool *visited, int *dfsstack, int *stackadjvisited, int *dfsnodes, int *ndfsnodes)
Definition: misc.c:5714
#define BMSallocClearMemoryArray(ptr, num)
Definition: memory.h:87
int SCIPgetRandomInt(int minrandval, int maxrandval, unsigned int *seedp)
Definition: misc.c:7212
void SCIPhashtableFree(SCIP_HASHTABLE **hashtable)
Definition: misc.c:1317
SCIP_Bool SCIPbtIsEmpty(SCIP_BT *tree)
Definition: misc.c:6533
SCIP_RETCODE SCIPptrarrayClear(SCIP_PTRARRAY *ptrarray)
Definition: misc.c:3471
#define GMLEDGECOLOR
Definition: misc.c:97
SCIP_HASHMAPLIST * next
Definition: struct_misc.h:97
#define SCIP_REAL_MAX
Definition: def.h:124
SCIP_Real SCIPgetRandomReal(SCIP_Real minrandval, SCIP_Real maxrandval, unsigned int *seedp)
Definition: misc.c:7231
SCIP_BTNODE * SCIPbtnodeGetLeftchild(SCIP_BTNODE *node)
Definition: misc.c:6280
#define EPSGT(x, y, eps)
Definition: def.h:150
#define SCIP_DECL_SORTINDCOMP(x)
Definition: type_misc.h:114
int SCIPsparseSolGetNVars(SCIP_SPARSESOL *sparsesol)
Definition: misc.c:395
void SCIPbtSetRoot(SCIP_BT *tree, SCIP_BTNODE *root)
Definition: misc.c:6556
SCIP_RETCODE SCIPhashmapRemove(SCIP_HASHMAP *hashmap, void *origin)
Definition: misc.c:1984
void SCIPbtnodeSetParent(SCIP_BTNODE *node, SCIP_BTNODE *parent)
Definition: misc.c:6393
void SCIPsort(int *perm, SCIP_DECL_SORTINDCOMP((*indcomp)), void *dataptr, int len)
Definition: misc.c:3636
SCIP_RETCODE SCIPqueueCreate(SCIP_QUEUE **queue, int initsize, SCIP_Real sizefac)
Definition: misc.c:549
SCIP_RETCODE SCIPptrarrayFree(SCIP_PTRARRAY **ptrarray)
Definition: misc.c:3302
static SCIP_RETCODE hashmaplistSetImage(SCIP_HASHMAPLIST **hashmaplist, BMS_BLKMEM *blkmem, void *origin, void *image)
Definition: misc.c:1801
#define GMLNODEBORDERCOLOR
Definition: misc.c:98
SCIP_RETCODE SCIPdigraphCopy(SCIP_DIGRAPH **targetdigraph, SCIP_DIGRAPH *sourcedigraph)
Definition: misc.c:5391
SCIP_RETCODE SCIPpqueueInsert(SCIP_PQUEUE *pqueue, void *elem)
Definition: misc.c:798
SCIP_Real SCIPcalcMachineEpsilon(void)
Definition: misc.c:6572
SCIP_RETCODE SCIPpqueueCreate(SCIP_PQUEUE **pqueue, int initsize, SCIP_Real sizefac, SCIP_DECL_SORTPTRCOMP((*ptrcomp)))
Definition: misc.c:752
SCIP_RETCODE SCIPintarrayExtend(SCIP_INTARRAY *intarray, int arraygrowinit, SCIP_Real arraygrowfac, int minidx, int maxidx)
Definition: misc.c:2595
SCIP_RETCODE SCIPptrarraySetVal(SCIP_PTRARRAY *ptrarray, int arraygrowinit, SCIP_Real arraygrowfac, int idx, void *val)
Definition: misc.c:3523
static int profileFindDownFeasibleStart(SCIP_PROFILE *profile, int pos, int ect, int duration, int demand, SCIP_Bool *infeasible)
Definition: misc.c:5181
int SCIPactivityGetDuration(SCIP_RESOURCEACTIVITY *activity)
Definition: misc.c:4659
SCIP_BTNODE * right
Definition: struct_misc.h:190
SCIP_RETCODE SCIPboolarrayFree(SCIP_BOOLARRAY **boolarray)
Definition: misc.c:2947
public methods for message output
void SCIPmessageFPrintInfo(SCIP_MESSAGEHDLR *messagehdlr, FILE *file, const char *formatstr,...)
Definition: message.c:602
static const SCIP_Real scalars[]
Definition: misc.c:6881
SCIP_RETCODE SCIPhashmapSetImage(SCIP_HASHMAP *hashmap, void *origin, void *image)
Definition: misc.c:1944
static SCIP_RETCODE profileInsertTimepoint(SCIP_PROFILE *profile, int timepoint, int *pos)
Definition: misc.c:4867
#define SCIP_Real
Definition: def.h:123
void SCIPpermuteIntArray(int *array, int begin, int end, unsigned int *randseed)
Definition: misc.c:7367
int componentstartsize
Definition: struct_misc.h:181
#define MIN(x, y)
Definition: memory.c:59
SCIP_RETCODE SCIPrealarrayExtend(SCIP_REALARRAY *realarray, int arraygrowinit, SCIP_Real arraygrowfac, int minidx, int maxidx)
Definition: misc.c:2224
#define BMSallocMemory(ptr)
Definition: memory.h:92
BMS_BLKMEM * blkmem
Definition: struct_misc.h:133
#define SCIP_INVALID
Definition: def.h:142
#define BMSreallocMemoryArray(ptr, num)
Definition: memory.h:80
static int primetable[]
Definition: misc.c:909
static void btnodeFreeLeaf(SCIP_BT *tree, SCIP_BTNODE **node)
Definition: misc.c:6174
#define SCIP_Longint
Definition: def.h:107
SCIP_RETCODE SCIPcalcIntegralScalar(SCIP_Real *vals, int nvals, SCIP_Real mindelta, SCIP_Real maxdelta, SCIP_Longint maxdnom, SCIP_Real maxscale, SCIP_Real *intscalar, SCIP_Bool *success)
Definition: misc.c:6887
static void btPrintSubtree(SCIP_BTNODE *node, FILE *file, int *nnodes)
Definition: misc.c:6467
SCIP_RETCODE SCIPrealarraySetVal(SCIP_REALARRAY *realarray, int arraygrowinit, SCIP_Real arraygrowfac, int idx, SCIP_Real val)
Definition: misc.c:2431
SCIP_Bool SCIPhashtableExists(SCIP_HASHTABLE *hashtable, void *element)
Definition: misc.c:1499
void * SCIPqueueRemove(SCIP_QUEUE *queue)
Definition: misc.c:639
SCIP_RETCODE SCIPintarrayClear(SCIP_INTARRAY *intarray)
Definition: misc.c:2750
int SCIP_ROUNDMODE
Definition: intervalarith.h:45
void ** vals
Definition: struct_misc.h:145
#define STARTSUCCESSORSSIZE
Definition: misc.c:5505
int SCIPprofileGetLatestFeasibleStart(SCIP_PROFILE *profile, int est, int lst, int duration, int demand, SCIP_Bool *infeasible)
Definition: misc.c:5238
void SCIPgmlWriteOpening(FILE *file, SCIP_Bool directed)
Definition: misc.c:288
BMS_BLKMEM * blkmem
Definition: struct_misc.h:144
#define BMSallocBlockMemory(mem, ptr)
Definition: memory.h:404
SCIP_RETCODE SCIPboolarrayExtend(SCIP_BOOLARRAY *boolarray, int arraygrowinit, SCIP_Real arraygrowfac, int minidx, int maxidx)
Definition: misc.c:2961
int * nsuccessors
Definition: struct_misc.h:177
#define EPSFLOOR(x, eps)
Definition: def.h:155
SCIP_Real sizefac
Definition: struct_misc.h:47
SCIP_RETCODE SCIPhashmapInsert(SCIP_HASHMAP *hashmap, void *origin, void *image)
Definition: misc.c:1901
#define BMSclearMemoryArray(ptr, num)
Definition: memory.h:98
SCIP_Real SCIPhashtableGetLoad(SCIP_HASHTABLE *hashtable)
Definition: misc.c:1591
common defines and data types used in all packages of SCIP
void * SCIPqueueFirst(SCIP_QUEUE *queue)
Definition: misc.c:673
void SCIPswapInts(int *value1, int *value2)
Definition: misc.c:7341
struct BMS_BlkMem BMS_BLKMEM
Definition: memory.h:371
SCIP_RETCODE SCIPbtCreate(SCIP_BT **tree, BMS_BLKMEM *blkmem)
Definition: misc.c:6432
static SCIP_RETCODE queueResize(SCIP_QUEUE *queue, int minsize)
Definition: misc.c:530
SCIP_HASHTABLELIST ** lists
Definition: struct_misc.h:86
int SCIPactivityGetDemand(SCIP_RESOURCEACTIVITY *activity)
Definition: misc.c:4669
void SCIPbtnodeSetData(SCIP_BTNODE *node, void *dataptr)
Definition: misc.c:6379
SCIP_RETCODE SCIPptrarrayCreate(SCIP_PTRARRAY **ptrarray, BMS_BLKMEM *blkmem)
Definition: misc.c:3259
void SCIPdigraphFree(SCIP_DIGRAPH **digraph)
Definition: misc.c:5472
int SCIPprofileGetNTimepoints(SCIP_PROFILE *profile)
Definition: misc.c:4765
void SCIPpqueueClear(SCIP_PQUEUE *pqueue)
Definition: misc.c:788
#define SCIP_ALLOC(x)
Definition: def.h:269
SCIP_DECL_HASHKEYEQ(SCIPhashKeyEqString)
Definition: misc.c:1646
char * SCIPstrtok(char *s, const char *delim, char **ptrptr)
Definition: misc.c:7537
SCIP_ROUNDMODE SCIPintervalGetRoundingMode(void)
SCIP_Longint SCIPcalcGreComDiv(SCIP_Longint val1, SCIP_Longint val2)
Definition: misc.c:6595
void SCIPdigraphPrintGml(SCIP_DIGRAPH *digraph, FILE *file)
Definition: misc.c:6059
SCIP_HASHMAPLIST * SCIPhashmapListGetNext(SCIP_HASHMAPLIST *hashmaplist)
Definition: misc.c:2134
SCIP_RETCODE SCIPintarrayCreate(SCIP_INTARRAY **intarray, BMS_BLKMEM *blkmem)
Definition: misc.c:2538
void SCIPbtPrintGml(SCIP_BT *tree, FILE *file)
Definition: misc.c:6503
SCIP_Longint SCIPhashtableGetNElements(SCIP_HASHTABLE *hashtable)
Definition: misc.c:1581
void SCIPintervalSetRoundingModeDownwards(void)
SCIP_Longint SCIPcalcSmaComMul(SCIP_Longint val1, SCIP_Longint val2)
Definition: misc.c:6706
int firstused
Definition: struct_misc.h:50
SCIP_RETCODE SCIPptrarrayCopy(SCIP_PTRARRAY **ptrarray, BMS_BLKMEM *blkmem, SCIP_PTRARRAY *sourceptrarray)
Definition: misc.c:3279
#define PQ_RIGHTCHILD(p)
Definition: misc.c:730
SCIP_Bool SCIPbtnodeIsLeaf(SCIP_BTNODE *node)
Definition: misc.c:6330
#define SCIP_HASHTABLE_RESIZE_PERCENTAGE
Definition: misc.c:1166
void SCIPsparseSolFree(SCIP_SPARSESOL **sparsesol)
Definition: misc.c:371
void SCIPprofileFree(SCIP_PROFILE **profile)
Definition: misc.c:4719
SCIP_RETCODE SCIPrealarrayClear(SCIP_REALARRAY *realarray)
Definition: misc.c:2379