Scippy

SCIP

Solving Constraint Integer Programs

misc_stp.c
Go to the documentation of this file.
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2 /* */
3 /* This file is part of the program and library */
4 /* SCIP --- Solving Constraint Integer Programs */
5 /* */
6 /* Copyright (C) 2002-2015 Konrad-Zuse-Zentrum */
7 /* fuer Informationstechnik Berlin */
8 /* */
9 /* SCIP is distributed under the terms of the ZIB Academic License. */
10 /* */
11 /* You should have received a copy of the ZIB Academic License */
12 /* along with SCIP; see the file COPYING. If not email to scip@zib.de. */
13 /* */
14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15 
16 /**@file misc_stp.c
17  * @brief Miscellaneous methods used for solving Steiner problems
18  * @author Daniel Rehfeldt
19  *
20  * This file includes miscellaneous methods used for solving Steiner problems. For more details see \ref MISCSTP page.
21  *
22  * @page MISCSTP Miscellaneous methods used for Steiner tree problems
23  *
24  * This file implements an integer data linked list, a linear link-cut tree, a union-find data structure
25  * and a pairing heap.
26  *
27  * A list of all interface methods can be found in misc_stp.h.
28  */
29 
30 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
31 
32 #include <assert.h>
33 #include <string.h>
34 #include "heur_tm.h"
35 #include "probdata_stp.h"
36 #include "portab.h"
37 #include "scip/misc.h"
38 
39 /** compares distances of two GNODE structures */
41 {
42  SCIP_Real first = ((GNODE*)elem1)->dist;
43  SCIP_Real second = ((GNODE*)elem2)->dist;
44  if( LT(first,second) )
45  {
46  return -1;
47  }
48  else if( EQ(first, second) ) /* first == second */
49  {
50  return 0;
51  }
52  else
53  {
54  return 1;
55  }
56 }
57 
58 /** insert a new node */
59 SCIP_RETCODE SCIPintListNodeInsert(
60  SCIP* scip, /**< SCIP data structure */
61  IDX** node, /**< pointer to the last list node */
62  int nodeval /**< data of the new node */
63  )
64 {
65  IDX* curr;
66  curr = *node;
67 
68  SCIP_CALL( SCIPallocMemory(scip, node) );
69  (*node)->index = nodeval;
70  (*node)->parent = (curr);
71 
72  return SCIP_OKAY;
73 }
74 
75 /** append copy of list pertaining to node2 to node1 */
77  SCIP* scip, /**< SCIP data structure */
78  IDX** node1, /**< pointer to the last node of list to be enlarged */
79  IDX* node2 /**< pointer to the last node of source list */
80  )
81 {
82  IDX* curr1;
83  IDX* curr2;
84  IDX* curr3 = NULL;
85  IDX* last = NULL;
86  IDX* new = NULL;
87 
88  curr1 = *node1;
89  if( curr1 != NULL )
90  {
91  while( curr1->parent != NULL )
92  curr1 = curr1->parent;
93  last = curr1;
94  }
95 
96  curr2 = node2;
97  while( curr2 != NULL )
98  {
99  if( curr1 != NULL )
100  {
101  curr3 = *node1;
102  assert(curr3 != NULL);
103 
104  while( curr3 != last )
105  {
106  if( curr3->index == curr2->index )
107  break;
108  curr3 = curr3->parent;
109  assert(curr3 != NULL);
110  }
111  if( curr3 == last && curr3->index != curr2->index )
112  {
113  curr3 = NULL;
114  SCIP_CALL( SCIPallocMemory(scip, &new) );
115  curr1->parent = new;
116  }
117  }
118  else
119  {
120  curr3 = NULL;
121  SCIP_CALL( SCIPallocMemory(scip, node1) );
122  new = *node1;
123  last = *node1;
124  }
125  if( curr3 == NULL )
126  {
127  assert(new != NULL);
128  new->index = curr2->index;
129  curr1 = new;
130  }
131  curr2 = curr2->parent;
132  }
133  if( new != NULL )
134  new->parent = NULL;
135 
136  return SCIP_OKAY;
137 }
138 
139 /** free list */
141  SCIP* scip, /**< SCIP data structure */
142  IDX** node /**< pointer to the last list node */
143  )
144 {
145  IDX* curr;
146  curr = *node;
147 
148  while( curr != NULL )
149  {
150  *node = curr->parent;
151  SCIPfreeMemory(scip, &curr);
152  curr = *node;
153  }
154  assert(*node == NULL);
155 }
156 
157 /*
158  * Linear Link Cut Tree
159  */
160 
161 /** inits a node, setting 'parent' and 'edge' to its default values */
163  NODE* v /**< pointer to node representing the tree */
164  )
165 {
166  v->parent = NULL;
167  v->edge = -1;
168 }
169 
170 /** renders w a child of v; v has to be the root of its tree */
172  NODE* v, /**< pointer to node representing the tree */
173  NODE* w, /**< pointer to the child */
174  int edge /**< link edge */
175  )
176 {
177  assert(v->parent == NULL);
178  assert(v->edge == -1);
179  v->parent = w;
180  v->edge = edge;
181 }
182 
183 /** cut tree at given node */
185  NODE* v /**< node to cut at */
186  )
187 {
188  v->edge = -1;
189  v->parent = NULL;
190 }
191 
192 /** finds minimal non-key-node value between node 'v' and the root of the tree **/
194  SCIP* scip, /**< SCIP data structure */
195  SCIP_Real* nodeweight, /**< node weight array */
196  int* tail, /**< tail of an arc */
197  int* stdeg, /**< degree in Steiner tree */
198  NODE* v /**< the node */
199  )
200 {
201  NODE* p = v;
202  NODE* q = v;
203  int node;
204  SCIP_Real min = 0.0;
205 
206  assert(scip != NULL);
207  assert(tail != NULL);
208  assert(nodeweight != NULL);
209  assert(stdeg != NULL);
210  assert(v != NULL);
211 
212  while( p->parent != NULL )
213  {
214  assert(p->edge >= 0);
215  node = tail[p->edge];
216 
217  if( SCIPisLT(scip, nodeweight[node], min) && stdeg[node] == 2 )
218  {
219  min = nodeweight[node];
220  q = p;
221  }
222  p = p->parent;
223  }
224  return q;
225 }
226 
227 
228 
229 /** finds the max edge value between node 'v' and the root of the tree **/
231  SCIP* scip, /**< SCIP data structure */
232  const SCIP_Real* cost, /**< edge cost array */
233  NODE* v /**< the node */
234  )
235 {
236  NODE* p = v;
237  NODE* q = v;
238  SCIP_Real max = -1;
239 
240  while( p->parent != NULL )
241  {
242  assert(p->edge >= 0);
243  if( SCIPisGE(scip, cost[p->edge], max) )
244  {
245  max = cost[p->edge];
246  q = p;
247  }
248  p = p->parent;
249  }
250  return q;
251 }
252 
253 /** makes vertex v the root of the link cut tree */
255  NODE* v /**< the vertex to become the root */
256  )
257 {
258  NODE* p = NULL;
259  NODE* q = v;
260  NODE* r;
261  int val = -1;
262  int tmpval;
263 
264  assert(v != NULL);
265 
266  while( q != NULL )
267  {
268  r = q->parent;
269  tmpval = q->edge;
270  if( val != -1 )
271  q->edge = flipedge(val);
272  else
273  q->edge = -1;
274  val = tmpval;
275  q->parent = p;
276  p = q;
277  q = r;
278  }
279 }
280 
281 
282 
283 /*
284  * Pairing Heap
285  */
286 
287 /** links nodes 'root1' and 'root2' together */
289  SCIP* scip, /**< SCIP data structure */
290  PHNODE *root1, /**< pointer to root of first heap */
291  PHNODE *root2 /**< pointer to root of second heap */
292  )
293 {
294  if( root2 == NULL )
295  return root1;
296  if( root1 == NULL )
297  return root2;
298 
299  if( root1->key <= root2->key )
300  {
301  /* attach root2 as (the leftmost) child of root1 */
302  root2->prev = root1;
303  root1->sibling = root2->sibling;
304  if( root1->sibling != NULL )
305  root1->sibling->prev = root1;
306 
307  root2->sibling = root1->child;
308  if( root2->sibling != NULL )
309  root2->sibling->prev = root2;
310 
311  root1->child = root2;
312 
313  return root1;
314  }
315  else
316  {
317  /* attach root1 as (the leftmost) child of root2 */
318  root2->prev = root1->prev;
319  root1->prev = root2;
320  root1->sibling = root2->child;
321  if( root1->sibling != NULL )
322  root1->sibling->prev = root1;
323 
324  root2->child = root1;
325 
326  return root2;
327  }
328 }
329 
330 /** add heap to heap */
332  SCIP* scip, /**< SCIP data structure */
333  PHNODE* root1, /**< pointer to root of first heap */
334  PHNODE* root2 /**< pointer to root of second heap */
335  )
336 {
337  assert(root2 != NULL);
338  assert(root1 != NULL);
339 
340  if( root1->key <= root2->key )
341  {
342  /* attach root2 as (the leftmost) child of root1 */
343  root2->prev = root1;
344  root1->sibling = root2->sibling;
345  /* @todo: should never happen */
346  if( root1->sibling != NULL )
347  {
348  root1->sibling->prev = root1;
349  }
350 
351  root2->sibling = root1->child;
352  if( root2->sibling != NULL )
353  root2->sibling->prev = root2;
354 
355  root1->child = root2;
356 
357  return root1;
358  }
359  else
360  {
361  /* attach root1 as (the leftmost) child of root2 */
362  root2->prev = root1->prev;
363  root1->prev = root2;
364  root1->sibling = root2->child;
365  if( root1->sibling != NULL )
366  root1->sibling->prev = root1;
367 
368  root2->child = root1;
369 
370  return root2;
371  }
372 }
373 
374 /** internal method for combining the siblings after the root has been deleted */
375 static
377  SCIP* scip, /**< SCIP data structure */
378  PHNODE** p, /**< the first sibling */
379  int size /**< the size of the heap */
380  )
381 {
382  PHNODE** treearray;
383  int i;
384  int j;
385  int nsiblings;
386  if( (*p)->sibling == NULL )
387  return SCIP_OKAY;
388 
389  SCIP_CALL( SCIPallocBufferArray(scip, &treearray, size) );
390 
391  /* store all siblings in an array */
392  for( nsiblings = 0; (*p) != NULL; nsiblings++ )
393  {
394  assert(size > nsiblings);
395  treearray[nsiblings] = (*p);
396  if( (*p)->prev != NULL )
397  (*p)->prev->sibling = NULL;
398  (*p) = (*p)->sibling;
399  }
400  assert(size > nsiblings);
401  treearray[nsiblings] = NULL;
402 
403 #if 0
404  /*combine the subtrees (simple) */
405  for(i = 1; i < nsiblings; i++)
406  treearray[i] = SCIPpairheapMergeheaps(scip, treearray[i-1], treearray[i]);
407 
408 
409  return treearray[nsiblings-1];
410 #endif
411 
412  /* combine the subtrees (two at a time) */
413  for( i = 0; i < nsiblings - 1; i += 2 )
414  {
415  treearray[i] = SCIPpairheapMergeheaps(scip, treearray[i], treearray[i + 1]);
416  }
417  j = i - 2;
418 
419  /* if the number of trees is odd, get the last one */
420  if( j == nsiblings - 3 )
421  {
422  treearray[j] = SCIPpairheapMergeheaps(scip, treearray[j], treearray[j + 2]);
423  }
424 
425  for( ; j >= 2; j -= 2 )
426  {
427  treearray[j - 2] = SCIPpairheapMergeheaps(scip, treearray[j - 2], treearray[j]);
428  }
429 
430  (*p) = treearray[0];
431 
432  SCIPfreeBufferArray(scip, &treearray);
433 
434  return SCIP_OKAY;
435 }
436 
437 
438 /** inserts a new node into the pairing heap */
439 SCIP_RETCODE SCIPpairheapInsert(
440  SCIP* scip, /**< SCIP data structure */
441  PHNODE** root, /**< pointer to root of the heap */
442  int element, /**< data of new node */
443  SCIP_Real key, /**< key of new node */
444  int* size /**< pointer to size of the heap */
445  )
446 {
447  if( (*root) == NULL )
448  {
449  (*size) = 1;
450  SCIP_CALL( SCIPallocBuffer(scip, root) );
451  (*root)->key = key;
452  (*root)->element = element;
453  (*root)->child = NULL;
454  (*root)->sibling = NULL;
455  (*root)->prev = NULL;
456  }
457  else
458  {
459  PHNODE* node;
460  (*size)++;
461  SCIP_CALL( SCIPallocBuffer(scip, &node) );
462  node->key = key;
463  node->element = element;
464  node->child = NULL;
465  node->sibling = NULL;
466  node->prev = NULL;
467  (*root) = SCIPpairheapAddtoheap(scip, (*root), node);
468  }
469  return SCIP_OKAY;
470 }
471 
472 /** deletes the root of the paring heap, concomitantly storing its data and key in '*element' and '*key' respectively */
474  SCIP* scip, /**< SCIP data structure */
475  int* element, /**< data of the root */
476  SCIP_Real* key, /**< key of the root */
477  PHNODE** root, /**< pointer to root of the heap */
478  int* size /**< pointer to size of the heap */
479  )
480 {
481  assert(scip != NULL);
482  if( (*root) == NULL )
483  {
484  *element = -1;
485  return SCIP_OKAY;
486  }
487  else
488  {
489  PHNODE *newroot = NULL;
490 
491  assert(key != NULL);
492  assert(size != NULL);
493 
494  *element = (*root)->element;
495  *key = (*root)->key;
496  if( (*root)->child != NULL )
497  {
498  newroot = (*root)->child;
499  SCIP_CALL( pairheapCombineSiblings(scip, &newroot, (*size)--) );
500  }
501 
502  SCIPfreeBuffer(scip, root);
503  (*root) = newroot;
504  }
505  return SCIP_OKAY;
506 }
507 
508 
509 /** links nodes 'root1' and 'root2' together, roots the resulting tree at root1 and sets root2 to NULL */
511  SCIP* scip, /**< SCIP data structure */
512  PHNODE** root1, /**< pointer to root of first heap */
513  PHNODE** root2, /**< pointer to root of second heap */
514  int* sizeroot1, /**< pointer to size of first heap */
515  int* sizeroot2 /**< pointer to size of second heap */
516  )
517 {
518  assert(scip != NULL);
519  assert(root1 != NULL);
520  assert(root2 != NULL);
521  assert(sizeroot1 != NULL);
522  assert(sizeroot2 != NULL);
523 
524  if( *root1 == NULL && *root2 == NULL )
525  {
526  assert(*sizeroot1 == 0);
527  assert(*sizeroot2 == 0);
528  return;
529  }
530 
531  (*root1) = SCIPpairheapMergeheaps(scip, *root1, *root2);
532  (*sizeroot1) += (*sizeroot2);
533  (*root2) = NULL;
534 }
535 
536 
537 /** frees the paring heap with root 'p' */
539  SCIP* scip, /**< SCIP data structure */
540  PHNODE** root /**< root of heap to be freed */
541  )
542 {
543  if( (*root) == NULL )
544  {
545  return;
546  }
547  if( (*root)->sibling != NULL )
548  {
549  SCIPpairheapFree(scip, &((*root)->sibling));
550  }
551  if( (*root)->child != NULL )
552  {
553  SCIPpairheapFree(scip, &((*root)->child));
554  }
555 
556  SCIPfreeBuffer(scip, root);
557  (*root) = NULL;
558 
559 }
560 
561 
562 /** internal method used by 'pairheap_buffarr' */
563 static
565  PHNODE* p,
566  int** arr,
567  int* n
568  )
569 {
570  if( p == NULL )
571  {
572  return;
573  }
574  (*arr)[(*n)++] = p->element;
575  pairheapRec(p->sibling, arr, n);
576  pairheapRec(p->child, arr, n);
577 }
578 
579 
580 /** stores all elements of the pairing heap in an array */
581 SCIP_RETCODE SCIPpairheapBuffarr(
582  SCIP* scip, /**< SCIP data structure */
583  PHNODE* root, /**< root of the heap */
584  int size, /**< size of the array */
585  int** elements /**< pointer to array */
586  )
587 {
588  int n = 0;
589  SCIP_CALL( SCIPallocBufferArray(scip, elements, size) );
590  pairheapRec(root, elements, &n);
591  return SCIP_OKAY;
592 }
593 
594 
595 /*
596  *Union-Find data structure
597  */
598 
599 /** initializes the union-find structure 'uf' with 'length' many components (of size one) */
600 SCIP_RETCODE SCIPunionfindInit(
601  SCIP* scip, /**< SCIP data structure */
602  UF* uf, /**< union find data structure */
603  int length /**< number of components */
604  )
605 {
606  int i;
607  uf->count = length;
608  SCIP_CALL( SCIPallocMemoryArray(scip, &(uf->parent), length) );
609  SCIP_CALL( SCIPallocMemoryArray(scip, &(uf->size), length) );
610  for( i = 0; i < length; i++ ) {
611  uf->parent[i] = i;
612  uf->size[i] = 1;
613  }
614 
615  return SCIP_OKAY;
616 }
617 
618 
619 /** finds and returns the component identifier */
621  UF* uf, /**< union find data structure */
622  int element /**< element to be found */
623  )
624 {
625  int newelement;
626  int root = element;
627  int* parent = uf->parent;
628 
629  while( root != parent[root] )
630  {
631  root = parent[root];
632  }
633 
634  while( element != root )
635  {
636  newelement = parent[element];
637  parent[element] = root;
638  element = newelement;
639  }
640  return root;
641 }
642 
643 /** merges the components containing p and q respectively */
645  UF* uf, /**< union find data structure */
646  int p, /**< first component */
647  int q, /**< second component*/
648  SCIP_Bool compress /**< compress union find structure? */
649  )
650 {
651  int idp;
652  int idq;
653  int* size = uf->size;
654  int* parent = uf->parent;
655  idp = SCIPunionfindFind(uf, p);
656  idq = SCIPunionfindFind(uf, q);
657 
658  /* if p and q lie in the same component, there is nothing to be done */
659  if( idp == idq )
660  return;
661 
662  if( !compress )
663  {
664  parent[idq] = idp;
665  size[idp] += size[idq];
666  }
667  else
668  {
669  if( size[idp] < size[idq] )
670  {
671  parent[idp] = idq;
672  size[idq] += size[idp];
673  }
674  else
675  {
676  parent[idq] = idp;
677  size[idp] += size[idq];
678  }
679  }
680 
681  /* one less component */
682  uf->count--;
683 
684 }
685 
686 /** frees the data fields of the union-find structure */
688  SCIP* scip, /**< SCIP data structure */
689  UF* uf /**< union find data structure */
690  )
691 {
692  SCIPfreeMemoryArray(scip, &uf->parent);
693  SCIPfreeMemoryArray(scip, &uf->size);
694 }
#define LT(a, b)
Definition: portab.h:64
void SCIPunionfindFree(SCIP *scip, UF *uf)
Definition: misc_stp.c:687
struct ST_Node * parent
Definition: misc_stp.h:62
int SCIPunionfindFind(UF *uf, int element)
Definition: misc_stp.c:620
void SCIPpairheapMeldheaps(SCIP *scip, PHNODE **root1, PHNODE **root2, int *sizeroot1, int *sizeroot2)
Definition: misc_stp.c:510
struct PHeap_Node * sibling
Definition: misc_stp.h:78
Problem data for stp problem.
struct PHeap_Node * child
Definition: misc_stp.h:77
PHNODE * SCIPpairheapAddtoheap(SCIP *scip, PHNODE *root1, PHNODE *root2)
Definition: misc_stp.c:331
SCIP_RETCODE SCIPpairheapDeletemin(SCIP *scip, int *element, SCIP_Real *key, PHNODE **root, int *size)
Definition: misc_stp.c:473
void SCIPpairheapFree(SCIP *scip, PHNODE **root)
Definition: misc_stp.c:538
NODE * SCIPlinkcuttreeFindMax(SCIP *scip, const SCIP_Real *cost, NODE *v)
Definition: misc_stp.c:230
void SCIPintListNodeFree(SCIP *scip, IDX **node)
Definition: misc_stp.c:140
static SCIP_RETCODE pairheapCombineSiblings(SCIP *scip, PHNODE **p, int size)
Definition: misc_stp.c:376
SCIP_DECL_SORTPTRCOMP(GNODECmpByDist)
Definition: misc_stp.c:40
#define EQ(a, b)
Definition: portab.h:62
int edge
Definition: misc_stp.h:61
Definition: grphload.c:78
void SCIPlinkcuttreeInit(NODE *v)
Definition: misc_stp.c:162
void SCIPlinkcuttreeEvert(NODE *v)
Definition: misc_stp.c:254
int GNODECmpByDist(void *first_arg, void *second_arg)
SCIP_RETCODE SCIPintListNodeInsert(SCIP *scip, IDX **node, int nodeval)
Definition: misc_stp.c:59
void SCIPlinkcuttreeLink(NODE *v, NODE *w, int edge)
Definition: misc_stp.c:171
SCIP_RETCODE SCIPintListNodeAppendCopy(SCIP *scip, IDX **node1, IDX *node2)
Definition: misc_stp.c:76
void SCIPunionfindUnion(UF *uf, int p, int q, SCIP_Bool compress)
Definition: misc_stp.c:644
NODE * SCIPlinkcuttreeFindMinMW(SCIP *scip, SCIP_Real *nodeweight, int *tail, int *stdeg, NODE *v)
Definition: misc_stp.c:193
SCIP_Real key
Definition: misc_stp.h:76
Portable defintions.
PHNODE * SCIPpairheapMergeheaps(SCIP *scip, PHNODE *root1, PHNODE *root2)
Definition: misc_stp.c:288
SCIP_RETCODE SCIPpairheapInsert(SCIP *scip, PHNODE **root, int element, SCIP_Real key, int *size)
Definition: misc_stp.c:439
struct PHeap_Node * prev
Definition: misc_stp.h:79
int element
Definition: misc_stp.h:75
void SCIPlinkcuttreeCut(NODE *v)
Definition: misc_stp.c:184
shortest paths based primal heuristics for Steiner problems
SCIP_RETCODE SCIPunionfindInit(SCIP *scip, UF *uf, int length)
Definition: misc_stp.c:600
#define flipedge(edge)
Definition: grph.h:143
SCIP_RETCODE SCIPpairheapBuffarr(SCIP *scip, PHNODE *root, int size, int **elements)
Definition: misc_stp.c:581
struct Int_List_Node * parent
Definition: misc_stp.h:69
static void pairheapRec(PHNODE *p, int **arr, int *n)
Definition: misc_stp.c:564