Scippy

SCIP

Solving Constraint Integer Programs

grphbase.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 grphbase.c
17  * @brief includes several methodes for Steiner problem graphs
18  * @author Thorsten Koch
19  * @author Daniel Rehfeldt
20  *
21  * This file contains several basic methods to process Steiner problem graphs.
22  * A graph can not be reduced in terms of edge or node size, but edges can be marked as
23  * EAT_FREE (to not be used anymore) and nodes may have degree one.
24  * The method 'graph_pack()' can be used to build a new graph that discards these nodes and edges.
25  *
26  */
27 
28 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
29 
30 /*lint -esym(766,stdlib.h) -esym(766,malloc.h) */
31 /*lint -esym(766,string.h) */
32 
33 
34 #include "scip/misc.h"
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <string.h>
38 #include <assert.h>
39 #include "portab.h"
40 #include "misc_stp.h"
41 #include "grph.h"
42 
43 /** initalize a graph */
44 SCIP_RETCODE graph_init(
45  SCIP* scip, /**< SCIP data structure */
46  GRAPH** g, /**< new graph */
47  int ksize, /**< slots for nodes */
48  int esize, /**< slots for edges */
49  int layers, /**< number of layers (only needed for packing, otherwise 1) */
50  int flags /**< flags */
51  )
52 {
53  GRAPH* p;
54  int i;
55 
56  assert(ksize > 0);
57  assert(ksize < INT_MAX);
58  assert(esize >= 0);
59  assert(esize < INT_MAX);
60  assert(layers > 0);
61  assert(layers < SHRT_MAX);
62 
63  SCIP_CALL( SCIPallocMemory(scip, g) );
64  p = *g;
65  assert(p != NULL);
66 
67  /* ancestor data for retransformation after reductions */
68  p->fixedges = NULL;
69  p->ancestors = NULL;
70  p->pcancestors = NULL;
71  p->orgtail = NULL;
72  p->orghead = NULL;
73 
74  p->norgmodelknots = 0;
75  p->norgmodeledges = 0;
76  p->ksize = ksize;
77  p->orgknots = 0;
78  p->orgedges = 0;
79  p->knots = 0;
80  p->terms = 0;
81  p->stp_type = UNKNOWN;
82  p->flags = flags;
83  p->layers = layers;
84  p->hoplimit = UNKNOWN;
85 
86  SCIP_CALL( SCIPallocMemoryArray(scip, &(p->locals), layers) );
87  SCIP_CALL( SCIPallocMemoryArray(scip, &(p->source), layers) );
88  SCIP_CALL( SCIPallocMemoryArray(scip, &(p->term), ksize) );
89  SCIP_CALL( SCIPallocMemoryArray(scip, &(p->mark), ksize) );
90  SCIP_CALL( SCIPallocMemoryArray(scip, &(p->grad), ksize) );
91  SCIP_CALL( SCIPallocMemoryArray(scip, &(p->inpbeg), ksize) );
92  SCIP_CALL( SCIPallocMemoryArray(scip, &(p->outbeg), ksize) );
93 
94  p->esize = esize;
95  p->edges = 0;
96 
97  SCIP_CALL( SCIPallocMemoryArray(scip, &(p->cost), esize) );
98  SCIP_CALL( SCIPallocMemoryArray(scip, &(p->tail), esize) );
99  SCIP_CALL( SCIPallocMemoryArray(scip, &(p->head), esize) );
100  SCIP_CALL( SCIPallocMemoryArray(scip, &(p->ieat), esize) );
101  SCIP_CALL( SCIPallocMemoryArray(scip, &(p->oeat), esize) );
102 
103  p->prize = NULL;
104  p->maxdeg = NULL;
105  p->grid_coordinates = NULL;
106  p->grid_ncoords = NULL;
107  p->mincut_dist = NULL;
108  p->mincut_head = NULL;
109  p->mincut_numb = NULL;
110  p->mincut_prev = NULL;
111  p->mincut_next = NULL;
112  p->mincut_temp = NULL;
113  p->mincut_e = NULL;
114  p->mincut_x = NULL;
115  p->mincut_r = NULL;
116  p->path_heap = NULL;
117  p->path_state = NULL;
118 
119  for( i = 0; i < p->layers; i++ )
120  {
121  p->source[i] = -1;
122  p->locals[i] = 0;
123  }
124  return SCIP_OKAY;
125 }
126 
127 /** initialize data structures required to keep track of reductions */
128 SCIP_RETCODE graph_init_history(
129  SCIP* scip, /**< SCIP data structure */
130  GRAPH* graph /**< graph */
131  )
132 {
133  IDX** ancestors; /* ancestor lists array (over all edges) */
134  IDX** pcancestors; /* ancestor lists array (over all nodes) */
135  int* orgtail; /* (original) tail of all orginal edges */
136  int* orghead; /* (original) head of all orginal edges */
137  int e;
138  int nedges;
139  SCIP_Bool pcmw;
140 
141  assert(scip != NULL);
142  assert(graph != NULL);
143 
144  pcmw = (graph->stp_type == STP_PRIZE_COLLECTING || graph->stp_type == STP_ROOTED_PRIZE_COLLECTING ||
145  graph->stp_type == STP_MAX_NODE_WEIGHT);
146 
147  nedges = graph->edges;
148 
149  SCIP_CALL( SCIPallocMemoryArray(scip, &(graph->orgtail), nedges) );
150  SCIP_CALL( SCIPallocMemoryArray(scip, &(graph->orghead), nedges) );
151 
152  orgtail = graph->orgtail;
153  orghead = graph->orghead;
154 
155  for( e = 0; e < nedges; e++ )
156  {
157  orgtail[e] = graph->tail[e];
158  orghead[e] = graph->head[e];
159  }
160 
161  SCIP_CALL( SCIPallocMemoryArray(scip, &(graph->ancestors), nedges) );
162  ancestors = graph->ancestors;
163 
164  for( e = 0; e < nedges; e++ )
165  {
166  SCIP_CALL( SCIPallocMemory(scip, &(ancestors[e])) ); /*lint !e866*/
167  (ancestors)[e]->index = e;
168  (ancestors)[e]->parent = NULL;
169 
170  }
171 
172  if( pcmw )
173  {
174  int k;
175  int nnodes = graph->knots;
176  SCIP_CALL( SCIPallocMemoryArray(scip, &(graph->pcancestors), nnodes) );
177  pcancestors = graph->pcancestors;
178  for( k = 0; k < nnodes; k++ )
179  pcancestors[k] = NULL;
180  }
181 
182  return SCIP_OKAY;
183 }
184 
185 /** enlarge the graph */
186 SCIP_RETCODE graph_resize(
187  SCIP* scip, /**< SCIP data structure */
188  GRAPH* g, /**< graph to be resized */
189  int ksize, /**< new node slots */
190  int esize, /**< new edge slots */
191  int layers /**< layers (set to -1 by default) */
192  )
193 {
194  int i;
195  assert(scip != NULL);
196  assert(g != NULL);
197  assert((ksize < 0) || (ksize >= g->knots));
198  assert((esize < 0) || (esize >= g->edges));
199  assert((layers < 0) || (layers >= g->layers));
200 
201  if( (layers > 0) && (layers != g->layers) )
202  {
203  SCIP_CALL( SCIPreallocMemoryArray(scip, &(g->locals), layers) );
204  SCIP_CALL( SCIPreallocMemoryArray(scip, &(g->source), layers) );
205  for( i = g->layers; i < layers; i++ )
206  {
207  g->source[i] = -1;
208  g->locals[i] = 0;
209  }
210  g->layers = layers;
211  }
212  if( (ksize > 0) && (ksize != g->ksize) )
213  {
214  g->ksize = ksize;
215  SCIP_CALL( SCIPreallocMemoryArray(scip, &(g->term), ksize) );
216  SCIP_CALL( SCIPreallocMemoryArray(scip, &(g->mark), ksize) );
217  SCIP_CALL( SCIPreallocMemoryArray(scip, &(g->grad), ksize) );
218  SCIP_CALL( SCIPreallocMemoryArray(scip, &(g->inpbeg), ksize) );
219  SCIP_CALL( SCIPreallocMemoryArray(scip, &(g->outbeg), ksize) );
220  }
221  if( (esize > 0) && (esize != g->esize) )
222  {
223  g->esize = esize;
224  SCIP_CALL( SCIPreallocMemoryArray(scip, &(g->cost), esize) );
225  SCIP_CALL( SCIPreallocMemoryArray(scip, &(g->tail), esize) );
226  SCIP_CALL( SCIPreallocMemoryArray(scip, &(g->head), esize) );
227  SCIP_CALL( SCIPreallocMemoryArray(scip, &(g->ieat), esize) );
228  SCIP_CALL( SCIPreallocMemoryArray(scip, &(g->oeat), esize) );
229  }
230 
231  return SCIP_OKAY;
232 }
233 
234 
235 /** used by graph_grid_create */
236 static
238  int grid_dim,
239  int shiftcoord,
240  int* ncoords,
241  int* currcoord
242  )
243 {
244  int number = 0;
245  int tmp;
246  int i;
247  int j;
248  for( i = 0; i < grid_dim; i++ )
249  {
250  tmp = 1;
251  for( j = i + 1; j < grid_dim; j++ )
252  {
253  tmp = tmp * ncoords[j];
254  }
255  if( shiftcoord == i )
256  number += (currcoord[i] + 1) * tmp;
257  else
258  number += currcoord[i] * tmp;
259  }
260  number++;
261  return number;
262 }
263 
264 /** used by graph_obstgrid_create */
265 static
267  int coord,
268  int grid_dim,
269  int nobstacles,
270  int* ncoords,
271  int* currcoord,
272  int* edgecosts,
273  int* gridedgecount,
274  int** coords,
275  int** gridedges,
276  int** obst_coords,
277  char* inobstacle
278  )
279 {
280  char inobst;
281  int i;
282  int j;
283  int z;
284  int x;
285  int y;
286  int node;
287  i = 0;
288  while( i < ncoords[coord] )
289  {
290  currcoord[coord] = i;
291  if( coord < grid_dim - 1 )
292  compEdgesObst(coord + 1, grid_dim, nobstacles, ncoords, currcoord, edgecosts, gridedgecount, coords, gridedges, obst_coords, inobstacle);
293  else
294  {
295  x = coords[0][currcoord[0]];
296  y = coords[1][currcoord[1]];
297  inobst = FALSE;
298  node = getNodeNumber(grid_dim, -1, ncoords, currcoord);
299  for( z = 0; z < nobstacles; z++ )
300  {
301 
302  /*printf("curr x1, y1 (%d,%d) \n ", obst_coords[0][z], obst_coords[1][z]);
303  printf("curr x2, y2(%d,%d) \n ", obst_coords[2][z], obst_coords[3][z]);
304  printf(" \n ");*/
305  assert(obst_coords[0][z] < obst_coords[2][z]);
306  assert(obst_coords[1][z] < obst_coords[3][z]);
307  if( x > obst_coords[0][z] && x < obst_coords[2][z] &&
308  y > obst_coords[1][z] && y < obst_coords[3][z] )
309  {
310  inobst = TRUE;
311  inobstacle[node-1] = TRUE;
312  break;
313  }
314  }
315  for( j = 0; j < grid_dim; j++ )
316  {
317  if( currcoord[j] + 1 < ncoords[j] )
318  {
319  if( inobst == FALSE )
320  {
321  gridedges[0][*gridedgecount] = node;
322  gridedges[1][*gridedgecount] = getNodeNumber(grid_dim, j, ncoords, currcoord);
323  edgecosts[*gridedgecount] = coords[j][currcoord[j] + 1] - coords[j][currcoord[j]];
324  (*gridedgecount)++;
325  }
326  /* printf("edge %d_%d \n ", getNodeNumber(-1), getNodeNumber(j) );*/
327  }
328  }
329  }
330  i++;
331  }
332 }
333 
334 /** used by graph_grid_create */
335 static
337  int coord,
338  int grid_dim,
339  int* ncoords,
340  int* currcoord,
341  int* edgecosts,
342  int* gridedgecount,
343  int** coords,
344  int** gridedges
345  )
346 {
347  int j;
348  int i = 0;
349  while( i < ncoords[coord] )
350  {
351  currcoord[coord] = i;
352  if( coord < grid_dim - 1 )
353  compEdges(coord + 1, grid_dim, ncoords, currcoord, edgecosts, gridedgecount, coords, gridedges);
354  else
355  {
356  for( j = 0; j < grid_dim; j++ )
357  {
358  if( currcoord[j] + 1 < ncoords[j] )
359  {
360  gridedges[0][*gridedgecount] = getNodeNumber(grid_dim, -1, ncoords, currcoord);
361  gridedges[1][*gridedgecount] = getNodeNumber(grid_dim, j, ncoords, currcoord);
362  edgecosts[*gridedgecount] = coords[j][currcoord[j] + 1] - coords[j][currcoord[j]];
363  /* printf("edgeXXX %d_%d %d \n ", coords[j][currcoord[j] + 1], coords[j][currcoord[j]], gridedgecount );*/
364  (*gridedgecount)++;
365  /* printf("edge %d_%d \n ", getNodeNumber(-1), getNodeNumber(j) );*/
366  }
367  }
368  }
369  i++;
370  }
371 }
372 
373 /** creates a graph out of a given grid */
375  SCIP* scip, /**< SCIP data structure */
376  GRAPH** gridgraph, /**< the (obstacle) grid graph to be constructed */
377  int** coords, /**< coordinates of all points */
378  int** obst_coords, /**< coordinates of obstacles */
379  int nterms, /**< number of terminals */
380  int grid_dim, /**< dimension of the problem */
381  int nobstacles, /**< number of obstacles*/
382  int scale_order /**< scale factor */
383  )
384 {
385  GRAPH* g;
386  GRAPH* gp;
387  double cost;
388  int i;
389  int j;
390  int k;
391  int tmp;
392  int shift;
393  int nnodes;
394  int nedges;
395  double scale_factor;
396  int gridedgecount;
397  int* ncoords;
398  int* currcoord;
399  int* edgecosts;
400  int** termcoords;
401  int** gridedges;
402  char* inobstacle;
403  assert(coords != NULL);
404  assert(grid_dim > 1);
405  assert(nterms > 0);
406  assert(grid_dim == 2);
407  scale_factor = pow(10.0, (double) scale_order);
408 
409  /* initalize the terminal-coordinates array */
410  SCIP_CALL( SCIPallocMemoryArray(scip, &termcoords, grid_dim) );
411 
412  for( i = 0; i < grid_dim; i++ )
413  {
414  SCIP_CALL( SCIPallocMemoryArray(scip, &(termcoords[i]), nterms) ); /*lint !e866*/
415  for( j = 0; j < nterms; j++ )
416  termcoords[i][j] = coords[i][j];
417  }
418 
419  SCIP_CALL( SCIPallocMemoryArray(scip, &ncoords, grid_dim) );
420  SCIP_CALL( SCIPallocMemoryArray(scip, &currcoord, grid_dim) );
421 
422  /* sort the coordinates and delete multiples */
423  for( i = 0; i < grid_dim; i++ )
424  {
425  ncoords[i] = 1;
426  SCIPsortInt(coords[i], nterms);
427  shift = 0;
428  for( j = 0; j < nterms - 1; j++ )
429  {
430  if( coords[i][j] == coords[i][j + 1] )
431  {
432  shift++;
433  }
434  else
435  {
436  coords[i][j + 1 - shift] = coords[i][j + 1];
437  ncoords[i]++;
438  }
439  }
440  }
441 
442  nnodes = 1;
443 
444  for( i = 0; i < grid_dim; i++ )
445  nnodes = nnodes * ncoords[i];
446 
447  tmp = 0;
448 
449  for( i = 0; i < grid_dim; i++ )
450  tmp = tmp + nnodes / ncoords[i];
451 
452  nedges = grid_dim * nnodes - tmp;
453  SCIP_CALL( SCIPallocMemoryArray(scip, &gridedges, 2) );
454  SCIP_CALL( SCIPallocMemoryArray(scip, &edgecosts, nedges) );
455  SCIP_CALL( SCIPallocMemoryArray(scip, &(gridedges[0]), nedges) );
456  SCIP_CALL( SCIPallocMemoryArray(scip, &(gridedges[1]), nedges) );
457  SCIP_CALL( SCIPallocMemoryArray(scip, &(inobstacle), nnodes) );
458  gridedgecount = 0;
459  for( i = 0; i < nnodes; i++ )
460  inobstacle[i] = FALSE;
461  compEdgesObst(0, grid_dim, nobstacles, ncoords, currcoord, edgecosts, &gridedgecount, coords, gridedges, obst_coords, inobstacle);
462  nedges = gridedgecount;
463  /* initialize empty g with allocated slots for nodes and edges */
464  SCIP_CALL( graph_init(scip, gridgraph, nnodes, 2 * nedges, 1, 0) );
465 
466  g = *gridgraph;
467  SCIP_CALL( SCIPallocMemoryArray(scip, &(g->grid_ncoords), grid_dim) );
468  for( i = 0; i < grid_dim; i++ )
469  g->grid_ncoords[i] = ncoords[i];
470 
471  g->grid_dim = grid_dim;
472  g->grid_coordinates = coords;
473 
474  /* add nodes */
475  for( i = 0; i < nnodes; i++ )
476  graph_knot_add(g, -1);
477 
478  /* add edges */
479  for( i = 0; i < nedges; i++ )
480  {
481  /* (re) scale edge costs */
482  if( inobstacle[gridedges[1][i] - 1] == FALSE )
483  {
484  cost = ((double) edgecosts[i]) / scale_factor;
485  graph_edge_add(scip, g, gridedges[0][i] - 1, gridedges[1][i] - 1, cost, cost);
486  }
487  }
488 
489  /* add terminals */
490  for( i = 0; i < nterms; i++ )
491  {
492  for( j = 0; j < grid_dim; j++ )
493  {
494  for( k = 0; k <= ncoords[j]; k++ )
495  {
496  assert(k != ncoords[j]);
497  if( coords[j][k] == termcoords[j][i] )
498  {
499  currcoord[j] = k;
500  break;
501  }
502  }
503  }
504  /* the position of the (future) terminal */
505  k = getNodeNumber(grid_dim, -1, ncoords, currcoord) - 1;
506 
507  if( i == 0 )
508  g->source[0] = k;
509 
510  /* make a terminal out of the node */
511  graph_knot_chg(g, k, 0);
512  }
513 
514  SCIP_CALL( graph_pack(scip, g, &gp, TRUE) );
515  g = gp;
517 
518  for( i = 0; i < grid_dim; i++ )
519  SCIPfreeMemoryArray(scip, &(termcoords[i]));
520  SCIPfreeMemoryArray(scip, &(gridedges[0]));
521  SCIPfreeMemoryArray(scip, &(gridedges[1]));
522  SCIPfreeMemoryArray(scip, &inobstacle);
523  SCIPfreeMemoryArray(scip, &termcoords);
524  SCIPfreeMemoryArray(scip, &edgecosts);
525  SCIPfreeMemoryArray(scip, &gridedges);
526  SCIPfreeMemoryArray(scip, &ncoords);
527  SCIPfreeMemoryArray(scip, &currcoord);
528 
529  return SCIP_OKAY;
530 }
531 
532 
533 
534 /** creates a graph out of a given grid */
535 SCIP_RETCODE graph_grid_create(
536  SCIP* scip, /**< SCIP data structure */
537  GRAPH** gridgraph, /**< the grid graph to be constructed */
538  int** coords, /**< coordinates */
539  int nterms, /**< number of terminals*/
540  int grid_dim, /**< problem dimension */
541  int scale_order /**< scale order */
542  )
543 {
544  GRAPH* g;
545  double cost;
546  int i;
547  int j;
548  int k;
549  int tmp;
550  int shift;
551  int nnodes;
552  int nedges;
553  double scale_factor;
554  int gridedgecount;
555  int* ncoords;
556  int* currcoord;
557  int* edgecosts;
558  int** termcoords;
559  int** gridedges;
560  assert(coords != NULL);
561  assert(grid_dim > 1);
562  assert(nterms > 0);
563 
564  scale_factor = pow(10.0, (double) scale_order);
565 
566  /* initalize the terminal-coordinates array */
567  SCIP_CALL( SCIPallocMemoryArray(scip, &termcoords, grid_dim) );
568  for( i = 0; i < grid_dim; i++ )
569  {
570  SCIP_CALL( SCIPallocMemoryArray(scip, &(termcoords[i]), nterms) ); /*lint !e866*/
571  for( j = 0; j < nterms; j++ )
572  termcoords[i][j] = coords[i][j];
573  }
574  SCIP_CALL( SCIPallocMemoryArray(scip, &ncoords, grid_dim) );
575  SCIP_CALL( SCIPallocMemoryArray(scip, &currcoord, grid_dim) );
576 
577  /* sort the coordinates and delete multiples */
578  for( i = 0; i < grid_dim; i++ )
579  {
580  ncoords[i] = 1;
581  SCIPsortInt(coords[i], nterms);
582  shift = 0;
583  for( j = 0; j < nterms - 1; j++ )
584  {
585  if( coords[i][j] == coords[i][j + 1] )
586  {
587  shift++;
588  }
589  else
590  {
591  coords[i][j + 1 - shift] = coords[i][j + 1];
592  ncoords[i]++;
593  }
594  }
595  }
596 
597  nnodes = 1;
598  for( i = 0; i < grid_dim; i++ )
599  nnodes = nnodes * ncoords[i];
600 
601  tmp = 0;
602  for( i = 0; i < grid_dim; i++ )
603  {
604  tmp = tmp + nnodes / ncoords[i];
605  }
606 
607  nedges = grid_dim * nnodes - tmp;
608 
609  SCIP_CALL( SCIPallocMemoryArray(scip, &gridedges, 2) );
610  SCIP_CALL( SCIPallocMemoryArray(scip, &edgecosts, nedges) );
611  SCIP_CALL( SCIPallocMemoryArray(scip, &(gridedges[0]), nedges) );
612  SCIP_CALL( SCIPallocMemoryArray(scip, &(gridedges[1]), nedges) );
613 
614  gridedgecount = 0;
615 
616  compEdges(0, grid_dim, ncoords, currcoord, edgecosts, &gridedgecount, coords, gridedges);
617 
618  /* initialize empty graph with allocated slots for nodes and edges */
619  SCIP_CALL( graph_init(scip, gridgraph, nnodes, 2 * nedges, 1, 0) );
620 
621  g = *gridgraph;
622 
623  SCIP_CALL( SCIPallocMemoryArray(scip, &(g->grid_ncoords), grid_dim) );
624  for( i = 0; i < grid_dim; i++ )
625  g->grid_ncoords[i] = ncoords[i];
626 
627  g->grid_dim = grid_dim;
628  g->grid_coordinates = coords;
629 
630  /* add nodes */
631  for( i = 0; i < nnodes; i++ )
632  graph_knot_add(g, -1);
633 
634  /* add edges */
635  for( i = 0; i < nedges; i++ )
636  {
637  /* (re) scale edge costs */
638  cost = (double) edgecosts[i] / scale_factor;
639  graph_edge_add(scip, g, gridedges[0][i] - 1, gridedges[1][i] - 1, cost, cost);
640  }
641 
642  /* add terminals */
643  for( i = 0; i < nterms; i++ )
644  {
645  for( j = 0; j < grid_dim; j++ )
646  {
647  for( k = 0; k <= ncoords[j]; k++ )
648  {
649  assert(k != ncoords[j]);
650  if( coords[j][k] == termcoords[j][i] )
651  {
652  currcoord[j] = k;
653  break;
654  }
655  }
656  }
657  /* the position of the (future) terminal */
658  k = getNodeNumber(grid_dim, -1, ncoords, currcoord) - 1;
659 
660 #if 0
661  if( i == 0 )
662  {
663  g->source[0] = k;
664  printf("root: (%d", termcoords[0][i]);
665  for( j = 1; j < grid_dim; j++ )
666  printf(", %d", termcoords[j][i]);
667  printf(")\n");
668  }
669 #endif
670  /* make a terminal out of the node */
671  graph_knot_chg(g, k, 0);
672  }
673 
674  g->stp_type = STP_GRID;
675 
676  for( i = 0; i < grid_dim; i++ )
677  SCIPfreeMemoryArray(scip, &(termcoords[i]));
678 
679  SCIPfreeMemoryArray(scip, &(gridedges[0]));
680  SCIPfreeMemoryArray(scip, &(gridedges[1]));
681  SCIPfreeMemoryArray(scip, &termcoords);
682  SCIPfreeMemoryArray(scip, &edgecosts);
683  SCIPfreeMemoryArray(scip, &gridedges);
684  SCIPfreeMemoryArray(scip, &ncoords);
685  SCIPfreeMemoryArray(scip, &currcoord);
686  return SCIP_OKAY;
687 }
688 
689 
690 /** computes coordinates of node 'node' */
692  SCIP* scip, /**< SCIP data structure */
693  int** coords, /**< coordinates */
694  int** nodecoords, /**< coordinates of the node (to be computed) */
695  int* ncoords, /**< array with number of coordinate */
696  int node, /**< the node */
697  int grid_dim /**< problem dimension */
698  )
699 {
700  int i;
701  int j;
702  int tmp;
703  int coord;
704  assert(grid_dim > 1);
705  assert(node >= 0);
706  assert(coords != NULL);
707  assert(ncoords != NULL);
708  if( *nodecoords == NULL )
709  SCIP_CALL( SCIPallocMemoryArray(scip, nodecoords, grid_dim) );
710 
711  for( i = 0; i < grid_dim; i++ )
712  {
713  tmp = 1;
714  for( j = i; j < grid_dim; j++ )
715  tmp = tmp * ncoords[j];
716 
717  coord = node % tmp;
718  tmp = tmp / ncoords[i];
719  coord = coord / tmp;
720  (*nodecoords)[i] = coords[i][coord];
721  }
722  return SCIP_OKAY;
723 }
724 
725 /** alters the graph for prize collecting problems */
727  SCIP* scip , /**< SCIP data structure */
728  GRAPH* graph /**< the graph */
729  )
730 {
731  SCIP_Real* prize;
732  int k;
733  int root;
734  int node;
735  int nnodes;
736  int nterms;
737  assert(graph != NULL);
738  assert(graph->edges == graph->esize);
739  nnodes = graph->knots;
740  nterms = graph->terms;
741  prize = graph->prize;
742  assert(prize != NULL);
743  assert(nnodes == graph->ksize);
744  graph->norgmodeledges = graph->edges;
745  graph->norgmodelknots = nnodes;
746 
747  /* for each terminal, except for the root, one node and three edges (i.e. six arcs) are to be added */
748  SCIP_CALL( graph_resize(scip, graph, (graph->ksize + graph->terms + 1), (graph->esize + graph->terms * 6) , -1) );
749 
750  /* create a new nodes */
751  for( k = 0; k < nterms; ++k )
752  graph_knot_add(graph, -1);
753 
754  /* new root */
755  root = graph->knots;
756  graph_knot_add(graph, 0);
757  nterms = 0;
758  for( k = 0; k < nnodes; ++k )
759  {
760  /* is the kth node a terminal other than the root? */
761  if( Is_term(graph->term[k]) )
762  {
763  /* the copied node */
764  node = nnodes + nterms;
765  nterms++;
766 
767  /* switch the terminal property, mark k */
768  graph_knot_chg(graph, k, -2);
769  graph_knot_chg(graph, node, 0);
770  assert(SCIPisGE(scip, prize[k], 0.0));
771 
772  /* add one edge going from the root to the 'copied' terminal and one going from the former terminal to its copy */
773  graph_edge_add(scip, graph, root, k, 0.0, FARAWAY);
774  graph_edge_add(scip, graph, root, node, prize[k], FARAWAY);
775  graph_edge_add(scip, graph, k, node, 0.0, FARAWAY);
776  }
777  else if( graph->stp_type != STP_MAX_NODE_WEIGHT )
778  {
779  prize[k] = 0;
780  }
781  }
782  graph->source[0] = root;
783  assert((nterms + 1) == graph->terms);
784  if( graph->stp_type != STP_MAX_NODE_WEIGHT )
786 
787  return SCIP_OKAY;
788 }
789 
790 
791 /** alters the graph for prize collecting problems */
792 SCIP_RETCODE graph_PcSapCopy(
793  SCIP* scip, /**< SCIP data structure */
794  GRAPH* graph, /**< the graph */
795  GRAPH** newgraph, /**< the new graph */
796  SCIP_Real* offset /**< offset */
797  )
798 {
799  SCIP_Real* prize;
800  SCIP_Real prizesum;
801  int k;
802  int e;
803  int enext;
804  int root;
805  int head;
806  int nnodes;
807  int nterms;
808  int stp_type;
809  int pseudoroot;
810 
811  assert(graph != NULL);
812  assert(graph->prize != NULL);
813  assert(graph->knots == graph->ksize);
814  assert(graph->edges == graph->esize);
815 
816  prize = graph->prize;
817  nnodes = graph->knots;
818  nterms = graph->terms;
819  prizesum = 0.0;
820 
821  stp_type = graph->stp_type;
822  graph->stp_type = STP_DIRECTED;
823 
824  /* for each terminal, except for the root, one node and three edges (i.e. six arcs) are to be added */
825  SCIP_CALL( graph_copy(scip, graph, newgraph) );
826 
827  graph->stp_type = stp_type;
828 
829  SCIP_CALL( graph_resize(scip, (*newgraph), ((*newgraph)->ksize + 1), ((*newgraph)->esize + 2 * (nterms - 1)) , -1) );
830 
831  (*newgraph)->source[0] = graph->source[0];
832  root = (*newgraph)->source[0];
833 
834  /* new pseudo-root */
835  pseudoroot = (*newgraph)->knots;
836  graph_knot_add((*newgraph), -1);
837 
838  for( k = 0; k < nnodes; k++ )
839  if( Is_pterm(graph->term[k]) )
840  prizesum += prize[k];
841 
842  prizesum += 1;
843 
844  *offset -= prizesum;
845 
846  e = (*newgraph)->outbeg[root];
847 
848  while( e != EAT_LAST )
849  {
850  enext = (*newgraph)->oeat[e];
851  head = (*newgraph)->head[e];
852  if( Is_term((*newgraph)->term[head]) )
853  {
854  (void) graph_edge_redirect(scip, (*newgraph), e, pseudoroot, head, graph->cost[e]);
855  (*newgraph)->cost[flipedge(e)] = FARAWAY;
856  assert((*newgraph)->head[e] == head);
857  assert((*newgraph)->tail[e] == pseudoroot);
858  }
859  else
860  {
861  (*newgraph)->cost[e] = prizesum;
862  }
863 
864  e = enext;
865  }
866 
867  for( k = 0; k < nnodes; k++ )
868  {
869  /* is the kth node a terminal other than the root? */
870  if( Is_pterm((*newgraph)->term[k]) )
871  {
872  graph_edge_add(scip, (*newgraph), k, pseudoroot, 0.0, FARAWAY);
873  }
874  }
875 
876  return SCIP_OKAY;
877 }
878 
879 /** alters the graph for prize collecting problems */
880 SCIP_RETCODE graph_PcToSap(
881  SCIP* scip, /**< SCIP data structure */
882  GRAPH* graph /**< the graph */
883  )
884 {
885  SCIP_Real* prize;
886  int k;
887  int root;
888  int node;
889  int nnodes;
890  int nterms;
891  int pseudoroot;
892 
893  assert(graph != NULL);
894  assert(graph->prize != NULL);
895  assert(graph->knots == graph->ksize);
896  assert(graph->edges == graph->esize);
897 
898  prize = graph->prize;
899  nnodes = graph->knots;
900  nterms = graph->terms;
901  graph->norgmodelknots = nnodes;
902  graph->norgmodeledges = graph->edges;
903 
904  /* for each terminal, except for the root, one node and three edges (i.e. six arcs) are to be added */
905  SCIP_CALL( graph_resize(scip, graph, (graph->ksize + graph->terms + 2), (graph->esize + graph->terms * 8) , -1) );
906 
907  /* create a new nodes */
908  for( k = 0; k < nterms; ++k )
909  graph_knot_add(graph, -1);
910 
911  /* new pseudo-root */
912  pseudoroot = graph->knots;
913  graph_knot_add(graph, -1);
914 
915  /* new root */
916  root = graph->knots;
917  graph_knot_add(graph, 0);
918 
919  nterms = 0;
920  for( k = 0; k < nnodes; ++k )
921  {
922  /* is the kth node a terminal other than the root? */
923  if( Is_term(graph->term[k]) )
924  {
925  /* the copied node */
926  node = nnodes + nterms;
927  nterms++;
928 
929  /* switch the terminal property, mark k */
930  graph_knot_chg(graph, k, -2);
931  graph_knot_chg(graph, node, 0);
932  assert(SCIPisGE(scip, prize[k], 0.0));
933 
934  /* add one edge going from the root to the 'copied' terminal and one going from the former terminal to its copy */
935  graph_edge_add(scip, graph, root, k, BLOCKED, FARAWAY);
936  graph_edge_add(scip, graph, pseudoroot, node, prize[k], FARAWAY);
937  graph_edge_add(scip, graph, k, node, 0.0, FARAWAY);
938  graph_edge_add(scip, graph, k, pseudoroot, 0.0, FARAWAY);
939  }
940  else if( graph->stp_type != STP_MAX_NODE_WEIGHT )
941  {
942  prize[k] = 0;
943  }
944  }
945  graph->source[0] = root;
946  assert((nterms + 1) == graph->terms);
947  if( graph->stp_type != STP_MAX_NODE_WEIGHT )
949 
950  return SCIP_OKAY;
951 }
952 
953 
954 /** alters the graph for rooted prize collecting problems */
956  SCIP* scip, /**< SCIP data structure */
957  GRAPH* graph /**< the graph */
958  )
959 {
960  SCIP_Real* prize;
961  int k;
962  int root;
963  int node;
964  int nnodes;
965  int nterms;
966 
967  assert(graph != NULL);
968  assert(graph->edges == graph->esize);
969 
970  root = graph->source[0];
971  nnodes = graph->knots;
972  nterms = graph->terms;
973  prize = graph->prize;
974  graph->norgmodeledges = graph->edges;
975  graph->norgmodelknots = nnodes;
976 
977  assert(prize != NULL);
978  assert(nnodes == graph->ksize);
979  assert(root >= 0);
980 
981  /* for each terminal, except for the root, one node and three edges (i.e. six arcs) are to be added */
982  SCIP_CALL( graph_resize(scip, graph, (graph->ksize + graph->terms), (graph->esize + graph->terms * 4) , -1) );
983 
984  /* create a new nodes */
985  for( k = 0; k < nterms - 1; ++k )
986  graph_knot_add(graph, -1);
987 
988  nterms = 0;
989 
990  for( k = 0; k < nnodes; ++k )
991  {
992  /* is the kth node a terminal other than the root? */
993  if( Is_term(graph->term[k]) && k != root )
994  {
995  /* the copied node */
996  node = nnodes + nterms;
997  nterms++;
998  /* switch the terminal property, mark k as former terminal */
999  graph_knot_chg(graph, k, -2);
1000  graph_knot_chg(graph, node, 0);
1001  assert(SCIPisGE(scip, prize[k], 0.0));
1002 
1003  /* add one edge going from the root to the 'copied' terminal and one going from the former terminal to its copy */
1004  graph_edge_add(scip, graph, root, node, prize[k], FARAWAY);
1005  graph_edge_add(scip, graph, k, node, 0.0, FARAWAY);
1006  }
1007  else
1008  {
1009  prize[k] = 0.0;
1010  }
1011  }
1012  /* one for the root */
1013  nterms++;
1014  assert((nterms) == graph->terms);
1016  return SCIP_OKAY;
1017 }
1018 
1019 /** alters the graph for MWCS problems */
1021  SCIP* scip, /**< SCIP data structure */
1022  GRAPH* graph, /**< the graph */
1023  SCIP_Real* maxweights /**< array containing the weight of each node */
1024  )
1025 {
1026  int e;
1027  int i;
1028  int nnodes;
1029  int nterms = 0;
1030 
1031  assert(maxweights != NULL);
1032  assert(scip != NULL);
1033  assert(graph != NULL);
1034  assert(graph->cost != NULL);
1035  assert(graph->terms == 0);
1036 
1037  nnodes = graph->knots;
1038 
1039  /* count number of terminals, modify incoming edges for non-terminals */
1040  for( i = 0; i < nnodes; i++ )
1041  {
1042  if( SCIPisLT(scip, maxweights[i], 0.0) )
1043  {
1044  for( e = graph->inpbeg[i]; e != EAT_LAST; e = graph->ieat[e] )
1045  {
1046  graph->cost[e] -= maxweights[i];
1047  }
1048  }
1049  else
1050  {
1051  graph_knot_chg(graph, i, 0);
1052  nterms++;
1053  }
1054  }
1055  nterms = 0;
1056  for( i = 0; i < nnodes; i++ )
1057  {
1058  graph->prize[i] = maxweights[i];
1059  if( Is_term(graph->term[i]) )
1060  {
1061  assert(SCIPisGE(scip, maxweights[i], 0.0));
1062  nterms++;
1063  }
1064  else
1065  {
1066  assert(SCIPisLT(scip, maxweights[i], 0.0));
1067  }
1068  }
1069  assert(nterms == graph->terms);
1070  graph->stp_type = STP_MAX_NODE_WEIGHT;
1071 
1072  SCIP_CALL( graph_prize_transform(scip, graph) );
1073  assert(graph->stp_type == STP_MAX_NODE_WEIGHT);
1074  return SCIP_OKAY;
1075 }
1076 
1077 
1078 /** tansforms an MWCSP to an SAP */
1079 SCIP_RETCODE graph_MwcsToSap(
1080  SCIP* scip, /**< SCIP data structure */
1081  GRAPH* graph, /**< the graph */
1082  SCIP_Real* maxweights /**< array containing the weight of each node */
1083  )
1084 {
1085  int e;
1086  int i;
1087  int nnodes;
1088  int nterms = 0;
1089 
1090  assert(maxweights != NULL);
1091  assert(scip != NULL);
1092  assert(graph != NULL);
1093  assert(graph->cost != NULL);
1094  assert(graph->terms == 0);
1095 
1096  nnodes = graph->knots;
1097 
1098  /* count number of terminals, modify incoming edges for non-terminals */
1099  for( i = 0; i < nnodes; i++ )
1100  {
1101  if( SCIPisLT(scip, maxweights[i], 0.0) )
1102  {
1103  for( e = graph->inpbeg[i]; e != EAT_LAST; e = graph->ieat[e] )
1104  {
1105  graph->cost[e] -= maxweights[i];
1106  }
1107  }
1108  else
1109  {
1110  graph_knot_chg(graph, i, 0);
1111  nterms++;
1112  }
1113  }
1114  nterms = 0;
1115  for( i = 0; i < nnodes; i++ )
1116  {
1117  graph->prize[i] = maxweights[i];
1118  if( Is_term(graph->term[i]) )
1119  {
1120  assert(SCIPisGE(scip, maxweights[i], 0.0));
1121  nterms++;
1122  }
1123  else
1124  {
1125  assert(SCIPisLT(scip, maxweights[i], 0.0));
1126  }
1127  }
1128  assert(nterms == graph->terms);
1129  graph->stp_type = STP_MAX_NODE_WEIGHT;
1130 
1131  SCIP_CALL( graph_PcToSap(scip, graph) );
1132  assert(graph->stp_type == STP_MAX_NODE_WEIGHT);
1133  return SCIP_OKAY;
1134 }
1135 
1136 /** free the graph */
1138  SCIP* scip, /**< SCIP data structure */
1139  GRAPH* p, /**< graph to be freed */
1140  SCIP_Bool final /**< delete ancestor data structures? */
1141  )
1142 {
1143  IDX* curr;
1144  int e;
1145 
1146  assert(scip != NULL);
1147  assert(p != NULL);
1148 
1149  SCIPfreeMemoryArray(scip, &(p->locals));
1150  SCIPfreeMemoryArray(scip, &(p->source));
1151  SCIPfreeMemoryArray(scip, &(p->term));
1152  SCIPfreeMemoryArray(scip, &(p->mark));
1153  SCIPfreeMemoryArray(scip, &(p->grad));
1154  SCIPfreeMemoryArray(scip, &(p->inpbeg));
1155  SCIPfreeMemoryArray(scip, &(p->outbeg));
1156  SCIPfreeMemoryArray(scip, &(p->cost));
1157  SCIPfreeMemoryArray(scip, &(p->tail));
1158  SCIPfreeMemoryArray(scip, &(p->head));
1159  SCIPfreeMemoryArray(scip, &(p->ieat));
1160  SCIPfreeMemoryArray(scip, &(p->oeat));
1161 
1162  if( p->prize != NULL )
1163  SCIPfreeMemoryArray(scip, &(p->prize));
1164  if( p->ancestors != NULL )
1165  {
1166  for( e = 0; e < p->edges; e++ )
1167  {
1168  curr = p->ancestors[e];
1169  while( curr != NULL )
1170  {
1171  p->ancestors[e] = curr->parent;
1172  SCIPfreeMemory(scip, &(curr));
1173  curr = p->ancestors[e];
1174  }
1175  }
1176  SCIPfreeMemoryArray(scip, &(p->ancestors));
1177  }
1178 
1179  if( final )
1180  {
1181  if( p->orgtail != NULL )
1182  {
1183  assert(p->orghead != NULL);
1184  SCIPfreeMemoryArray(scip, &(p->orgtail));
1185  SCIPfreeMemoryArray(scip, &(p->orghead));
1186  }
1187  curr = p->fixedges;
1188  while( curr != NULL )
1189  {
1190  p->fixedges = curr->parent;
1191  SCIPfreeMemory(scip, &(curr));
1192  curr = p->fixedges;
1193  }
1194 
1195  if( p->pcancestors != NULL )
1196  {
1197  for( e = 0; e < p->norgmodelknots; e++ )
1198  {
1199  curr = p->pcancestors[e];
1200  while( curr != NULL )
1201  {
1202  p->pcancestors[e] = curr->parent;
1203  SCIPfreeMemory(scip, &(curr));
1204  curr = p->pcancestors[e];
1205  }
1206  }
1207  SCIPfreeMemoryArray(scip, &(p->pcancestors));
1208  }
1209  }
1210 
1211  if( p->stp_type == STP_DEG_CONS )
1212  {
1213  SCIPfreeMemoryArray(scip, &(p->maxdeg));
1214  }
1215  else if( p->stp_type == STP_GRID )
1216  {
1217  int i;
1218  for( i = 0; i < p->grid_dim; i++ )
1219  SCIPfreeMemoryArray(scip, &(p->grid_coordinates[i]));
1220 
1221  SCIPfreeMemoryArray(scip, &(p->grid_coordinates));
1222  SCIPfreeMemoryArray(scip, &(p->grid_ncoords));
1223  }
1224  SCIPfreeMemory(scip, &(p));
1225 }
1226 
1227 /** copy the graph */
1228 SCIP_RETCODE graph_copy(
1229  SCIP* scip, /**< SCIP data structure */
1230  GRAPH* orgraph, /**< original graph */
1231  GRAPH** copygraph /**< graph to be copied */
1232  )
1233 {
1234  GRAPH* g;
1235  GRAPH* p;
1236  int ksize;
1237 
1238  p = orgraph;
1239  assert(p != NULL);
1240 
1241  ksize = p->ksize;
1242 
1243  SCIP_CALL( graph_init(scip, copygraph, p->ksize, p->esize, p->layers, p->flags) );
1244  g = *copygraph;
1245 
1248  g->knots = p->knots;
1249  g->terms = p->terms;
1250  g->edges = p->edges;
1251  g->orgedges = p->orgedges;
1252  g->orgknots = p->orgknots;
1253  g->grid_dim = p->grid_dim;
1254  g->stp_type = p->stp_type;
1255  g->hoplimit = p->hoplimit;
1256 
1257  BMScopyMemoryArray(g->locals, p->locals, p->layers);
1258  BMScopyMemoryArray(g->source, p->source, p->layers);
1259  BMScopyMemoryArray(g->term, p->term, ksize);
1260  BMScopyMemoryArray(g->mark, p->mark, ksize);
1261  BMScopyMemoryArray(g->grad, p->grad, ksize);
1262  BMScopyMemoryArray(g->inpbeg, p->inpbeg, ksize);
1263  BMScopyMemoryArray(g->outbeg, p->outbeg, ksize);
1264  BMScopyMemoryArray(g->term, p->term, ksize);
1265  BMScopyMemoryArray(g->cost, p->cost, p->esize);
1266  BMScopyMemoryArray(g->tail, p->tail, p->esize);
1267  BMScopyMemoryArray(g->head, p->head, p->esize);
1268  BMScopyMemoryArray(g->ieat, p->ieat, p->esize);
1269  BMScopyMemoryArray(g->oeat, p->oeat, p->esize);
1270 
1272  || g->stp_type == STP_MAX_NODE_WEIGHT )
1273  {
1274  SCIPdebugMessage("norgmodelknots %d \n", g->norgmodelknots);
1275  SCIP_CALL( SCIPallocMemoryArray(scip, &(g->prize), g->norgmodelknots) );
1276 
1277  BMScopyMemoryArray(&(g->prize), p->prize, g->norgmodelknots);
1278  }
1279  else if( g->stp_type == STP_DEG_CONS )
1280  {
1281  assert(p->maxdeg != NULL);
1282  SCIP_CALL( SCIPallocMemoryArray(scip, &(g->maxdeg), g->knots) );
1283  BMScopyMemoryArray(&(g->maxdeg), p->maxdeg, g->knots);
1284  }
1285  else if( p->stp_type == STP_GRID )
1286  {
1287  int i;
1288  assert(p->grid_ncoords != NULL);
1289  assert(p->grid_coordinates != NULL);
1290 
1291  SCIP_CALL( SCIPallocMemoryArray(scip, &(g->grid_coordinates), p->grid_dim) );
1292  BMScopyMemoryArray(g->grid_coordinates, p->grid_coordinates, p->grid_dim);
1293  for( i = 0; i < p->grid_dim; i++ )
1294  {
1295  SCIP_CALL( SCIPallocMemoryArray(scip, &(g->grid_coordinates[i]), p->terms) ); /*lint !e866*/
1296  BMScopyMemoryArray(g->grid_coordinates[i], p->grid_coordinates[i], p->terms); /*lint !e866*/
1297  }
1298  SCIP_CALL( SCIPallocMemoryArray(scip, &(g->grid_ncoords), p->grid_dim) );
1299  BMScopyMemoryArray(g->grid_ncoords, p->grid_ncoords, p->grid_dim);
1300  }
1301  assert(graph_valid(g));
1302 
1303  return SCIP_OKAY;
1304 }
1305 
1306 /** set flags */
1308  GRAPH* p, /**< the graph */
1309  int flags /**< new flags */
1310  )
1311 {
1312  assert(p != NULL);
1313  assert(flags >= 0);
1314 
1315  p->flags |= flags;
1316 }
1317 
1319  const GRAPH* p /**< the graph */
1320  )
1321 {
1322  int i;
1323 
1324  assert(p != NULL);
1325 
1326  for(i = 0; i < p->knots; i++)
1327  if (p->grad[i] > 0)
1328  (void)printf("Knot %d, term=%d, grad=%d, inpbeg=%d, outbeg=%d\n",
1329  i, p->term[i], p->grad[i], p->inpbeg[i], p->outbeg[i]);
1330 
1331  (void)fputc('\n', stdout);
1332 
1333  for(i = 0; i < p->edges; i++)
1334  if (p->ieat[i] != EAT_FREE)
1335  (void)printf("Edge %d, cost=%g, tail=%d, head=%d, ieat=%d, oeat=%d\n",
1336  i, p->cost[i], p->tail[i], p->head[i], p->ieat[i], p->oeat[i]);
1337 
1338  (void)fputc('\n', stdout);
1339 }
1340 
1342  const GRAPH* p /**< the graph */
1343  )
1344 {
1345  int i;
1346  int ident = 0;
1347 
1348  assert(p != NULL);
1349 
1350  for(i = 0; i < p->knots; i++)
1351  ident += (i + 1) * (p->term[i] * 2 + p->grad[i] * 3
1352  + p->inpbeg[i] * 5 + p->outbeg[i] * 7);
1353 
1354  for(i = 0; i < p->edges; i++)
1355  ident += (i + 1) * ((int)p->cost[i] + p->tail[i]
1356  + p->head[i] + p->ieat[i] + p->oeat[i]);
1357 
1358  (void)printf("Graph Ident = %d\n", ident);
1359 }
1360 
1361 /** add a vertex */
1363  GRAPH* p, /**< the graph */
1364  int term /**< terminal property */
1365  )
1366 {
1367  assert(p != NULL);
1368  assert(p->ksize > p->knots);
1369  assert(term < p->layers);
1370 
1371  p->term [p->knots] = term;
1372  p->mark [p->knots] = TRUE;
1373  p->grad [p->knots] = 0;
1374  p->inpbeg[p->knots] = EAT_LAST;
1375  p->outbeg[p->knots] = EAT_LAST;
1376 
1377  if (Is_term(term))
1378  {
1379  p->terms++;
1380  p->locals[term]++;
1381  }
1382  p->knots++;
1383 }
1384 
1385 /** change terminal property of a vertex */
1387  GRAPH* p, /**< the graph */
1388  int node, /**< node to be changed */
1389  int term /**< terminal property */
1390  )
1391 {
1392  assert(p != NULL);
1393  assert(node >= 0);
1394  assert(node < p->knots);
1395  assert(term < p->layers);
1396 
1397  if (term != p->term[node])
1398  {
1399  if (Is_term(p->term[node]))
1400  {
1401  p->terms--;
1402  p->locals[p->term[node]]--;
1403  }
1404  p->term[node] = term;
1405 
1406  if (Is_term(p->term[node]))
1407  {
1408  p->terms++;
1409  p->locals[p->term[node]]++;
1410  }
1411  }
1412 }
1413 
1414 /** contract an edge, given by its endpoints */
1415 SCIP_RETCODE graph_knot_contract(
1416  SCIP* scip, /**< SCIP data structure */
1417  GRAPH* p, /**< graph data structure */
1418  int t, /**< tail node to be contracted */
1419  int s /**< head node to be contracted */
1420  )
1421 {
1422  typedef struct save_list
1423  {
1424  unsigned int mark;
1425  signed int edge;
1426  signed int knot;
1427  double incost;
1428  double outcost;
1429  } SLIST;
1430 
1431  SLIST* slp = NULL;
1432  IDX** ancestors = NULL;
1433  IDX** revancestors = NULL;
1434  IDX* tsancestors = NULL;
1435  IDX* stancestors = NULL;
1436  int slc = 0;
1437  int i;
1438  int et;
1439  int anti;
1440  int es;
1441  int cedgeout = UNKNOWN;
1442  int head;
1443  int tail;
1444  int sgrad;
1445 
1446  assert(p != NULL);
1447  assert(t >= 0);
1448  assert(t < p->knots);
1449  assert(s >= 0);
1450  assert(s < p->knots);
1451  assert(s != t);
1452  assert(scip != NULL);
1453  assert(p->grad[s] > 0);
1454  assert(p->grad[t] > 0);
1455  assert(p->layers == 1);
1456 
1457  /* change terminal property */
1458  if( Is_term(p->term[s]) )
1459  {
1460  graph_knot_chg(p, t, p->term[s]);
1461  graph_knot_chg(p, s, -1);
1462  }
1463 
1464  /* retain root */
1465  if( p->source[0] == s )
1466  p->source[0] = t;
1467 
1468  sgrad = p->grad[s];
1469  if( sgrad >= 2 )
1470  {
1471  SCIP_CALL( SCIPallocBufferArray(scip, &slp, sgrad - 1) );
1472  SCIP_CALL( SCIPallocBufferArray(scip, &ancestors, sgrad - 1) );
1473  SCIP_CALL( SCIPallocBufferArray(scip, &revancestors, sgrad - 1) );
1474  }
1475 
1476  /* store edges to be moved/removed */
1477  for( es = p->outbeg[s]; es != EAT_LAST; es = p->oeat[es] )
1478  {
1479  assert(p->tail[es] == s);
1480 
1481  if( p->head[es] != t )
1482  {
1483  assert(ancestors != NULL);
1484  assert(revancestors != NULL);
1485  assert(slp != NULL);
1486 
1487  ancestors[slc] = NULL;
1488  SCIP_CALL( SCIPintListNodeAppendCopy(scip, &(ancestors[slc]), p->ancestors[es]) );
1489  revancestors[slc] = NULL;
1490  SCIP_CALL( SCIPintListNodeAppendCopy(scip, &(revancestors[slc]), p->ancestors[Edge_anti(es)]) );
1491 
1492  slp[slc].mark = FALSE;
1493  slp[slc].edge = es;
1494  slp[slc].knot = p->head[es];
1495  slp[slc].outcost = p->cost[es];
1496  slp[slc].incost = p->cost[Edge_anti(es)];
1497  slc++;
1498 
1499  assert(slc < sgrad);
1500  }
1501  else
1502  {
1503  cedgeout = Edge_anti(es); /* The edge out of t and into s. */
1504  SCIP_CALL( SCIPintListNodeAppendCopy(scip, &stancestors, p->ancestors[es]) );
1505  SCIP_CALL( SCIPintListNodeAppendCopy(scip, &tsancestors, p->ancestors[cedgeout]) );
1506  }
1507  }
1508 
1509  assert(slc == sgrad - 1);
1510  assert(tsancestors != NULL);
1511  assert(stancestors != NULL);
1512  /* Kantenliste durchgehen
1513  */
1514  for( i = 0; i < slc; i++ )
1515  {
1516  assert(slp != NULL);
1517 
1518  /* search for an edge out of t with same head as current edge */
1519  for(et = p->outbeg[t]; et != EAT_LAST; et = p->oeat[et])
1520  if( p->head[et] == slp[i].knot )
1521  break;
1522 
1523  /* does such an edge not exist? */
1524  if( et == EAT_LAST )
1525  {
1526  slp[i].mark = TRUE;
1527  }
1528  else
1529  {
1530  assert(et != EAT_LAST);
1531 
1532  /* This is for nodes with edges to s and t.
1533  * Need to adjust the out and in costs of the edge
1534  */
1535  if( SCIPisGT(scip, p->cost[et], slp[i].outcost) )
1536  {
1537  SCIPintListNodeFree(scip, &((p->ancestors)[et]));
1538  assert(ancestors != NULL);
1539  assert(slp != NULL);
1540  SCIP_CALL( SCIPintListNodeAppendCopy(scip, &((p->ancestors)[et]), ancestors[i]) );
1541  SCIP_CALL( SCIPintListNodeAppendCopy(scip, &((p->ancestors)[et]), tsancestors) );
1542  p->cost[et] = slp[i].outcost;
1543  }
1544  if( SCIPisGT(scip, p->cost[Edge_anti(et)], slp[i].incost) )
1545  {
1546  anti = Edge_anti(et);
1547  SCIPintListNodeFree(scip, &(p->ancestors[anti]));
1548  assert(revancestors != NULL);
1549  assert(slp != NULL);
1550  SCIP_CALL( SCIPintListNodeAppendCopy(scip, &((p->ancestors)[anti]), revancestors[i]) );
1551  SCIP_CALL( SCIPintListNodeAppendCopy(scip, &((p->ancestors)[anti]), stancestors) );
1552  p->cost[anti] = slp[i].incost;
1553  }
1554  }
1555  }
1556 
1557  /* insert edges */
1558  for( i = 0; i < slc; i++ )
1559  {
1560  assert(slp != NULL);
1561  if( slp[i].mark )
1562  {
1563  es = p->outbeg[s];
1564 
1565  assert(es != EAT_LAST);
1566  assert(ancestors != NULL);
1567  assert(revancestors != NULL);
1568  assert(ancestors[i] != NULL);
1569  assert(revancestors[i] != NULL);
1570  assert(slp != NULL);
1571  SCIPintListNodeFree(scip, &(p->ancestors[es]));
1572  SCIP_CALL( SCIPintListNodeAppendCopy(scip, &(p->ancestors[es]), ancestors[i]) );
1573  SCIP_CALL( SCIPintListNodeAppendCopy(scip, &(p->ancestors[es]), tsancestors) );
1574  graph_edge_del(scip, p, es, FALSE);
1575 
1576  head = slp[i].knot;
1577  tail = t;
1578 
1579  p->grad[head]++;
1580  p->grad[tail]++;
1581 
1582  p->cost[es] = slp[i].outcost;
1583  p->tail[es] = tail;
1584  p->head[es] = head;
1585  p->ieat[es] = p->inpbeg[head];
1586  p->oeat[es] = p->outbeg[tail];
1587  p->inpbeg[head] = es;
1588  p->outbeg[tail] = es;
1589 
1590  es = Edge_anti(es);
1591  SCIPintListNodeFree(scip, &(p->ancestors[es]));
1592 
1593  SCIP_CALL( SCIPintListNodeAppendCopy(scip, &(p->ancestors[es]), revancestors[i]) );
1594  SCIP_CALL( SCIPintListNodeAppendCopy(scip, &(p->ancestors[es]), stancestors) );
1595  p->cost[es] = slp[i].incost;
1596  p->tail[es] = head;
1597  p->head[es] = tail;
1598  p->ieat[es] = p->inpbeg[tail];
1599  p->oeat[es] = p->outbeg[head];
1600  p->inpbeg[tail] = es;
1601  p->outbeg[head] = es;
1602  }
1603  }
1604 
1605  /* delete remaining edges */
1606  while( p->outbeg[s] != EAT_LAST )
1607  {
1608  es = p->outbeg[s];
1609  SCIPintListNodeFree(scip, &(p->ancestors[es]));
1610  SCIPintListNodeFree(scip, &(p->ancestors[Edge_anti(es)]));
1611  graph_edge_del(scip, p, es, FALSE);
1612  }
1613 
1614  SCIPintListNodeFree(scip, &stancestors);
1615  SCIPintListNodeFree(scip, &tsancestors);
1616 
1617  if( sgrad >= 2 )
1618  {
1619  assert(ancestors != NULL);
1620  assert(revancestors != NULL);
1621  for( i = 0; i < slc; i++ )
1622  {
1623  SCIPintListNodeFree(scip, &(ancestors[i]));
1624  SCIPintListNodeFree(scip, &(revancestors[i]));
1625  }
1626  SCIPfreeBufferArray(scip, &revancestors);
1627  SCIPfreeBufferArray(scip, &ancestors);
1628  SCIPfreeBufferArray(scip, &slp);
1629  }
1630  assert(p->grad[s] == 0);
1631  assert(p->outbeg[s] == EAT_LAST);
1632  assert(p->inpbeg[s] == EAT_LAST);
1633  return SCIP_OKAY;
1634 }
1635 
1636 /** subtract a given sum from the prize of a terminal */
1638  SCIP* scip, /**< SCIP data structure */
1639  GRAPH* g, /**< the graph */
1640  SCIP_Real cost, /**< cost to be subtracted */
1641  int i /**< the terminal */
1642  )
1643 {
1644  int e;
1645  int j;
1646 
1647  assert(scip != NULL);
1648  assert(g != NULL);
1649 
1650  if( g->stp_type == STP_ROOTED_PRIZE_COLLECTING && i == g->source[0] )
1651  return;
1652 
1653  g->prize[i] -= cost;
1654  for( e = g->outbeg[i]; e != EAT_LAST; e = g->oeat[e] )
1655  if( Is_pterm(g->term[g->head[e]]) )
1656  break;
1657 
1658  assert(e != EAT_LAST);
1659  assert(!g->mark[g->head[e]]);
1660 
1661  j = g->head[e];
1662 
1663  assert(j != g->source[0]);
1664 
1665  for( e = g->inpbeg[j]; e != EAT_LAST; e = g->ieat[e] )
1666  if( g->source[0] == g->tail[e] )
1667  break;
1668 
1669  assert(e != EAT_LAST);
1670  assert(!g->mark[g->tail[e]] || g->stp_type == STP_ROOTED_PRIZE_COLLECTING);
1671 
1672  g->cost[e] -= cost;
1673 
1674  assert(g->stp_type == STP_MAX_NODE_WEIGHT || SCIPisGE(scip, g->prize[i], 0.0));
1675  assert(SCIPisEQ(scip, g->prize[i], g->cost[e]));
1676 }
1677 
1678 /** contract an edge of (rooted) prize-collecting Steiner tree problem */
1680  SCIP* scip, /**< SCIP data structure */
1681  GRAPH* g, /**< the graph */
1682  int t, /**< tail node to be contracted */
1683  int s, /**< head node to be contracted */
1684  int i /**< terminal to add offset to */
1685  )
1686 {
1687  int ets;
1688 
1689  assert(g != NULL);
1690  assert(scip != NULL);
1691  assert(Is_term(g->term[i]));
1692 
1693  /* get edge from t to s */
1694  for( ets = g->outbeg[t]; ets != EAT_LAST; ets = g->oeat[ets] )
1695  if( g->head[ets] == s )
1696  break;
1697 
1698  assert(ets != EAT_LAST);
1699 
1700  /* are both endpoints of the edge to be contracted terminals? */
1701  if( Is_term(g->term[t]) && Is_term(g->term[s]) )
1702  {
1703  int e;
1704  int j;
1705 #if 0
1706  IDX* etsancestors = NULL;
1707  SCIP_CALL( SCIPintListNodeAppendCopy(scip, &etsancestors, g->ancestors[ets]) );
1708 #endif
1709  /* get edge from s to its artificial terminal */
1710  for( e = g->outbeg[s]; e != EAT_LAST; e = g->oeat[e] )
1711  if( Is_pterm(g->term[g->head[e]]) )
1712  break;
1713 
1714  assert(e != EAT_LAST);
1715  assert(g->pcancestors != NULL);
1716 #if 1
1717  if( g->pcancestors[s] != NULL )
1718  {
1719  SCIP_CALL( SCIPintListNodeAppendCopy(scip, &(g->pcancestors[t]), g->pcancestors[s]) );
1720  SCIPintListNodeFree(scip, &(g->pcancestors[s]));
1721  }
1722  SCIP_CALL( SCIPintListNodeAppendCopy(scip, &(g->pcancestors[t]), g->ancestors[ets]) );
1723 #endif
1724  /* artificial terminal to s */
1725  j = g->head[e];
1726 
1727  assert(j != g->source[0]);
1728  assert(!g->mark[j]);
1729 
1730  /* delete edge and unmark artificial terminal */
1731  graph_knot_chg(g, j, -1);
1732  graph_edge_del(scip, g, e, TRUE);
1733 
1734  /* delete remaining incident edge of artificial terminal */
1735  e = g->inpbeg[j];
1736 
1737  assert(e != EAT_LAST);
1738  assert(g->source[0] == g->tail[e] || g->source[0] == j);
1739  assert(SCIPisEQ(scip, g->prize[s], g->cost[e]));
1740 
1741  prize_subtract(scip, g, g->cost[ets] - g->prize[s], i);
1742  graph_edge_del(scip, g, e, TRUE);
1743 
1744  assert(g->inpbeg[j] == EAT_LAST);
1745 
1746  /* contract s into t */
1747  SCIP_CALL( graph_knot_contract(scip, g, t, s) );
1748  graph_knot_chg(g, s, -1);
1749 
1750  assert(g->grad[s] == 0);
1751 
1752  SCIPdebugMessage("PC contract: %d, %d \n", t, s);
1753 #if 0
1754  for( e = g->inpbeg[t]; e != EAT_LAST; e = g->ieat[e] )
1755  SCIP_CALL( SCIPintListNodeAppendCopy(scip, &(g->ancestors[e]), etsancestors) );
1756  for( e = g->outbeg[t]; e != EAT_LAST; e = g->oeat[e] )
1757  SCIP_CALL( SCIPintListNodeAppendCopy(scip, &(g->ancestors[e]), etsancestors) );
1758 
1759  SCIPintListNodeFree(scip, &etsancestors);
1760 #endif
1761  }
1762  else
1763  {
1764 #if 1
1765  if( g->pcancestors[s] != NULL )
1766  {
1767  SCIP_CALL( SCIPintListNodeAppendCopy(scip, &(g->pcancestors[t]), g->pcancestors[s]) );
1768  SCIPintListNodeFree(scip, &(g->pcancestors[s]));
1769  }
1770  SCIP_CALL( SCIPintListNodeAppendCopy(scip, &(g->pcancestors[t]), g->ancestors[ets]) );
1771 #endif
1772 
1773  if( g->stp_type != STP_MAX_NODE_WEIGHT )
1774  prize_subtract(scip, g, g->cost[ets], i);
1775  else
1776  prize_subtract(scip, g, -(g->prize[s]), i);
1777  SCIP_CALL( graph_knot_contract(scip, g, t, s) );
1778 
1779  }
1780  return SCIP_OKAY;
1781 }
1782 
1784  SCIP* scip, /**< SCIP data structure */
1785  GRAPH* g, /**< the graph */
1786  int eki, /**< the edge */
1787  int k, /**< new tail */
1788  int j, /**< new head */
1789  SCIP_Real cost /**< new cost */
1790  )
1791 {
1792  int e;
1793 
1794  graph_edge_del(NULL, g, eki, FALSE);
1795 
1796  for( e = g->outbeg[k]; e != EAT_LAST; e = g->oeat[e] )
1797  if( (g->tail[e] == k) && (g->head[e] == j) )
1798  break;
1799 
1800  /* does edge already exist? */
1801  if( e != EAT_LAST )
1802  {
1803  /* correct cost */
1804  if( SCIPisGT(scip, g->cost[e], cost) )
1805  {
1806  g->cost[e] = cost;
1807  g->cost[Edge_anti(e)] = cost;
1808  }
1809  else
1810  {
1811  e = -1;
1812  }
1813  }
1814  else
1815  {
1816  assert(g->oeat[eki] == EAT_FREE);
1817 
1818  e = eki;
1819 
1820  g->grad[k]++;
1821  g->grad[j]++;
1822 
1823  g->cost[e] = cost;
1824  g->head[e] = j;
1825  g->tail[e] = k;
1826  g->ieat[e] = g->inpbeg[j];
1827  g->oeat[e] = g->outbeg[k];
1828  g->inpbeg[j] = e;
1829  g->outbeg[k] = e;
1830 
1831  e = Edge_anti(eki);
1832 
1833  g->cost[e] = cost;
1834  g->head[e] = k;
1835  g->tail[e] = j;
1836  g->ieat[e] = g->inpbeg[k];
1837  g->oeat[e] = g->outbeg[j];
1838  g->inpbeg[k] = e;
1839  g->outbeg[j] = e;
1840  return eki;
1841  }
1842  return e;
1843 }
1844 
1845 /** reinsert an edge to replace two other edges */
1846 SCIP_RETCODE graph_edge_reinsert(
1847  SCIP* scip, /**< SCIP data structure */
1848  GRAPH* g, /**< the graph */
1849  int e1, /**< edge to reinsert */
1850  int k1, /**< tail */
1851  int k2, /**< head */
1852  SCIP_Real cost, /**< edgecost */
1853  IDX* ancestors0, /**< ancestors of first edge */
1854  IDX* ancestors1, /**< ancestors of second edge */
1855  IDX* revancestors0, /**< reverse ancestors of first edge */
1856  IDX* revancestors1 /**< reverse ancestors of first edge */
1857  )
1858 {
1859  int n1;
1860 
1861  /* redirect; store new edge in n1 */
1862  n1 = graph_edge_redirect(scip, g, e1, k1, k2, cost);
1863  if( n1 >= 0 )
1864  {
1865  SCIPintListNodeFree(scip, &(g->ancestors[n1]));
1866  SCIPintListNodeFree(scip, &(g->ancestors[Edge_anti(n1)]));
1867 
1868  SCIP_CALL( SCIPintListNodeAppendCopy(scip, &(g->ancestors[n1]), revancestors0) );
1869  SCIP_CALL( SCIPintListNodeAppendCopy(scip, &(g->ancestors[n1]), ancestors1) );
1870 
1871  SCIP_CALL( SCIPintListNodeAppendCopy(scip, &(g->ancestors[Edge_anti(n1)]), ancestors0) );
1872  SCIP_CALL( SCIPintListNodeAppendCopy(scip, &(g->ancestors[Edge_anti(n1)]), revancestors1) );
1873  }
1874  return SCIP_OKAY;
1875 }
1876 
1877 
1878 /** add a new edge to the graph */
1880  SCIP* scip, /**< SCIP data structure */
1881  GRAPH* g, /**< the graph */
1882  int tail, /**< tail of the new edge */
1883  int head, /**< head of the new edge*/
1884  SCIP_Real cost1, /**< tail to head cost */
1885  SCIP_Real cost2 /**< head to tail cost */
1886  )
1887 {
1888  int e;
1889 
1890  assert(g != NULL);
1891  assert(SCIPisGE(scip, cost1, 0.0) || SCIPisEQ(scip, cost1, (double) UNKNOWN));
1892  assert(SCIPisGE(scip, cost2, 0.0) || SCIPisEQ(scip, cost2, (double) UNKNOWN));
1893  assert(tail >= 0);
1894  assert(tail < g->knots);
1895  assert(head >= 0);
1896  assert(head < g->knots);
1897 
1898  assert(g->esize >= g->edges + 2);
1899 
1900  e = g->edges;
1901 
1902  g->grad[head]++;
1903  g->grad[tail]++;
1904 
1905  if( cost1 != UNKNOWN )
1906  g->cost[e] = cost1;
1907  g->tail[e] = tail;
1908  g->head[e] = head;
1909  g->ieat[e] = g->inpbeg[head];
1910  g->oeat[e] = g->outbeg[tail];
1911  g->inpbeg[head] = e;
1912  g->outbeg[tail] = e;
1913 
1914  e++;
1915 
1916  if( cost2 != UNKNOWN )
1917  g->cost[e] = cost2;
1918  g->tail[e] = head;
1919  g->head[e] = tail;
1920  g->ieat[e] = g->inpbeg[tail];
1921  g->oeat[e] = g->outbeg[head];
1922  g->inpbeg[tail] = e;
1923  g->outbeg[head] = e;
1924 
1925  g->edges += 2;
1926 }
1927 
1928 inline static void edge_remove(
1929  GRAPH* g, /**< the graph */
1930  int e /**< the edge to be removed */
1931  )
1932 {
1933  int i;
1934  int head;
1935  int tail;
1936 
1937  assert(g != NULL);
1938  assert(e >= 0);
1939  assert(e < g->edges);
1940 
1941  head = g->head[e];
1942  tail = g->tail[e];
1943 
1944  if( g->inpbeg[head] == e )
1945  g->inpbeg[head] = g->ieat[e];
1946  else
1947  {
1948  for( i = g->inpbeg[head]; g->ieat[i] != e; i = g->ieat[i] )
1949  assert(i >= 0);
1950 
1951  g->ieat[i] = g->ieat[e];
1952  }
1953  if( g->outbeg[tail] == e )
1954  g->outbeg[tail] = g->oeat[e];
1955  else
1956  {
1957  for( i = g->outbeg[tail]; g->oeat[i] != e; i = g->oeat[i] )
1958  assert(i >= 0);
1959 
1960  g->oeat[i] = g->oeat[e];
1961  }
1962 }
1963 
1964 /** delete an edge */
1966  SCIP* scip, /**< SCIP data structure */
1967  GRAPH* g, /**< the graph */
1968  int e, /**< the edge */
1969  SCIP_Bool freeancestors /**< free edge ancestors? */
1970  )
1971 {
1972  assert(g != NULL);
1973  assert(e >= 0);
1974  assert(e < g->edges);
1975 
1976  if( freeancestors )
1977  {
1978  assert(scip != NULL);
1979  SCIPintListNodeFree(scip, &((g->ancestors)[e]));
1980  SCIPintListNodeFree(scip, &((g->ancestors)[Edge_anti(e)]));
1981  }
1982 
1983  /* delete first arc */
1984  e -= e % 2;
1985  assert(g->head[e] == g->tail[e + 1]);
1986  assert(g->tail[e] == g->head[e + 1]);
1987 
1988  g->grad[g->head[e]]--;
1989  g->grad[g->tail[e]]--;
1990 
1991  edge_remove(g, e);
1992 
1993  assert(g->ieat[e] != EAT_FREE);
1994  assert(g->ieat[e] != EAT_HIDE);
1995  assert(g->oeat[e] != EAT_FREE);
1996  assert(g->oeat[e] != EAT_HIDE);
1997 
1998  g->ieat[e] = EAT_FREE;
1999  g->oeat[e] = EAT_FREE;
2000 
2001  /* delete second arc */
2002  e++;
2003  edge_remove(g, e);
2004 
2005  assert(g->ieat[e] != EAT_FREE);
2006  assert(g->ieat[e] != EAT_HIDE);
2007  assert(g->oeat[e] != EAT_FREE);
2008  assert(g->oeat[e] != EAT_HIDE);
2009 
2010  g->ieat[e] = EAT_FREE;
2011  g->oeat[e] = EAT_FREE;
2012 }
2013 
2014 /** hide edge */
2016  GRAPH* g, /**< the graph */
2017  int e /**< the edge */
2018  )
2019 {
2020  assert(g != NULL);
2021  assert(e >= 0);
2022  assert(e < g->edges);
2023 
2024  /* Immer mit der ersten von beiden Anfangen
2025  */
2026  e -= e % 2;
2027 
2028  assert(g->head[e] == g->tail[e + 1]);
2029  assert(g->tail[e] == g->head[e + 1]);
2030 
2031  g->grad[g->head[e]]--;
2032  g->grad[g->tail[e]]--;
2033 
2034  edge_remove(g, e);
2035 
2036  assert(g->ieat[e] != EAT_FREE);
2037  assert(g->ieat[e] != EAT_HIDE);
2038  assert(g->oeat[e] != EAT_FREE);
2039  assert(g->oeat[e] != EAT_HIDE);
2040 
2041  g->ieat[e] = EAT_HIDE;
2042  g->oeat[e] = EAT_HIDE;
2043 
2044  e++;
2045 
2046  edge_remove(g, e);
2047 
2048  assert(g->ieat[e] != EAT_FREE);
2049  assert(g->ieat[e] != EAT_HIDE);
2050  assert(g->oeat[e] != EAT_FREE);
2051  assert(g->oeat[e] != EAT_HIDE);
2052 
2053  g->ieat[e] = EAT_HIDE;
2054  g->oeat[e] = EAT_HIDE;
2055 }
2056 
2057 /** reinsert all hidden edges */
2059  GRAPH* g /**< the graph */
2060  )
2061 {/*lint --e{850}*/
2062  int head;
2063  int tail;
2064  int e;
2065 
2066  assert(g != NULL);
2067 
2068  for( e = 0; e < g->edges; e++ )
2069  {
2070  if( g->ieat[e] == EAT_HIDE )
2071  {
2072  assert(e % 2 == 0);
2073  assert(g->oeat[e] == EAT_HIDE);
2074 
2075  head = g->head[e];
2076  tail = g->tail[e];
2077 
2078  g->grad[head]++;
2079  g->grad[tail]++;
2080 
2081  g->ieat[e] = g->inpbeg[head];
2082  g->oeat[e] = g->outbeg[tail];
2083  g->inpbeg[head] = e;
2084  g->outbeg[tail] = e;
2085 
2086  e++;
2087 
2088  assert(g->ieat[e] == EAT_HIDE);
2089  assert(g->oeat[e] == EAT_HIDE);
2090  assert(g->head[e] == tail);
2091  assert(g->tail[e] == head);
2092 
2093  head = g->head[e];
2094  tail = g->tail[e];
2095  g->ieat[e] = g->inpbeg[head];
2096  g->oeat[e] = g->outbeg[tail];
2097  g->inpbeg[head] = e;
2098  g->outbeg[tail] = e;
2099  }
2100  }
2101 }
2102 
2103 /** mark terminals and switch terminal property to original terminals */
2104 SCIP_RETCODE pcgraphorg(
2105  SCIP* scip, /**< SCIP data structure */
2106  GRAPH* graph /**< the graph */
2107  )
2108 {
2109  int k;
2110  int root;
2111  int nnodes;
2112 
2113  assert(scip != NULL);
2114  assert(graph != NULL);
2115 
2116  root = graph->source[0];
2117  nnodes = graph->knots;
2118 
2119  for( k = 0; k < nnodes; k++ )
2120  {
2121  graph->mark[k] = (graph->grad[k] > 0);
2122 
2123  if( Is_pterm(graph->term[k]) )
2124  {
2125  graph_knot_chg(graph, k, 0);
2126  }
2127  else if( Is_term(graph->term[k]) )
2128  {
2129  graph->mark[k] = FALSE;
2130  if( k != root )
2131  graph_knot_chg(graph, k, -2);
2132  }
2133  }
2134 
2135  if( graph->stp_type == STP_ROOTED_PRIZE_COLLECTING )
2136  graph->mark[root] = TRUE;
2137 
2138  return SCIP_OKAY;
2139 }
2140 
2141 /** unmark terminals and switch terminal property to transformed terminals */
2142 SCIP_RETCODE pcgraphtrans(
2143  SCIP* scip, /**< SCIP data structure */
2144  GRAPH* graph /**< the graph */
2145  )
2146 {
2147  int k;
2148  int root;
2149  int nnodes;
2150 
2151  assert(scip != NULL);
2152  assert(graph != NULL);
2153 
2154  root = graph->source[0];
2155  nnodes = graph->knots;
2156 
2157  for( k = 0; k < nnodes; k++ )
2158  {
2159  graph->mark[k] = (graph->grad[k] > 0);
2160 
2161  if( Is_pterm(graph->term[k]) )
2162  graph_knot_chg(graph, k, 0);
2163  else if( Is_term(graph->term[k]) && k != root )
2164  graph_knot_chg(graph, k, -2);
2165  }
2166 
2167  return SCIP_OKAY;
2168 }
2169 #if 0
2170 GRAPH *graph_pack2(
2171  SCIP* scip,
2172  GRAPH* p,
2173  SCIP_Bool verbose)
2174 {
2175  const char* msg1 = "Knots: %d Edges: %d Terminals: %d\n";
2176  SCIP_RETCODE rcode;
2177  GRAPH* q;
2178  int* new;
2179  int knots = 0;
2180  int edges = 0;
2181  int i;
2182  int l;
2183 
2184  assert(p != NULL);
2185  assert(graph_valid(p));
2186  if( verbose )
2187  printf("Packing graph: ");
2188  printf("Packing graph: \n ");
2189  new = malloc((size_t)p->knots * sizeof(new[0]));
2190 
2191  assert(new != NULL);
2192 
2193  /* Knoten zaehlen
2194  */
2195  for(i = 0; i < p->knots; i++)
2196  {
2197  new[i] = knots;
2198 
2199  /* Hat der Knoten noch Kanten ?
2200  */
2201  if (p->grad[i] > 0)
2202  knots++;
2203  else
2204  new[i] = -1;
2205  }
2206 
2207  /* Ist ueberhaupt noch ein Graph vorhanden ?
2208  */
2209  if (knots == 0)
2210  {
2211  free(new);
2212  new = NULL;
2213  if( verbose )
2214  printf(" graph vanished!\n");
2215 
2216  knots = 1;
2217  }
2218 
2219  /* Kanten zaehlen
2220  */
2221  for(i = 0; i < p->edges; i++)
2222  {
2223  if (p->oeat[i] != EAT_FREE)
2224  {
2225  assert(p->ieat[i] != EAT_FREE);
2226  edges++;
2227  }
2228  }
2229  if( knots == 1 )
2230  assert(edges == 0);
2231  rcode = graph_init(scip, &q, knots, edges, p->layers, p->flags);
2234  q->orgtail = p->orgtail;
2235  q->orghead = p->orghead;
2236  q->orgknots = p->knots;
2237  q->orgedges = p->edges;
2238  q->stp_type = p->stp_type;
2239  q->maxdeg = p->maxdeg;
2240  q->grid_dim = p->grid_dim;
2241  q->grid_ncoords = p->grid_ncoords;
2243  q->fixedges = p->fixedges;
2244  /*SCIP_CALL( SCIPintListNodeAppendCopy(scip, &(q->fixedges), p->fixedges);*/
2245 
2246  q->hoplimit = p->hoplimit;
2247  if( new == NULL )
2248  {
2249  q->ancestors = NULL;
2250  graph_free(scip, p, FALSE);
2251  graph_knot_add(q, 0);
2252  q->source[0] = 0;
2253  return q;
2254  }
2255 
2256  q->ancestors = malloc((size_t)(edges) * sizeof(IDX*));
2257  for( i = 0; i < edges; i++ )
2258  q->ancestors[i] = NULL;
2259 
2260  /* Knoten umladen
2261  */
2262  for(i = 0; i < p->knots; i++)
2263  {
2264  assert(p->term[i] < p->layers);
2265 #if 0
2266  if ((i % 100) == 0)
2267  {
2268  (void)fputc('k', stdout);
2269  (void)fflush(stdout);
2270  }
2271 #endif
2272  if( p->grad[i] > 0 )
2273  graph_knot_add(q, p->term[i]);
2274  }
2275 
2276  /* Kanten umladen
2277  */
2278  for( i = 0; i < p->edges; i += 2 )
2279  {
2280 #if 0
2281  if ((i % 1000) == 0)
2282  {
2283  (void)fputc('e', stdout);
2284  (void)fflush(stdout);
2285  }
2286 #endif
2287  if (p->ieat[i] == EAT_FREE)
2288  {
2289  assert(p->oeat[i] == EAT_FREE);
2290  assert(p->ieat[i + 1] == EAT_FREE);
2291  assert(p->oeat[i + 1] == EAT_FREE);
2292  SCIPintListNodeFree(scip, &(p->ancestors[i]));
2293  SCIPintListNodeFree(scip, &(p->ancestors[i + 1]));
2294  continue;
2295  }
2296  assert(p->ieat[i] != EAT_FREE);
2297  assert(p->oeat[i] != EAT_FREE);
2298  assert(p->ieat[i + 1] != EAT_FREE);
2299  assert(p->oeat[i + 1] != EAT_FREE);
2300  assert(new[p->tail[i]] >= 0);
2301  assert(new[p->head[i]] >= 0);
2302 
2303  rcode = SCIPintListNodeAppendCopy(scip, &(q->ancestors[q->edges]), p->ancestors[i]);
2304  rcode = SCIPintListNodeAppendCopy(scip, &(q->ancestors[q->edges + 1]), p->ancestors[i + 1]);
2305  graph_edge_add(scip, q, new[p->tail[i]], new[p->head[i]],
2306  p->cost[i], p->cost[Edge_anti(i)]);
2307 
2308 
2309  }
2310 
2311  /* Wurzeln umladen
2312  */
2313  for(l = 0; l < q->layers; l++)
2314  {
2315  assert(q->term[new[p->source[l]]] == l);
2316  q->source[l] = new[p->source[l]];
2317  }
2318 
2319  free(new);
2320 
2321  p->stp_type = UNKNOWN;
2322  graph_free(scip, p, FALSE);
2323 
2324 #if 0
2325  for(l = 0; l < q->layers; l++)
2326  q->source[l] = -1;
2327 
2328  for(i = 0; i < q->knots; i++)
2329  if ((q->term[i] >= 0) && ((q->source[q->term[i]] < 0)
2330  || (q->grad[i] > q->grad[q->source[q->term[i]]])))
2331  q->source[q->term[i]] = i;
2332 #endif
2333  assert(q->source[0] >= 0);
2334  if( verbose )
2335  printf(msg1, q->knots, q->edges, q->terms);
2336 
2337  return(q);
2338 }
2339 #endif
2340 
2341 /** pack the graph, i.e. build a new graph that discards deleted edges and nodes */
2342 SCIP_RETCODE graph_pack(
2343  SCIP* scip, /**< SCIP data structure */
2344  GRAPH* graph, /**< the graph */
2345  GRAPH** newgraph, /**< the new graph */
2346  SCIP_Bool verbose /**< verbose? */
2347  )
2348 {
2349  const char* msg1 = "Nodes: %d Edges: %d Terminals: %d\n";
2350  GRAPH* g;
2351  GRAPH* q;
2352  int* new;
2353  int i;
2354  int nnodes;
2355  int nedges;
2356  SCIP_Bool pcmw;
2357 
2358  assert(scip != NULL);
2359  assert(graph != NULL);
2360  assert(graph_valid(graph));
2361 
2362  g = graph;
2363  nnodes = 0;
2364  nedges = 0;
2365  SCIP_CALL( SCIPallocBufferArray(scip, &new, g->knots) );
2366 
2367  if( verbose )
2368  printf("Reduced graph: ");
2369 
2370  /* count nodes */
2371  for( i = 0; i < g->knots; i++ )
2372  {
2373  /* are there incident edges to current node? */
2374  if( g->grad[i] > 0 )
2375  new[i] = nnodes++;
2376  else
2377  new[i] = -1;
2378  }
2379 
2380  /* graph vanished? */
2381  if( nnodes == 0 )
2382  {
2383  SCIPfreeBufferArray(scip, &new);
2384  new = NULL;
2385  if( verbose )
2386  printf(" graph vanished!\n");
2387 
2388  nnodes = 1;
2389  }
2390 
2391  /* count edges */
2392  for( i = 0; i < g->edges; i++ )
2393  {
2394  if( g->oeat[i] != EAT_FREE )
2395  {
2396  assert(g->ieat[i] != EAT_FREE);
2397  nedges++;
2398  }
2399  }
2400 
2401  assert(nnodes > 1 || nedges == 0);
2402  SCIP_CALL( graph_init(scip, newgraph, nnodes, nedges, g->layers, g->flags) );
2403  q = *newgraph;
2406  q->orgtail = g->orgtail;
2407  q->orghead = g->orghead;
2408  q->orgknots = g->knots;
2409  q->orgedges = g->edges;
2410  q->stp_type = g->stp_type;
2411  q->maxdeg = g->maxdeg;
2412  q->grid_dim = g->grid_dim;
2413  q->grid_ncoords = g->grid_ncoords;
2415  q->fixedges = g->fixedges;
2416  q->hoplimit = g->hoplimit;
2417  q->pcancestors = g->pcancestors;
2418 
2419  if( new == NULL )
2420  {
2421  q->ancestors = NULL;
2422  graph_free(scip, g, FALSE);
2423  graph_knot_add(q, 0);
2424  q->source[0] = 0;
2425  return SCIP_OKAY;
2426  }
2427 
2428  SCIP_CALL( SCIPallocMemoryArray(scip, &(q->ancestors), nedges) );
2430  if( pcmw )
2431  {
2432  SCIP_CALL( SCIPallocMemoryArray(scip, &(q->prize), nnodes) );
2433  }
2434 
2435  for( i = 0; i < nedges; i++ )
2436  q->ancestors[i] = NULL;
2437 #if 0
2438  if( pcmw )
2439  {
2440  SCIP_CALL( SCIPallocMemoryArray(scip, &(q->pcancestors), nedges) );
2441  for( i = 0; i < nnodes; i++ )
2442  q->pcancestors[i] = NULL;
2443  }
2444 #endif
2445 
2446  /* add nodes (of positive degree) */
2447  for( i = 0; i < g->knots; i++ )
2448  {
2449  assert(g->term[i] < g->layers);
2450  if( g->grad[i] > 0 )
2451  {
2452 #if 0
2453  if( pcmw )
2454  SCIP_CALL( SCIPintListNodeAppendCopy(scip, &(q->pcancestors[q->knots]), g->pcancestors[i]) );
2455 #endif
2456  if( pcmw )
2457  {
2458  if( !Is_term(g->term[i]) )
2459  q->prize[q->knots] = g->prize[i];
2460  else
2461  q->prize[q->knots] = 0.0;
2462  }
2463  graph_knot_add(q, g->term[i]);
2464  }
2465  }
2466 
2467  /* add edges */
2468  for( i = 0; i < g->edges; i += 2 )
2469  {
2470  if( g->ieat[i] == EAT_FREE )
2471  {
2472  assert(g->oeat[i] == EAT_FREE);
2473  assert(g->ieat[i + 1] == EAT_FREE);
2474  assert(g->oeat[i + 1] == EAT_FREE);
2475  SCIPintListNodeFree(scip, &(g->ancestors[i]));
2476  SCIPintListNodeFree(scip, &(g->ancestors[i + 1]));
2477  continue;
2478  }
2479  assert(g->ieat[i] != EAT_FREE);
2480  assert(g->oeat[i] != EAT_FREE);
2481  assert(g->ieat[i + 1] != EAT_FREE);
2482  assert(g->oeat[i + 1] != EAT_FREE);
2483  assert(new[g->tail[i]] >= 0);
2484  assert(new[g->head[i]] >= 0);
2485 
2486  SCIP_CALL( SCIPintListNodeAppendCopy(scip, &(q->ancestors[q->edges]), g->ancestors[i]) );
2487  SCIP_CALL( SCIPintListNodeAppendCopy(scip, &(q->ancestors[q->edges + 1]), g->ancestors[i + 1]) );
2488 
2489  graph_edge_add(scip, q, new[g->tail[i]], new[g->head[i]], g->cost[i], g->cost[Edge_anti(i)]);
2490  }
2491 
2492  /* add root */
2493  assert(q->term[new[g->source[0]]] == 0);
2494  q->source[0] = new[g->source[0]];
2496  q->prize[q->source[0]] = FARAWAY;
2497  SCIPfreeBufferArray(scip, &new);
2498 
2499  g->stp_type = UNKNOWN;
2500  graph_free(scip, g, FALSE);
2501 
2502  assert(q->source[0] >= 0);
2503  if( verbose )
2504  printf(msg1, q->knots, q->edges, q->terms);
2505 
2506  return SCIP_OKAY;
2507 }
2508 
2509 /** traverse the graph */
2511  const GRAPH* p, /**< the new graph */
2512  int i /**< node to start from */
2513  )
2514 {
2515  int k;
2516 
2517  assert(p != NULL);
2518  assert(i >= 0);
2519  assert(i < p->knots);
2520 
2521  if( !p->mark[i] )
2522  {
2523  p->mark[i] = TRUE;
2524 
2525  for( k = p->outbeg[i]; k != EAT_LAST; k = p->oeat[k] )
2526  if (!p->mark[p->head[k]])
2527  graph_trail(p, p->head[k]);
2528  }
2529 }
2530 
2531 /** is the graph valid? */
2533  const GRAPH* p /**< the new graph */
2534  )
2535 {
2536  const char* fehler1 = "*** Graph Validation Error: Head invalid, Knot %d, Edge %d, Tail=%d, Head=%d\n";
2537  const char* fehler2 = "*** Graph Validation Error: Tail invalid, Knot %d, Edge %d, Tail=%d, Head=%d\n";
2538  const char* fehler3 = "*** Graph Validation Error: Source invalid, Layer %d, Source %d, Terminal %d\n";
2539  const char* fehler4 = "*** Graph Validation Error: FREE invalid, Edge %d/%d\n";
2540  const char* fehler5 = "*** Graph Validation Error: Anti invalid, Edge %d/%d, Tail=%d/%d, Head=%d/%d\n";
2541  const char* fehler6 = "*** Graph Validation Error: Knot %d with Grad 0 has Edges\n";
2542  const char* fehler7 = "*** Graph Validation Error: Knot %d not connected\n";
2543 #if 0
2544  const char* fehler8 = "*** Graph Validation Error: Wrong locals count, Layer %d, count is %d, should be %d\n";
2545 #endif
2546  const char* fehler9 = "*** Graph Validation Error: Wrong Terminal count, count is %d, should be %d\n";
2547 
2548  int k;
2549  int l;
2550  int e;
2551  int terms;
2552 #if 0
2553  int* locals;
2554  locals = malloc((size_t)p->layers * sizeof(int));
2555  assert(locals != NULL);
2556  for( l = 0; l < p->layers; l++ )
2557  locals[l] = p->locals[l];
2558 #endif
2559  assert(p != NULL);
2560 
2561  terms = p->terms;
2562 
2563  for( k = 0; k < p->knots; k++ )
2564  {
2565  if( Is_term(p->term[k]) )
2566  {
2567 #if 0
2568  locals[p->term[k]]--;
2569 #endif
2570  terms--;
2571  }
2572  for( e = p->inpbeg[k]; e != EAT_LAST; e = p->ieat[e] )
2573  if( p->head[e] != k )
2574  break;
2575 
2576  if( e != EAT_LAST )
2577  return((void)fprintf(stderr, fehler1, k, e, p->tail[e], p->head[e]), FALSE);
2578 
2579  for( e = p->outbeg[k]; e != EAT_LAST; e = p->oeat[e] )
2580  if( p->tail[e] != k )
2581  break;
2582 
2583  if( e != EAT_LAST )
2584  return((void)fprintf(stderr, fehler2, k, e, p->tail[e], p->head[e]), FALSE);
2585  }
2586  if( terms != 0 )
2587  return((void)fprintf(stderr, fehler9, p->terms, p->terms - terms), FALSE);
2588 
2589  for( l = 0; l < p->layers; l++ )
2590  {
2591 #if 0
2592  if( locals[l] != 0 )
2593  return((void)fprintf(stderr, fehler8,
2594  l, p->locals[l], p->locals[l] - locals[l]), FALSE);
2595 #endif
2596  if( (p->source[l] < 0 )
2597  || (p->source[l] >= p->knots)
2598  || (p->term[p->source[l]] != l))
2599  return((void)fprintf(stderr, fehler3,
2600  l, p->source[l], p->term[p->source[l]]), FALSE);
2601  }
2602 #if 0
2603  free(locals);
2604 #endif
2605  for( e = 0; e < p->edges; e += 2 )
2606  {
2607  if( (p->ieat[e ] == EAT_FREE) && (p->oeat[e ] == EAT_FREE)
2608  && (p->ieat[e + 1] == EAT_FREE) && (p->oeat[e + 1] == EAT_FREE) )
2609  continue;
2610 
2611  if( (p->ieat[e] == EAT_FREE) || (p->oeat[e] == EAT_FREE)
2612  || (p->ieat[e + 1] == EAT_FREE) || (p->oeat[e + 1] == EAT_FREE) )
2613  return((void)fprintf(stderr, fehler4, e, e + 1), FALSE);
2614 
2615  if( (p->head[e] != p->tail[e + 1]) || (p->tail[e] != p->head[e + 1]) )
2616  return((void)fprintf(stderr, fehler5,
2617  e, e + 1, p->head[e], p->tail[e + 1],
2618  p->tail[e], p->head[e + 1]), FALSE);
2619 
2620  }
2621  for( k = 0; k < p->knots; k++ )
2622  p->mark[k] = FALSE;
2623 
2624  graph_trail(p, p->source[0]);
2625 
2626  for( k = 0; k < p->knots; k++ )
2627  {
2628  if( (p->grad[k] == 0)
2629  && ((p->inpbeg[k] != EAT_LAST) || (p->outbeg[k] != EAT_LAST)) )
2630  return((void)fprintf(stderr, fehler6, k), FALSE);
2631 
2632  if( !p->mark[k] && (p->grad[k] > 0) && p->stp_type != STP_PRIZE_COLLECTING && p->stp_type != STP_MAX_NODE_WEIGHT )
2633  return((void)fprintf(stderr, fehler7, k), FALSE);
2634  }
2635  return TRUE;
2636 }
2637 
2638 /** verifies whether a given primal solution is feasible */
2640  SCIP* scip, /**< SCIP data structure */
2641  const GRAPH* graph, /**< graph data structure */
2642  int* result /**< solution array, indicating whether an edge is in the solution */
2643  )
2644 {
2645  SCIP_QUEUE* queue;
2646 
2647  char* terminal;
2648  int* pnode;
2649  int e;
2650  int i;
2651  int root;
2652  int nnodes;
2653  int termcount;
2654  assert(graph != NULL);
2655  assert(result != NULL);
2656  nnodes = graph->knots;
2657  root = graph->source[0];
2658  assert(root >= 0);
2659 
2660  SCIP_CALL_ABORT( SCIPallocBufferArray(scip, &terminal, nnodes) );
2661  for( i = 0; i < nnodes; i++ )
2662  terminal[i] = FALSE;
2663  /* BFS until all terminals are reached */
2664  SCIP_CALL_ABORT( SCIPqueueCreate(&queue, nnodes, 2.0) );
2665 
2666  SCIP_CALL_ABORT( SCIPqueueInsert(queue, &root) );
2667  termcount = 1;
2668  terminal[root] = TRUE;
2669 
2670  while( !SCIPqueueIsEmpty(queue) )
2671  {
2672  pnode = (SCIPqueueRemove(queue));
2673  for( e = graph->outbeg[*pnode]; e != EAT_LAST; e = graph->oeat[e] )
2674  {
2675 
2676  if( result[e] == CONNECT )
2677  {
2678  i = graph->head[e];
2679  if( Is_term(graph->term[i]) )
2680  {
2681  assert(!terminal[i]);
2682  terminal[i] = TRUE;
2683  termcount++;
2684  }
2685  SCIP_CALL_ABORT( SCIPqueueInsert(queue, &graph->head[e]) );
2686  }
2687  }
2688 
2689  }
2690 
2691  if( termcount != graph->terms )
2692  {
2693  for( i = 0; i < nnodes; i++ )
2694  if( Is_term(graph->term[i]) && !terminal[i] )
2695  SCIPdebugMessage("not reached, node: %d\n", i);
2696  SCIPdebugMessage("a: %d, b: %d: \n", termcount, graph->terms);
2697  }
2698 
2699  SCIPfreeBufferArray(scip, &terminal);
2700  SCIPqueueFree(&queue);
2701 
2702  return (termcount == graph->terms);
2703 }
2704 
2705 
2707  SCIP* scip,
2708  const GRAPH* graph,
2709  SCIP_Real* cost
2710  )
2711 {
2712  SCIP_QUEUE* queue;
2713 
2714  char* terminal;
2715  char* reached;
2716  int* pnode;
2717  int e;
2718  int i;
2719  int root;
2720  int nnodes;
2721  int termcount;
2722  assert(graph != NULL);
2723  assert(cost != NULL);
2724  nnodes = graph->knots;
2725  root = graph->source[0];
2726  assert(root >= 0);
2727 
2728  SCIP_CALL_ABORT( SCIPallocBufferArray(scip, &terminal, nnodes) );
2729  SCIP_CALL_ABORT( SCIPallocBufferArray(scip, &reached, nnodes) );
2730  for( i = 0; i < nnodes; i++ )
2731  {
2732  terminal[i] = FALSE;
2733  reached[i] = FALSE;
2734  }
2735  /* BFS until all terminals are reached */
2736  SCIP_CALL_ABORT( SCIPqueueCreate(&queue, nnodes, 2.0) );
2737 
2738  SCIP_CALL_ABORT( SCIPqueueInsert(queue, &root) );
2739  termcount = 1;
2740  terminal[root] = TRUE;
2741  reached[root] = TRUE;
2742  while( !SCIPqueueIsEmpty(queue) )
2743  {
2744  pnode = (SCIPqueueRemove(queue));
2745  for( e = graph->outbeg[*pnode]; e != EAT_LAST; e = graph->oeat[e] )
2746  {
2747  if( SCIPisLT(scip, cost[e], BLOCKED) && !reached[graph->head[e]] )
2748  {
2749  i = graph->head[e];
2750  reached[i] = TRUE;
2751  if( Is_term(graph->term[i]) )
2752  {
2753  assert(!terminal[i]);
2754  terminal[i] = TRUE;
2755  termcount++;
2756  }
2757  SCIP_CALL_ABORT( SCIPqueueInsert(queue, &graph->head[e]) );
2758  }
2759  }
2760  }
2761  SCIPfreeBufferArray(scip, &reached);
2762  SCIPfreeBufferArray(scip, &terminal);
2763  SCIPqueueFree(&queue);
2764  if (termcount != graph->terms)
2765  {
2766  for( i = 0; i < nnodes; i++ )
2767  if( Is_term(graph->term[i]) && !terminal[i] )
2768  printf("not reached, node: %d\n", i);
2769  return FALSE;
2770  }
2771 
2772  return (termcount == graph->terms);
2773 }
#define Is_term(a)
Definition: grph.h:158
SCIP_RETCODE graph_MwcsToSap(SCIP *scip, GRAPH *graph, SCIP_Real *maxweights)
Definition: grphbase.c:1079
int * orgtail
Definition: grph.h:95
SCIP_RETCODE graph_copy(SCIP *scip, GRAPH *orgraph, GRAPH **copygraph)
Definition: grphbase.c:1228
Definition: grph.h:55
SCIP_RETCODE graph_knot_contract(SCIP *scip, GRAPH *p, int t, int s)
Definition: grphbase.c:1415
#define TRUE
Definition: portab.h:34
SCIP_RETCODE graph_grid_create(SCIP *scip, GRAPH **gridgraph, int **coords, int nterms, int grid_dim, int scale_order)
Definition: grphbase.c:535
int * path_heap
Definition: grph.h:114
int terms
Definition: grph.h:63
int * mincut_r
Definition: grph.h:111
void graph_ident(const GRAPH *p)
Definition: grphbase.c:1341
int norgmodeledges
Definition: grph.h:85
#define EAT_LAST
Definition: grph.h:31
#define Edge_anti(a)
Definition: grph.h:161
SCIP_RETCODE pcgraphorg(SCIP *scip, GRAPH *graph)
Definition: grphbase.c:2104
#define BLOCKED
Definition: grph.h:150
void graph_uncover(GRAPH *g)
Definition: grphbase.c:2058
static int getNodeNumber(int grid_dim, int shiftcoord, int *ncoords, int *currcoord)
Definition: grphbase.c:237
int * path_state
Definition: grph.h:115
char graph_valid2(SCIP *scip, const GRAPH *graph, SCIP_Real *cost)
Definition: grphbase.c:2706
int flags
Definition: grph.h:59
SCIP_RETCODE graph_PcSapCopy(SCIP *scip, GRAPH *graph, GRAPH **newgraph, SCIP_Real *offset)
Definition: grphbase.c:792
int * oeat
Definition: grph.h:100
SCIP_RETCODE graph_maxweight_transform(SCIP *scip, GRAPH *graph, SCIP_Real *maxweights)
Definition: grphbase.c:1020
#define STP_GRID
Definition: grph.h:45
int * head
Definition: grph.h:94
SCIP_RETCODE graph_pack(SCIP *scip, GRAPH *graph, GRAPH **newgraph, SCIP_Bool verbose)
Definition: grphbase.c:2342
IDX * fixedges
Definition: grph.h:82
#define STP_OBSTACLES_GRID
Definition: grph.h:46
SCIP_RETCODE graph_edge_reinsert(SCIP *scip, GRAPH *g, int e1, int k1, int k2, SCIP_Real cost, IDX *ancestors0, IDX *ancestors1, IDX *revancestors0, IDX *revancestors1)
Definition: grphbase.c:1846
#define FALSE
Definition: portab.h:37
void SCIPintListNodeFree(SCIP *scip, IDX **node)
Definition: misc_stp.c:140
void graph_show(const GRAPH *p)
Definition: grphbase.c:1318
void graph_knot_add(GRAPH *p, int term)
Definition: grphbase.c:1362
int * mark
Definition: grph.h:71
#define CONNECT
Definition: grph.h:147
miscellaneous methods used for solving Steiner problems
int * mincut_prev
Definition: grph.h:106
int stp_type
Definition: grph.h:123
IDX ** ancestors
Definition: grph.h:83
int orgedges
Definition: grph.h:90
int * outbeg
Definition: grph.h:77
#define Is_pterm(a)
Definition: grph.h:159
int * locals
Definition: grph.h:65
SCIP_Real * prize
Definition: grph.h:92
static void compEdges(int coord, int grid_dim, int *ncoords, int *currcoord, int *edgecosts, int *gridedgecount, int **coords, int **gridedges)
Definition: grphbase.c:336
SCIP_RETCODE graph_obstgrid_create(SCIP *scip, GRAPH **gridgraph, int **coords, int **obst_coords, int nterms, int grid_dim, int nobstacles, int scale_order)
Definition: grphbase.c:374
int * maxdeg
Definition: grph.h:79
int * tail
Definition: grph.h:93
int * term
Definition: grph.h:69
SCIP_RETCODE graph_init(SCIP *scip, GRAPH **g, int ksize, int esize, int layers, int flags)
Definition: grphbase.c:44
void graph_edge_del(SCIP *scip, GRAPH *g, int e, SCIP_Bool freeancestors)
Definition: grphbase.c:1965
int knots
Definition: grph.h:61
IDX ** pcancestors
Definition: grph.h:84
#define STP_MAX_NODE_WEIGHT
Definition: grph.h:47
SCIP_RETCODE graph_resize(SCIP *scip, GRAPH *g, int ksize, int esize, int layers)
Definition: grphbase.c:186
#define EAT_HIDE
Definition: grph.h:32
int orgknots
Definition: grph.h:62
#define STP_DEG_CONS
Definition: grph.h:43
int * inpbeg
Definition: grph.h:75
SCIP_RETCODE graph_prize_transform(SCIP *scip, GRAPH *graph)
Definition: grphbase.c:726
int * mincut_temp
Definition: grph.h:108
#define FARAWAY
Definition: grph.h:149
SCIP_RETCODE SCIPintListNodeAppendCopy(SCIP *scip, IDX **node1, IDX *node2)
Definition: misc_stp.c:76
#define UNKNOWN
Definition: grph.h:148
int * mincut_e
Definition: grph.h:109
#define STP_PRIZE_COLLECTING
Definition: grph.h:40
static void compEdgesObst(int coord, int grid_dim, int nobstacles, int *ncoords, int *currcoord, int *edgecosts, int *gridedgecount, int **coords, int **gridedges, int **obst_coords, char *inobstacle)
Definition: grphbase.c:266
SCIP_RETCODE graph_knot_contractpc(SCIP *scip, GRAPH *g, int t, int s, int i)
Definition: grphbase.c:1679
static void edge_remove(GRAPH *g, int e)
Definition: grphbase.c:1928
int grid_dim
Definition: grph.h:118
includes various files containing graph methods used for Steiner problems
SCIP_RETCODE graph_init_history(SCIP *scip, GRAPH *graph)
Definition: grphbase.c:128
int ** grid_coordinates
Definition: grph.h:120
void graph_edge_hide(GRAPH *g, int e)
Definition: grphbase.c:2015
Portable defintions.
int graph_valid(const GRAPH *p)
Definition: grphbase.c:2532
int layers
Definition: grph.h:64
SCIP_RETCODE pcgraphtrans(SCIP *scip, GRAPH *graph)
Definition: grphbase.c:2142
SCIP_Bool graph_sol_valid(SCIP *scip, const GRAPH *graph, int *result)
Definition: grphbase.c:2639
#define EAT_FREE
Definition: grph.h:30
int * grad
Definition: grph.h:74
void graph_trail(const GRAPH *p, int i)
Definition: grphbase.c:2510
void graph_free(SCIP *scip, GRAPH *p, SCIP_Bool final)
Definition: grphbase.c:1137
SCIP_Real * cost
Definition: grph.h:91
void graph_flags(GRAPH *p, int flags)
Definition: grphbase.c:1307
int * mincut_dist
Definition: grph.h:103
#define STP_ROOTED_PRIZE_COLLECTING
Definition: grph.h:41
int * mincut_x
Definition: grph.h:110
int esize
Definition: grph.h:88
int * source
Definition: grph.h:67
void prize_subtract(SCIP *scip, GRAPH *g, SCIP_Real cost, int i)
Definition: grphbase.c:1637
int * mincut_next
Definition: grph.h:107
#define STP_DIRECTED
Definition: grph.h:39
int edges
Definition: grph.h:89
int * grid_ncoords
Definition: grph.h:119
#define flipedge(edge)
Definition: grph.h:143
int * ieat
Definition: grph.h:99
void graph_knot_chg(GRAPH *p, int node, int term)
Definition: grphbase.c:1386
int graph_edge_redirect(SCIP *scip, GRAPH *g, int eki, int k, int j, SCIP_Real cost)
Definition: grphbase.c:1783
int * orghead
Definition: grph.h:96
int ksize
Definition: grph.h:60
SCIP_RETCODE graph_rootprize_transform(SCIP *scip, GRAPH *graph)
Definition: grphbase.c:955
struct Int_List_Node * parent
Definition: misc_stp.h:69
SCIP_RETCODE graph_PcToSap(SCIP *scip, GRAPH *graph)
Definition: grphbase.c:880
int hoplimit
Definition: grph.h:86
int * mincut_head
Definition: grph.h:104
void graph_edge_add(SCIP *scip, GRAPH *g, int tail, int head, SCIP_Real cost1, SCIP_Real cost2)
Definition: grphbase.c:1879
int * mincut_numb
Definition: grph.h:105
int norgmodelknots
Definition: grph.h:58
SCIP_RETCODE graph_grid_coordinates(SCIP *scip, int **coords, int **nodecoords, int *ncoords, int node, int grid_dim)
Definition: grphbase.c:691