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-2018 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 visit 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 packages of reduction techniques for different Steiner problem variants.
24  *
25  * A list of all interface methods can be found in grph.h.
26  *
27  */
28 
29 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
30 /*lint -esym(750,REDUCE_C) -esym(766,stdlib.h) -esym(766,string.h) */
31 #define REDUCE_C
32 #define STP_RED_SDSPBOUND 200 /**< visited edges bound for SDSP test */
33 #define STP_RED_SDSPBOUND2 600 /**< visited edges bound for SDSP test */
34 #define STP_RED_BD3BOUND 500 /**< visited edges bound for BD3 test */
35 #define STP_RED_EXTENSIVE FALSE
36 #define STP_RED_MWTERMBOUND 400
37 #define STP_RED_MAXNROUNDS 15
38 #define STP_RED_EXFACTOR 2
39 
40 
41 #include <stdio.h>
42 #include <stdlib.h>
43 #include <string.h>
44 #include <assert.h>
45 #include "grph.h"
46 #include "heur_tm.h"
47 #include "misc_stp.h"
48 #include "scip/scip.h"
49 #include "probdata_stp.h"
50 #include "prop_stp.h"
51 
52 
53 /** print reduction information */
54 static
57  const char* method,
58  int nelims
59 )
60 {
61  assert(nelims >= 0);
62 
63 #ifdef STP_PRINT_STATS
64  if( print )
65  printf("%s: %d \n", method, nelims);
66 #endif
67 
68 }
69 
70 /** iterate NV and SL test while at least minelims many contractions are being performed */
71 static
73  SCIP* scip,
74  GRAPH* g,
75  PATH* vnoi,
76  SCIP_Real* nodearrreal,
77  SCIP_Real* fixed,
78  int* edgearrint,
79  int* heap,
80  int* state,
81  int* vbase,
82  int* neighb,
83  int* distnode,
84  int* solnode,
85  STP_Bool* visited,
86  int* nelims,
87  int minelims
88  )
89 {
90  int elims;
91  int nvelims;
92  int slelims;
93  int degelims;
94  int totalelims;
95 
96  assert(g != NULL);
97  assert(heap != NULL);
98  assert(state != NULL);
99  assert(vbase != NULL);
100  assert(vnoi != NULL);
101  assert(nodearrreal != NULL);
102  assert(visited != NULL);
103  assert(minelims >= 0);
104 
105  *nelims = 0;
106  totalelims = 0;
107 
108  do
109  {
110  elims = 0;
111  degelims = 0;
112 
113  /* NV-reduction */
114  SCIP_CALL( reduce_nvAdv(scip, g, vnoi, nodearrreal, fixed, edgearrint, heap, state, vbase, neighb, distnode, solnode, &nvelims) );
115  elims += nvelims;
116 
117  SCIPdebugMessage("NV-reduction (in NVSL): %d \n", nvelims);
118 
119  /* SL-reduction */
120  SCIP_CALL( reduce_sl(scip, g, vnoi, fixed, heap, state, vbase, neighb, visited, solnode, &slelims) );
121  elims += slelims;
122 
123  SCIPdebugMessage("SL-reduction (in NVSL): %d \n", slelims);
124 
125  /* trivial reductions */
126  if( elims > 0 )
127  {
128  if( g->stp_type == STP_PCSPG || g->stp_type == STP_RPCSPG )
129  SCIP_CALL( reduce_simple_pc(scip, g, fixed, &degelims, solnode, FALSE) );
130  else
131  SCIP_CALL( reduce_simple(scip, g, fixed, solnode, &degelims, NULL) );
132  }
133  else
134  {
135  degelims = 0;
136  }
137 
138  elims += degelims;
139 
140  SCIPdebugMessage("Degree Test-reduction (in NVSL): %d \n", degelims);
141 
142  totalelims += elims;
143  }while( elims > minelims );
144 
145  *nelims = totalelims;
146 
147  assert(graph_valid(g));
148 
149  return SCIP_OKAY;
150 }
151 
152 /* remove unconnected vertices, overwrites g->mark */
154  SCIP* scip, /**< SCIP data structure */
155  GRAPH* g /**< graph data structure */
156 )
157 {
158  int k;
159  int nnodes;
160 
161  assert(scip != NULL);
162  assert(g != NULL);
163 
164  nnodes = g->knots;
165 
166  for( k = nnodes - 1; k >= 0 ; k-- )
167  g->mark[k] = FALSE;
168 
169  SCIP_CALL( graph_trail_arr(scip, g, g->source) );
170 
171  for( k = nnodes - 1; k >= 0 ; k-- )
172  {
173  if( !g->mark[k] && (g->grad[k] > 0) )
174  {
175  assert(!Is_term(g->term[k]));
176 
177  while( g->inpbeg[k] != EAT_LAST )
178  graph_edge_del(scip, g, g->inpbeg[k], TRUE);
179  }
180  }
181  return SCIP_OKAY;
182 }
183 
184 /* remove unconnected vertices, keep g->mark */
186  SCIP* scip, /**< SCIP data structure */
187  GRAPH* g /**< graph data structure */
188 )
189 {
190  int* savemark;
191  const int nnodes = g->knots;
192 
193  assert(scip != NULL);
194  assert(g != NULL);
195 
196  SCIP_CALL( SCIPallocBufferArray(scip, &savemark, nnodes) );
197  BMScopyMemoryArray(savemark, g->mark, nnodes);
198 
199  for( int k = nnodes - 1; k >= 0; k-- )
200  g->mark[k] = FALSE;
201 
202  SCIP_CALL( graph_trail_arr(scip, g, g->source) );
203 
204  for( int k = nnodes - 1; k >= 0 ; k-- )
205  {
206  if( !g->mark[k] && (g->grad[k] > 0) )
207  {
208  assert(!Is_term(g->term[k]));
209 
210  while( g->inpbeg[k] != EAT_LAST )
211  graph_edge_del(scip, g, g->inpbeg[k], TRUE);
212  }
213  }
214 
215  BMScopyMemoryArray(g->mark, savemark, nnodes);
216 
217  SCIPfreeBufferArray(scip, &savemark);
218 
219  return SCIP_OKAY;
220 }
221 
222 /** basic reduction package for the STP */
224  SCIP* scip, /**< SCIP data structure */
225  GRAPH** graph, /**< graph data structure */
226  SCIP_Real* fixed, /**< pointer to store the offset value */
227  int minelims, /**< minimal number of edges to be eliminated in order to reiterate reductions */
228  SCIP_Bool dualascent, /**< perform dual-ascent reductions? */
229  SCIP_Bool nodereplacing, /**< should node replacement (by edges) be performed? */
230  SCIP_Bool userec /**< use recombination heuristic? */
231  )
232 {
233  PATH* vnoi;
234  PATH* path;
235  GRAPH* g;
236  GNODE** gnodearr;
237  SCIP_Real* nodearrreal;
238  SCIP_Real* edgearrreal;
239  SCIP_Real* edgearrreal2;
240  int* heap;
241  int* state;
242  int* vbase;
243  int* nodearrint;
244  int* edgearrint;
245  int* nodearrint2;
246  int i;
247  int nnodes;
248  int nedges;
249  int nterms;
250  int reductbound;
251  STP_Bool* nodearrchar;
252 
253  SCIP_Bool bred = FALSE;
254 
255  assert(scip != NULL);
256  assert(graph != NULL);
257  assert(*graph != NULL);
258  assert(minelims >= 0);
259 
260  g = *graph;
261 
262  nterms = g->terms;
263  nnodes = g->knots;
264  nedges = g->edges;
265 
266  if( SCIPisLE(scip, (double) nterms / (double) nnodes, 0.03) )
267  bred = TRUE;
268 
269  if( dualascent )
270  {
271  SCIP_CALL( SCIPallocBufferArray(scip, &gnodearr, nterms - 1) );
272  for( i = 0; i < nterms - 1; i++ )
273  {
274  SCIP_CALL( SCIPallocBlockMemory(scip, &gnodearr[i]) ); /*lint !e866*/
275  }
276  }
277  else
278  {
279  gnodearr = NULL;
280  }
281 
282  /* allocate memory */
283  SCIP_CALL( SCIPallocBufferArray(scip, &edgearrint, nedges) );
284  SCIP_CALL( SCIPallocBufferArray(scip, &nodearrchar, nnodes) );
285  SCIP_CALL( SCIPallocBufferArray(scip, &heap, nnodes + 1) );
286  SCIP_CALL( SCIPallocBufferArray(scip, &state, 4 * nnodes) );
287  SCIP_CALL( SCIPallocBufferArray(scip, &nodearrreal, nnodes) );
288  SCIP_CALL( SCIPallocBufferArray(scip, &edgearrreal, nedges) );
289  SCIP_CALL( SCIPallocBufferArray(scip, &vbase, 4 * nnodes) );
290  SCIP_CALL( SCIPallocBufferArray(scip, &nodearrint, nnodes) );
291  SCIP_CALL( SCIPallocBufferArray(scip, &nodearrint2, nnodes) );
292  SCIP_CALL( SCIPallocBufferArray(scip, &vnoi, 4 * nnodes) );
293  SCIP_CALL( SCIPallocBufferArray(scip, &path, nnodes) );
294 
295  if( bred || dualascent )
296  {
297  SCIP_CALL( SCIPallocBufferArray(scip, &edgearrreal2, nedges) );
298  }
299  else
300  {
301  edgearrreal2 = NULL;
302  }
303 
304  reductbound = MAX(nedges / 1000, minelims);
305 
306  /* reduction loop */
307  SCIP_CALL( redLoopStp(scip, g, vnoi, path, gnodearr, nodearrreal, edgearrreal, edgearrreal2, heap, state,
308  vbase, nodearrint, edgearrint, nodearrint2, NULL, nodearrchar, fixed, -1.0, dualascent, bred, nodereplacing, reductbound, userec, (dualascent && userec)) );
309 
310  SCIPdebugMessage("Reduction Level 1: Fixed Cost = %.12e\n", *fixed);
311 
312  /* free memory */
313  SCIPfreeBufferArrayNull(scip, &edgearrreal2);
314  SCIPfreeBufferArray(scip, &path);
315  SCIPfreeBufferArray(scip, &vnoi);
316  SCIPfreeBufferArray(scip, &nodearrint2);
317  SCIPfreeBufferArray(scip, &nodearrint);
318  SCIPfreeBufferArray(scip, &vbase);
319  SCIPfreeBufferArray(scip, &edgearrreal);
320  SCIPfreeBufferArray(scip, &nodearrreal);
321  SCIPfreeBufferArray(scip, &state);
322  SCIPfreeBufferArray(scip, &heap);
323  SCIPfreeBufferArray(scip, &nodearrchar);
324  SCIPfreeBufferArray(scip, &edgearrint);
325 
326  if( gnodearr != NULL )
327  {
328  for( i = nterms - 2; i >= 0; i-- )
329  SCIPfreeBlockMemory(scip, &gnodearr[i]);
330  SCIPfreeBufferArray(scip, &gnodearr);
331  }
332 
333  return SCIP_OKAY;
334 }
335 
336 /** basic reduction package for the (R)PCSTP */
337 static
339  SCIP* scip, /**< SCIP data structure */
340  GRAPH** graph, /**< graph data structure */
341  SCIP_Real* fixed, /**< pointer to store the offset value */
342  int minelims, /**< minimal number of edges to be eliminated in order to reiterate reductions */
343  STP_Bool dualascent, /**< perform dual ascent reductions? */
344  SCIP_Bool userec /**< use recombination heuristic? */
345  )
346 {
347  PATH* vnoi;
348  PATH* path;
349  GRAPH* g = *graph;
350  GNODE** gnodearr;
351  SCIP_Real* exedgearrreal;
352  SCIP_Real* nodearrreal;
353  SCIP_Real* exedgearrreal2;
354  SCIP_Real timelimit;
355  int* heap;
356  int* state;
357  int* vbase;
358  int* nodearrint;
359  int* edgearrint;
360  int* nodearrint2;
361  int i;
362  int nnodes;
363  int nterms;
364  int nedges;
365  int extnedges;
366  int reductbound;
367  STP_Bool* nodearrchar;
368  SCIP_Bool bred = FALSE;
369 
370  assert(scip != NULL);
371  assert(g != NULL);
372  assert(minelims >= 0);
373 
374  nterms = g->terms;
375  nnodes = g->knots;
376  nedges = g->edges;
377 
378  /* for PCSPG more memory is necessary */
379  if( g->stp_type == STP_RPCSPG || !dualascent )
380  extnedges = nedges;
381  else
382  extnedges = nedges + 2 * (g->terms - 1);
383 
384  /* get timelimit parameter*/
385  SCIP_CALL( SCIPgetRealParam(scip, "limits/time", &timelimit) );
386 
387  /* allocate memory */
388  SCIP_CALL( SCIPallocBufferArray(scip, &heap, nnodes + 1) );
389  SCIP_CALL( SCIPallocBufferArray(scip, &state, 4 * nnodes) );
390  SCIP_CALL( SCIPallocBufferArray(scip, &nodearrreal, nnodes + 2) );
391  SCIP_CALL( SCIPallocBufferArray(scip, &exedgearrreal, extnedges ) );
392  SCIP_CALL( SCIPallocBufferArray(scip, &vbase, 4 * nnodes) );
393  SCIP_CALL( SCIPallocBufferArray(scip, &vnoi, 4 * nnodes) );
394  SCIP_CALL( SCIPallocBufferArray(scip, &path, nnodes + 1) );
395  SCIP_CALL( SCIPallocBufferArray(scip, &nodearrint, nnodes + 1) );
396  SCIP_CALL( SCIPallocBufferArray(scip, &nodearrint2, nnodes + 1) );
397  SCIP_CALL( SCIPallocBufferArray(scip, &nodearrchar, nnodes + 1) );
398 
399  if( SCIPisLE(scip, (double) nterms / (double) nnodes, 0.03) )
400  bred = TRUE;
401 
402  if( bred || dualascent )
403  {
404  SCIP_CALL( SCIPallocBufferArray(scip, &exedgearrreal2, extnedges) );
405  }
406  else
407  {
408  exedgearrreal2 = NULL;
409  }
410 
411  if( dualascent )
412  {
413  SCIP_CALL( SCIPallocBufferArray(scip, &edgearrint, extnedges) );
414  SCIP_CALL( SCIPallocBufferArray(scip, &gnodearr, nterms - 1) );
415  for( i = 0; i < nterms - 1; i++ )
416  {
417  SCIP_CALL( SCIPallocBlockMemory(scip, &gnodearr[i]) ); /*lint !e866*/
418  }
419  }
420  else
421  {
422  gnodearr = NULL;
423  SCIP_CALL( SCIPallocBufferArray(scip, &edgearrint, nedges) );
424  }
425 
426  /* define minimal number of edge/node eliminations for a reduction test to be continued */
427  reductbound = MAX(nnodes / 1000, minelims);
428 
429  /* reduction loop */
430  SCIP_CALL( redLoopPc(scip, g, vnoi, path, gnodearr, nodearrreal, exedgearrreal, exedgearrreal2, heap, state,
431  vbase, nodearrint, edgearrint, nodearrint2, NULL, nodearrchar, fixed, dualascent, bred, reductbound, userec) );
432 
433  /* free memory */
434 
435  if( gnodearr != NULL )
436  {
437  for( i = nterms - 2; i >= 0; i-- )
438  SCIPfreeBlockMemory(scip, &gnodearr[i]);
439  SCIPfreeBufferArray(scip, &gnodearr);
440  }
441  SCIPfreeBufferArray(scip, &edgearrint);
442  SCIPfreeBufferArrayNull(scip, &exedgearrreal2);
443  SCIPfreeBufferArray(scip, &nodearrchar);
444  SCIPfreeBufferArray(scip, &nodearrint2);
445  SCIPfreeBufferArray(scip, &nodearrint);
446  SCIPfreeBufferArray(scip, &path);
447  SCIPfreeBufferArray(scip, &vnoi);
448  SCIPfreeBufferArray(scip, &vbase);
449  SCIPfreeBufferArray(scip, &exedgearrreal);
450  SCIPfreeBufferArray(scip, &nodearrreal);
451  SCIPfreeBufferArray(scip, &state);
452  SCIPfreeBufferArray(scip, &heap);
453 
454  return SCIP_OKAY;
455 }
456 
457 /** reduction package for the MWCSP */
458 static
460  SCIP* scip, /**< SCIP data structure */
461  GRAPH** graph, /**< graph data structure */
462  SCIP_Real* fixed, /**< pointer to store the offset value */
463  int minelims, /**< minimal number of edges to be eliminated in order to reiterate reductions */
464  STP_Bool advanced, /**< perform advanced reductions? */
465  SCIP_Bool userec /**< use recombination heuristic? */
466  )
467 {
468  GRAPH* g = *graph;
469  PATH* vnoi;
470  PATH* path;
471  GNODE** gnodearr;
472  SCIP_Real* nodearrreal;
473  SCIP_Real* edgearrreal;
474  SCIP_Real* edgearrreal2;
475  int* state;
476  int* vbase;
477  int* edgearrint;
478  int* nodearrint;
479  int* nodearrint2;
480  int* nodearrint3;
481  int i;
482  int nterms;
483  int nnodes;
484  int nedges;
485  int redbound;
486  int extnedges;
487  STP_Bool* nodearrchar;
488  STP_Bool bred = FALSE;
489 
490  assert(scip != NULL);
491  assert(g != NULL);
492  assert(fixed != NULL);
493  nnodes = g->knots;
494  nedges = g->edges;
495  nterms = g->terms;
496  redbound = MAX(nnodes / 1000, minelims);
497 
498  if( SCIPisLE(scip, (double) nterms / (double) nnodes, 0.1) )
499  bred = TRUE;
500 
501  if( advanced )
502  {
503  extnedges = nedges + 2 * (g->terms - 1);
504 
505  SCIP_CALL( SCIPallocBufferArray(scip, &gnodearr, nterms - 1) );
506  for( i = 0; i < nterms - 1; i++ )
507  {
508  SCIP_CALL( SCIPallocBlockMemory(scip, &gnodearr[i]) ); /*lint !e866*/
509  }
510  SCIP_CALL( SCIPallocBufferArray(scip, &edgearrint, extnedges) );
511  }
512  else
513  {
514  extnedges = nedges;
515  edgearrint = NULL;
516  gnodearr = NULL;
517  }
518 
519  SCIP_CALL( SCIPallocBufferArray(scip, &nodearrint, nnodes + 1) );
520  SCIP_CALL( SCIPallocBufferArray(scip, &nodearrint2, nnodes + 1) );
521  SCIP_CALL( SCIPallocBufferArray(scip, &nodearrint3, nnodes + 1) );
522  SCIP_CALL( SCIPallocBufferArray(scip, &nodearrchar, nnodes + 1) );
523  SCIP_CALL( SCIPallocBufferArray(scip, &state, 3 * nnodes) );
524  SCIP_CALL( SCIPallocBufferArray(scip, &vbase, 3 * nnodes) );
525  SCIP_CALL( SCIPallocBufferArray(scip, &vnoi, 3 * nnodes) );
526  SCIP_CALL( SCIPallocBufferArray(scip, &path, nnodes + 1) );
527 
528  if( bred || advanced )
529  {
530  SCIP_CALL( SCIPallocBufferArray(scip, &nodearrreal, nnodes + 2) );
531  SCIP_CALL( SCIPallocBufferArray(scip, &edgearrreal, extnedges) );
532  SCIP_CALL( SCIPallocBufferArray(scip, &edgearrreal2, extnedges) );
533  }
534  else
535  {
536  nodearrreal = NULL;
537  edgearrreal = NULL;
538  edgearrreal2 = NULL;
539  }
540 
541  /* reduction loop */
542  SCIP_CALL( redLoopMw(scip, g, vnoi, path, gnodearr, nodearrreal, edgearrreal, edgearrreal2, state,
543  vbase, nodearrint, edgearrint, nodearrint2, nodearrint3, NULL, nodearrchar, fixed, advanced, bred, advanced, redbound, userec) );
544 
545  /* free memory */
546  SCIPfreeBufferArrayNull(scip, &edgearrreal2);
547  SCIPfreeBufferArrayNull(scip, &edgearrreal);
548  SCIPfreeBufferArrayNull(scip, &nodearrreal);
549  SCIPfreeBufferArray(scip, &path);
550  SCIPfreeBufferArray(scip, &vnoi);
551  SCIPfreeBufferArray(scip, &vbase);
552  SCIPfreeBufferArray(scip, &state);
553  SCIPfreeBufferArray(scip, &nodearrchar);
554  SCIPfreeBufferArray(scip, &nodearrint3);
555  SCIPfreeBufferArray(scip, &nodearrint2);
556  SCIPfreeBufferArray(scip, &nodearrint);
557  SCIPfreeBufferArrayNull(scip, &edgearrint);
558 
559  if( gnodearr != NULL )
560  {
561  for( i = nterms - 2; i >= 0; i-- )
562  SCIPfreeBlockMemory(scip, &gnodearr[i]);
563  SCIPfreeBufferArray(scip, &gnodearr);
564  }
565 
566  return SCIP_OKAY;
567 }
568 
569 /** basic reduction package for the HCDSTP */
570 static
572  SCIP* scip, /**< SCIP data structure */
573  GRAPH** graph, /**< graph data structure */
574  SCIP_Real* fixed, /**< pointer to store the offset value */
575  int minelims /**< minimal number of edges to be eliminated in order to reiterate reductions */
576  )
577 {
578  GRAPH* g = *graph;
579  PATH* vnoi;
580  SCIP_Real* cost;
581  SCIP_Real* radius;
582  SCIP_Real* costrev;
583  SCIP_Real timelimit;
584  SCIP_Real upperbound;
585  int* heap;
586  int* state;
587  int* vbase;
588  int* pathedge;
589  int nnodes;
590  int nedges;
591  int redbound;
592 #if 0
593  int danelims;
594 #endif
595  int degnelims;
596  int brednelims;
597  int hbrednelims;
598  int hcrnelims;
599  int hcrcnelims;
600  STP_Bool* nodearrchar;
601 #if 0
602  DOES NOT WORK for HC!
603  STP_Bool da = !TRUE;
604 #endif
605  STP_Bool bred = TRUE;
606  STP_Bool hbred = TRUE;
607  STP_Bool rbred = TRUE;
608  STP_Bool rcbred = TRUE;
609 
610  assert(scip != NULL);
611  assert(g != NULL);
612  assert(minelims >= 0);
613 
614  nnodes = g->knots;
615  nedges = g->edges;
616  degnelims = 0;
617  upperbound = -1.0;
618  redbound = MAX(g->knots / 1000, minelims);
619  SCIP_CALL( SCIPgetRealParam(scip, "limits/time", &timelimit) );
620 
621  /* allocate memory */
622  SCIP_CALL( SCIPallocBufferArray(scip, &nodearrchar, nnodes) );
623  SCIP_CALL( SCIPallocBufferArray(scip, &heap, nnodes + 1) );
624  SCIP_CALL( SCIPallocBufferArray(scip, &state, 3 * nnodes) );
625  SCIP_CALL( SCIPallocBufferArray(scip, &cost, nedges) );
626  SCIP_CALL( SCIPallocBufferArray(scip, &radius, nnodes) );
627  SCIP_CALL( SCIPallocBufferArray(scip, &costrev, nedges) );
628  SCIP_CALL( SCIPallocBufferArray(scip, &vbase, 3 * nnodes) );
629  SCIP_CALL( SCIPallocBufferArray(scip, &pathedge, nnodes) );
630  SCIP_CALL( SCIPallocBufferArray(scip, &vnoi, 3 * nnodes) );
631 
632  SCIP_CALL( reduce_simple_hc(scip, g, fixed, &degnelims) );
633 
634  while( (bred || hbred || rbred || rcbred) && !SCIPisStopped(scip) )
635  {
636  if( SCIPgetTotalTime(scip) > timelimit )
637  break;
638 
639  upperbound = -1.0;
640 
641  if( rbred )
642  {
643  SCIP_CALL( reduce_boundHopR(scip, g, vnoi, cost, costrev, radius, heap, state, vbase, &hcrnelims, pathedge) );
644  if( hcrnelims <= redbound )
645  rbred = FALSE;
646  }
647 
648  if( rcbred )
649  {
650  SCIP_CALL( reduce_boundHopRc(scip, g, vnoi, cost, costrev, radius, -1.0, heap, state, vbase, &hcrcnelims, pathedge, FALSE) );
651  if( hcrcnelims <= redbound )
652  rcbred = FALSE;
653  }
654 
655  if( bred )
656  {
657  SCIP_CALL( reduce_bound(scip, g, vnoi, cost, NULL, radius, costrev, fixed, &upperbound, heap, state, vbase, &brednelims) );
658  if( brednelims <= redbound )
659  bred = FALSE;
660  }
661 
662  if( SCIPgetTotalTime(scip) > timelimit )
663  break;
664 
665  if( hbred )
666  {
667  SCIP_CALL( reduce_boundHop(scip, g, vnoi, cost, radius, costrev, heap, state, vbase, &hbrednelims) );
668  if( hbrednelims <= redbound )
669  hbred = FALSE;
670  if( SCIPgetTotalTime(scip) > timelimit )
671  break;
672  }
673  }
674 
675  /* free memory */
676  SCIPfreeBufferArray(scip, &vnoi);
677  SCIPfreeBufferArray(scip, &pathedge);
678  SCIPfreeBufferArray(scip, &vbase);
679  SCIPfreeBufferArray(scip, &costrev);
680  SCIPfreeBufferArray(scip, &radius);
681  SCIPfreeBufferArray(scip, &cost);
682  SCIPfreeBufferArray(scip, &state);
683  SCIPfreeBufferArray(scip, &heap);
684  SCIPfreeBufferArray(scip, &nodearrchar);
685 
686  return SCIP_OKAY;
687 }
688 
689 /** basic reduction package for the SAP */
690 static
692  SCIP* scip, /**< SCIP data structure */
693  GRAPH** graph, /**< graph data structure */
694  SCIP_Real* fixed, /**< pointer to store the offset value */
695  int minelims /**< minimal number of edges to be eliminated in order to reiterate reductions */
696  )
697 {
698  PATH* vnoi;
699  PATH* path;
700  SCIP_Real ub = FARAWAY;
701  SCIP_Real timelimit;
702  SCIP_Real* nodearrreal;
703  SCIP_Real* edgearrreal;
704  SCIP_Real* edgearrreal2;
705  GRAPH* g = *graph;
706  GNODE** gnodearr;
707  int* heap;
708  int* state;
709  int* vbase;
710  int* nodearrint;
711  int* edgearrint;
712  int* nodearrint2;
713  int e;
714  int i;
715  int nnodes;
716  int nedges;
717  int nterms;
718  int danelims;
719  int sdnelims;
720  int rptnelims;
721  int degtnelims;
722  int redbound;
723  STP_Bool da = TRUE;
724  STP_Bool sd = !TRUE;
725  STP_Bool* nodearrchar;
726  STP_Bool rpt = TRUE;
727  SCIP_RANDNUMGEN* randnumgen;
728 
729  /* create random number generator */
730  SCIP_CALL( SCIPcreateRandom(scip, &randnumgen, 1, TRUE) );
731 
732  nnodes = g->knots;
733  nedges = g->edges;
734  nterms = g->terms;
735 
736  redbound = MAX(nnodes / 1000, minelims);
737  SCIP_CALL( SCIPgetRealParam(scip, "limits/time", &timelimit) );
738 
739  SCIP_CALL( SCIPallocBufferArray(scip, &gnodearr, nterms - 1) );
740  for( i = 0; i < nterms - 1; i++ )
741  {
742  SCIP_CALL( SCIPallocBlockMemory(scip, &gnodearr[i]) ); /*lint !e866*/
743  }
744 
745  /* allocate memory */
746  SCIP_CALL( SCIPallocBufferArray(scip, &edgearrint, nedges) );
747  SCIP_CALL( SCIPallocBufferArray(scip, &nodearrchar, nnodes) );
748  SCIP_CALL( SCIPallocBufferArray(scip, &heap, nnodes + 1) );
749  SCIP_CALL( SCIPallocBufferArray(scip, &state, nnodes) );
750  SCIP_CALL( SCIPallocBufferArray(scip, &nodearrreal, nnodes) );
751  SCIP_CALL( SCIPallocBufferArray(scip, &edgearrreal, nedges) );
752  SCIP_CALL( SCIPallocBufferArray(scip, &vbase, nnodes) );
753  SCIP_CALL( SCIPallocBufferArray(scip, &nodearrint, nnodes) );
754  SCIP_CALL( SCIPallocBufferArray(scip, &nodearrint2, nnodes) );
755  SCIP_CALL( SCIPallocBufferArray(scip, &vnoi, nnodes) );
756  SCIP_CALL( SCIPallocBufferArray(scip, &path, nnodes) );
757  SCIP_CALL( SCIPallocBufferArray(scip, &edgearrreal2, nedges) );
758 
759  /* @todo change .stp file format for SAP! */
760  for( e = 0; e < g->edges; e++ )
761  if( SCIPisEQ(scip, g->cost[e], 20000.0) )
762  g->cost[e] = FARAWAY;
763 
764  SCIP_CALL( reduce_simple_sap(scip, g, fixed, &degtnelims) );
765 
766  /* main loop */
767  while( (sd || rpt || da) && !SCIPisStopped(scip) )
768  {
769  if( SCIPgetTotalTime(scip) > timelimit )
770  break;
771 
772  if( sd )
773  {
774  SCIP_CALL( reduce_sdspSap(scip, g, vnoi, path, heap, state, vbase, nodearrint, nodearrint2, &sdnelims, 300) );
775  if( sdnelims <= redbound )
776  sd = FALSE;
777  }
778 
779  if( rpt )
780  {
781  SCIP_CALL( reduce_rpt(scip, g, fixed, &rptnelims) );
782  if( rptnelims <= redbound )
783  rpt = FALSE;
784  }
785 
786  SCIP_CALL( reduce_simple_sap(scip, g, fixed, &degtnelims) );
787 
788  if( da )
789  {
790  SCIP_CALL( reduce_da(scip, g, vnoi, gnodearr, edgearrreal, edgearrreal2, nodearrreal, &ub, fixed, edgearrint, vbase, state, heap, nodearrint,
791  nodearrint2, nodearrchar, &danelims, 0, randnumgen, FALSE, FALSE) );
792 
793  if( danelims <= 2 * redbound )
794  da = FALSE;
795  }
796  }
797 
798  SCIP_CALL( reduce_simple_sap(scip, g, fixed, &degtnelims) );
799 
800  SCIPfreeBufferArray(scip, &edgearrreal2);
801  SCIPfreeBufferArray(scip, &path);
802  SCIPfreeBufferArray(scip, &vnoi);
803  SCIPfreeBufferArray(scip, &nodearrint2);
804  SCIPfreeBufferArray(scip, &nodearrint);
805  SCIPfreeBufferArray(scip, &vbase);
806  SCIPfreeBufferArray(scip, &edgearrreal);
807  SCIPfreeBufferArray(scip, &nodearrreal);
808  SCIPfreeBufferArray(scip, &state);
809  SCIPfreeBufferArray(scip, &heap);
810  SCIPfreeBufferArray(scip, &nodearrchar);
811  SCIPfreeBufferArray(scip, &edgearrint);
812 
813  for( i = nterms - 2; i >= 0; i-- )
814  SCIPfreeBlockMemory(scip, &gnodearr[i]);
815  SCIPfreeBufferArray(scip, &gnodearr);
816 
817  /* free random number generator */
818  SCIPfreeRandom(scip, &randnumgen);
819 
820  return SCIP_OKAY;
821 }
822 
823 
824 static
826  SCIP* scip, /**< SCIP data structure */
827  GRAPH** graph, /**< graph data structure */
828  SCIP_Real* fixed, /**< pointer to store the offset value */
829  int minelims /**< minimal number of edges to be eliminated in order to reiterate reductions */
830  )
831 {
832  PATH* vnoi;
833  SCIP_Real* nodearrreal;
834  SCIP_Real* edgearrreal;
835  SCIP_Real* edgearrreal2;
836  SCIP_Real ub = FARAWAY;
837  SCIP_Real timelimit;
838  GRAPH* g = *graph;
839  GNODE** gnodearr;
840  int* heap;
841  int* state;
842  int* vbase;
843  int* nodearrint;
844  int* edgearrint;
845  int* nodearrint2;
846  int i;
847  int nnodes;
848  int nedges;
849  int nterms;
850  int danelims;
851  int redbound;
852 
853  STP_Bool* nodearrchar;
854  STP_Bool da = TRUE;
855  SCIP_RANDNUMGEN* randnumgen;
856 
857  /* create random number generator */
858  SCIP_CALL( SCIPcreateRandom(scip, &randnumgen, 1, TRUE) );
859 
860  nnodes = g->knots;
861  nedges = g->edges;
862  nterms = g->terms;
863 
864  redbound = MAX(nnodes / 1000, minelims);
865  SCIP_CALL( SCIPgetRealParam(scip, "limits/time", &timelimit) );
866 
867  SCIP_CALL( SCIPallocBufferArray(scip, &gnodearr, nterms - 1) );
868  for( i = 0; i < nterms - 1; i++ )
869  {
870  SCIP_CALL( SCIPallocBlockMemory(scip, &gnodearr[i]) ); /*lint !e866*/
871  }
872 
873  /* allocate memory */
874  SCIP_CALL( SCIPallocBufferArray(scip, &edgearrint, nedges) );
875  SCIP_CALL( SCIPallocBufferArray(scip, &nodearrchar, nnodes) );
876  SCIP_CALL( SCIPallocBufferArray(scip, &heap, nnodes + 1) );
877  SCIP_CALL( SCIPallocBufferArray(scip, &state, nnodes) );
878  SCIP_CALL( SCIPallocBufferArray(scip, &nodearrreal, nnodes) );
879  SCIP_CALL( SCIPallocBufferArray(scip, &edgearrreal, nedges) );
880  SCIP_CALL( SCIPallocBufferArray(scip, &vbase, nnodes) );
881  SCIP_CALL( SCIPallocBufferArray(scip, &nodearrint, nnodes) );
882  SCIP_CALL( SCIPallocBufferArray(scip, &nodearrint2, nnodes) );
883  SCIP_CALL( SCIPallocBufferArray(scip, &vnoi, nnodes) );
884  SCIP_CALL( SCIPallocBufferArray(scip, &edgearrreal2, nedges) );
885 
886  while( (da) && !SCIPisStopped(scip) )
887  {
888  if( SCIPgetTotalTime(scip) > timelimit )
889  break;
890 
891  SCIP_CALL( reduce_da(scip, g, vnoi, gnodearr, edgearrreal, edgearrreal2, nodearrreal, &ub, fixed, edgearrint, vbase, state, heap, nodearrint,
892  nodearrint2, nodearrchar, &danelims, 0, randnumgen, FALSE, FALSE) );
893 
894  if( danelims <= 2 * redbound )
895  da = FALSE;
896  }
897 
898  SCIPfreeBufferArray(scip, &edgearrreal2);
899  SCIPfreeBufferArray(scip, &vnoi);
900  SCIPfreeBufferArray(scip, &nodearrint2);
901  SCIPfreeBufferArray(scip, &nodearrint);
902  SCIPfreeBufferArray(scip, &vbase);
903  SCIPfreeBufferArray(scip, &edgearrreal);
904  SCIPfreeBufferArray(scip, &nodearrreal);
905  SCIPfreeBufferArray(scip, &state);
906  SCIPfreeBufferArray(scip, &heap);
907  SCIPfreeBufferArray(scip, &nodearrchar);
908  SCIPfreeBufferArray(scip, &edgearrint);
909 
910  for( i = nterms - 2; i >= 0; i-- )
911  SCIPfreeBlockMemory(scip, &gnodearr[i]);
912  SCIPfreeBufferArray(scip, &gnodearr);
913 
914  /* free random number generator */
915  SCIPfreeRandom(scip, &randnumgen);
916 
917  return SCIP_OKAY;
918 }
919 
920 /** MWCS loop */
922  SCIP* scip, /**< SCIP data structure */
923  GRAPH* g, /**< graph data structure */
924  PATH* vnoi, /**< Voronoi data structure */
925  PATH* path, /**< path data structure */
926  GNODE** gnodearr, /**< nodes-sized array */
927  SCIP_Real* nodearrreal, /**< nodes-sized array */
928  SCIP_Real* edgearrreal, /**< edges-sized array */
929  SCIP_Real* edgearrreal2, /**< edges-sized array */
930  int* state, /**< shortest path array */
931  int* vbase, /**< voronoi base array */
932  int* nodearrint, /**< nodes-sized array */
933  int* edgearrint, /**< edges-sized array */
934  int* nodearrint2, /**< nodes-sized array */
935  int* nodearrint3, /**< nodes-sized array */
936  int* solnode, /**< array to indicate whether a node is part of the current solution (==CONNECT) */
937  STP_Bool* nodearrchar, /**< nodes-sized array */
938  SCIP_Real* fixed, /**< pointer to store the offset value */
939  STP_Bool advanced, /**< do advanced reduction? */
940  STP_Bool bred, /**< do bound-based reduction? */
941  STP_Bool tryrmw, /**< try to convert problem to RMWCSP? Only possible if advanced = TRUE and userec = TRUE */
942  int redbound, /**< minimal number of edges to be eliminated in order to reiterate reductions */
943  SCIP_Bool userec /**< use recombination heuristic? */
944  )
945 {
946  SCIP_Real timelimit;
947  int daelims;
948  int anselims;
949  int nnpelims;
950  int degelims;
951  int npvelims;
952  int bredelims;
953  int ansadelims;
954  int ansad2elims;
955  int chain2elims;
956 
957  STP_Bool da = advanced;
958  STP_Bool ans = TRUE;
959  STP_Bool nnp = TRUE;
960  STP_Bool npv = TRUE;
961  STP_Bool rerun = TRUE;
962  STP_Bool ansad = TRUE;
963  STP_Bool ansad2 = TRUE;
964  STP_Bool chain2 = TRUE;
965  STP_Bool extensive = STP_RED_EXTENSIVE;
966  SCIP_RANDNUMGEN* randnumgen;
967  SCIP_Real prizesum;
968 
969  assert(scip != NULL);
970  assert(g != NULL);
971  assert(fixed != NULL);
972  assert(advanced || !tryrmw);
973 
974  tryrmw = tryrmw && userec;
975 
976  /* create random number generator */
977  SCIP_CALL( SCIPcreateRandom(scip, &randnumgen, 1, TRUE) );
978 
979  SCIP_CALL( SCIPgetRealParam(scip, "limits/time", &timelimit) );
980 
981  graph_pc_2org(g);
982 
983  degelims = 0;
984 
985  SCIP_CALL( reduce_simple_mw(scip, g, solnode, fixed, &degelims) );
986  assert(graph_pc_term2edgeConsistent(g));
987 
988  prizesum = graph_pc_getPosPrizeSum(scip, g);
989 
990  for( int rounds = 0; rounds < STP_RED_MAXNROUNDS && !SCIPisStopped(scip) && rerun; rounds++ )
991  {
992  daelims = 0;
993  anselims = 0;
994  nnpelims = 0;
995  degelims = 0;
996  npvelims = 0;
997  bredelims = 0;
998  ansadelims = 0;
999  ansad2elims = 0;
1000  chain2elims = 0;
1001 
1002  if( SCIPgetTotalTime(scip) > timelimit )
1003  break;
1004 
1005  if( ans || extensive )
1006  {
1007  reduce_ans(scip, g, nodearrint2, &anselims);
1008 
1009  if( anselims <= redbound )
1010  ans = FALSE;
1011 
1012  SCIPdebugMessage("ans deleted: %d \n", anselims);
1013  }
1014 
1015  if( ansad || extensive )
1016  {
1017  reduce_ansAdv(scip, g, nodearrint2, &ansadelims, FALSE);
1018 
1019  if( ansadelims <= redbound )
1020  ansad = FALSE;
1021 
1022  SCIPdebugMessage("ans advanced deleted: %d \n", ansadelims);
1023  }
1024 
1025  if( ans || ansad || nnp || npv || extensive )
1026  SCIP_CALL( reduce_simple_mw(scip, g, solnode, fixed, &degelims) );
1027 
1028  if( (da || (advanced && extensive)) )
1029  {
1030  SCIP_CALL( reduce_daPcMw(scip, g, vnoi, gnodearr, edgearrreal, edgearrreal2, nodearrreal, vbase, nodearrint, edgearrint,
1031  state, nodearrchar, &daelims, TRUE, FALSE, FALSE, userec, (rounds == 0), randnumgen, prizesum) );
1032 
1033  if( daelims <= 2 * redbound )
1034  da = FALSE;
1035  else
1036  SCIP_CALL( reduce_simple_mw(scip, g, solnode, fixed, &degelims) );
1037 
1038  SCIPdebugMessage("Dual-Ascent Elims: %d \n", daelims);
1039  }
1040 
1041  if( nnp )
1042  {
1043  reduce_nnp(scip, g, nodearrint2, &nnpelims);
1044 
1045  if( nnpelims <= redbound )
1046  nnp = FALSE;
1047 
1048  SCIPdebugMessage("nnp deleted: %d \n", nnpelims);
1049  }
1050 
1051  if( nnp || extensive )
1052  {
1053  SCIP_CALL(reduce_chain2(scip, g, vnoi, path, state, vbase, nodearrint, nodearrint2, nodearrint3, &chain2elims, 500));
1054 
1055  if( chain2elims <= redbound )
1056  chain2 = FALSE;
1057 
1058  SCIPdebugMessage("chain2 delete: %d \n", chain2elims);
1059 
1060  if( SCIPgetTotalTime(scip) > timelimit )
1061  break;
1062  }
1063 
1064  if( npv || extensive )
1065  {
1066  SCIP_CALL(reduce_npv(scip, g, vnoi, path, state, vbase, nodearrint, nodearrint2, nodearrint3, &npvelims, 400));
1067 
1068  if( npvelims <= redbound )
1069  npv = FALSE;
1070 
1071  SCIPdebugMessage("npv delete: %d \n", npvelims);
1072  }
1073 
1074  if( chain2 || extensive )
1075  {
1076  SCIP_CALL(reduce_chain2(scip, g, vnoi, path, state, vbase, nodearrint, nodearrint2, nodearrint3, &chain2elims, 300));
1077 
1078  if( chain2elims <= redbound )
1079  chain2 = FALSE;
1080 
1081  SCIPdebugMessage("chain2 delete: %d \n", chain2elims);
1082  }
1083 
1084  SCIP_CALL( reduce_simple_mw(scip, g, solnode, fixed, &degelims) );
1085 
1086  if( ansad2 || extensive )
1087  {
1088  reduce_ansAdv2(scip, g, nodearrint2, &ansad2elims);
1089 
1090  if( ansad2elims <= redbound )
1091  ansad2 = FALSE;
1092  else
1093  SCIP_CALL( reduce_simple_mw(scip, g, solnode, fixed, &ansad2elims) );
1094 
1095  SCIPdebugMessage("ans advanced 2 deleted: %d (da? %d ) \n", ansad2elims, da);
1096  }
1097 
1098  if( bred )
1099  {
1100  SCIP_CALL( reduce_boundMw(scip, g, vnoi, path, edgearrreal, nodearrreal, edgearrreal2, fixed, nodearrint, state, vbase, NULL, &bredelims) );
1101 
1102  if( bredelims <= redbound )
1103  bred = FALSE;
1104 
1105 
1106  SCIPdebugMessage("reduce_bound: %d \n", bredelims);
1107  }
1108 
1109  if( anselims + nnpelims + chain2elims + bredelims + npvelims + ansadelims + ansad2elims + daelims <= redbound )
1110  rerun = FALSE;
1111 
1112  if( !rerun && advanced && g->terms > 2 )
1113  {
1114  int cnsadvelims = 0;
1115 
1116  SCIP_CALL( reduce_simple_mw(scip, g, solnode, fixed, &degelims) );
1117 
1118  SCIP_CALL( reduce_daPcMw(scip, g, vnoi, gnodearr, edgearrreal, edgearrreal2, nodearrreal, vbase, nodearrint, edgearrint,
1119  state, nodearrchar, &daelims, TRUE, (g->terms > STP_RED_MWTERMBOUND), tryrmw, userec, FALSE, randnumgen, prizesum) );
1120 
1121  userec = FALSE;
1122 
1123  if( cnsadvelims + daelims >= redbound || (extensive && (cnsadvelims + daelims > 0)) )
1124  {
1125  ans = TRUE;
1126  nnp = TRUE;
1127  npv = TRUE;
1128  ansad = TRUE;
1129  ansad2 = TRUE;
1130  chain2 = TRUE;
1131  rerun = TRUE;
1132  advanced = FALSE;
1133 
1134  SCIP_CALL( reduce_simple_mw(scip, g, solnode, fixed, &degelims) );
1135  SCIPdebugMessage("Restarting reduction loop! (%d eliminations) \n\n ", cnsadvelims + daelims);
1136  if( extensive )
1137  advanced = TRUE;
1138  }
1139  }
1140  }
1141 
1142  SCIP_CALL( reduce_simple_mw(scip, g, solnode, fixed, &degelims) );
1143 
1144  /* go back to the extended graph */
1145  graph_pc_2trans(g);
1146 
1147  SCIP_CALL( level0(scip, g) );
1148 
1149  if( tryrmw && g->terms > 2 )
1150  SCIP_CALL( graph_pc_mw2rmw(scip, g, prizesum) );
1151 
1152  SCIPfreeRandom(scip, &randnumgen);
1153 
1154  return SCIP_OKAY;
1155 }
1156 
1157 /** (R)PC loop */
1159  SCIP* scip, /**< SCIP data structure */
1160  GRAPH* g, /**< graph data structure */
1161  PATH* vnoi, /**< Voronoi data structure */
1162  PATH* path, /**< path data structure */
1163  GNODE** gnodearr, /**< nodes-sized array */
1164  SCIP_Real* nodearrreal, /**< nodes-sized array */
1165  SCIP_Real* exedgearrreal, /**< edges-sized array */
1166  SCIP_Real* exedgearrreal2, /**< edges-sized array */
1167  int* heap, /**< shortest path array */
1168  int* state, /**< voronoi base array */
1169  int* vbase, /**< nodes-sized array */
1170  int* nodearrint, /**< edges-sized array */
1171  int* edgearrint, /**< nodes-sized array */
1172  int* nodearrint2, /**< nodes-sized array */
1173  int* solnode, /**< solution nodes array (or NULL) */
1174  STP_Bool* nodearrchar, /**< nodes-sized array */
1175  SCIP_Real* fixed, /**< pointer to store the offset value */
1176  SCIP_Bool dualascent, /**< do dual-ascent reduction? */
1177  SCIP_Bool bred, /**< do bound-based reduction? */
1178  int reductbound, /**< minimal number of edges to be eliminated in order to reiterate reductions */
1179  SCIP_Bool userec /**< use recombination heuristic? */
1180  )
1181 {
1182  SCIP_Real ub;
1183  SCIP_Real fix;
1184  SCIP_Real timelimit;
1185  SCIP_Real rootprize = 0.0;
1186  const SCIP_Bool rpc = (g->stp_type == STP_RPCSPG);
1187  int nelims;
1188  int danelims;
1189  int sdnelims;
1190  int sdcnelims;
1191  int bd3nelims;
1192  int degnelims;
1193  int nvslnelims;
1194  int brednelims;
1195  SCIP_Bool da = dualascent;
1196  SCIP_Bool sd = TRUE;
1197  SCIP_Bool sdc = TRUE;
1198  SCIP_Bool bd3 = TRUE;
1199  SCIP_Bool nvsl = TRUE;
1200  SCIP_Bool rerun = TRUE;
1201  SCIP_Bool extensive = STP_RED_EXTENSIVE;
1202  SCIP_Bool advancedrun = dualascent;
1203  SCIP_Real prizesum;
1204  SCIP_RANDNUMGEN* randnumgen;
1205 
1206  if( g->grad[g->source] == 0 )
1207  return SCIP_OKAY;
1208 
1209  /* create random number generator */
1210  SCIP_CALL( SCIPcreateRandom(scip, &randnumgen, 1, TRUE) );
1211 
1212  if( rpc )
1213  {
1214  rootprize = g->prize[g->source];
1215  g->prize[g->source] = FARAWAY;
1216  }
1217 
1218  ub = -1.0;
1219  fix = 0.0;
1220 
1221  graph_pc_2org(g);
1222  assert(graph_pc_term2edgeConsistent(g));
1223 
1224  SCIP_CALL( graph_pc_presolInit(scip, g) );
1225 
1226  SCIP_CALL( reduce_simple_pc(scip, g, &fix, &degnelims, solnode, FALSE) );
1227  assert(graph_pc_term2edgeConsistent(g));
1228 
1229  prizesum = graph_pc_getPosPrizeSum(scip, g);
1230 
1231  /* get timelimit parameter */
1232  SCIP_CALL( SCIPgetRealParam(scip, "limits/time", &timelimit) );
1233 
1234  for( int rounds = 0; rounds < STP_RED_MAXNROUNDS && !SCIPisStopped(scip) && rerun; rounds++ )
1235  {
1236  if( SCIPgetTotalTime(scip) > timelimit )
1237  break;
1238 
1239  nelims = 0;
1240  danelims = 0;
1241  sdnelims = 0;
1242  sdcnelims = 0;
1243  bd3nelims = 0;
1244  nvslnelims = 0;
1245  degnelims = 0;
1246  brednelims = 0;
1247 
1248  if( sd || extensive )
1249  {
1250  SCIP_CALL( reduce_sdPc(scip, g, vnoi, heap, state, vbase, nodearrint, nodearrint2, &sdnelims) );
1251 
1252  if( sdnelims <= reductbound )
1253  sd = FALSE;
1254 
1255  SCIPdebugMessage("SDpc: %d \n", sdnelims);
1256  if( SCIPgetTotalTime(scip) > timelimit )
1257  break;
1258  }
1259 
1260  if( sdc || extensive )
1261  {
1262  SCIP_CALL( reduce_sdsp(scip, g, vnoi, path, heap, state, vbase, nodearrint, nodearrint2, &sdcnelims,
1263  ((rounds > 0) ? STP_RED_SDSPBOUND2 : STP_RED_SDSPBOUND), NULL) );
1264 
1265  if( sdcnelims <= reductbound )
1266  sdc = FALSE;
1267 
1268  SCIPdebugMessage("SDsp: %d \n", sdcnelims);
1269  if( SCIPgetTotalTime(scip) > timelimit )
1270  break;
1271  }
1272 
1273  SCIP_CALL( reduce_simple_pc(scip, g, &fix, &nelims, solnode, FALSE) );
1274 
1275  degnelims += nelims;
1276 
1277  if( bd3 && dualascent )
1278  {
1279  SCIP_CALL( reduce_bd34(scip, g, vnoi, path, heap, state, vbase, nodearrint, nodearrint2, &bd3nelims, STP_RED_BD3BOUND) );
1280  if( bd3nelims <= reductbound )
1281  {
1282  bd3 = FALSE;
1283  }
1284  else if( !rpc )
1285  {
1286  SCIP_CALL( reduce_sdPc(scip, g, vnoi, heap, state, vbase, nodearrint, nodearrint2, &sdnelims) );
1287  SCIP_CALL( reduce_sdsp(scip, g, vnoi, path, heap, state, vbase, nodearrint, nodearrint2, &sdcnelims, ((rounds > 0) ? STP_RED_SDSPBOUND2 : STP_RED_SDSPBOUND), NULL) );
1288  }
1289 
1290  SCIPdebugMessage("bd3: %d \n", bd3nelims);
1291  if( SCIPgetTotalTime(scip) > timelimit )
1292  break;
1293  }
1294 
1295  if( nvsl || extensive )
1296  {
1297  SCIP_CALL( nvreduce_sl(scip, g, vnoi, nodearrreal, &fix, edgearrint, heap, state, vbase, nodearrint, nodearrint2, solnode, nodearrchar, &nvslnelims, reductbound) );
1298 
1299  if( nvslnelims <= 0.5 * reductbound )
1300  nvsl = FALSE;
1301 
1302  SCIPdebugMessage("nvsl: %d \n", nvslnelims);
1303  if( SCIPgetTotalTime(scip) > timelimit )
1304  break;
1305  }
1306 
1307  if( bred )
1308  {
1309  ub = -1.0;
1310  SCIP_CALL( reduce_bound(scip, g, vnoi, exedgearrreal, g->prize, nodearrreal, exedgearrreal2, &fix, &ub, heap, state, vbase, &brednelims) );
1311  if( brednelims <= reductbound )
1312  bred = FALSE;
1313 
1314  SCIPdebugMessage("bndelims %d \n", brednelims);
1315  if( SCIPgetTotalTime(scip) > timelimit )
1316  break;
1317  }
1318 
1319  ub = -1.0;
1320 
1321  assert(graph_pc_term2edgeConsistent(g));
1322 
1323  if( da || (dualascent && extensive) )
1324  {
1325  SCIP_CALL( reduce_simple_pc(scip, g, &fix, &degnelims, solnode, TRUE) );
1326 
1327  if( rpc )
1328  SCIP_CALL( reduce_da(scip, g, vnoi, gnodearr, exedgearrreal, exedgearrreal2, nodearrreal, &ub, &fix, edgearrint, vbase, state, heap,
1329  nodearrint, nodearrint2, nodearrchar, &danelims, 0, randnumgen, FALSE, FALSE) );
1330  else
1331  SCIP_CALL( reduce_daPcMw(scip, g, vnoi, gnodearr, exedgearrreal, exedgearrreal2, nodearrreal, vbase, heap, edgearrint,
1332  state, nodearrchar, &danelims, TRUE, FALSE, FALSE, userec, (rounds == 0), randnumgen, prizesum) );
1333 
1334  if( danelims <= reductbound )
1335  da = FALSE;
1336 
1337  SCIPdebugMessage("da: %d \n", danelims);
1338  }
1339 
1340  SCIP_CALL( reduce_simple_pc(scip, g, &fix, &degnelims, solnode, TRUE) );
1341 
1342  if( ub >= 0 )
1343  {
1344  SCIP_CALL( reduce_bound(scip, g, vnoi, exedgearrreal, g->prize, nodearrreal, exedgearrreal2, &fix, &ub, heap, state, vbase, &brednelims) );
1345  if( brednelims <= reductbound )
1346  bred = FALSE;
1347 
1348  SCIPdebugMessage("bndelims %d \n", brednelims);
1349  if( SCIPgetTotalTime(scip) > timelimit )
1350  break;
1351  }
1352 
1353  if( degnelims + sdnelims + sdcnelims + bd3nelims + danelims + brednelims + nvslnelims <= reductbound )
1354  rerun = FALSE;
1355 
1356  if( !rerun && advancedrun && g->terms > 2 )
1357  {
1358  rerun = TRUE;
1359  danelims = 0;
1360  degnelims = 0;
1361  advancedrun = FALSE;
1362  if( rpc )
1363  {
1364  SCIP_CALL( reduce_da(scip, g, vnoi, gnodearr, exedgearrreal, exedgearrreal2, nodearrreal, &ub, &fix, edgearrint, vbase, state, heap,
1365  nodearrint, nodearrint2, nodearrchar, &danelims, 0, randnumgen, FALSE, FALSE) );
1366  }
1367  else
1368  {
1369  SCIP_CALL( reduce_daPcMw(scip, g, vnoi, gnodearr, exedgearrreal, exedgearrreal2, nodearrreal, vbase, heap, edgearrint,
1370  state, nodearrchar, &danelims, TRUE, TRUE, TRUE, userec, FALSE, randnumgen, prizesum) );
1371  }
1372  SCIP_CALL( reduce_simple_pc(scip, g, &fix, &degnelims, solnode, TRUE) );
1373  if( danelims + degnelims > reductbound || (extensive && (danelims + degnelims > 0)) )
1374  {
1375  da = dualascent;
1376  sd = TRUE;
1377  sdc = TRUE;
1378  bd3 = TRUE;
1379  nvsl = TRUE;
1380  if( extensive )
1381  advancedrun = TRUE;
1382  }
1383  else
1384  {
1385  rerun = FALSE;
1386  }
1387  }
1388  }
1389  SCIP_CALL( reduce_simple_pc(scip, g, &fix, &degnelims, solnode, TRUE) );
1390 
1391  if( rpc )
1392  g->prize[g->source] = rootprize;
1393 
1394  assert(graph_pc_term2edgeConsistent(g));
1395  graph_pc_2trans(g);
1396 
1397  graph_pc_presolExit(scip, g);
1398 
1399  /* free random number generator */
1400  SCIPfreeRandom(scip, &randnumgen);
1401 
1402  *fixed += fix;
1403 
1404  SCIPdebugMessage("Reduction Level PC 1: Fixed Cost = %.12e\n", *fixed);
1405  return SCIP_OKAY;
1406 }
1407 
1408 /** STP loop */
1410  SCIP* scip, /**< SCIP data structure */
1411  GRAPH* g, /**< graph data structure */
1412  PATH* vnoi, /**< Voronoi data structure */
1413  PATH* path, /**< path data structure */
1414  GNODE** gnodearr, /**< nodes-sized array */
1415  SCIP_Real* nodearrreal, /**< nodes-sized array */
1416  SCIP_Real* edgearrreal, /**< edges-sized array */
1417  SCIP_Real* edgearrreal2, /**< edges-sized array */
1418  int* heap, /**< heap array */
1419  int* state, /**< shortest path array */
1420  int* vbase, /**< Voronoi base array */
1421  int* nodearrint, /**< edges-sized array */
1422  int* edgearrint, /**< nodes-sized array */
1423  int* nodearrint2, /**< nodes-sized array */
1424  int* solnode, /**< solution nodes array (or NULL) */
1425  STP_Bool* nodearrchar, /**< nodes-sized array */
1426  SCIP_Real* fixed, /**< pointer to store the offset value */
1427  SCIP_Real upperbound, /**< upper bound */
1428  SCIP_Bool dualascent, /**< do dual-ascent reduction? */
1429  SCIP_Bool boundreduce, /**< do bound-based reduction? */
1430  SCIP_Bool nodereplacing, /**< should node replacement (by edges) be performed? */
1431  int reductbound, /**< minimal number of edges to be eliminated in order to reiterate reductions */
1432  SCIP_Bool userec, /**< use recombination heuristic? */
1433  SCIP_Bool fullreduce /**< use full reductions? (including extended techniques) */
1434  )
1435 {
1436  SCIP_Real ub;
1437  SCIP_Real fix;
1438  SCIP_Real timelimit;
1439  SCIP_Bool le = TRUE;
1440  SCIP_Bool sd = TRUE;
1441  SCIP_Bool da = dualascent;
1442  SCIP_Bool sdc = TRUE;
1443  SCIP_Bool bd3 = nodereplacing;
1444  SCIP_Bool bred = boundreduce;
1445  SCIP_Bool nvsl = nodereplacing;
1446  SCIP_Bool rerun = TRUE;
1447 
1448  const SCIP_Bool extensive = STP_RED_EXTENSIVE;
1449  int i = 0;
1450 
1451  SCIP_RANDNUMGEN* randnumgen;
1452 
1453  assert(reductbound > 0);
1454  assert(graph_valid(g));
1455 
1456  /* create random number generator */
1457  SCIP_CALL( SCIPcreateRandom(scip, &randnumgen, 1, TRUE) );
1458 
1459  ub = upperbound;
1460  fix = 0.0;
1461 
1463  SCIP_CALL( reduce_simple(scip, g, &fix, solnode, &i, NULL) );
1464 
1465  /* get timelimit parameter */
1466  SCIP_CALL( SCIPgetRealParam(scip, "limits/time", &timelimit) );
1467 
1468  do
1469  {
1470  int inner_rounds = 0;
1471  int inner_restarts = 0;
1472 
1473  /* inner reduction loop */
1474  while( rerun && !SCIPisStopped(scip) )
1475  {
1476  int danelims = 0;
1477  int lenelims = 0;
1478  int sdnelims = 0;
1479  int sdcnelims = 0;
1480  int bd3nelims = 0;
1481  int nvslnelims = 0;
1482  int brednelims = 0;
1483  int degtnelims = 0;
1484 
1485  if( SCIPgetTotalTime(scip) > timelimit )
1486  break;
1487 
1488  if( le || extensive )
1489  {
1490  SCIP_CALL(reduce_ledge(scip, g, vnoi, heap, state, vbase, &lenelims, NULL));
1491 
1492  if( lenelims <= reductbound )
1493  le = FALSE;
1494  else
1495  SCIP_CALL(reduce_simple(scip, g, &fix, solnode, &degtnelims, NULL));
1496 
1497  reduceStatsPrint(fullreduce, "le", lenelims);
1498  SCIPdebugMessage("le: %d \n", lenelims);
1499 
1500  if( SCIPgetTotalTime(scip) > timelimit )
1501  break;
1502  }
1503 
1504  if( sd || extensive )
1505  {
1506  SCIP_CALL(
1507  reduce_sd(scip, g, vnoi, edgearrreal, nodearrreal, heap, state, vbase, nodearrint, nodearrint2, edgearrint, &sdnelims,
1508  nodereplacing, NULL));
1509 
1510  if( sdnelims <= reductbound )
1511  sd = FALSE;
1512 
1513  reduceStatsPrint(fullreduce, "sd", sdnelims);
1514  SCIPdebugMessage("sd: %d, \n", sdnelims);
1515 
1516  if( SCIPgetTotalTime(scip) > timelimit )
1517  break;
1518  }
1519 
1520  if( sdc || extensive )
1521  {
1522  SCIP_CALL(
1523  reduce_sdsp(scip, g, vnoi, path, heap, state, vbase, nodearrint, nodearrint2, &sdcnelims, ((inner_rounds > 0) ? (STP_RED_SDSPBOUND2 / 2) : (STP_RED_SDSPBOUND / 2)), NULL));
1524 
1525  if( sdcnelims <= reductbound )
1526  sdc = FALSE;
1527 
1528  reduceStatsPrint(fullreduce, "sdsp", sdcnelims);
1529  SCIPdebugMessage("sdsp: %d \n", sdcnelims);
1530 
1531  if( SCIPgetTotalTime(scip) > timelimit )
1532  break;
1533  }
1534 
1535  if( sd || sdc )
1536  SCIP_CALL(reduce_simple(scip, g, &fix, solnode, &degtnelims, NULL));
1537 
1538  if( bd3 || extensive )
1539  {
1540  SCIP_CALL(reduce_bd34(scip, g, vnoi, path, heap, state, vbase, nodearrint, nodearrint2, &bd3nelims, STP_RED_BD3BOUND));
1541  if( bd3nelims <= reductbound )
1542  bd3 = FALSE;
1543  else
1544  SCIP_CALL(reduce_simple(scip, g, &fix, solnode, &degtnelims, NULL));
1545 
1546  reduceStatsPrint(fullreduce, "bd3", bd3nelims);
1547  SCIPdebugMessage("bd3: %d \n", bd3nelims);
1548 
1549  if( SCIPgetTotalTime(scip) > timelimit )
1550  break;
1551  }
1552 
1553  if( nvsl || extensive )
1554  {
1555  SCIP_CALL(
1556  nvreduce_sl(scip, g, vnoi, nodearrreal, &fix, edgearrint, heap, state, vbase, nodearrint, NULL, solnode, nodearrchar, &nvslnelims, reductbound));
1557 
1558  if( nvslnelims <= reductbound )
1559  nvsl = FALSE;
1560 
1561  reduceStatsPrint(fullreduce, "nvsl", nvslnelims);
1562  SCIPdebugMessage("nvsl: %d \n", nvslnelims);
1563 
1564  if( SCIPgetTotalTime(scip) > timelimit )
1565  break;
1566  }
1567 
1568  ub = -1.0;
1569 
1570  if( da )
1571  {
1572  SCIP_CALL(
1573  reduce_da(scip, g, vnoi, gnodearr, edgearrreal, edgearrreal2, nodearrreal, &ub, &fix, edgearrint, vbase, state, heap, nodearrint,
1574  nodearrint2, nodearrchar, &danelims, inner_rounds, randnumgen, userec, FALSE));
1575 
1576  if( danelims <= STP_RED_EXFACTOR * reductbound )
1577  da = FALSE;
1578 
1579  reduceStatsPrint(fullreduce, "da", danelims);
1580  SCIPdebugMessage("da: %d \n", danelims);
1581 
1582  if( SCIPgetTotalTime(scip) > timelimit )
1583  break;
1584  }
1585 
1586  if( bred && nodereplacing )
1587  {
1588  SCIP_CALL(reduce_bound(scip, g, vnoi, edgearrreal, NULL, nodearrreal, edgearrreal2, &fix, &ub, heap, state, vbase, &brednelims));
1589 
1590  SCIP_CALL(level0(scip, g));
1591 
1592  if( brednelims <= reductbound )
1593  bred = FALSE;
1594 
1595  reduceStatsPrint(fullreduce, "bnd", brednelims);
1596  SCIPdebugMessage("bnd: %d \n\n", brednelims);
1597 
1598  if( SCIPgetTotalTime(scip) > timelimit )
1599  break;
1600  }
1601  SCIP_CALL(level0(scip, g));
1602  SCIP_CALL(reduce_simple(scip, g, &fix, solnode, &degtnelims, NULL));
1603 
1604  if( (danelims + sdnelims + bd3nelims + nvslnelims + lenelims + brednelims + sdcnelims) <= 2 * reductbound )
1605  {
1606  // at least one successful round and full reduce and no inner_restarts yet?
1607  if( inner_rounds > 0 && fullreduce && inner_restarts == 0 )
1608  {
1609  inner_restarts++;
1610  le = TRUE;
1611  sd = TRUE;
1612  sdc = TRUE;
1613  da = TRUE;
1614  bd3 = nodereplacing;
1615  nvsl = nodereplacing;
1616 
1617 #ifdef STP_PRINT_STATS
1618  printf("RESTART reductions (restart %d) \n", inner_restarts);
1619 #endif
1620  }
1621  else
1622  rerun = FALSE;
1623  }
1624 
1625  if( extensive && (danelims + sdnelims + bd3nelims + nvslnelims + lenelims + brednelims + sdcnelims) > 0 )
1626  rerun = TRUE;
1627 
1628  inner_rounds++;
1629  } /* inner reduction loop */
1630 
1631  if( fullreduce && !SCIPisStopped(scip) )
1632  {
1633  int extendedelims = 0;
1634 
1635  assert(!rerun);
1636 
1637  SCIP_CALL( reduce_da(scip, g, vnoi, gnodearr, edgearrreal, edgearrreal2, nodearrreal, &ub, &fix, edgearrint, vbase, state, heap, nodearrint,
1638  nodearrint2, nodearrchar, &extendedelims, inner_rounds, randnumgen, userec, TRUE));
1639 
1640  reduceStatsPrint(fullreduce, "ext", extendedelims);
1641 
1642  SCIP_CALL(reduce_simple(scip, g, &fix, solnode, &extendedelims, NULL));
1643 
1644  if( extendedelims > STP_RED_EXFACTOR * reductbound )
1645  {
1646  le = TRUE;
1647  sd = TRUE;
1648  sdc = TRUE;
1649  da = TRUE;
1650  bd3 = nodereplacing;
1651  nvsl = nodereplacing;
1652  rerun = TRUE;
1653  }
1654  }
1655  }
1656  while( rerun && !SCIPisStopped(scip) ); /* extensive reduction loop*/
1657 
1658  if( fullreduce )
1659  {
1661  }
1662 
1663  /* free random number generator */
1664  SCIPfreeRandom(scip, &randnumgen);
1665 
1666  *fixed += fix;
1667 
1668  return SCIP_OKAY;
1669 }
1670 
1671 
1672 /** reduces the graph */
1674  SCIP* scip, /**< SCIP data structure */
1675  GRAPH** graph, /**< graph structure */
1676  SCIP_Real* offset, /**< pointer to store offset generated by reductions */
1677  int level, /**< reduction level 0: none, 1: basic, 2: advanced */
1678  int minelims, /**< minimal amount of reductions to reiterate reduction methods */
1679  SCIP_Bool userec /**< use recombination heuristic? */
1680  )
1681 {
1682  int stp_type;
1683 
1684  assert((*graph) != NULL);
1685  assert((*graph)->fixedges == NULL);
1686  assert(level >= 0 && level <= 2);
1687  assert(minelims >= 0);
1688  assert((*graph)->layers == 1);
1689 
1690  *offset = 0.0;
1691 
1692  stp_type = (*graph)->stp_type;
1693 
1694  /* initialize ancestor list for each edge */
1695  SCIP_CALL( graph_init_history(scip, (*graph)) );
1696 
1697  /* initialize shortest path algorithms */
1698  SCIP_CALL( graph_path_init(scip, (*graph)) );
1699 
1700  SCIP_CALL( level0(scip, (*graph)) );
1701 
1702  /* if no reduction methods available, return */
1703  if( (*graph)->stp_type == STP_DCSTP || (*graph)->stp_type == STP_RMWCSP )
1704  {
1705  graph_path_exit(scip, (*graph));
1706  return SCIP_OKAY;
1707  }
1708 
1709  if( level == 1 )
1710  {
1711  if( stp_type == STP_PCSPG || stp_type == STP_RPCSPG )
1712  {
1713  SCIP_CALL( reducePc(scip, (graph), offset, minelims, FALSE, FALSE) );
1714  }
1715  else if( stp_type == STP_MWCSP )
1716  {
1717  SCIP_CALL( reduceMw(scip, (graph), offset, minelims, FALSE, FALSE) );
1718  }
1719  else if( stp_type == STP_DHCSTP )
1720  {
1721  SCIP_CALL( reduceHc(scip, (graph), offset, minelims) );
1722  }
1723  else if( stp_type == STP_SAP )
1724  {
1725  SCIP_CALL( reduceSap(scip, (graph), offset, minelims) );
1726  }
1727  else if( stp_type == STP_NWSPG )
1728  {
1729  SCIP_CALL( reduceNw(scip, (graph), offset, minelims) );
1730  }
1731  else
1732  {
1733  SCIP_CALL( reduceStp(scip, (graph), offset, minelims, FALSE, TRUE, FALSE) );
1734  }
1735  }
1736  else if( level == 2 )
1737  {
1738  if( stp_type == STP_PCSPG || stp_type == STP_RPCSPG )
1739  {
1740  SCIP_CALL( reducePc(scip, (graph), offset, minelims, TRUE, userec) );
1741  }
1742  else if( stp_type == STP_MWCSP )
1743  {
1744  SCIP_CALL( reduceMw(scip, (graph), offset, minelims, TRUE, userec) );
1745  }
1746  else if( stp_type == STP_DHCSTP )
1747  {
1748  SCIP_CALL( reduceHc(scip, (graph), offset, minelims) );
1749  }
1750  else if( stp_type == STP_SAP )
1751  {
1752  SCIP_CALL( reduceSap(scip, (graph), offset, minelims) );
1753  }
1754  else if( stp_type == STP_NWSPG )
1755  {
1756  SCIP_CALL( reduceNw(scip, (graph), offset, minelims) );
1757  }
1758  else
1759  {
1760  SCIP_CALL( reduceStp(scip, (graph), offset, minelims, TRUE, TRUE, userec) );
1761  }
1762  }
1763  SCIPdebugMessage("offset : %f \n", *offset);
1764 
1765  SCIP_CALL( level0(scip, (*graph)) );
1766 
1767  assert(graph_valid(*graph));
1768 
1769  graph_path_exit(scip, (*graph));
1770 
1771  return SCIP_OKAY;
1772 }
SCIP_RETCODE graph_path_init(SCIP *, GRAPH *)
Definition: grphpath.c:444
void SCIPfreeRandom(SCIP *scip, SCIP_RANDNUMGEN **randnumgen)
void reduce_nnp(SCIP *, GRAPH *, int *, int *)
Definition: reduce_alt.c:5450
static volatile int nterms
Definition: interrupt.c:37
SCIP_RETCODE level0(SCIP *scip, GRAPH *g)
Definition: reduce.c:153
#define NULL
Definition: def.h:239
static SCIP_RETCODE reducePc(SCIP *scip, GRAPH **graph, SCIP_Real *fixed, int minelims, STP_Bool dualascent, SCIP_Bool userec)
Definition: reduce.c:338
Definition: grph.h:57
int source
Definition: grph.h:67
SCIP_RETCODE SCIPgetRealParam(SCIP *scip, const char *name, SCIP_Real *value)
Definition: scip_param.c:379
SCIP_RETCODE graph_trail_arr(SCIP *, const GRAPH *, int)
Definition: grphbase.c:4238
void reduce_ans(SCIP *, GRAPH *, int *, int *)
Definition: reduce_alt.c:4447
SCIP_Bool graph_valid(const GRAPH *)
Definition: grphbase.c:4324
int terms
Definition: grph.h:64
SCIP_RETCODE reduce_rpt(SCIP *, GRAPH *, SCIP_Real *, int *)
SCIP_RETCODE reduceStp(SCIP *scip, GRAPH **graph, SCIP_Real *fixed, int minelims, SCIP_Bool dualascent, SCIP_Bool nodereplacing, SCIP_Bool userec)
Definition: reduce.c:223
SCIP_RETCODE graph_init_history(SCIP *, GRAPH *)
Definition: grphbase.c:3569
#define EAT_LAST
Definition: grph.h:31
SCIP_RETCODE reduce_boundMw(SCIP *, GRAPH *, PATH *, PATH *, SCIP_Real *, SCIP_Real *, SCIP_Real *, SCIP_Real *, int *, int *, int *, int *, int *)
Definition: reduce_bnd.c:5243
SCIP_RETCODE level0save(SCIP *scip, GRAPH *g)
Definition: reduce.c:185
SCIP_RETCODE graph_pc_presolInit(SCIP *, GRAPH *)
Definition: grphbase.c:794
#define FALSE
Definition: def.h:65
SCIP_RETCODE reduce_contractZeroEdges(SCIP *, GRAPH *, SCIP_Bool)
int *RESTRICT inpbeg
Definition: grph.h:74
SCIP_RETCODE graph_pc_mw2rmw(SCIP *, GRAPH *, SCIP_Real)
Definition: grphbase.c:1846
#define STP_RMWCSP
Definition: grph.h:50
Problem data for stp problem.
#define TRUE
Definition: def.h:64
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:53
SCIP_RETCODE reduce_boundHopRc(SCIP *, GRAPH *, PATH *, SCIP_Real *, SCIP_Real *, SCIP_Real *, SCIP_Real, int *, int *, int *, int *, int *, SCIP_Bool)
Definition: reduce_bnd.c:6226
void graph_path_exit(SCIP *, GRAPH *)
Definition: grphpath.c:466
#define STP_DHCSTP
Definition: grph.h:48
#define SCIPfreeBlockMemory(scip, ptr)
Definition: scip_mem.h:114
#define STP_PCSPG
Definition: grph.h:40
#define SCIPdebugMessage
Definition: pub_message.h:77
SCIP_RETCODE redLoopMw(SCIP *scip, GRAPH *g, PATH *vnoi, PATH *path, GNODE **gnodearr, SCIP_Real *nodearrreal, SCIP_Real *edgearrreal, SCIP_Real *edgearrreal2, int *state, int *vbase, int *nodearrint, int *edgearrint, int *nodearrint2, int *nodearrint3, int *solnode, STP_Bool *nodearrchar, SCIP_Real *fixed, STP_Bool advanced, STP_Bool bred, STP_Bool tryrmw, int redbound, SCIP_Bool userec)
Definition: reduce.c:921
static SCIP_RETCODE nvreduce_sl(SCIP *scip, GRAPH *g, PATH *vnoi, SCIP_Real *nodearrreal, SCIP_Real *fixed, int *edgearrint, int *heap, int *state, int *vbase, int *neighb, int *distnode, int *solnode, STP_Bool *visited, int *nelims, int minelims)
Definition: reduce.c:72
static SCIP_RETCODE reduceNw(SCIP *scip, GRAPH **graph, SCIP_Real *fixed, int minelims)
Definition: reduce.c:825
#define STP_RED_BD3BOUND
Definition: reduce.c:34
SCIP_Bool SCIPisEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
#define SCIPfreeBufferArray(scip, ptr)
Definition: scip_mem.h:142
#define SCIPallocBlockMemory(scip, ptr)
Definition: scip_mem.h:97
SCIP_RETCODE reduce_daPcMw(SCIP *, GRAPH *, PATH *, GNODE **, SCIP_Real *, SCIP_Real *, SCIP_Real *, int *, int *, int *, int *, STP_Bool *, int *, SCIP_Bool, SCIP_Bool, SCIP_Bool, SCIP_Bool, SCIP_Bool, SCIP_RANDNUMGEN *, SCIP_Real)
Definition: reduce_bnd.c:3801
SCIP_RETCODE reduce_simple(SCIP *, GRAPH *, SCIP_Real *, int *, int *, int *)
#define STP_RED_MAXNROUNDS
Definition: reduce.c:37
#define STP_RED_SDSPBOUND2
Definition: reduce.c:33
int *RESTRICT mark
Definition: grph.h:70
#define STP_RED_EXTENSIVE
Definition: reduce.c:35
SCIP_Bool graph_pc_term2edgeConsistent(const GRAPH *)
Definition: grphbase.c:853
SCIP_RETCODE reduce_boundHopR(SCIP *, GRAPH *, PATH *, SCIP_Real *, SCIP_Real *, SCIP_Real *, int *, int *, int *, int *, int *)
Definition: reduce_bnd.c:6098
void graph_pc_2org(GRAPH *)
Definition: grphbase.c:964
static SCIP_RETCODE reduceHc(SCIP *scip, GRAPH **graph, SCIP_Real *fixed, int minelims)
Definition: reduce.c:571
SCIP_RETCODE reduce_simple_mw(SCIP *, GRAPH *, int *, SCIP_Real *, int *)
miscellaneous methods used for solving Steiner problems
#define STP_SAP
Definition: grph.h:39
int stp_type
Definition: grph.h:127
SCIP_RETCODE reduce_deleteConflictEdges(SCIP *, GRAPH *)
Definition: reduce_bnd.c:2421
SCIP_RETCODE reduce_sd(SCIP *, GRAPH *, PATH *, SCIP_Real *, SCIP_Real *, int *, int *, int *, int *, int *, int *, int *, SCIP_Bool, int *)
Definition: reduce_alt.c:1105
SCIP_RETCODE reduce_da(SCIP *, GRAPH *, PATH *, GNODE **, SCIP_Real *, SCIP_Real *, SCIP_Real *, SCIP_Real *, SCIP_Real *, int *, int *, int *, int *, int *, int *, STP_Bool *, int *, int, SCIP_RANDNUMGEN *, SCIP_Bool, SCIP_Bool)
Definition: reduce_bnd.c:2861
void graph_pc_2trans(GRAPH *)
Definition: grphbase.c:1002
SCIP_RETCODE redLoopPc(SCIP *scip, GRAPH *g, PATH *vnoi, PATH *path, GNODE **gnodearr, SCIP_Real *nodearrreal, SCIP_Real *exedgearrreal, SCIP_Real *exedgearrreal2, int *heap, int *state, int *vbase, int *nodearrint, int *edgearrint, int *nodearrint2, int *solnode, STP_Bool *nodearrchar, SCIP_Real *fixed, SCIP_Bool dualascent, SCIP_Bool bred, int reductbound, SCIP_Bool userec)
Definition: reduce.c:1158
unsigned char STP_Bool
Definition: grph.h:52
#define STP_DCSTP
Definition: grph.h:43
#define SCIPfreeBufferArrayNull(scip, ptr)
Definition: scip_mem.h:143
SCIP_Real * prize
Definition: grph.h:82
SCIP_RETCODE reduce_simple_sap(SCIP *, GRAPH *, SCIP_Real *, int *)
int *RESTRICT grad
Definition: grph.h:73
void print(const Container &container, const std::string &prefix="", const std::string &suffix="", std::ostream &os=std::cout, bool negate=false, int prec=6)
void graph_pc_presolExit(SCIP *, GRAPH *)
Definition: grphbase.c:837
int knots
Definition: grph.h:62
#define SCIP_CALL(x)
Definition: def.h:351
SCIP_RETCODE reduce_bd34(SCIP *, GRAPH *, PATH *, PATH *, int *, int *, int *, int *, int *, int *, int)
Definition: reduce_alt.c:2964
SCIP_RETCODE reduce_nvAdv(SCIP *, GRAPH *, PATH *, SCIP_Real *, double *, int *, int *, int *, int *, int *, int *, int *, int *)
Definition: reduce_alt.c:3903
#define STP_NWSPG
Definition: grph.h:42
SCIP_Real graph_pc_getPosPrizeSum(SCIP *, const GRAPH *)
Definition: grphbase.c:1054
SCIP_RETCODE reduce_simple_hc(SCIP *, GRAPH *, SCIP_Real *, int *)
#define FARAWAY
Definition: grph.h:156
SCIP_RETCODE SCIPcreateRandom(SCIP *scip, SCIP_RANDNUMGEN **randnumgen, unsigned int initialseed, SCIP_Bool useglobalseed)
propagator for Steiner tree problems, using the LP reduced costs
#define SCIPallocBufferArray(scip, ptr, num)
Definition: scip_mem.h:130
void reduce_ansAdv2(SCIP *, GRAPH *, int *, int *)
Definition: reduce_alt.c:4621
void reduce_ansAdv(SCIP *, GRAPH *, int *, int *, SCIP_Bool)
Definition: reduce_alt.c:4515
SCIP_RETCODE reduce(SCIP *scip, GRAPH **graph, SCIP_Real *offset, int level, int minelims, SCIP_Bool userec)
Definition: reduce.c:1673
SCIP_RETCODE reduce_simple_pc(SCIP *, GRAPH *, SCIP_Real *, int *, int *, SCIP_Bool)
#define SCIP_Bool
Definition: def.h:62
SCIP_RETCODE reduce_boundHop(SCIP *, GRAPH *, PATH *, SCIP_Real *, SCIP_Real *, SCIP_Real *, int *, int *, int *, int *)
Definition: reduce_bnd.c:5904
#define STP_MWCSP
Definition: grph.h:47
static SCIP_RETCODE reduceSap(SCIP *scip, GRAPH **graph, SCIP_Real *fixed, int minelims)
Definition: reduce.c:691
SCIP_RETCODE reduce_sl(SCIP *, GRAPH *, PATH *, double *, int *, int *, int *, int *, STP_Bool *, int *, int *)
Definition: reduce_alt.c:3483
#define STP_RED_MWTERMBOUND
Definition: reduce.c:36
int *RESTRICT term
Definition: grph.h:68
void graph_edge_del(SCIP *, GRAPH *, int, SCIP_Bool)
Definition: grphbase.c:2837
#define BMScopyMemoryArray(ptr, source, num)
Definition: memory.h:116
SCIP_RETCODE reduce_ledge(SCIP *, GRAPH *, PATH *, int *, int *, int *, int *, int *)
Definition: reduce_alt.c:4143
SCIP_RETCODE reduce_sdPc(SCIP *, GRAPH *, PATH *, int *, int *, int *, int *, int *, int *)
Definition: reduce_alt.c:1499
SCIP_RETCODE redLoopStp(SCIP *scip, GRAPH *g, PATH *vnoi, PATH *path, GNODE **gnodearr, SCIP_Real *nodearrreal, SCIP_Real *edgearrreal, SCIP_Real *edgearrreal2, int *heap, int *state, int *vbase, int *nodearrint, int *edgearrint, int *nodearrint2, int *solnode, STP_Bool *nodearrchar, SCIP_Real *fixed, SCIP_Real upperbound, SCIP_Bool dualascent, SCIP_Bool boundreduce, SCIP_Bool nodereplacing, int reductbound, SCIP_Bool userec, SCIP_Bool fullreduce)
Definition: reduce.c:1409
includes various files containing graph methods used for Steiner tree problems
SCIP_RETCODE reduce_bound(SCIP *, GRAPH *, PATH *, SCIP_Real *, SCIP_Real *, SCIP_Real *, SCIP_Real *, SCIP_Real *, SCIP_Real *, int *, int *, int *, int *)
Definition: reduce_bnd.c:4653
#define Is_term(a)
Definition: grph.h:168
#define MAX(x, y)
Definition: def.h:208
SCIP_Real * cost
Definition: grph.h:94
SCIP_RETCODE reduce_sdspSap(SCIP *, GRAPH *, PATH *, PATH *, int *, int *, int *, int *, int *, int *, int)
Definition: reduce_alt.c:2308
#define SCIP_Real
Definition: def.h:150
SCIP_Bool SCIPisStopped(SCIP *scip)
Definition: scip_general.c:739
static SCIP_RETCODE reduceMw(SCIP *scip, GRAPH **graph, SCIP_Real *fixed, int minelims, STP_Bool advanced, SCIP_Bool userec)
Definition: reduce.c:459
shortest paths based primal heuristics for Steiner problems
#define STP_RED_SDSPBOUND
Definition: reduce.c:32
int edges
Definition: grph.h:92
SCIP_Real SCIPgetTotalTime(SCIP *scip)
Definition: scip_timing.c:409
static void reduceStatsPrint(SCIP_Bool print, const char *method, int nelims)
Definition: reduce.c:55
SCIP_Bool SCIPisLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
#define nnodes
Definition: gastrans.c:65
SCIP_RETCODE reduce_npv(SCIP *, GRAPH *, PATH *, PATH *, int *, int *, int *, int *, int *, int *, int)
Definition: reduce_alt.c:5024
#define STP_RPCSPG
Definition: grph.h:41
SCIP_RETCODE reduce_sdsp(SCIP *, GRAPH *, PATH *, PATH *, int *, int *, int *, int *, int *, int *, int, int *)
Definition: reduce_alt.c:2459
SCIP callable library.
SCIP_RETCODE reduce_chain2(SCIP *, GRAPH *, PATH *, PATH *, int *, int *, int *, int *, int *, int *, int)
Definition: reduce_alt.c:5367
#define STP_RED_EXFACTOR
Definition: reduce.c:38