Scippy

SCIP

Solving Constraint Integer Programs

extreduce_contract.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-2022 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 extreduce_contract.c
17  * @brief extended-reduction tree contraction algorithms for Steiner tree problems
18  * @author Daniel Rehfeldt
19  *
20  * This file implements rule-out algorithms for extended reduction techniques for Steiner problems.
21  * Allows to compute and store special distance (SD) MSTs / SPGs between the leaves of extension tree,
22  * after the contraction of certain parts of the tree.
23  *
24  * Similarly to the extmst methods, we keep two distance storages: One from all component vertices to the
25  * lower leaves. One from the component root to the lower leafs and to the siblings.
26  *
27  *
28  * A list of all interface methods can be found in extreduce.h.
29  *
30  */
31 
32 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
33 // #define SCIP_DEBUG
34 //#define STP_DEBUG_EXT
35 
36 #include "extreduce.h"
37 #include "extreducedefs.h"
38 
39 
40 
42 {
43  CSR* mst_buffer; /**< buffer that can keep at least leaves_maxn many nodes */
44  SCIP_Real* leafToCompRootDists;/**< stores distances from leaves to component root */
45  SCIP_Real* leafToCompUpDists; /**< stores distances from leaves to all above components */
46  SCIP_Real* level_treecost; /**< cost of tree per level */
47  SCIP_Real* leaves_mindists; /**< minimum distances from leaves to contracted node (buffer, of size leaves_maxn) */
48  int* leaves_start; /**< start pointer per level */
49  int leaves_maxn; /**< maximum number of leaves */
50  int level_maxn; /**< maximum number of levels */
51  int level_n; /**< current number of levels */
52 #ifndef NDEBUG
53  SCIP_Real* leafToCompLeaves; /**< stores leaves for leafToCompDists */
54 #endif
55 
56 };
57 
58 
59 
60 /**@name Local methods
61  *
62  * @{
63  */
64 
65 
66 /** gets position of distance value */
67 static inline
69  int leaf_id, /**< id */
70  int level, /**< level */
71  const CONTRACT* contraction /**< contraction data */
72 )
73 {
74  const int maxnlevels = contraction->level_maxn;
75  const int position = leaf_id * maxnlevels + level;
76 
77  assert(level >= 0);
78  assert(0 <= leaf_id && leaf_id < contraction->leaves_maxn);
79 
80  assert(position >= 0);
81 
82  return position;
83 }
84 
85 
86 /** adds distance */
87 static inline
89  int leaf_id, /**< id */
90  SCIP_Real dist, /**< distance */
91  SCIP_Bool override, /**< override distance? (take in otherwise) */
92  EXTDATA* extdata, /**< extension data */
93  CONTRACT* contraction /**< contraction data */
94 )
95 {
96  const int level = contraction->level_n - 1;
97  const int position = compDistGetPosition(leaf_id, level, contraction);
98 
99  assert(leaf_id < extdata->tree_nleaves);
100  assert(extdata->tree_leaves[leaf_id] == contraction->leafToCompLeaves[leaf_id]);
101  assert(GE(dist, 0.0));
102 
103  if( override )
104  {
105  contraction->leafToCompUpDists[position] = dist;
106  }
107  else if( LT(dist, contraction->leafToCompUpDists[position]) )
108  {
109  contraction->leafToCompUpDists[position] = dist;
110  }
111 
112  assert(GE(contraction->leafToCompUpDists[position], 0.0));
113 }
114 
115 
116 
117 /** updates distances from lower leafs to top component */
118 static inline
120  const GRAPH* graph, /**< graph data structure */
121  EXTDATA* extdata, /**< extension data */
122  CONTRACT* contraction /**< contraction data */
123 )
124 {
125  const MLDISTS* const sds_vertical = extdata->reddata->sds_vertical;
126  const int* const extstack_data = extdata->extstack_data;
127  const int level = contraction->level_n;
128  const int stackpos = extStackGetPosition(extdata);
129  const int topedges_start = extStackGetTopOutEdgesStart(extdata, stackpos);
130  const int topedges_end = extStackGetTopOutEdgesEnd(extdata, stackpos);
131  const int leaves_end = contraction->leaves_start[level];
132 
133  assert(leaves_end >= 1);
134  assert(extreduce_mldistsLevelNTopTargets(sds_vertical) == leaves_end);
135 
136  /* add the 'up' leaf to components distances */
137  for( int i = topedges_start; i < topedges_end; i++ )
138  {
139  const SCIP_Bool override = (i == topedges_start);
140  const int edge = extstack_data[i];
141  const int topleaf = graph->head[edge];
142  const SCIP_Real* const sdvertical_dists = extreduce_mldistsTopTargetDists(sds_vertical, topleaf);
143 #ifndef NDEBUG
144  const int* const sdvertical_ids = extreduce_mldistsTopTargetIds(sds_vertical, topleaf);
145 #endif
146 
147  for( int j = 0; j < leaves_end; j++ )
148  {
149  assert(sdvertical_ids[j] == extdata->tree_leaves[j]);
150 
151  SCIPdebugMessage("top=%d leaf=%d, dist=%f \n", topleaf, extdata->tree_leaves[j], sdvertical_dists[j]);
152 
153  compUpDistAddLeaf(j, sdvertical_dists[j], override, extdata, contraction);
154  }
155  }
156 }
157 
158 
159 /** adds distance */
160 static inline
162  int leaf_id, /**< id */
163  SCIP_Real dist, /**< distance */
164  EXTDATA* extdata, /**< extension data */
165  CONTRACT* contraction /**< contraction data */
166 )
167 {
168  const int level = contraction->level_n - 1;
169  const int position = compDistGetPosition(leaf_id, level, contraction);
170 
171  assert(level >= 1);
172  assert(leaf_id < extdata->tree_nleaves);
173  assert(extdata->tree_leaves[leaf_id] == contraction->leafToCompLeaves[leaf_id]);
174  assert(GE(dist, 0.0));
175 
176  contraction->leafToCompRootDists[position] = dist;
177 }
178 
179 
180 /** updates distances from lower leafs (w.r.t top component) to top component root */
181 static inline
183  const GRAPH* graph, /**< graph data structure */
184  EXTDATA* extdata, /**< extension data */
185  CONTRACT* contraction /**< contraction data */
186 )
187 {
188  const MLDISTS* const sds_vertical = extdata->reddata->sds_vertical;
189  const MLDISTS* const sds_horizontal = extdata->reddata->sds_horizontal;
190  const int level = contraction->level_n;
191  const int leavesSame_start = contraction->leaves_start[level - 1];
192  const int leavesSame_end = contraction->leaves_start[level];
193  const int comproot = extStackGetTopRoot(graph, extdata);
194  const SCIP_Bool hasSiblings = (leavesSame_start != leavesSame_end);
195  const SCIP_Real* const sdvertical_dists = extreduce_mldistsTargetDists(sds_vertical, level - 1, comproot);
196  const SCIP_Real* const sdhorizontal_dists = hasSiblings ? extreduce_mldistsTargetDists(sds_horizontal, level - 1, comproot) : NULL;
197  const int* const sdhorizontal_ids = hasSiblings ? extreduce_mldistsTargetIds(sds_horizontal, level - 1, comproot) : NULL;
198  const int sdhorizontal_ntargets = extreduce_mldistsLevelNTargets(sds_horizontal, level - 1);
199 
200 #ifndef NDEBUG
201  const int* const sdvertical_ids = extreduce_mldistsTargetIds(sds_vertical, level - 1, comproot);
202 #endif
203 
204  assert(level > 1);
205  assert(leavesSame_end >= 1 && leavesSame_start >= 1);
206  assert(extreduce_mldistsLevelNTargets(sds_vertical, level - 1) == leavesSame_start);
207  assert(sdhorizontal_ntargets >= (leavesSame_end - leavesSame_start));
208 
209  SCIPdebugMessage("horizontal root component distances: \n");
210 
211  /* update leafs on same level as root */
212  for( int i = leavesSame_start; i < leavesSame_end; i++ )
213  {
214  int j;
215  assert(sdvertical_dists && sdhorizontal_dists);
216 
217  for( j = 0; j < sdhorizontal_ntargets; j++ )
218  {
219  if( sdhorizontal_ids[j] == extdata->tree_leaves[i] )
220  break;
221  }
222 
223  assert(j != sdhorizontal_ntargets);
224 
225  SCIPdebugMessage("comproot=%d leaf=%d, dist=%f \n", comproot, sdhorizontal_ids[j],
226  sdhorizontal_dists[j]);
227 
228  compRootDistAddLeaf(i, sdhorizontal_dists[j], extdata, contraction);
229  }
230 
231  SCIPdebugMessage("vertical root component distances: \n");
232 
233  /* update leafs below root */
234  for( int i = 0; i < leavesSame_start; i++ )
235  {
236  assert(sdvertical_ids[i] == extdata->tree_leaves[i]);
237 
238  SCIPdebugMessage("comproot=%d leaf=%d, dist=%f \n", comproot, extdata->tree_leaves[i],
239  sdvertical_dists[i]);
240 
241  compRootDistAddLeaf(i, sdvertical_dists[i], extdata, contraction);
242  }
243 }
244 
245 
246 /** initializes distances from component to lower leaves */
247 static inline
249  int level, /**< level from which to initialize */
250  EXTDATA* extdata, /**< extension data */
251  CONTRACT* contraction /**< contraction data */
252 )
253 {
254  const SCIP_Real* const leafToCompDists = contraction->leafToCompUpDists;
255  SCIP_Real* RESTRICT leaves_mindists = contraction->leaves_mindists;
256  const int leaves_end = contraction->leaves_start[level + 1];
257 
258  assert(0 <= level && level < contraction->level_n);
259  assert(0 < leaves_end && leaves_end < extdata->tree_nleaves);
260 
261  for( int i = 0; i < leaves_end; i++ )
262  {
263  const int position = compDistGetPosition(i, level, contraction);
264  leaves_mindists[i] = leafToCompDists[position];
265  }
266 
267 #ifndef NDEBUG
268  for( int i = leaves_end; i < contraction->leaves_maxn; i++ )
269  leaves_mindists[i] = -FARAWAY;
270 #endif
271 }
272 
273 
274 /** updates distances from component to lower leaves */
275 static inline
277  int level, /**< level from which to initialize */
278  EXTDATA* extdata, /**< extension data */
279  CONTRACT* contraction /**< contraction data */
280 )
281 {
282  const SCIP_Real* const leafToCompDists = contraction->leafToCompUpDists;
283  SCIP_Real* RESTRICT leaves_mindists = contraction->leaves_mindists;
284  const int leaves_end = contraction->leaves_start[level + 1];
285 
286  assert(0 <= level && level < contraction->level_n);
287  assert(0 < leaves_end && leaves_end < extdata->tree_nleaves);
288 
289  for( int i = 0; i < leaves_end; i++ )
290  {
291  const int position = compDistGetPosition(i, level, contraction);
292  const SCIP_Real dist = leafToCompDists[position];
293  assert(GE(dist, 0.0));
294 
295  if( LT(dist, leaves_mindists[i]) )
296  leaves_mindists[i] = dist;
297  }
298 }
299 
300 
301 /** updates leaf distances from component root to lower leaves */
302 static inline
304  int level, /**< level from which to initialize */
305  EXTDATA* extdata, /**< extension data */
306  CONTRACT* contraction /**< contraction data */
307 )
308 {
309  const SCIP_Real* const leafToCompDists = contraction->leafToCompRootDists;
310  SCIP_Real* RESTRICT leaves_mindists = contraction->leaves_mindists;
311  const int leaves_end = contraction->leaves_start[level + 1];
312 
313  assert(1 <= level && level < contraction->level_n);
314  assert(0 < leaves_end && leaves_end < extdata->tree_nleaves);
315 
316  for( int i = 0; i < leaves_end; i++ )
317  {
318  const int position = compDistGetPosition(i, level, contraction);
319  const SCIP_Real dist = leafToCompDists[position];
320  assert(GE(dist, 0.0));
321 
322  if( LT(dist, leaves_mindists[i]) )
323  leaves_mindists[i] = dist;
324  }
325 }
326 
327 
328 /** helper */
329 static inline
331  const GRAPH* graph, /**< graph data structure */
332  EXTDATA* extdata, /**< extension data */
333  CONTRACT* contraction /**< contraction data */
334 )
335 {
336  SCIP_Real treecost = extdata->tree_cost;
337  const int* const extstack_data = extdata->extstack_data;
338  const int stackpos = extStackGetPosition(extdata);
339  const int topedges_start = extStackGetTopOutEdgesStart(extdata, stackpos);
340  const int topedges_end = extStackGetTopOutEdgesEnd(extdata, stackpos);
341  const int level = contraction->level_n;
342 
343  assert(level >= 1);
344 
345  for( int i = topedges_start; i < topedges_end; i++ )
346  {
347  const int edge = extstack_data[i];
348  assert(graph_edge_isInRange(graph, edge));
349 
350  treecost -= graph->cost[edge];
351  }
352 
353  if( extProbIsPc(graph, extdata) )
354  {
355  assert(extdata->pcdata);
356  treecost -= extdata->pcdata->tree_innerPrize;
357  assert(GE(treecost, 0.0));
358  }
359 
360  SCIPdebugMessage("tree cost for level %d: %f \n", level - 1, treecost);
361  contraction->level_treecost[level - 1] = treecost;
362 }
363 
364 
365 /** helper */
366 static inline
368  const GRAPH* graph, /**< graph data structure */
369  EXTDATA* extdata, /**< extension data */
370  CONTRACT* contraction /**< contraction data */
371 )
372 {
373  const int nleaves = extdata->tree_nleaves;
374  const int stackpos = extStackGetPosition(extdata);
375  const int topedges_start = extStackGetTopOutEdgesStart(extdata, stackpos);
376  const int topedges_end = extStackGetTopOutEdgesEnd(extdata, stackpos);
377  const int ntopedges = topedges_end - topedges_start;
378  const int level = contraction->level_n;
379 
380  assert(ntopedges > 0);
381  assert(ntopedges < nleaves);
382  assert(level >= 1);
383 
384  contraction->leaves_start[level] = nleaves - ntopedges;
385 
386 #ifndef NDEBUG
387  for( int i = contraction->leaves_start[level - 1]; i < contraction->leaves_start[level]; i++ )
388  contraction->leafToCompLeaves[i] = extdata->tree_leaves[i];
389 #endif
390 
391 #ifdef SCIP_DEBUG
392  {
393  const int* const leaves = extdata->tree_leaves;
394 
395  SCIPdebugMessage("contraction lower leafs: \n");
396  for( int i = 0; i < contraction->leaves_start[level]; i++ )
397  graph_knot_printInfo(graph, leaves[i]);
398  }
399 #endif
400 
401 }
402 
403 
404 /** helper */
405 static inline
407  const GRAPH* graph, /**< graph data structure */
408  EXTDATA* extdata, /**< extension data */
409  CONTRACT* contraction /**< contraction data */
410 )
411 {
412  const int level = contraction->level_n;
413 
414  if( level > 1 )
415  {
416  compUpDistUpdateLeavesDists(graph, extdata, contraction);
417  compRootDistsUpdateLeavesDists(graph, extdata, contraction);
418  }
419 }
420 
421 
422 /** adds top component */
423 static
425  SCIP* scip, /**< SCIP */
426  const GRAPH* graph, /**< graph data structure */
427  EXTDATA* extdata /**< extension data */
428  )
429 {
430  CONTRACT* const contraction = extdata->reddata->contration;
431 
432  SCIPdebugMessage("contraction: adding component for level %d \n", extdata->tree_depth);
433  /* NOTE: will always be >= 1 */
434  contraction->level_n = extdata->tree_depth;
435  assert(contraction->level_n <= contraction->level_maxn);
436 
437  /* NOTE: calling order should not be changed */
438  addComponentUpdateTreeCosts(graph, extdata, contraction);
439  addComponentUpdateLeavesStarts(graph, extdata, contraction);
440  addComponentUpdateLeavesToCompDists(graph, extdata, contraction);
441 }
442 
443 
444 /** can the current tree be ruled out? */
445 static
447  SCIP* scip, /**< SCIP */
448  const GRAPH* graph, /**< graph data structure */
449  EXTDATA* extdata /**< extension data */
450  )
451 {
452  REDDATA* const reddata = extdata->reddata;
453  CONTRACT* const contraction = reddata->contration;
454  CSR* const mst_new = contraction->mst_buffer;
455  DCMST* const dcmst = reddata->dcmst;
456  CSRDEPO* const msts_levelbase = reddata->msts_levelbase;
457  const int level = contraction->level_n;
459  const int mst_maxnedges = mst_new->nedges_max;
460  const int mst_maxnnodes = mst_new->nnodes;
461 
462  for( int i = level - 1; i >= 1; i-- )
463  {
464  CSR mst_parent;
465  SCIP_Real mstweight;
466  const SCIP_Real tree_cost = contraction->level_treecost[i];
467 #ifdef SCIP_DEBUG
468  const int leaves_end = contraction->leaves_start[i + 1];
469 #endif
470 
471  graph_csrdepo_getCSR(msts_levelbase, i + 1, &mst_parent);
472 
473  if( i == (level - 1) )
474  {
475  compUpDistInitMindists(i, extdata, contraction);
476  }
477  else
478  {
479  compUpDistUpdateMindists(i, extdata, contraction);
480  }
481 
482  compRootDistUpdateMindists(i, extdata, contraction);
483 
484 #ifdef SCIP_DEBUG
485  printf("\n level=%d: \n", i);
486  for( int j = 0; j < leaves_end; j++ )
487  {
488  printf("...distance from %d to contracted supernode: %f \n",
489  extdata->tree_leaves[j], contraction->leaves_mindists[j]);
490  }
491 #endif
492 
493  mst_new->nedges_max = mst_parent.nedges_max + 2;
494  mst_new->nnodes = mst_parent.nnodes + 1;
495  assert(mst_new->nedges_max <= mst_maxnedges && mst_new->nnodes <= mst_maxnnodes);
496 
497  SCIPdebugMessage("extending MST with n=%d, m=%d \n", mst_parent.nnodes ,mst_parent.nedges_max);
498 
499  reduce_dcmstAddNode(scip, &mst_parent, contraction->leaves_mindists, dcmst, mst_new);
500 
501  mstweight = reduce_dcmstGetWeight(scip, mst_new);
502 
503  SCIPdebugMessage("weigh of old %f \n", reduce_dcmstGetWeight(scip, &mst_parent));
504  SCIPdebugMessage("weigh of new %f \n", mstweight);
505 
506  // todo also allow for equality if mst_new->nnodes > 3? */
507  if( LT(mstweight, tree_cost) )
508  {
509  SCIPdebugMessage("ruled-out with %f < %f, contraction-level=%d \n", mstweight, tree_cost, i);
510  ruledOut = TRUE;
511  break;
512  }
513 
514  if( mst_new->nnodes > 3 && EQ(mstweight, tree_cost) )
515  {
516  SCIPdebugMessage("ruled-out with equality %f <= %f, contraction-level=%d \n", mstweight, tree_cost, i);
517  ruledOut = TRUE;
518  break;
519  }
520  }
521 
522  mst_new->nedges_max = mst_maxnedges;
523  mst_new->nnodes = mst_maxnnodes;
524 
525  return ruledOut;
526 }
527 
528 
529 /**@} */
530 
531 /**@name Interface methods
532  *
533  * @{
534  */
535 
536 
537 /** initializes */
539  SCIP* scip, /**< SCIP */
540  int maxnlevels, /**< maximum number of levels that can be handled */
541  int maxnleaves, /**< maximum number of leaves that can be handled */
542  CONTRACT** contraction /**< to be initialized */
543 )
544 {
545  CONTRACT* cont;
546 
547  assert(scip && contraction);
548  assert(maxnlevels >= 1 && maxnleaves >= 1);
549 
550  SCIP_CALL( SCIPallocMemory(scip, contraction) );
551  cont = *contraction;
552 
553  SCIP_CALL( SCIPallocMemoryArray(scip, &(cont->leaves_start), maxnlevels + 1) );
554  SCIP_CALL( SCIPallocMemoryArray(scip, &(cont->leafToCompRootDists), maxnlevels * maxnleaves) );
555  SCIP_CALL( SCIPallocMemoryArray(scip, &(cont->leafToCompUpDists), maxnlevels * maxnleaves) );
556  SCIP_CALL( SCIPallocMemoryArray(scip, &(cont->level_treecost), maxnlevels) );
557  SCIP_CALL( SCIPallocMemoryArray(scip, &(cont->leaves_mindists), maxnleaves) );
558 
559  SCIP_CALL( graph_csr_alloc(scip, maxnleaves, 2 * (maxnleaves - 1), &(cont->mst_buffer)) );
560 
561  cont->leaves_start[0] = 0;
562 
563  cont->level_maxn = maxnlevels;
564  cont->leaves_maxn = maxnleaves;
565 
566 #ifndef NDEBUG
567  SCIP_CALL( SCIPallocMemoryArray(scip, &(cont->leafToCompLeaves), maxnleaves) );
568 
569  for( int i = 0; i < maxnlevels * maxnleaves; i++ )
570  {
571  cont->leafToCompRootDists[i] = -FARAWAY;
572  cont->leafToCompUpDists[i] = -FARAWAY;
573  }
574 #endif
575 
576  return SCIP_OKAY;
577 }
578 
579 
580 /** frees */
582  SCIP* scip, /**< SCIP */
583  CONTRACT** contraction /**< to be initialized */
584 )
585 {
586  CONTRACT* cont;
587 
588  assert(scip && contraction);
589  cont = *contraction;
590 
591 #ifndef NDEBUG
592  SCIPfreeMemoryArray(scip, &(cont->leafToCompLeaves));
593 #endif
594 
595  graph_csr_free(scip, &(cont->mst_buffer));
596 
597  SCIPfreeMemoryArray(scip, &(cont->leaves_mindists));
598  SCIPfreeMemoryArray(scip, &(cont->level_treecost));
599  SCIPfreeMemoryArray(scip, &(cont->leafToCompUpDists));
601  SCIPfreeMemoryArray(scip, &(cont->leaves_start));
602 
603  SCIPfreeMemory(scip, contraction);
604 }
605 
606 
607 
608 /** can current tree be peripherally ruled out by using contraction based arguments? */
610  SCIP* scip, /**< SCIP */
611  const GRAPH* graph, /**< graph data structure */
612  EXTDATA* extdata /**< extension data */
613 )
614 {
615  assert(scip && graph && extdata);
616  assert(extdata->reddata && extdata->reddata->contration);
617 
618  addComponent(scip, graph, extdata);
619 
620  if( extdata->tree_nleaves <= 2 )
621  {
622  return FALSE;
623  }
624 
625  if( ruledOut(scip, graph, extdata) )
626  {
627  SCIPdebugMessage("Rule-out periph (via contraction) \n");
628 
629  return TRUE;
630  }
631 
632  return FALSE;
633 }
634 
635 /**@} */
int *RESTRICT head
Definition: graphdefs.h:224
static int compDistGetPosition(int leaf_id, int level, const CONTRACT *contraction)
#define SCIPfreeMemoryArray(scip, ptr)
Definition: scip_mem.h:71
const int * extreduce_mldistsTargetIds(const MLDISTS *, int, int)
static void compUpDistInitMindists(int level, EXTDATA *extdata, CONTRACT *contraction)
#define SCIPallocMemoryArray(scip, ptr, num)
Definition: scip_mem.h:55
SCIP_Real tree_innerPrize
void graph_knot_printInfo(const GRAPH *, int)
Definition: graph_stats.c:151
SCIP_Bool extreduce_contractionRuleOutPeriph(SCIP *scip, const GRAPH *graph, EXTDATA *extdata)
#define FALSE
Definition: def.h:87
static void compUpDistAddLeaf(int leaf_id, SCIP_Real dist, SCIP_Bool override, EXTDATA *extdata, CONTRACT *contraction)
#define TRUE
Definition: def.h:86
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:54
int *const extstack_data
static void compRootDistsUpdateLeavesDists(const GRAPH *graph, EXTDATA *extdata, CONTRACT *contraction)
static int extStackGetTopOutEdgesStart(const EXTDATA *extdata, int stackpos)
#define SCIPdebugMessage
Definition: pub_message.h:87
#define FARAWAY
Definition: graphdefs.h:89
static int extStackGetTopOutEdgesEnd(const EXTDATA *extdata, int stackpos)
static int extStackGetPosition(const EXTDATA *extdata)
static void addComponentUpdateLeavesStarts(const GRAPH *graph, EXTDATA *extdata, CONTRACT *contraction)
REDDATA *const reddata
static void compRootDistUpdateMindists(int level, EXTDATA *extdata, CONTRACT *contraction)
int *const tree_leaves
void reduce_dcmstAddNode(SCIP *, const CSR *, const SCIP_Real *, DCMST *, CSR *)
Definition: reduce_util.c:1411
This file implements extended reduction techniques for several Steiner problems.
#define GE(a, b)
Definition: portab.h:85
int nedges_max
Definition: graphdefs.h:144
SCIP_Real reduce_dcmstGetWeight(SCIP *, const CSR *)
Definition: reduce_util.c:1573
int extreduce_mldistsLevelNTargets(const MLDISTS *, int)
#define NULL
Definition: lpi_spx1.cpp:155
static SCIP_Bool extProbIsPc(const GRAPH *graph, const EXTDATA *extdata)
#define EQ(a, b)
Definition: portab.h:79
CONTRACT * contration
#define SCIP_CALL(x)
Definition: def.h:384
SCIP_RETCODE graph_csr_alloc(SCIP *, int, int, CSR **)
Definition: graph_util.c:1231
#define LT(a, b)
Definition: portab.h:81
#define SCIP_Bool
Definition: def.h:84
const SCIP_Real * extreduce_mldistsTopTargetDists(const MLDISTS *, int)
includes extended reductions definitions and inline methods used for Steiner tree problems ...
CSRDEPO *const msts_levelbase
SCIP_RETCODE extreduce_contractionInit(SCIP *scip, int maxnlevels, int maxnleaves, CONTRACT **contraction)
static void addComponentUpdateLeavesToCompDists(const GRAPH *graph, EXTDATA *extdata, CONTRACT *contraction)
void extreduce_contractionFree(SCIP *scip, CONTRACT **contraction)
PCDATA *const pcdata
int extreduce_mldistsLevelNTopTargets(const MLDISTS *)
static void addComponent(SCIP *scip, const GRAPH *graph, EXTDATA *extdata)
#define SCIPfreeMemory(scip, ptr)
Definition: scip_mem.h:69
DCMST *const dcmst
SCIP_Real * cost
Definition: graphdefs.h:221
SCIP_Bool graph_edge_isInRange(const GRAPH *, int)
Definition: graph_stats.c:110
static SCIP_Bool ruledOut(SCIP *scip, const GRAPH *graph, EXTDATA *extdata)
void graph_csr_free(SCIP *, CSR **)
Definition: graph_util.c:1554
static void compRootDistAddLeaf(int leaf_id, SCIP_Real dist, EXTDATA *extdata, CONTRACT *contraction)
#define SCIP_Real
Definition: def.h:177
static void compUpDistUpdateMindists(int level, EXTDATA *extdata, CONTRACT *contraction)
const SCIP_Real * extreduce_mldistsTargetDists(const MLDISTS *, int, int)
MLDISTS *const sds_vertical
#define SCIPallocMemory(scip, ptr)
Definition: scip_mem.h:51
MLDISTS *const sds_horizontal
static int extStackGetTopRoot(const GRAPH *graph, const EXTDATA *extdata)
const int * extreduce_mldistsTopTargetIds(const MLDISTS *, int)
SCIP_Real tree_cost
static void addComponentUpdateTreeCosts(const GRAPH *graph, EXTDATA *extdata, CONTRACT *contraction)
void graph_csrdepo_getCSR(const CSRDEPO *, int, CSR *)
Definition: graph_util.c:667
static void compUpDistUpdateLeavesDists(const GRAPH *graph, EXTDATA *extdata, CONTRACT *contraction)