Scippy

SCIP

Solving Constraint Integer Programs

reduce.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 reduce.c
17  * @brief Reduction tests for Steiner problems
18  * @author Gerald Gamrath
19  * @author Thorsten Koch
20  * @author Stephen Maher
21  * @author Daniel Rehfeldt
22  *
23  * This file includes several easy reduction techniques ('degree_test'), bound-based reductions (e.g. 'bound_reduce')
24  * and several packages of reduction techniques for different Steiner problem variants.
25  *
26  * A list of all interface methods can be found in grph.h.
27  *
28  */
29 
30 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
31 /*lint -esym(750,REDUCE_C) -esym(766,stdlib.h) -esym(766,string.h) */
32 
33 #define REDUCE_C
34 #define SDSP_BOUND 400 /**< visited edges bound for SDSP test */
35 #define BD3_BOUND 400 /**< visited edges bound for BD3 test */
36 
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <string.h>
40 #include <assert.h>
41 #include "grph.h"
42 #include "heur_tm.h"
43 #include "misc_stp.h"
44 #include "scip/scip.h"
45 #include "probdata_stp.h"
46 #include "prop_stp.h"
47 
48 /** set entries of (char) array to FALSE */
49 static
50 void setTrue(
51  char** arr,
52  int arrsize
53  )
54 {
55  int i;
56 
57  assert(arr != NULL);
58  assert(arrsize >= 0);
59 
60  for( i = 0; i < arrsize; i++ )
61  {
62  assert(arr[i] != NULL);
63  *(arr[i]) = TRUE;
64  }
65 }
66 
67 /** iterate NV and SL test while at least minelims many contractions are being performed */
68 static
69 SCIP_RETCODE nvsl_reduction(
70  SCIP* scip,
71  GRAPH* g,
72  PATH* vnoi,
73  SCIP_Real* nodearrreal,
74  SCIP_Real* fixed,
75  int* edgearrint,
76  int* heap,
77  int* state,
78  int* vbase,
79  int* neighb,
80  int* distnode,
81  char* visited,
82  int* nelims,
83  int minelims
84  )
85 {
86  int elims;
87  int nvelims;
88  int slelims;
89  int degelims;
90  int totalelims;
91 
92  assert(g != NULL);
93  assert(heap != NULL);
94  assert(state != NULL);
95  assert(vbase != NULL);
96  assert(vnoi != NULL);
97  assert(nodearrreal != NULL);
98  assert(visited != NULL);
99  assert(minelims >= 0);
100 
101  *nelims = 0;
102  totalelims = 0;
103 
104  do
105  {
106  elims = 0;
107  degelims = 0;
108 
109  /* NV-reduction */
110  SCIP_CALL( nv_reductionAdv(scip, g, vnoi, nodearrreal, fixed, edgearrint, heap, state, vbase, neighb, distnode, &nvelims) );
111  elims += nvelims;
112 
113  SCIPdebugMessage("NV-reduction (in NVSL): %d \n", nvelims);
114 
115  /* SL-reduction */
116  SCIP_CALL( sl_reduction(scip, g, vnoi, fixed, heap, state, vbase, neighb, visited, &slelims) );
117  elims += slelims;
118 
119  SCIPdebugMessage("SL-reduction (in NVSL): %d \n", slelims);
120 
121  /* trivial reductions */
122  if( elims > 0 )
123  {
125  SCIP_CALL( degree_test_pc(scip, g, fixed, &degelims) );
126  else
127  SCIP_CALL( degree_test(scip, g, fixed, &degelims) );
128  }
129  else
130  {
131  degelims = 0;
132  }
133 
134  elims += degelims;
135 
136  SCIPdebugMessage("Degree Test-reduction (in NVSL): %d \n", degelims);
137 
138  totalelims += elims;
139  }while( elims > minelims );
140 
141  *nelims = totalelims;
142  return SCIP_OKAY;
143 }
144 
145 #if 0
146 
147 /* A. Balakrishnan and N. R. Patel
148  *
149  * "Problem Reduction Methods and a Tree Generation Algorithm
150  * for the Steiner Network Problem"
151  *
152  * NETWORKS, Vol 17 (1985) 65-85
153  *
154  * Demand Node Aggregation, Page 68
155  */
156 static int tt_aggregation(
157  SCIP* scip,
158  GRAPH* g,
159  double* fixed)
160 {
161  PATH* mst;
162  int i;
163  int head;
164  int tail;
165  int count = 0;
166  int retry;
167 
168  assert(g != NULL);
169  assert(fixed != NULL);
170 
171  SCIPdebugMessage("T-T Aggregation: ");
172  fflush(stdout);
173 
174  mst = malloc((size_t)g->knots * sizeof(PATH));
175 
176  assert(mst != NULL);
177 
178  for(i = 0; i < g->knots; i++)
179  g->mark[i] = TRUE;
180 
181  do
182  {
183  retry = FALSE;
184 
185  graph_path_exec(g, MST_MODE, g->source[0], g->cost, mst);
186 
187  for(i = 0; !retry && (i < g->knots); i++)
188  {
189  assert((mst[i].edge >= 0) || (g->grad[i] == 0) || (i == g->source[0]));
190 
191  if (mst[i].edge >= 0)
192  {
193  head = g->head[mst[i].edge];
194  tail = g->tail[mst[i].edge];
195 
196  /* Ist es eine T-T Verbindung ?
197  */
198  if (Is_term(g->term[head]) && Is_term(g->term[tail]))
199  {
200  SCIP_CALL( graph_knot_contract(scip, g, head, tail) );
201 
202  *fixed += mst[i].dist;
203 
204  count++;
205 
206  /* Neuen MST berechnen und nochmal.
207  */
208  retry = TRUE;
209  }
210  }
211  }
212  } while(retry);
213 
214  free(mst);
215 
216  SCIPdebugMessage("%d Knots deleted\n", count);
217 
218  assert(graph_valid(g));
219 
220  return(count);
221 }
222 
223 /* A. Balakrishnan and N. R. Patel
224  *
225  * "Problem Reduction Methods and a Tree Generation Algorithm
226  * for the Steiner Network Problem"
227  *
228  * NETWORKS, Vol 17 (1985) 65-85
229  *
230  * R-R Edge Deletion, Page 69
231  */
232 static int tt_deletion(
233  GRAPH* g)
234 {
235  PATH* mst;
236  double* cost;
237  int count = 0;
238  int i;
239  int k;
240  int e;
241  int f;
242  double max = 0.0;
243 
244  assert(g != NULL);
245 
246  SCIPdebugMessage("T-T Edge deletion: ");
247  fflush(stdout);
248 
249  for(i = 0; i < g->edges; i++)
250  if (GT(g->cost[i], max))
251  max = g->cost[i];
252 
253  assert(GT(max, 0.0));
254 
255  /* Groesser als alle anderen.
256  */
257  max = max * 2.0 + 1.0;
258 
259  cost = malloc((size_t)g->edges * sizeof(double));
260 
261  assert(cost != NULL);
262 
263  for(i = 0; i < g->edges; i++)
264  cost[i] = (Is_term(g->term[g->head[i]]) && Is_term(g->term[g->tail[i]])) ? g->cost[i] : max;
265 
266  mst = malloc((size_t)g->knots * sizeof(PATH));
267 
268  assert(mst != NULL);
269 
270  for(i = 0; i < g->knots; i++)
271  g->mark[i] = (g->grad[i] > 0);
272 
273  graph_path_exec(g, MST_MODE, g->source[0], cost, mst);
274 
275  for(i = 0; i < g->knots; i++)
276  {
277  if (!g->mark[i])
278  continue;
279 
280  assert(g->grad[i] > 0);
281 
282  if (!Is_term(g->term[i]))
283  continue;
284 
285  e = g->outbeg[i];
286 
287  while(e != EAT_LAST)
288  {
289  k = g->head[e];
290  f = e;
291  e = g->oeat[e];
292 
293  if (!Is_term(g->term[k]))
294  continue;
295 
296  assert(Is_term(g->term[i]));
297  assert(Is_term(g->term[k]));
298  assert(g->tail[f] == i);
299  assert(g->head[f] == k);
300 
301  if ((mst[k].edge == f) || (mst[k].edge == Edge_anti(f)))
302  continue;
303 
304  if ((mst[i].edge == f) || (mst[i].edge == Edge_anti(f)))
305  continue;
306 
307  graph_edge_del(NULL, g, f, FALSE);
308 
309  /* Weil ja zwei Kanten geloescht wurden
310  */
311  count += 2;
312  }
313  }
314 #ifndef NDEBUG
315  /* Es darf keine Kante geloescht worden sein, die Teil des MST war.
316  */
317  for(i = 0; i < g->knots; i++)
318  {
319  if ((e = mst[i].edge) < 0)
320  continue;
321 
322  assert(g->oeat[e] != EAT_FREE);
323  assert(g->ieat[e] != EAT_FREE);
324  }
325 #endif
326 
327  free(mst);
328  free(cost);
329 
330  /* Vielleicht sogar noch mehr Kanten, bei der Knoten Kontraktion
331  */
332  SCIPdebugMessage("%d Edges deleted\n", count);
333 
334  assert(graph_valid(g));
335 
336  return(count);
337 }
338 #endif
339 
340 
341 
342 
343 
344 #if 0
345 /* P. Winter and J. MacGregor Smith
346  *
347  * "Path-Distance Heuristics for the Steiner Problem in Undirected Networks"
348  *
349  * Algorithmica, 1992, 309-327
350  *
351  * Closest Z-Vertices Reductions, Page 316
352  */
353 static int czv_reduction(
354  GRAPH* g,
355  double* fixed)
356 {
357  int i;
358  int k;
359  int e1;
360  int e2;
361  int count = 0;
362  double cost;
363  double min1;
364  double min2;
365  double min3;
366 
367  assert(g != NULL);
368  assert(fixed != NULL);
369 
370  SCIPdebugMessage("Lazy closest T-Edge Reduction: ");
371  fflush(stdout);
372 
373  for(i = 0; i < g->knots; i++)
374  {
375  if (!Is_term(g->term[i]))
376  continue;
377 
378  if (g->grad[i] < 2)
379  continue;
380 
381  min1 = FARAWAY;
382  min2 = FARAWAY;
383  e1 = -1;
384  e2 = -1;
385 
386  /* Die beiden kuerzesten Kanten finden
387  */
388  for(k = g->outbeg[i]; k != EAT_LAST; k = g->oeat[k])
389  {
390  cost = g->cost[k];
391 
392  if (LT(cost, min1))
393  {
394  min2 = min1;
395  e2 = e1;
396  min1 = cost;
397  e1 = k;
398  }
399  else
400  {
401  if (LT(cost, min2))
402  {
403  min2 = cost;
404  e2 = k;
405  }
406  }
407  }
408  /* Da ja Grad > 1 war muesste es die Kanten geben
409  */
410  if( e2 < 0 )
411  printf("Error in czv_reduction (will be ignored) \n");
412  assert(e1 >= 0);
413  assert(e2 >= 0);
414  assert(e1 != e2);
415 
416  /* Wenn der naechste ein Terminal war, brauchen wir nicht mehr suchen.
417  */
418  if (Is_term(g->term[g->head[e1]]))
419  min3 = 0.0;
420  else
421  {
422  min3 = FARAWAY;
423 
424  for(k = g->outbeg[g->head[e1]]; k != EAT_LAST; k = g->oeat[k])
425  {
426  if (!Is_term(g->term[g->head[k]]))
427  continue;
428 
429  if (g->head[k] == i)
430  continue;
431 
432  cost = g->cost[k];
433 
434  if (LT(cost, min3))
435  min3 = cost;
436  }
437  }
438  /* Gab es denn ein Terminal ?
439  */
440  if (EQ(min3, FARAWAY))
441  continue;
442 
443  if (GE(min1 + min3, min2))
444  continue;
445 
446  assert(g->tail[e1] == i);
447 
448  SCIP_CALL( graph_knot_contract(scip, g, i, g->head[e1]) );
449 
450  *fixed += min1;
451 
452  count++;
453  }
454  SCIPdebugMessage("%d Knots deleted\n", count);
455 
456  assert(graph_valid(g));
457 
458  return(count);
459 }
460 
461 /* P. Winter and J. MacGregor Smith
462  *
463  * "Path-Distance Heuristics for the Steiner Problem in Undirected Networks"
464  *
465  * Algorithmica, 1992, 309-327
466  *
467  * Longest Edge Reductions, Page 316
468  */
469 static int lle_reduction(
470  GRAPH* g)
471 {
472  int i;
473  int k;
474  int j;
475  int l;
476  int m;
477  int i1;
478  int i2;
479  int count = 0;
480 
481  assert(g != NULL);
482 
483  SCIPdebugMessage("Lazy Longest Edge Reduction: ");
484  fflush(stdout);
485 
486  for(i = 0; i < g->knots; i++)
487  g->mark[i] = FALSE;
488 
489  for(i = 0; i < g->knots; i++)
490  {
491  if (!Is_term(g->term[i]))
492  continue;
493 
494  if (g->grad[i] < 2)
495  continue;
496 
497  assert(Is_term(g->term[i]));
498 
499  /* Erst mal markieren wo wir ueberall hinkommen
500  */
501  for(k = g->outbeg[i]; k != EAT_LAST; k = g->oeat[k])
502  g->mark[g->head[k]] = TRUE;
503 
504  for(k = g->outbeg[i]; k != EAT_LAST; k = g->oeat[k])
505  {
506  i1 = g->head[k];
507  j = g->outbeg[i1];
508 
509  while(j != EAT_LAST)
510  {
511  m = j;
512  j = g->oeat[j];
513  i2 = g->head[m];
514 
515  if (g->mark[i2])
516  {
517  for(l = g->outbeg[i]; l != EAT_LAST; l = g->oeat[l])
518  if (g->head[l] == i2)
519  break;
520 
521  assert(l != EAT_LAST);
522 
523  if (LE(Max(g->cost[l], g->cost[k]), g->cost[m]))
524  {
525  graph_edge_del(NULL, g, m, FALSE);
526  count++;
527  }
528  }
529  }
530  g->mark[i1] = FALSE;
531  }
532  }
533  SCIPdebugMessage("%d Edges deleted\n", count * 2);
534 
535  assert(graph_valid(g));
536 
537  return(count);
538 }
539 
540 /* P. Winter and J. MacGregor Smith
541  *
542  * "Path-Distance Heuristics for the Steiner Problem in Undirected Networks"
543  *
544  * Algorithmica, 1992, 309-327
545  *
546  * Longest Edge Reductions, Page 316
547  */
548 static int le_reduction(
549  GRAPH* g)
550 {
551  PATH** path;
552  char* used;
553  int* term;
554  int terms;
555  int i;
556  int k;
557  int j;
558  int m;
559  int i1;
560  int i2;
561  int count = 0;
562 
563  assert(g != NULL);
564 
565  SCIPdebugMessage("Longest Edge Reduction: ");
566  fflush(stdout);
567 
568  for(i = 0; i < g->knots; i++)
569  g->mark[i] = (g->grad[i] > 0);
570 
571  terms = 0;
572  term = malloc((size_t)g->knots * sizeof(int));
573 
574  assert(term != NULL);
575 
576  used = malloc((size_t)(g->edges / 2) * sizeof(char));
577 
578  assert(used != NULL);
579 
580  for(i = 0; i < g->edges / 2; i++)
581  used[i] = FALSE;
582 
583  path = malloc((size_t)g->knots * sizeof(PATH*));
584 
585  assert(path != NULL);
586 
587  for(i = 0; i < g->knots; i++)
588  {
589  if ((g->grad[i] < 1) || (!Is_term(g->term[i])))
590  path[i] = NULL;
591  else
592  {
593  term[terms++] = i;
594 
595  path[i] = malloc((size_t)g->knots * sizeof(PATH));
596 
597  assert(path[i] != NULL);
598 
599  graph_path_exec(g, FSP_MODE, i, g->cost, path[i]);
600 
601  /* Alle benutzen Kanten markieren
602  */
603  for(k = 0; k < g->knots; k++)
604  {
605  assert((k == i) || !g->mark[k] || (path[i][k].edge >= 0));
606 
607  if (path[i][k].edge >= 0)
608  used[path[i][k].edge / 2] = TRUE;
609  }
610 #ifndef NDEBUG
611  for(k = 0; k < g->knots; k++)
612  assert(!g->mark[k] || (path[i][k].dist < FARAWAY));
613 #endif
614  }
615  }
616  for(i = 0; i < g->knots; i++)
617  {
618  if (Is_term(g->term[i]))
619  continue;
620 
621  /* Nicht Terminals mit Grad 2 macht die Degree-Reduktion weg
622  */
623  if (g->grad[i] < 3)
624  continue;
625 
626  assert(!Is_term(g->term[i]));
627 
628  k = g->outbeg[i];
629 
630  while(k != EAT_LAST)
631  {
632  m = k;
633  k = g->oeat[k];
634 
635  if (used[m / 2])
636  continue;
637 
638  i1 = g->head[m];
639 
640  for(j = 0; j < terms; j++)
641  {
642  i2 = term[j];
643 
644  assert(Is_term(g->term[i2]));
645  assert(g->grad[i2] > 0);
646  assert(path[i2] != NULL);
647  assert(LT(path[i2][i ].dist, FARAWAY));
648  assert(LT(path[i2][i1].dist, FARAWAY));
649 
650  if (LE(Max(path[i2][i].dist, path[i2][i1].dist), g->cost[k]))
651  {
652  graph_edge_del(scip, g, m);
653  count++;
654  break;
655  }
656  }
657  }
658  }
659  for(i = 0; i < g->knots; i++)
660  if (path[i] != NULL)
661  free(path[i]);
662 
663  free(path);
664  free(used);
665  free(term);
666 
667  SCIPdebugMessage("%d Edges deleted\n", count * 2);
668 
669  assert(graph_valid(g));
670 
671  return(count);
672 }
673 #endif
674 
675 #if 0
676 static int hops_test(
677  GRAPH* g)
678 {
679  const int max_hops = param_get("MAX_HOPS")->i;
680 
681  PATH* root;
682  PATH* path;
683  double* cost;
684  int* mark;
685  int min_hops = 0;
686  double term_dist;
687  int count = 0;
688  int retry = TRUE;
689  int i;
690  int k;
691  int e;
692 
693  assert(g != NULL);
694 
695  if (!param_get("HOPS_SEP")->i)
696  return(0);
697 
698  assert(g->layers == 1);
699 
700  SCIPdebugMessage("Max-Hops reachability Test: ");
701  fflush(stdout);
702 
703  cost = malloc((size_t)g->edges * sizeof(*cost));
704  path = malloc((size_t)g->knots * sizeof(*path));
705  root = malloc((size_t)g->knots * sizeof(*root));
706  mark = malloc((size_t)g->knots * sizeof(*mark));
707 
708  assert(cost != NULL);
709  assert(path != NULL);
710  assert(root != NULL);
711  assert(mark != NULL);
712 
713  for(i = 0; i < g->knots; i++)
714  g->mark[i] = TRUE;
715 
716  for(i = 0; i < g->edges; i++)
717  cost[i] = 1.0;
718 
719  while(retry)
720  {
721  retry = FALSE;
722 
723  for(i = 0; i < g->knots; i++)
724  {
725  if (!Is_term(g->term[i]) && g->mark[i] && (g->grad[i] == 1))
726  {
727  graph_edge_del(scip, g, g->outbeg[i]);
728  g->mark[i] = FALSE;
729  retry = TRUE;
730  count++;
731  }
732  }
733  }
734 
735  graph_path_exec(g, FSP_MODE, g->source[0], cost, root);
736 
737  for(i = 0; i < g->knots; i++)
738  {
739  if (!g->mark[i])
740  continue;
741 
742  if (Is_term(g->term[i]))
743  {
744  if (root[i].dist > min_hops)
745  min_hops = root[i].dist;
746  }
747  else
748  {
749  if (root[i].dist >= max_hops)
750  {
751  for(e = g->outbeg[i]; e != EAT_LAST; e = g->outbeg[i])
752  graph_edge_del(scip, g, e);
753 
754  g->mark[i] = FALSE;
755  count++;
756  }
757  }
758  }
759  for(i = 0; i < g->knots; i++)
760  mark[i] = g->mark[i];
761  while(retry)
762  {
763  retry = FALSE;
764 
765  for(i = 0; i < g->knots; i++)
766  {
767  if (!Is_term(g->term[i]) && g->mark[i] && (g->grad[i] == 1))
768  {
769  graph_edge_del(scip, g, g->outbeg[i]);
770  g->mark[i] = FALSE;
771  retry = TRUE;
772  count++;
773  }
774  }
775  }
776 
777 
778  free(mark);
779  free(root);
780  free(path);
781  free(cost);
782 
783  SCIPdebugMessage("%d Knots removed (%d/%d)\n", count, min_hops, max_hops);
784 
785  assert(graph_valid(g));
786 
787  return(count);
788 }
789 #endif
790 
791 void level0(
792  SCIP* scip,
793  GRAPH* g)
794 {
795  int k;
796  assert(scip != NULL);
797  assert(g != NULL);
798 
799  for( k = 0; k < g->knots; k++ )
800  g->mark[k] = FALSE;
801 
802  graph_trail(g, g->source[0]);
803 
804  for( k = 0; k < g->knots; k++ )
805  {
806  if( !g->mark[k] && (g->grad[k] > 0) )
807  {
808  assert(!Is_term(g->term[k]));
809 
810  while( g->inpbeg[k] != EAT_LAST )
811  graph_edge_del(scip, g, g->inpbeg[k], TRUE);
812  }
813  }
814 }
815 
816 /** basic reduction package for the STP */
817 static
818 SCIP_RETCODE reduceStp(
819  SCIP* scip, /**< SCIP data structure */
820  GRAPH** graph, /**< graph data structure */
821  SCIP_Real* fixed, /**< pointer to store the offset value */
822  int minelims, /**< minimal number of edges to be eliminated in order to reiterate reductions */
823  SCIP_Bool dualascent /**< perform dualascent reductions? */
824  )
825 {
826  PATH* vnoi;
827  PATH* path;
828  SCIP_Real timelimit;
829  GRAPH* g = *graph;
830  GNODE** gnodearr;
831  SCIP_Real* nodearrreal;
832 #if 0
833  SCIP_Real* nodearrreal2;
834  SCIP_Real* nodearrreal3;
835 #endif
836  SCIP_Real* edgearrreal;
837  SCIP_Real* edgearrreal2;
838  SCIP_Real upperbound;
839  int* heap;
840  int* state;
841  int* vbase;
842  int* nodearrint;
843  int* edgearrint;
844  int* nodearrint2;
845  int i;
846  int nnodes;
847  int nedges;
848  int nterms;
849  int danelims;
850  int sdnelims;
851  int lenelims;
852  int sdcnelims;
853  int bd3nelims;
854  int nvslnelims;
855  int brednelims;
856  int degtnelims;
857  int reductbound;
858  char* nodearrchar;
859 
860  SCIP_Bool le = TRUE;
861  SCIP_Bool sd = TRUE;
862  SCIP_Bool da = dualascent;
863  SCIP_Bool sdc = TRUE;
864  SCIP_Bool bd3 = TRUE;
865  SCIP_Bool nvsl = TRUE;
866  SCIP_Bool bred = FALSE;
867  SCIP_Bool rerun = TRUE;
868 
869  assert(scip != NULL);
870  assert(g != NULL);
871  assert(minelims >= 0);
872 
873  nterms = g->terms;
874  nnodes = g->knots;
875  nedges = g->edges;
876  degtnelims = 0;
877 
878  if( SCIPisLE(scip, (double) g->terms / (double) nnodes, 0.03 ) )
879  bred = TRUE;
880 
881 #if 0
882 da = FALSE
883 bd3 = FALSE;
884 sdc = FALSE;
885 
886 le = FALSE;
887 nvsl = FALSE;
888 bred = FALSE;
889 #endif
890 
891  /* get timelimit parameter */
892  SCIP_CALL( SCIPgetRealParam(scip, "limits/time", &timelimit) );
893 
894  if( da )
895  {
896  SCIP_CALL( SCIPallocBufferArray(scip, &gnodearr, nterms - 1) );
897  for( i = 0; i < nterms - 1; i++ )
898  {
899  SCIP_CALL( SCIPallocBuffer(scip, &gnodearr[i]) ); /*lint !e866*/
900  }
901  }
902  else
903  {
904  gnodearr = NULL;
905  }
906 
907  /* allocate memory */
908  SCIP_CALL( SCIPallocBufferArray(scip, &edgearrint, nedges) );
909  SCIP_CALL( SCIPallocBufferArray(scip, &nodearrchar, nnodes) );
910  SCIP_CALL( SCIPallocBufferArray(scip, &heap, nnodes + 1) );
911  SCIP_CALL( SCIPallocBufferArray(scip, &state, 4 * nnodes) );
912  SCIP_CALL( SCIPallocBufferArray(scip, &nodearrreal, nnodes) );
913 #if 0
914  SCIP_CALL( SCIPallocBufferArray(scip, &nodearrreal2, nnodes) );
915  SCIP_CALL( SCIPallocBufferArray(scip, &nodearrreal3, nnodes) );
916 #endif
917  SCIP_CALL( SCIPallocBufferArray(scip, &edgearrreal, nedges) );
918  SCIP_CALL( SCIPallocBufferArray(scip, &vbase, 4 * nnodes) );
919  SCIP_CALL( SCIPallocBufferArray(scip, &nodearrint, nnodes) );
920  SCIP_CALL( SCIPallocBufferArray(scip, &nodearrint2, nnodes) );
921  SCIP_CALL( SCIPallocBufferArray(scip, &vnoi, 4 * nnodes) );
922  SCIP_CALL( SCIPallocBufferArray(scip, &path, nnodes) );
923 
924  if( bred || da )
925  {
926  SCIP_CALL( SCIPallocBufferArray(scip, &edgearrreal2, nedges) );
927  }
928  else
929  {
930  edgearrreal2 = NULL;
931  }
932 
933  /* define minimal number of edge/node eliminations for a reduction test to be continued */
934  reductbound = MAX(nnodes / 1000, minelims);
935 
936  SCIP_CALL( degree_test(scip, g, fixed, &degtnelims) );
937 
938  while( rerun && !SCIPisStopped(scip) )
939  {
940  if( SCIPgetTotalTime(scip) > timelimit )
941  break;
942 
943  danelims = 0;
944  lenelims = 0;
945  sdnelims = 0;
946  sdcnelims = 0;
947  bd3nelims = 0;
948  nvslnelims = 0;
949  degtnelims = 0;
950  brednelims = 0;
951  upperbound = -1.0;
952 
953  if( le )
954  {
955  SCIP_CALL( ledge_reduction(scip, g, vnoi, heap, state, vbase, &lenelims) );
956 
957  if( lenelims <= reductbound )
958  le = FALSE;
959  else
960  SCIP_CALL( degree_test(scip, g, fixed, &degtnelims) );
961 
962  SCIPdebugMessage("le: %d \n", lenelims);
963  if( SCIPgetTotalTime(scip) > timelimit )
964  break;
965  }
966 
967  if( sd )
968  {
969  SCIP_CALL( sd_red(scip, g, vnoi, edgearrreal, nodearrreal, heap, state, vbase, nodearrint, nodearrint2, edgearrint, &sdnelims) );
970 
971  if( sdnelims <= reductbound )
972  sd = FALSE;
973 
974  SCIPdebugMessage("sd: %d, \n", sdnelims);
975  if( SCIPgetTotalTime(scip) > timelimit )
976  break;
977  }
978 
979  if( sdc )
980  {
981  SCIP_CALL( sdsp_reduction(scip, g, vnoi, path, heap, state, vbase, nodearrint, nodearrint2, &sdcnelims, SDSP_BOUND) );
982 
983  if( sdcnelims <= reductbound )
984  sdc = FALSE;
985 
986  SCIPdebugMessage("sdsp: %d \n", sdcnelims);
987  if( SCIPgetTotalTime(scip) > timelimit )
988  break;
989  }
990 
991  if( sd || sdc )
992  SCIP_CALL( degree_test(scip, g, fixed, &degtnelims) );
993 
994  if( bd3 )
995  {
996  SCIP_CALL( bd3_reduction(scip, g, vnoi, path, heap, state, vbase, nodearrint, nodearrint2, &bd3nelims, BD3_BOUND) );
997  if( bd3nelims <= reductbound )
998  bd3 = FALSE;
999  else
1000  SCIP_CALL( degree_test(scip, g, fixed, &degtnelims) );
1001 
1002  SCIPdebugMessage("bd3: %d \n", bd3nelims);
1003  if( SCIPgetTotalTime(scip) > timelimit )
1004  break;
1005  }
1006 
1007  if( nvsl )
1008  {
1009  SCIP_CALL( nvsl_reduction(scip, g, vnoi, nodearrreal, fixed, edgearrint, heap, state, vbase, nodearrint, NULL, nodearrchar, &nvslnelims, reductbound) );
1010 
1011  if( nvslnelims <= reductbound )
1012  nvsl = FALSE;
1013 
1014  SCIPdebugMessage("nvsl: %d \n", nvslnelims);
1015  if( SCIPgetTotalTime(scip) > timelimit )
1016  break;
1017  }
1018 
1019  if( bred )
1020  {
1021  SCIP_CALL( bound_reduce(scip, g, vnoi, edgearrreal, NULL, nodearrreal, edgearrreal2, fixed, &upperbound, heap, state, vbase, &brednelims) );
1022 
1023  if( brednelims <= 2 * reductbound )
1024  bred = FALSE;
1025 
1026  SCIPdebugMessage("bnd: %d \n", brednelims);
1027  if( SCIPgetTotalTime(scip) > timelimit )
1028  break;
1029  }
1030 
1031  if( da )
1032  {
1033  SCIP_CALL( da_reduce(scip, g, vnoi, gnodearr, edgearrreal, edgearrreal2, nodearrreal, edgearrint, vbase, heap, state, nodearrint2, nodearrchar, &danelims) );
1034 
1035  if( danelims <= 5 * reductbound )
1036  da = FALSE;
1037 
1038  SCIPdebugMessage("da: %d \n", danelims);
1039  if( SCIPgetTotalTime(scip) > timelimit )
1040  break;
1041  }
1042 
1043  SCIP_CALL( degree_test(scip, g, fixed, &degtnelims) );
1044 
1045  if( (danelims + sdnelims + bd3nelims + nvslnelims + lenelims + brednelims + sdcnelims) <= 2 * reductbound )
1046  {
1047  rerun = FALSE;
1048 #if 0
1049  if( advanced )
1050  {
1051  int nelims;
1052  int runnum;
1053  unsigned int seed;
1054  seed = 0;
1055  runnum = 0;
1056  advanced = FALSE;
1057  sdnelims = 0;
1058  for( i = 0; i < nnodes; i++ )
1059  nodearrint[i] = -1;
1060  for( i = 0; i < 5; i++ )
1061  {
1062  SCIP_CALL( sd_reduction(scip, g, nodearrreal, nodearrreal2, nodearrreal3, edgearrreal, edgearrreal2, heap, state, nodearrint, &nelims, runnum, &seed) );
1063  runnum++;
1064  sdnelims += nelims;
1065  if( nelims <= 5 * reductbound )
1066  break;
1067  SCIP_CALL( degree_test(scip, g, fixed, &degtnelims) );
1068  }
1069 
1070  printf("final sd: %d, \n", sdnelims);
1071  if( sdnelims > 5 * reductbound )
1072  {
1073  rerun = TRUE;
1074  le = TRUE;
1075  sd = TRUE;
1076  sdc = TRUE;
1077  bd3 = TRUE;
1078  nvsl = TRUE;
1079  da = TRUE;
1080  }
1081  }
1082 #endif
1083  }
1084  }
1085 
1086  SCIPdebugMessage("Reduction Level 1: Fixed Cost = %.12e\n", *fixed);
1087 
1088  /* free memory */
1089  SCIPfreeBufferArrayNull(scip, &edgearrreal2);
1090  SCIPfreeBufferArray(scip, &path);
1091  SCIPfreeBufferArray(scip, &vnoi);
1092  SCIPfreeBufferArray(scip, &nodearrint2);
1093  SCIPfreeBufferArray(scip, &nodearrint);
1094  SCIPfreeBufferArray(scip, &vbase);
1095  SCIPfreeBufferArray(scip, &edgearrreal);
1096 #if 0
1097  SCIPfreeBufferArray(scip, &nodearrreal3);
1098  SCIPfreeBufferArray(scip, &nodearrreal2);
1099 #endif
1100  SCIPfreeBufferArray(scip, &nodearrreal);
1101  SCIPfreeBufferArray(scip, &state);
1102  SCIPfreeBufferArray(scip, &heap);
1103  SCIPfreeBufferArray(scip, &nodearrchar);
1104  SCIPfreeBufferArray(scip, &edgearrint);
1105 
1106  if( gnodearr != NULL )
1107  {
1108  for( i = nterms - 2; i >= 0; i-- )
1109  SCIPfreeBuffer(scip, &gnodearr[i]);
1110  SCIPfreeBufferArray(scip, &gnodearr);
1111  }
1112 
1113  return SCIP_OKAY;
1114 }
1115 
1116 /** basic reduction package for the (R)PCSTP */
1117 static
1118 SCIP_RETCODE reducePc(
1119  SCIP* scip, /**< SCIP data structure */
1120  GRAPH** graph, /**< graph data structure */
1121  SCIP_Real* fixed, /**< pointer to store the offset value */
1122  int minelims, /**< minimal number of edges to be eliminated in order to reiterate reductions */
1123  char dualascent /**< perform dual ascent reductions? */
1124  )
1125 {
1126  PATH* vnoi;
1127  PATH* path;
1128  GRAPH* g = *graph;
1129  GNODE** gnodearr;
1130  SCIP_Real* exedgearrreal;
1131  SCIP_Real* nodearrreal;
1132  SCIP_Real* exedgearrreal2;
1133  SCIP_Real timelimit;
1134  SCIP_Real upperbound;
1135  int* heap;
1136  int* state;
1137  int* vbase;
1138  int* nodearrint;
1139  int* edgearrint;
1140  int* nodearrint2;
1141  int i;
1142  int nelims;
1143  int nnodes;
1144  int nterms;
1145  int nedges;
1146  int danelims;
1147  int sdnelims;
1148  int extnedges;
1149  int sdcnelims;
1150  int bd3nelims;
1151  int degnelims;
1152  int nvslnelims;
1153  int brednelims;
1154  int reductbound;
1155  char* nodearrchar;
1156  char sd = TRUE;
1157  char da = dualascent;
1158  char sdc = TRUE;
1159  char bd3 = TRUE;
1160  char nvsl = TRUE;
1161  char bred = FALSE;
1162  char rerun = TRUE;
1163 
1164  assert(scip != NULL);
1165  assert(g != NULL);
1166  assert(minelims >= 0);
1167 
1168  nterms = g->terms;
1169  nnodes = g->knots;
1170  nedges = g->edges;
1171 
1172  /* for PCSPG more memory is necessary */
1173  if( g->stp_type == STP_ROOTED_PRIZE_COLLECTING || !da )
1174  extnedges = nedges;
1175  else
1176  extnedges = nedges + 2 * (g->terms - 1);
1177 
1178  /* get timelimit parameter*/
1179  SCIP_CALL( SCIPgetRealParam(scip, "limits/time", &timelimit) );
1180 
1181  /* allocate memory */
1182  SCIP_CALL( SCIPallocBufferArray(scip, &heap, nnodes + 1) );
1183  SCIP_CALL( SCIPallocBufferArray(scip, &state, 4 * nnodes) );
1184  SCIP_CALL( SCIPallocBufferArray(scip, &nodearrreal, nnodes + 1) );
1185  SCIP_CALL( SCIPallocBufferArray(scip, &exedgearrreal, extnedges ) );
1186  SCIP_CALL( SCIPallocBufferArray(scip, &vbase, 4 * nnodes) );
1187  SCIP_CALL( SCIPallocBufferArray(scip, &vnoi, 4 * nnodes) );
1188  SCIP_CALL( SCIPallocBufferArray(scip, &path, nnodes) );
1189  SCIP_CALL( SCIPallocBufferArray(scip, &nodearrint, nnodes + 1) );
1190  SCIP_CALL( SCIPallocBufferArray(scip, &nodearrint2, nnodes) );
1191  SCIP_CALL( SCIPallocBufferArray(scip, &nodearrchar, nnodes + 1) );
1192 
1193  if( SCIPisLE(scip, (double) g->terms / (double) nnodes, 0.03) )
1194  bred = TRUE;
1195 
1196  if( bred || da )
1197  {
1198  SCIP_CALL( SCIPallocBufferArray(scip, &exedgearrreal2, extnedges) );
1199  }
1200  else
1201  {
1202  exedgearrreal2 = NULL;
1203  }
1204 
1205  if( da )
1206  {
1207  SCIP_CALL( SCIPallocBufferArray(scip, &edgearrint, extnedges) );
1208  SCIP_CALL( SCIPallocBufferArray(scip, &gnodearr, nterms - 1) );
1209  for( i = 0; i < nterms - 1; i++ )
1210  {
1211  SCIP_CALL( SCIPallocBuffer(scip, &gnodearr[i]) ); /*lint !e866*/
1212  }
1213  }
1214  else
1215  {
1216  gnodearr = NULL;
1217  SCIP_CALL( SCIPallocBufferArray(scip, &edgearrint, nedges) );
1218  }
1219 
1220 
1221  /* define minimal number of edge/node eliminations for a reduction test to be continued */
1222  reductbound = MAX(nnodes / 1000, minelims);
1223 
1224  SCIP_CALL( pcgraphorg(scip, g) );
1225 
1226  SCIP_CALL( degree_test_pc(scip, g, fixed, &degnelims) );
1227 
1228  while( rerun && !SCIPisStopped(scip) )
1229  {
1230  if( SCIPgetTotalTime(scip) > timelimit )
1231  break;
1232 
1233  danelims = 0;
1234  sdnelims = 0;
1235  sdcnelims = 0;
1236  bd3nelims = 0;
1237  nvslnelims = 0;
1238  degnelims = 0;
1239  brednelims = 0;
1240  upperbound = -1.0;
1241 
1242  if( sdc )
1243  {
1244  SCIP_CALL( sdsp_reduction(scip, g, vnoi, path, heap, state, vbase, nodearrint, nodearrint2, &sdcnelims, SDSP_BOUND) );
1245 
1246  if( sdcnelims <= reductbound )
1247  sdc = FALSE;
1248 
1249  SCIPdebugMessage("SDsp: %d \n", sdcnelims);
1250  if( SCIPgetTotalTime(scip) > timelimit )
1251  break;
1252  }
1253 
1254  if( sd )
1255  {
1256  SCIP_CALL( sdpc_reduction(scip, g, vnoi, exedgearrreal, heap, state, vbase, nodearrint, nodearrint2, &sdnelims) );
1257  if( sdnelims <= reductbound )
1258  sd = FALSE;
1259 
1260  SCIPdebugMessage("SDpc: %d \n", sdnelims);
1261  if( SCIPgetTotalTime(scip) > timelimit )
1262  break;
1263  }
1264 
1265  SCIP_CALL( degree_test_pc(scip, g, fixed, &nelims) );
1266  degnelims += nelims;
1267 
1268  if( bd3 )
1269  {
1270  SCIP_CALL( bd3_reduction(scip, g, vnoi, path, heap, state, vbase, nodearrint, nodearrint2, &bd3nelims, BD3_BOUND) );
1271  if( bd3nelims <= reductbound )
1272  bd3 = FALSE;
1273 
1274  SCIPdebugMessage("bd3: %d, ", bd3nelims);
1275  if( SCIPgetTotalTime(scip) > timelimit )
1276  break;
1277  }
1278 
1279  if( nvsl )
1280  {
1281  SCIP_CALL( nvsl_reduction(scip, g, vnoi, nodearrreal, fixed, edgearrint, heap, state, vbase, nodearrint, nodearrint2, nodearrchar, &nvslnelims, reductbound) );
1282 
1283  if( nvslnelims <= 0.5 * reductbound )
1284  nvsl = FALSE;
1285 
1286  SCIPdebugMessage("nvsl: %d \n", nvslnelims);
1287  if( SCIPgetTotalTime(scip) > timelimit )
1288  break;
1289  }
1290 
1291  if( bred )
1292  {
1293  SCIP_CALL( bound_reduce(scip, g, vnoi, exedgearrreal, g->prize, nodearrreal, exedgearrreal2, fixed, &upperbound, heap, state, vbase, &brednelims) );
1294  if( brednelims <= reductbound )
1295  bred = FALSE;
1296 
1297  SCIPdebugMessage("bnd %d \n", brednelims);
1298  if( SCIPgetTotalTime(scip) > timelimit )
1299  break;
1300  }
1301 
1302  if( da )
1303  {
1305  {
1306  SCIP_CALL( da_reduce(scip, g, vnoi, gnodearr, exedgearrreal, exedgearrreal2, nodearrreal, edgearrint, vbase, heap, state, nodearrint2, nodearrchar, &danelims) );
1307  }
1308  else
1309  {
1310  SCIP_CALL( daPc_reduce(scip, g, vnoi, gnodearr, exedgearrreal, exedgearrreal2, nodearrreal, vbase, heap, edgearrint, state, nodearrchar, &danelims) );
1311  }
1312 
1313  if( danelims <= 2 * reductbound )
1314  da = FALSE;
1315 
1316  SCIPdebugMessage("da: %d \n", danelims);
1317  }
1318 
1319  if( degnelims + sdnelims + sdcnelims + bd3nelims + danelims + brednelims + nvslnelims <= reductbound )
1320  rerun = FALSE;
1321  }
1322 
1323  SCIP_CALL( pcgraphtrans(scip, g) );
1324  SCIPdebugMessage("Reduction Level PC 1: Fixed Cost = %.12e\n", *fixed);
1325 
1326  /* free memory */
1327 
1328  if( gnodearr != NULL )
1329  {
1330  for( i = nterms - 2; i >= 0; i-- )
1331  SCIPfreeBuffer(scip, &gnodearr[i]);
1332  SCIPfreeBufferArray(scip, &gnodearr);
1333  }
1334  SCIPfreeBufferArray(scip, &edgearrint);
1335  SCIPfreeBufferArrayNull(scip, &exedgearrreal2);
1336  SCIPfreeBufferArray(scip, &nodearrchar);
1337  SCIPfreeBufferArray(scip, &nodearrint2);
1338  SCIPfreeBufferArray(scip, &nodearrint);
1339  SCIPfreeBufferArray(scip, &path);
1340  SCIPfreeBufferArray(scip, &vnoi);
1341  SCIPfreeBufferArray(scip, &vbase);
1342  SCIPfreeBufferArray(scip, &exedgearrreal);
1343  SCIPfreeBufferArray(scip, &nodearrreal);
1344  SCIPfreeBufferArray(scip, &state);
1345  SCIPfreeBufferArray(scip, &heap);
1346 
1347  return SCIP_OKAY;
1348 }
1349 
1350 /** reduction package for the MWCSP */
1351 static
1352 SCIP_RETCODE reduceMwcs(
1353  SCIP* scip, /**< SCIP data structure */
1354  GRAPH** graph, /**< graph data structure */
1355  SCIP_Real* fixed, /**< pointer to store the offset value */
1356  int minelims, /**< minimal number of edges to be eliminated in order to reiterate reductions */
1357  char dualascent /**< perform dual ascent reductions? */
1358  )
1359 {
1360  GRAPH* g = *graph;
1361  PATH* vnoi;
1362  PATH* path;
1363  GNODE** gnodearr;
1364  SCIP_Real* nodearrreal;
1365  SCIP_Real* edgearrreal;
1366  SCIP_Real* edgearrreal2;
1367  SCIP_Real timelimit;
1368  SCIP_Real upperbound;
1369  int* state;
1370  int* vbase;
1371  int* edgearrint;
1372  int* nodearrint;
1373  int* nodearrint2;
1374  int* nodearrint3;
1375  int i;
1376  int nterms;
1377  int nnodes;
1378  int nedges;
1379  int daelims;
1380  int anselims;
1381  int nnpelims;
1382  int degelims;
1383  int npvelims;
1384  int redbound;
1385  int extnedges;
1386  int bredelims;
1387  int ansadelims;
1388  int ansad2elims;
1389  int chain2elims;
1390  char* nodearrchar;
1391  char da = dualascent;
1392  char ans = TRUE;
1393  char nnp = TRUE;
1394  char npv = TRUE;
1395  char bred = TRUE;
1396  char rerun = TRUE;
1397  char ansad = TRUE;
1398  char ansad2 = TRUE;
1399  char chain2 = TRUE;
1400  char* boolarr[16];
1401 
1402  assert(scip != NULL);
1403  assert(g != NULL);
1404  assert(fixed != NULL);
1405 
1406  boolarr[0] = &ans;
1407  boolarr[1] = &nnp;
1408  boolarr[2] = &npv;
1409  boolarr[3] = &bred;
1410  boolarr[4] = &ansad;
1411  boolarr[5] = &ansad2;
1412  boolarr[6] = &chain2;
1413  boolarr[7] = &da;
1414 
1415  nnodes = g->knots;
1416  nedges = g->edges;
1417  nterms = g->terms;
1418  redbound = MAX(nnodes / 1000, minelims);
1419 
1420  if( da )
1421  {
1422  extnedges = nedges + 2 * (g->terms - 1);
1423 
1424 
1425  SCIP_CALL( SCIPallocBufferArray(scip, &gnodearr, nterms - 1) );
1426  for( i = 0; i < nterms - 1; i++ )
1427  {
1428  SCIP_CALL( SCIPallocBuffer(scip, &gnodearr[i]) ); /*lint !e866*/
1429  }
1430  SCIP_CALL( SCIPallocBufferArray(scip, &edgearrint, extnedges) );
1431  }
1432  else
1433  {
1434  extnedges = nedges;
1435  edgearrint = NULL;
1436  gnodearr = NULL;
1437  }
1438  SCIP_CALL( SCIPgetRealParam(scip, "limits/time", &timelimit) );
1439 
1440  SCIP_CALL( SCIPallocBufferArray(scip, &nodearrint, nnodes + 1) );
1441  SCIP_CALL( SCIPallocBufferArray(scip, &nodearrint2, nnodes) );
1442  SCIP_CALL( SCIPallocBufferArray(scip, &nodearrint3, nnodes) );
1443  SCIP_CALL( SCIPallocBufferArray(scip, &nodearrchar, nnodes) );
1444  SCIP_CALL( SCIPallocBufferArray(scip, &state, 3 * nnodes) );
1445  SCIP_CALL( SCIPallocBufferArray(scip, &vbase, 3 * nnodes) );
1446  SCIP_CALL( SCIPallocBufferArray(scip, &vnoi, 3 * nnodes) );
1447  SCIP_CALL( SCIPallocBufferArray(scip, &path, nnodes) );
1448 
1449  if( bred || da )
1450  {
1451  SCIP_CALL( SCIPallocBufferArray(scip, &nodearrreal, nnodes + 1) );
1452  SCIP_CALL( SCIPallocBufferArray(scip, &edgearrreal, extnedges) );
1453  SCIP_CALL( SCIPallocBufferArray(scip, &edgearrreal2, extnedges) );
1454  }
1455  else
1456  {
1457  nodearrreal = NULL;
1458  edgearrreal = NULL;
1459  edgearrreal2 = NULL;
1460  }
1461 
1462 
1463  SCIP_CALL( pcgraphorg(scip, g) );
1464 
1465  degelims = 0;
1466 
1467  SCIP_CALL( degree_test_mw(scip, g, fixed, &degelims) );
1468 
1469  while( rerun && !SCIPisStopped(scip) )
1470  {
1471  daelims = 0;
1472  anselims = 0;
1473  nnpelims = 0;
1474  degelims = 0;
1475  npvelims = 0;
1476  bredelims = 0;
1477  ansadelims = 0;
1478  ansad2elims = 0;
1479  chain2elims = 0;
1480 
1481  upperbound = -1.0;
1482 
1483  if( SCIPgetTotalTime(scip) > timelimit )
1484  break;
1485 #if 0
1486  if( chain2 )
1487  {
1488  SCIP_CALL( chain2Reduction(scip, g, vnoi, path, state, vbase, nodearrint, nodearrint2, nodearrint3, &chain2elims, 300) );
1489 
1490  if( chain2elims <= redbound )
1491  chain2 = FALSE;
1492 
1493  printf("chain2 delete: %d \n", chain2elims);
1494  }
1495 
1496  if( npv )
1497  {
1498  SCIP_CALL( npvReduction(scip, g, vnoi, path, state, vbase, nodearrint, nodearrint2, nodearrint3, &npvelims, 400) );
1499 
1500  if( npvelims <= redbound )
1501  npv = FALSE;
1502 
1503  printf("npv delete: %d \n", npvelims);
1504  }
1505 #endif
1506 
1507  if( ans )
1508  {
1509  SCIP_CALL( ansReduction(scip, g, fixed, nodearrint2, &anselims) );
1510 
1511  if( anselims <= redbound )
1512  ans = FALSE;
1513 
1514  SCIPdebugMessage("ans deleted: %d \n", anselims);
1515  }
1516 
1517  if( ansad )
1518  {
1519  SCIP_CALL( ansadvReduction(scip, g, fixed, nodearrint2, &ansadelims) );
1520 
1521  if( ansadelims <= redbound )
1522  ansad = FALSE;
1523 
1524  SCIPdebugMessage("ans advanced deleted: %d \n", ansadelims);
1525  }
1526 #if 0
1527  if( ansad2 )
1528  {
1529  SCIP_CALL( ansadv2Reduction(scip, g, fixed, nodearrint2, &ansad2elims) );
1530 
1531  if( ansad2elims <= redbound )
1532  ansad2 = FALSE;
1533  else
1534  SCIP_CALL( degree_test_mw(scip, g, fixed, &degelims) );
1535 
1536  printf("ans advanced 2 deleted: %d \n", degelims);
1537  }
1538 #endif
1539  if( ans || ansad )
1540  SCIP_CALL( degree_test_mw(scip, g, fixed, &degelims) );
1541 
1542 #if 1
1543  if( chain2 )
1544  {
1545  SCIP_CALL( chain2Reduction(scip, g, vnoi, path, state, vbase, nodearrint, nodearrint2, nodearrint3, &chain2elims, 300) );
1546 
1547  if( chain2elims <= redbound )
1548  chain2 = FALSE;
1549 
1550  SCIPdebugMessage("chain2 delete: %d \n", chain2elims);
1551  }
1552 
1553  if( npv )
1554  {
1555  SCIP_CALL( npvReduction(scip, g, vnoi, path, state, vbase, nodearrint, nodearrint2, nodearrint3, &npvelims, 400) );
1556 
1557  if( npvelims <= redbound )
1558  npv = FALSE;
1559 
1560  SCIPdebugMessage("npv delete: %d \n", npvelims);
1561  }
1562 #endif
1563 #if 1 /* org */
1564  if( nnp )
1565  {
1566  SCIP_CALL( nnpReduction(scip, g, fixed, nodearrint, nodearrint2, nodearrint3, &nnpelims, 300, nodearrchar) );
1567 
1568  if( nnpelims <= redbound )
1569  nnp = FALSE;
1570 
1571  SCIPdebugMessage("nnp deleted: %d \n", nnpelims);
1572  }
1573 #endif
1574  if( nnp )
1575  {
1576  SCIP_CALL( chain2Reduction(scip, g, vnoi, path, state, vbase, nodearrint, nodearrint2, nodearrint3, &chain2elims, 500) );
1577 
1578  if( chain2elims <= redbound )
1579  chain2 = FALSE;
1580 
1581  SCIPdebugMessage("chain2 delete: %d \n", chain2elims);
1582 
1583  if( SCIPgetTotalTime(scip) > timelimit )
1584  break;
1585  }
1586 
1587  SCIP_CALL( degree_test_mw(scip, g, fixed, &degelims) );
1588 #if 1 /* org */
1589  if( ansad2 )
1590  {
1591  SCIP_CALL( ansadv2Reduction(scip, g, fixed, nodearrint2, &ansad2elims) );
1592 
1593  if( ansad2elims <= redbound )
1594  ansad2 = FALSE;
1595  else
1596  SCIP_CALL( degree_test_mw(scip, g, fixed, &degelims) );
1597 
1598  SCIPdebugMessage("ans advanced 2 deleted: %d \n", degelims);
1599  }
1600 #endif
1601 
1602  if( bred )
1603  {
1604  SCIP_CALL( bound_reduce(scip, g, vnoi, edgearrreal, g->prize, nodearrreal, edgearrreal2, fixed, &upperbound, nodearrint, state, vbase, &bredelims) );
1605 
1606  if( bredelims <= redbound )
1607  bred = FALSE;
1608  else
1609  SCIP_CALL( degree_test_mw(scip, g, fixed, &degelims) );
1610 
1611  SCIPdebugMessage("bound_reduce: %d \n", bredelims);
1612  }
1613 
1614  if( da )
1615  {
1616  SCIP_CALL( daPc_reduce(scip, g, vnoi, gnodearr, edgearrreal, edgearrreal2, nodearrreal, vbase, nodearrint, edgearrint, nodearrint2, nodearrchar, &daelims) );
1617 
1618  if( daelims <= 2 * redbound )
1619  da = FALSE;
1620  else
1621  SCIP_CALL( degree_test_mw(scip, g, fixed, &degelims) );
1622  }
1623 
1624  if( anselims + nnpelims + chain2elims + bredelims + npvelims + ansadelims + ansad2elims + daelims <= redbound )
1625  rerun = FALSE;
1626 
1627  if( !rerun && dualascent )
1628  {
1629  int cnsadvelims = 0;
1630  SCIP_CALL( degree_test_mw(scip, g, fixed, &degelims) );
1631  SCIP_CALL( cnsAdvReduction(scip, g, nodearrint2, &cnsadvelims) );
1632 
1633  if( cnsadvelims > 2 * redbound )
1634  {
1635  setTrue(boolarr, 8);
1636  rerun = TRUE;
1637  dualascent = FALSE;
1638  SCIP_CALL( degree_test_mw(scip, g, fixed, &degelims) );
1639  SCIPdebugMessage("RELAOD! %d\n\n ", cnsadvelims);
1640  }
1641  }
1642  }
1643 
1644  SCIP_CALL( degree_test_mw(scip, g, fixed, &degelims) );
1645 
1646  /* go back to the extended graph */
1647  SCIP_CALL( pcgraphtrans(scip, g) );
1648 
1649  level0(scip, g);
1650 
1651  /* free memory */
1652  SCIPfreeBufferArrayNull(scip, &edgearrreal2);
1653  SCIPfreeBufferArrayNull(scip, &edgearrreal);
1654  SCIPfreeBufferArrayNull(scip, &nodearrreal);
1655  SCIPfreeBufferArray(scip, &path);
1656  SCIPfreeBufferArray(scip, &vnoi);
1657  SCIPfreeBufferArray(scip, &vbase);
1658  SCIPfreeBufferArray(scip, &state);
1659  SCIPfreeBufferArray(scip, &nodearrchar);
1660  SCIPfreeBufferArray(scip, &nodearrint3);
1661  SCIPfreeBufferArray(scip, &nodearrint2);
1662  SCIPfreeBufferArray(scip, &nodearrint);
1663  SCIPfreeBufferArrayNull(scip, &edgearrint);
1664 
1665  if( gnodearr != NULL )
1666  {
1667  for( i = nterms - 2; i >= 0; i-- )
1668  SCIPfreeBuffer(scip, &gnodearr[i]);
1669  SCIPfreeBufferArray(scip, &gnodearr);
1670  }
1671 
1672  return SCIP_OKAY;
1673 }
1674 
1675 /** basic reduction package for the HCDSTP */
1676 static
1677 SCIP_RETCODE reduceHc(
1678  SCIP* scip, /**< SCIP data structure */
1679  GRAPH** graph, /**< graph data structure */
1680  SCIP_Real* fixed, /**< pointer to store the offset value */
1681  int minelims /**< minimal number of edges to be eliminated in order to reiterate reductions */
1682  )
1683 {
1684  GRAPH* g = *graph;
1685  PATH* vnoi;
1686  SCIP_Real* cost;
1687  SCIP_Real* radius;
1688  SCIP_Real* costrev;
1689  SCIP_Real timelimit;
1690  SCIP_Real upperbound;
1691  int* heap;
1692  int* state;
1693  int* vbase;
1694  int* pathedge;
1695  int nnodes;
1696  int nedges;
1697  int redbound;
1698 #if 0
1699  int danelims;
1700 #endif
1701  int degnelims;
1702  int brednelims;
1703  int hbrednelims;
1704  int hcrnelims;
1705  int hcrcnelims;
1706  char* nodearrchar;
1707 #if 0
1708  DOES NOT WORK for HC!
1709  char da = !TRUE;
1710 #endif
1711  char bred = TRUE;
1712  char hbred = TRUE;
1713  char rbred = TRUE;
1714  char rcbred = TRUE;
1715 
1716  assert(scip != NULL);
1717  assert(g != NULL);
1718  assert(minelims >= 0);
1719 
1720  nnodes = g->knots;
1721  nedges = g->edges;
1722  degnelims = 0;
1723  upperbound = -1.0;
1724  redbound = MAX(g->knots / 1000, minelims);
1725  SCIP_CALL( SCIPgetRealParam(scip, "limits/time", &timelimit) );
1726 
1727  /* allocate memory */
1728  SCIP_CALL( SCIPallocBufferArray(scip, &nodearrchar, nnodes) );
1729  SCIP_CALL( SCIPallocBufferArray(scip, &heap, nnodes + 1) );
1730  SCIP_CALL( SCIPallocBufferArray(scip, &state, 3 * nnodes) );
1731  SCIP_CALL( SCIPallocBufferArray(scip, &cost, nedges) );
1732  SCIP_CALL( SCIPallocBufferArray(scip, &radius, nnodes) );
1733  SCIP_CALL( SCIPallocBufferArray(scip, &costrev, nedges) );
1734  SCIP_CALL( SCIPallocBufferArray(scip, &vbase, 3 * nnodes) );
1735  SCIP_CALL( SCIPallocBufferArray(scip, &pathedge, nnodes) );
1736  SCIP_CALL( SCIPallocBufferArray(scip, &vnoi, 3 * nnodes) );
1737 
1738  SCIP_CALL( degree_test_hc(scip, g, fixed, &degnelims) );
1739 
1740  while( (bred || hbred || rbred || rcbred) && !SCIPisStopped(scip) )
1741  {
1742  if( SCIPgetTotalTime(scip) > timelimit )
1743  break;
1744 
1745  if( rbred )
1746  {
1747  SCIP_CALL( hcrbound_reduce(scip, g, vnoi, cost, costrev, radius, heap, state, vbase, &hcrnelims, pathedge) );
1748  if( hcrnelims <= redbound )
1749  rbred = FALSE;
1750  }
1751 
1752  if( rcbred )
1753  {
1754  SCIP_CALL( hcrcbound_reduce(scip, g, vnoi, cost, costrev, radius, -1.0, heap, state, vbase, &hcrcnelims, pathedge, FALSE) );
1755  if( hcrcnelims <= redbound )
1756  rcbred = FALSE;
1757  }
1758 
1759  if( bred )
1760  {
1761  SCIP_CALL( bound_reduce(scip, g, vnoi, cost, NULL, radius, costrev, fixed, &upperbound, heap, state, vbase, &brednelims) );
1762  if( brednelims <= redbound )
1763  bred = FALSE;
1764  }
1765 
1766  if( SCIPgetTotalTime(scip) > timelimit )
1767  break;
1768 
1769  if( hbred )
1770  {
1771  SCIP_CALL( hopbound_reduce(scip, g, vnoi, cost, radius, costrev, heap, state, vbase, &hbrednelims) );
1772  if( hbrednelims <= redbound )
1773  hbred = FALSE;
1774  if( SCIPgetTotalTime(scip) > timelimit )
1775  break;
1776  }
1777 #if 0
1778  if( da )
1779  {
1780  SCIP_CALL( da_reduce(scip, g, vnoi, gnodarr, cost, costrev, radius, vbase, heap, state, pathedge, nodearrchar, &danelims) );
1781  if( danelims <= 2 * redbound )
1782  da = FALSE;
1783 
1784  }
1785 #endif
1786  }
1787 
1788  /* free memory */
1789  SCIPfreeBufferArray(scip, &vnoi);
1790  SCIPfreeBufferArray(scip, &pathedge);
1791  SCIPfreeBufferArray(scip, &vbase);
1792  SCIPfreeBufferArray(scip, &costrev);
1793  SCIPfreeBufferArray(scip, &radius);
1794  SCIPfreeBufferArray(scip, &cost);
1795  SCIPfreeBufferArray(scip, &state);
1796  SCIPfreeBufferArray(scip, &heap);
1797  SCIPfreeBufferArray(scip, &nodearrchar);
1798 
1799  return SCIP_OKAY;
1800 }
1801 
1802 /** basic reduction package for the SAP (@todo under construction) */
1803 static
1804 SCIP_RETCODE reduceSap(
1805  SCIP* scip, /**< SCIP data structure */
1806  GRAPH** graph, /**< graph data structure */
1807  SCIP_Real* fixed, /**< pointer to store the offset value */
1808  int minelims /**< minimal number of edges to be eliminated in order to reiterate reductions */
1809  )
1810 {
1811  PATH* vnoi;
1812  PATH* path;
1813  SCIP_Real timelimit;
1814  GRAPH* g = *graph;
1815  int* heap;
1816  int* state;
1817  int* vbase;
1818  int* nodearrint;
1819  int* nodearrint2;
1820  int e;
1821  int nnodes;
1822  int sdnelims;
1823  int rptnelims;
1824  int degtnelims;
1825  int redbound;
1826  char sd = !TRUE;
1827  char rpt = TRUE;
1828 
1829  nnodes = g->knots;
1830  redbound = MAX(nnodes / 1000, minelims);
1831  SCIP_CALL( SCIPgetRealParam(scip, "limits/time", &timelimit) );
1832 
1833  SCIP_CALL( SCIPallocBufferArray(scip, &vnoi, nnodes) );
1834  SCIP_CALL( SCIPallocBufferArray(scip, &path, nnodes) );
1835  SCIP_CALL( SCIPallocBufferArray(scip, &heap, nnodes) );
1836  SCIP_CALL( SCIPallocBufferArray(scip, &state, nnodes) );
1837  SCIP_CALL( SCIPallocBufferArray(scip, &vbase, nnodes) );
1838  SCIP_CALL( SCIPallocBufferArray(scip, &nodearrint, nnodes) );
1839  SCIP_CALL( SCIPallocBufferArray(scip, &nodearrint2, nnodes) );
1840 
1841  /* @todo change .stp file format for SAP! */
1842  for( e = 0; e < g->edges; e++ )
1843  if( SCIPisEQ(scip, g->cost[e], 20000.0) )
1844  g->cost[e] = FARAWAY;
1845 
1846  /* @todo: add additional tests */
1847  while( (sd || rpt) && !SCIPisStopped(scip) )
1848  {
1849  if( SCIPgetTotalTime(scip) > timelimit )
1850  break;
1851 
1852  if( sd )
1853  {
1854  SCIP_CALL( sdsp_sap_reduction(scip, g, vnoi, path, heap, state, vbase, nodearrint, nodearrint2, &sdnelims, 300) );
1855  if( sdnelims <= redbound )
1856  sd = FALSE;
1857  sd = FALSE;
1858  }
1859 
1860  SCIP_CALL( degree_test_sap(scip, g, fixed, &degtnelims) );
1861 
1862  if( rpt )
1863  {
1864  SCIP_CALL( rptReduction(scip, g, fixed, &rptnelims) );
1865  if( rptnelims <= redbound )
1866  rpt = FALSE;
1867  }
1868 
1869  SCIP_CALL( degree_test_sap(scip, g, fixed, &degtnelims) );
1870  }
1871 
1872 
1873  SCIPfreeBufferArray(scip, &vnoi);
1874  SCIPfreeBufferArray(scip, &path);
1875  SCIPfreeBufferArray(scip, &heap);
1876  SCIPfreeBufferArray(scip, &state);
1877  SCIPfreeBufferArray(scip, &vbase);
1878  SCIPfreeBufferArray(scip, &nodearrint);
1879  SCIPfreeBufferArray(scip, &nodearrint2);
1880 
1881  return SCIP_OKAY;
1882 }
1883 
1884 
1885 /** reduces the graph */
1886 SCIP_RETCODE reduce(
1887  SCIP* scip, /**< SCIP data structure */
1888  GRAPH** graph, /**< graph structure */
1889  SCIP_Real* offset, /**< pointer to store offset generated by reductions */
1890  int level, /**< reduction level 0: none, 1: basic, 2: advanced */
1891  int minelims /**< minimal amount of reductions to reiterate reduction methods */
1892  )
1893 {
1894  int stp_type;
1895 
1896  assert((*graph) != NULL);
1897  assert((*graph)->fixedges == NULL);
1898  assert(level >= 0 && level <= 2);
1899  assert(minelims >= 0);
1900  assert((*graph)->layers == 1);
1901 
1902  *offset = 0.0;
1903 
1904  stp_type = (*graph)->stp_type;
1905 
1906  /* initialise ancestor list for each edge */
1907  SCIP_CALL( graph_init_history(scip, (*graph)) );
1908 
1909  /* initialise shortest path algorithms */
1910  SCIP_CALL( graph_path_init(scip, (*graph)) );
1911 
1912  level0(scip, (*graph));
1913 
1914  /* if no reduction methods available, return */
1915  if( (*graph)->stp_type == STP_DEG_CONS )
1916  return SCIP_OKAY;
1917 
1918  if( level == 1 )
1919  {
1920  if( stp_type == STP_PRIZE_COLLECTING || stp_type == STP_ROOTED_PRIZE_COLLECTING )
1921  SCIP_CALL( reducePc(scip, (graph), offset, minelims, FALSE) );
1922  else if( stp_type == STP_MAX_NODE_WEIGHT )
1923  SCIP_CALL( reduceMwcs(scip, (graph), offset, minelims, FALSE) );
1924  else if( stp_type == STP_HOP_CONS )
1925  SCIP_CALL( reduceHc(scip, (graph), offset, minelims) );
1926  else if( stp_type == STP_DIRECTED || stp_type == STP_NODE_WEIGHTS )
1927  SCIP_CALL( reduceSap(scip, (graph), offset, minelims) );
1928  else
1929  SCIP_CALL( reduceStp(scip, (graph), offset, minelims, FALSE) );
1930  }
1931  else if( level == 2 )
1932  {
1933  if( stp_type == STP_PRIZE_COLLECTING || stp_type == STP_ROOTED_PRIZE_COLLECTING )
1934  SCIP_CALL( reducePc(scip, (graph), offset, minelims, TRUE) );
1935  else if( stp_type == STP_MAX_NODE_WEIGHT )
1936  SCIP_CALL( reduceMwcs(scip, (graph), offset, minelims, TRUE) );
1937  else if( stp_type == STP_HOP_CONS )
1938  SCIP_CALL( reduceHc(scip, (graph), offset, minelims) );
1939  else if( stp_type == STP_DIRECTED || stp_type == STP_NODE_WEIGHTS )
1940  SCIP_CALL( reduceSap(scip, (graph), offset, minelims) );
1941  else
1942  SCIP_CALL( reduceStp(scip, (graph), offset, minelims, TRUE) );
1943  }
1944  SCIPdebugMessage("offset : %f \n", *offset);
1945 
1946  assert(graph_valid(*graph));
1947 
1948  graph_path_exit(scip, (*graph));
1949 
1950  return SCIP_OKAY;
1951 }
SCIP_RETCODE graph_path_init(SCIP *, GRAPH *)
Definition: grphpath.c:407
#define Is_term(a)
Definition: grph.h:158
#define LT(a, b)
Definition: portab.h:64
int graph_valid(const GRAPH *)
Definition: grphbase.c:2532
SCIP_RETCODE hcrcbound_reduce(SCIP *, GRAPH *, PATH *, SCIP_Real *, SCIP_Real *, SCIP_Real *, SCIP_Real, int *, int *, int *, int *, int *, SCIP_Bool)
Definition: reduce_bnd.c:1878
#define LE(a, b)
Definition: portab.h:65
Definition: grph.h:55
#define TRUE
Definition: portab.h:34
signed int edge
Definition: grph.h:140
SCIP_RETCODE nnpReduction(SCIP *, GRAPH *, SCIP_Real *, int *, int *, int *, int *, int, char *)
Definition: reduce_alt.c:5564
#define MST_MODE
Definition: grph.h:152
int terms
Definition: grph.h:63
SCIP_RETCODE sdpc_reduction(SCIP *, GRAPH *, PATH *, SCIP_Real *, int *, int *, int *, int *, int *, int *)
Definition: reduce_alt.c:1144
SCIP_RETCODE graph_init_history(SCIP *, GRAPH *)
Definition: grphbase.c:128
#define GT(a, b)
Definition: portab.h:66
#define STP_HOP_CONS
Definition: grph.h:48
#define EAT_LAST
Definition: grph.h:31
#define Edge_anti(a)
Definition: grph.h:161
SCIP_RETCODE pcgraphtrans(SCIP *, GRAPH *)
Definition: grphbase.c:2142
Problem data for stp problem.
SCIP_RETCODE graph_knot_contract(SCIP *, GRAPH *, int, int)
Definition: grphbase.c:1415
void graph_path_exit(SCIP *, GRAPH *)
Definition: grphpath.c:429
SCIP_RETCODE npvReduction(SCIP *, GRAPH *, PATH *, PATH *, int *, int *, int *, int *, int *, int *, int)
Definition: reduce_alt.c:5146
#define STP_NODE_WEIGHTS
Definition: grph.h:42
int * oeat
Definition: grph.h:100
SCIP_RETCODE degree_test(SCIP *, GRAPH *, SCIP_Real *, int *)
void level0(SCIP *scip, GRAPH *g)
Definition: reduce.c:791
static SCIP_RETCODE reduceStp(SCIP *scip, GRAPH **graph, SCIP_Real *fixed, int minelims, SCIP_Bool dualascent)
Definition: reduce.c:818
int * head
Definition: grph.h:94
#define FALSE
Definition: portab.h:37
SCIP_RETCODE pcgraphorg(SCIP *, GRAPH *)
Definition: grphbase.c:2104
static SCIP_RETCODE reducePc(SCIP *scip, GRAPH **graph, SCIP_Real *fixed, int minelims, char dualascent)
Definition: reduce.c:1118
SCIP_RETCODE ansadvReduction(SCIP *, GRAPH *, SCIP_Real *, int *, int *)
Definition: reduce_alt.c:4867
int * mark
Definition: grph.h:71
static SCIP_RETCODE reduceHc(SCIP *scip, GRAPH **graph, SCIP_Real *fixed, int minelims)
Definition: reduce.c:1677
SCIP_RETCODE hopbound_reduce(SCIP *, GRAPH *, PATH *, SCIP_Real *, SCIP_Real *, SCIP_Real *, int *, int *, int *, int *)
Definition: reduce_bnd.c:1552
miscellaneous methods used for solving Steiner problems
#define EQ(a, b)
Definition: portab.h:62
int stp_type
Definition: grph.h:123
int * outbeg
Definition: grph.h:77
SCIP_Real * prize
Definition: grph.h:92
SCIP_RETCODE sd_red(SCIP *, GRAPH *, PATH *, SCIP_Real *, SCIP_Real *, int *, int *, int *, int *, int *, int *, int *)
Definition: reduce_alt.c:598
SCIP_RETCODE sdsp_sap_reduction(SCIP *, GRAPH *, PATH *, PATH *, int *, int *, int *, int *, int *, int *, int)
Definition: reduce_alt.c:1900
static SCIP_RETCODE reduceMwcs(SCIP *scip, GRAPH **graph, SCIP_Real *fixed, int minelims, char dualascent)
Definition: reduce.c:1352
int * tail
Definition: grph.h:93
#define BD3_BOUND
Definition: reduce.c:35
#define FSP_MODE
Definition: grph.h:153
#define GE(a, b)
Definition: portab.h:67
int * term
Definition: grph.h:69
#define Max(a, b)
Definition: portab.h:48
int knots
Definition: grph.h:61
#define STP_MAX_NODE_WEIGHT
Definition: grph.h:47
SCIP_RETCODE rptReduction(SCIP *, GRAPH *, SCIP_Real *, int *)
#define STP_DEG_CONS
Definition: grph.h:43
int * inpbeg
Definition: grph.h:75
#define FARAWAY
Definition: grph.h:149
propagator for Steiner tree problems, using the LP reduced costs
SCIP_RETCODE degree_test_mw(SCIP *, GRAPH *, SCIP_Real *, int *)
SCIP_RETCODE sd_reduction(SCIP *, GRAPH *, SCIP_Real *, SCIP_Real *, SCIP_Real *, SCIP_Real *, SCIP_Real *, int *, int *, int *, int *, int, unsigned int *)
Definition: reduce_alt.c:2227
SCIP_RETCODE degree_test_pc(SCIP *, GRAPH *, SCIP_Real *, int *)
#define SDSP_BOUND
Definition: reduce.c:34
static SCIP_RETCODE reduceSap(SCIP *scip, GRAPH **graph, SCIP_Real *fixed, int minelims)
Definition: reduce.c:1804
SCIP_RETCODE reduce(SCIP *scip, GRAPH **graph, SCIP_Real *offset, int level, int minelims)
Definition: reduce.c:1886
SCIP_RETCODE chain2Reduction(SCIP *, GRAPH *, PATH *, PATH *, int *, int *, int *, int *, int *, int *, int)
Definition: reduce_alt.c:5484
#define STP_PRIZE_COLLECTING
Definition: grph.h:40
void graph_edge_del(SCIP *, GRAPH *, int, SCIP_Bool)
Definition: grphbase.c:1965
SCIP_RETCODE degree_test_hc(SCIP *, GRAPH *, SCIP_Real *, int *)
SCIP_RETCODE ledge_reduction(SCIP *, GRAPH *, PATH *, int *, int *, int *, int *)
Definition: reduce_alt.c:4372
includes various files containing graph methods used for Steiner problems
SCIP_RETCODE daPc_reduce(SCIP *, GRAPH *, PATH *, GNODE **, SCIP_Real *, SCIP_Real *, SCIP_Real *, int *, int *, int *, int *, char *, int *)
Definition: reduce_bnd.c:577
int layers
Definition: grph.h:64
SCIP_RETCODE bd3_reduction(SCIP *, GRAPH *, PATH *, PATH *, int *, int *, int *, int *, int *, int *, int)
Definition: reduce_alt.c:2817
#define EAT_FREE
Definition: grph.h:30
int * grad
Definition: grph.h:74
SCIP_Real * cost
Definition: grph.h:91
#define STP_ROOTED_PRIZE_COLLECTING
Definition: grph.h:41
static void setTrue(char **arr, int arrsize)
Definition: reduce.c:50
int * source
Definition: grph.h:67
static SCIP_RETCODE nvsl_reduction(SCIP *scip, GRAPH *g, PATH *vnoi, SCIP_Real *nodearrreal, SCIP_Real *fixed, int *edgearrint, int *heap, int *state, int *vbase, int *neighb, int *distnode, char *visited, int *nelims, int minelims)
Definition: reduce.c:69
SCIP_RETCODE ansadv2Reduction(SCIP *, GRAPH *, SCIP_Real *, int *, int *)
Definition: reduce_alt.c:4991
shortest paths based primal heuristics for Steiner problems
#define STP_DIRECTED
Definition: grph.h:39
int edges
Definition: grph.h:89
SCIP_RETCODE sl_reduction(SCIP *, GRAPH *, PATH *, double *, int *, int *, int *, int *, char *, int *)
Definition: reduce_alt.c:3656
int * ieat
Definition: grph.h:99
SCIP_RETCODE degree_test_sap(SCIP *, GRAPH *, SCIP_Real *, int *)
SCIP_RETCODE bound_reduce(SCIP *, GRAPH *, PATH *, SCIP_Real *, SCIP_Real *, SCIP_Real *, SCIP_Real *, SCIP_Real *, SCIP_Real *, int *, int *, int *, int *)
Definition: reduce_bnd.c:845
SCIP_RETCODE cnsAdvReduction(SCIP *, GRAPH *, int *, int *)
Definition: reduce_alt.c:4675
SCIP_RETCODE hcrbound_reduce(SCIP *, GRAPH *, PATH *, SCIP_Real *, SCIP_Real *, SCIP_Real *, int *, int *, int *, int *, int *)
Definition: reduce_bnd.c:1750
SCIP_RETCODE ansReduction(SCIP *, GRAPH *, SCIP_Real *, int *, int *)
Definition: reduce_alt.c:4579
SCIP_RETCODE da_reduce(SCIP *, GRAPH *, PATH *, GNODE **, SCIP_Real *, SCIP_Real *, SCIP_Real *, int *, int *, int *, int *, int *, char *, int *)
Definition: reduce_bnd.c:202
SCIP_RETCODE sdsp_reduction(SCIP *, GRAPH *, PATH *, PATH *, int *, int *, int *, int *, int *, int *, int)
Definition: reduce_alt.c:2058
double dist
Definition: grph.h:139
void graph_trail(const GRAPH *, int)
Definition: grphbase.c:2510
void graph_path_exec(SCIP *, const GRAPH *, int, int, SCIP_Real *, PATH *)
Definition: grphpath.c:453
SCIP_RETCODE nv_reductionAdv(SCIP *, GRAPH *, PATH *, SCIP_Real *, double *, int *, int *, int *, int *, int *, int *, int *)
Definition: reduce_alt.c:4083