Scippy

SCIP

Solving Constraint Integer Programs

extreducedefs.h
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 extreducedefs.h
17  * @brief includes extended reductions definitions and inline methods used for Steiner tree problems
18  * @author Daniel Rehfeldt
19  *
20  *
21  */
22 
23 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
24 
25 
26 #ifndef APPLICATIONS_STP_SRC_EXTREDUCEDEFS_H_
27 #define APPLICATIONS_STP_SRC_EXTREDUCEDEFS_H_
28 
29 
30 #ifdef __cplusplus
31 extern "C" {
32 #endif
33 
34 
35 #define STP_EXT_CLOSENODES_MAXN 50
36 #define STP_EXT_MAXSTACKSIZE 5000
37 #define STP_EXT_MAXNCOMPS 1000
38 #define STP_EXT_MAXDFSDEPTH 6
39 #define STP_EXT_MAXDFSDEPTH_GUARD (STP_EXT_MAXDFSDEPTH + 2)
40 #define STP_EXT_MIDDFSDEPTH 5
41 #define STP_EXT_MINDFSDEPTH 4
42 #define STP_EXT_MAXGRAD 9
43 #define STP_EXT_MAXEDGES 500
44 #define STP_EXT_DEPTH_MIDNEDGES 50000
45 #define STP_EXT_DEPTH_MAXNEDGES 100000
46 #define STP_EXTTREE_MAXNEDGES 25
47 #define STP_EXTTREE_MAXNLEAVES 20
48 #define STP_EXTTREE_MAXNLEAVES_GUARD (STP_EXTTREE_MAXNLEAVES + STP_EXT_MAXGRAD)
49 #define EXT_EDGE_WRAPPED -10
50 
51 
52 #define EXT_STATE_NONE 0
53 #define EXT_STATE_EXPANDED 1
54 #define EXT_STATE_MARKED 2
55 
56 #define STP_MLDISTS_ID_EMPTY -2
57 #define STP_MLDISTS_ID_UNSET -1
58 #define STP_MLDISTS_DIST_UNSET -1.0
59 
60 #include "scip/scip.h"
61 #include "reduce.h"
62 #include "graph.h"
63 
64 /** structure for storing distances in the extension tree */
66 
67 /** structure for storing data for algorithms based on contraction of extension tree */
69 
70 
71 /** path root state */
72 typedef struct pathroot_state
73 {
76 } PRSTATE;
77 
78 /** distance data */
79 typedef struct distance_data
80 {
81  // SCIP_Bool* pathrootsd_isdirty;
82  SD* sdistdata; /* can be NULL */
84  RANGE* closenodes_range; /* of size nnodes */
85  int* closenodes_indices; /* of size closenodes_totalsize */
86  int* closenodes_prededges; /* of size closenodes_totalsize; NULL in opt mode */
87  SCIP_Real* closenodes_distances; /* of size closenodes_totalsize */
88  int* pathroot_blocksizes; /* of size nedges / 2 */
89  int* pathroot_blocksizesmax; /* of size nedges / 2 */
90  PRSTATE** pathroot_blocks; /* of size nedges / 2 */
91  SCIP_Bool* pathroot_isdirty; /* of size nnodes */
92  int* pathroot_nrecomps; /* of size nnodes */
97 } DISTDATA;
98 
99 
100 /** permanent extension data */
102 {
103 /* non-owned data: */
104  SCIP_RANDNUMGEN* randnumgen; /**< random number generator (initialized to NULL) */
105  REDCOST* redcostdata; /**< reduced cost data (initialized to NULL) */
106  DISTDATA* distdata_default; /**< default distance data (initialized to NULL) */
107  DISTDATA* distdata_biased; /**< biased distance data (initialized to NULL) */
108 /* owned data: */
109  CONTRACT* contration; /**< contraction data */
110  DCMST* dcmst; /**< dynamic MST */
111  CSRDEPO* msts_comp; /**< storage for MSTs with extending node of the given level */
112  CSRDEPO* msts_levelbase; /**< storage for MSTs without extending node of the level below */
113  MLDISTS* sds_horizontal; /**< SDs from deepest leaves to remaining ones */
114  MLDISTS* sds_vertical; /**< SDs between leaves of same depth */
115  MLDISTS* sdsbias_horizontal; /**< as above, but for biased SDs; can be NULL */
116  MLDISTS* sdsbias_vertical; /**< as above, but for biased SDs; can be NULL */
117  STP_Bool* edgedeleted; /**< (non-owned!) edge array to mark which directed edge can be removed */
118  SCIP_Bool* isterm; /**< marks whether node is a terminal (or proper terminal for PC) */
119  SCIP_Real* bottleneckDistNode; /**< needs to be set to -1.0 (size nnodes) */
120  SCIP_Real* pcSdToNode; /**< needs to be set to -1.0 for all nodes, or NULL if not Pc */
121  int* tree_deg; /**< -1 for forbidden nodes (e.g. PC terminals), nnodes for tail, 0 otherwise; in method: position ( > 0) for nodes in tree */
122  const int* result; /**< solution array or NULL... NON-OWNED! */
123  STP_Vectype(int)* nodes_implications; /**< implied nodes for each node */
124  int nnodes; /**< number of nodes */
128  SCIP_Bool redcostEqualAllow; /**< delete also for equality of reduced costs? */
129  SCIP_Bool useSdBias; /**< use biased bottleneck Steiner distance? (only for pseudo-elimination) */
130  SCIP_Bool solIsValid; /**< use primal solution? */
131  enum EXTRED_MODE mode; /**< mode */
132 } EXTPERMA;
133 
134 
135 /** Reduction data; just used internally.
136  * Stores information for SDs between tree vertices,
137  * reduced costs, and pseudo-ancestor conflicts. */
138 typedef struct reduction_data
139 {
140  CONTRACT* contration; /**< contraction data */
141  DCMST* const dcmst;
146  MLDISTS* const sdsbias_horizontal; /**< can be NULL */
147  MLDISTS* const sdsbias_vertical; /**< can be NULL */
148  const STP_Bool* const edgedeleted;
150  STP_Vectype(int)* nodes_implications;
151  SCIP_Real* const redcost_treecosts; /* for each level */
152  SCIP_Bool* const redcost_noReversedTree; /* for each level */
153  SCIP_Real* const redcost_treenodeswaps; /* for each level and each node */
154  const int redcost_nlevels;
157 } REDDATA;
158 
159 
160 /** PC/MW data; just used internally. */
161 typedef struct pcmw_specific_data
162 {
163  SCIP_Real* const pcSdToNode; /**< all entries need to be set to -1.0 */
164  int* const pcSdCands;
168 } PCDATA;
169 
170 
171 /** initial extension component
172  * NOTE: it is vital the the first edge of the star component comes from the root!
173  * (will thus be constantly asserted) */
175 {
176  int* compedges; /**< edges of the component */
177  int* extleaves; /**< leaves to extend from */
178  int nextleaves; /**< number of extension nodes */
179  int ncompedges; /**< number of edges of the component */
180  int comproot; /**< component root */
181  int genstar_centeredge; /**< center-edge or -1 */
182  SCIP_Bool allowReversion; /**< allow change of comproot? (with extleaves = \{comproot\}) */
183 } EXTCOMP;
184 
185 
186 /** extension data; just used internally */
187 typedef struct extension_data
188 {
189  int* const extstack_data;
190  int* const extstack_start;
191  int* const extstack_state;
192  int* const tree_leaves;
193  int* const tree_innerNodes;
194  int* const tree_edges;
195  int* const tree_deg; /**< -1 for forbidden nodes (e.g. PC terminals), nnodes for current tail,
196  0 otherwise; in method: position ( > 0) for nodes in tree */
197  SCIP_Real* const tree_bottleneckDistNode; /**< needs to be set to -1.0 (for all nodes) */
198  int* const tree_parentNode;
199  SCIP_Real* const tree_parentEdgeCost; /**< of size nnodes */
200  const SCIP_Bool* const node_isterm; /**< marks whether node is a terminal (or proper terminal for PC) */
201  REDDATA* const reddata;
203  DISTDATA* const distdata_biased; /**< can be NULL */
204  const REDCOST* const redcostdata;
205  PCDATA* const pcdata;
207  STP_Vectype(int) sdeq_resetStack;
218  int ncostupdatestalls; /**< cost update stalls counter */
219  int genstar_centeredge; /* center edge or -1 */
221  const int extstack_maxsize;
222  const int tree_maxnleaves;
223  const int tree_maxdepth;
224  const int tree_maxnedges;
225  enum EXTRED_MODE mode; /**< mode */
226  const EXTCOMP* const extcomp;
227 } EXTDATA;
228 
229 
230 
231 /* inline methods
232  */
233 
234 
235 /** prize-collecting problem? */
236 static inline
238  const GRAPH* graph, /**< graph data structure */
239  const EXTDATA* extdata /**< extension data */
240 )
241 {
242  assert(graph && extdata);
243  assert(graph_pc_isPc(graph) == (extdata->pcdata->pcSdToNode != NULL));
244 
245  return (extdata->pcdata->pcSdToNode != NULL);
246 }
247 
248 
249 /** currently at initial component? */
250 static inline
252  const EXTDATA* extdata /**< extension data */
253 )
254 {
255  assert(extdata);
256  assert(extdata->extstack_ncomponents > 0);
257 
258  return ((extdata->extstack_ncomponents - 1) == 0);
259 }
260 
261 
262 /** is the initial component a single edge? */
263 static inline
265  const EXTDATA* extdata /**< extension data */
266 )
267 {
268  assert(extdata);
269  assert(extdata->extstack_start[1] >= 1);
270  assert(extdata->extstack_start[1] == 1 || extdata->extstack_start[1] >= 3);
271  assert(extdata->extstack_start[1] != 1 || extdata->genstar_centeredge == -1);
272 
273  return (extdata->extstack_start[1] == 1);
274 }
275 
276 
277 /** is the initial component a star? */
278 static inline
280  const EXTDATA* extdata /**< extension data */
281 )
282 {
283  assert(extdata);
284  assert(extdata->extstack_start[1] >= 1);
285  assert(extdata->extstack_start[1] == 1 || extdata->extstack_start[1] >= 3);
286 
287  return (extdata->extstack_start[1] >= 3 && extdata->genstar_centeredge == -1);
288 }
289 
290 
291 /** is the initial component a star? */
292 static inline
294  const EXTDATA* extdata /**< extension data */
295 )
296 {
297  assert(extdata);
298 
299  return (extdata->genstar_centeredge != -1);
300 }
301 
302 
303 /** currently at initial star? */
304 static inline
306  const EXTDATA* extdata /**< extension data */
307 )
308 {
309  return (extInitialCompIsStar(extdata) && extIsAtInitialComp(extdata));
310 }
311 
312 
313 /** currently at initial general star? */
314 static inline
316  const EXTDATA* extdata /**< extension data */
317 )
318 {
319  return (extInitialCompIsGenStar(extdata) && extIsAtInitialComp(extdata));
320 }
321 
322 
323 /** returns current position in the stack */
324 static inline
326  const EXTDATA* extdata /**< extension data */
327 )
328 {
329  assert(extdata);
330  assert(extdata->extstack_ncomponents > 0);
331 
332  return (extdata->extstack_ncomponents - 1);
333 }
334 
335 
336 /** returns root of top component on the stack */
337 static inline
339  const GRAPH* graph, /**< graph data structure */
340  const EXTDATA* extdata /**< extension data */
341 )
342 {
343  const int stackpos = extStackGetPosition(extdata);
344  const int comproot = graph->tail[extdata->extstack_data[extdata->extstack_start[stackpos]]];
345 
346  assert(comproot >= 0);
347  assert(extdata->tree_deg[comproot] >= 1 || comproot == extdata->tree_root);
348 
349  return comproot;
350 }
351 
352 
353 /** returns start of outgoing edges */
354 static inline
356  const EXTDATA* extdata, /**< extension data */
357  int stackpos /**< current position */
358 )
359 {
360  int start;
361 
362  assert(extdata);
363  assert(stackpos >= 0 && stackpos <= extStackGetPosition(extdata));
364 
365  if( stackpos == 0 && extInitialCompIsStar(extdata) )
366  {
367  start = extdata->extstack_start[stackpos] + 1;
368  }
369  else if( stackpos == 0 && extInitialCompIsGenStar(extdata) )
370  {
371  start = extdata->extstack_start[stackpos] + 2;
372  }
373  else
374  {
375  start = extdata->extstack_start[stackpos];
376  }
377 
378  return start;
379 }
380 
381 
382 /** returns end of outgoing edges */
383 static inline
385  const EXTDATA* extdata, /**< extension data */
386  int stackpos /**< current position */
387 )
388 {
389  assert(extdata);
390  assert(stackpos >= 0 && stackpos <= extStackGetPosition(extdata));
391 
392  return (extdata->extstack_start[stackpos + 1]);
393 }
394 
395 
396 /** returns start of outgoing edges of top */
397 static inline
399  const EXTDATA* extdata, /**< extension data */
400  int stackpos /**< current position */
401 )
402 {
403  assert(extdata);
404  assert(stackpos == extStackGetPosition(extdata));
405 
406  return extStackGetOutEdgesStart(extdata, stackpos);
407 }
408 
409 
410 /** returns end of outgoing edges of top */
411 static inline
413  const EXTDATA* extdata, /**< extension data */
414  int stackpos /**< current position */
415 )
416 {
417  assert(extdata);
418  assert(stackpos == extStackGetPosition(extdata));
419 
420  return extStackGetOutEdgesEnd(extdata, stackpos);
421 }
422 
423 
424 /** is component at top position wrapped? */
425 static inline
427  const EXTDATA* extdata /**< extension data */
428  )
429 {
430  const int pos = extStackGetPosition(extdata);
431 
432  assert(extdata->extstack_start[pos + 1] - extdata->extstack_start[pos] >= 1);
433 
434  if( extdata->extstack_start[pos + 1] - extdata->extstack_start[pos] == 1
435  && extdata->extstack_data[extdata->extstack_start[pos]] == EXT_EDGE_WRAPPED )
436  {
437  return TRUE;
438  }
439 
440  assert(extdata->extstack_data[extdata->extstack_start[pos]] != EXT_EDGE_WRAPPED);
441 
442  return FALSE;
443 }
444 
445 
446 /** is component at top position a singleton edge? */
447 static inline
449  const EXTDATA* extdata /**< extension data */
450  )
451 {
452  const int pos = extStackGetPosition(extdata);
453  assert(extdata->extstack_start[pos + 1] - extdata->extstack_start[pos] >= 1);
454 
455  return (extdata->extstack_start[pos + 1] - extdata->extstack_start[pos] == 1);
456 }
457 
458 
459 /** Finds position of given leaf in leaves data.
460  * Returns -1 if leaf could not be found. */
461 static inline
463  const EXTDATA* extdata, /**< extension data */
464  int leaf /**< leaf to find */
465 )
466 {
467  int i;
468  const int* const tree_leaves = extdata->tree_leaves;
469 
470  assert(tree_leaves);
471  assert(extdata->tree_nleaves > 1);
472  assert(leaf >= 0 && extdata->tree_deg[leaf] >= 1);
473 
474  for( i = extdata->tree_nleaves - 1; i >= 0; i-- )
475  {
476  const int currleaf = tree_leaves[i];
477 
478  if( currleaf == leaf )
479  break;
480  }
481 
482  return i;
483 }
484 
485 
486 /** can we extend the tree from given leaf? */
487 inline static
489  const GRAPH* graph, /**< graph data structure */
490  const SCIP_Bool* isterm, /**< marks whether node is a terminal (or proper terminal for PC) */
491  int leaf /**< the leaf */
492 )
493 {
494  assert(graph && isterm);
495  assert(leaf >= 0 && leaf < graph->knots);
496 
497  return (!isterm[leaf] && graph->grad[leaf] <= STP_EXT_MAXGRAD);
498 }
499 
500 
501 /** Gets proper SD value. I.e., non-negative, but possible FARAWAY */
502 static inline
504  SCIP_Real sd_in /**< the special distance */
505 )
506 {
507  assert(LE(sd_in, FARAWAY));
508  assert(EQ(sd_in, -1.0) || GE(sd_in, 0.0));
509 
510  return (sd_in >= -0.5) ? sd_in : FARAWAY;
511 }
512 
513 
514 /** is given SD non-trivial? */
515 static inline
517  SCIP_Real specialDist /**< SD */
518  )
519 {
520  assert(specialDist >= 0 || EQ(specialDist, -1.0));
521  assert(LT(specialDist, FARAWAY) && "todo: might fail for edge replacement");
522 
523  return (specialDist >= -0.5);
524 }
525 
526 
527 /** does reduction data have biased SD information? */
528 static inline
530  const REDDATA* reddata /**< reduction data */
531 )
532 {
533  assert(reddata);
534  assert((reddata->sdsbias_vertical != NULL) == (reddata->sdsbias_horizontal != NULL));
535  assert(!reddata->sdsbias_use || (reddata->sdsbias_vertical != NULL));
536 
537  return (reddata->sdsbias_use);
538 }
539 
540 
541 
542 #ifdef __cplusplus
543 }
544 #endif
545 
546 
547 #endif /* APPLICATIONS_STP_SRC_EXTREDUCEDEFS_H_ */
#define STP_Vectype(type)
Definition: stpvector.h:44
const STP_Bool *const edgedeleted
int closenodes_maxnumber
Definition: extreducedefs.h:95
static SCIP_Bool extInitialCompIsGenStar(const EXTDATA *extdata)
#define EXT_EDGE_WRAPPED
Definition: extreducedefs.h:49
static int extLeafFindPos(const EXTDATA *extdata, int leaf)
int *const pcSdCands
const int extstack_maxsize
static SCIP_Bool extIsAtInitialStar(const EXTDATA *extdata)
const int extstack_maxncomponents
static SCIP_Bool extStackTopIsWrapped(const EXTDATA *extdata)
SCIP_Real tree_innerPrize
SCIP_Real *const redcost_treecosts
#define FALSE
Definition: def.h:87
int *const pseudoancestor_mark
struct pcmw_specific_data PCDATA
#define TRUE
Definition: def.h:86
includes various files containing graph methods used for Steiner tree problems
int * pathroot_nrecomps
Definition: extreducedefs.h:92
static SCIP_Bool extInitialCompIsEdge(const EXTDATA *extdata)
const SCIP_Bool redcost_allowEquality
int *const extstack_data
int *const tree_edges
static int extStackGetTopOutEdgesStart(const EXTDATA *extdata, int stackpos)
static SCIP_Bool extStackTopIsSingleton(const EXTDATA *extdata)
static SCIP_Bool extInitialCompIsStar(const EXTDATA *extdata)
#define FARAWAY
Definition: graphdefs.h:89
static int extStackGetTopOutEdgesEnd(const EXTDATA *extdata, int stackpos)
int * closenodes_prededges
Definition: extreducedefs.h:86
static int extStackGetPosition(const EXTDATA *extdata)
RANGE * closenodes_range
Definition: extreducedefs.h:84
int * closenodes_indices
Definition: extreducedefs.h:85
REDDATA *const reddata
const EXTCOMP *const extcomp
int * pathroot_blocksizes
Definition: extreducedefs.h:88
struct extension_data_permanent EXTPERMA
int *const tree_leaves
#define LE(a, b)
Definition: portab.h:83
static SCIP_Real extSdGetProper(SCIP_Real sd_in)
#define GE(a, b)
Definition: portab.h:85
PRSTATE ** pathroot_blocks
Definition: extreducedefs.h:90
struct reduction_data REDDATA
SCIP_Real *const pcSdToNode
static SCIP_Real extSdIsNonTrivial(SCIP_Real specialDist)
int *const tree_parentNode
int *const tree_innerNodes
static SCIP_Bool extIsAtInitialComp(const EXTDATA *extdata)
SCIP_Real * bottleneckDistNode
static SCIP_Bool extReddataHasBiasedSds(const REDDATA *reddata)
int *RESTRICT grad
Definition: graphdefs.h:201
struct extension_data EXTDATA
const int tree_maxnedges
SCIP_Real * closenodes_distances
Definition: extreducedefs.h:87
#define NULL
Definition: lpi_spx1.cpp:155
int *const extstack_state
static SCIP_Bool extProbIsPc(const GRAPH *graph, const EXTDATA *extdata)
#define EQ(a, b)
Definition: portab.h:79
CONTRACT * contration
SCIP_Bool hasPathReplacement
Definition: extreducedefs.h:96
const int tree_maxdepth
static int extStackGetOutEdgesEnd(const EXTDATA *extdata, int stackpos)
DISTDATA *const distdata_biased
SCIP_RANDNUMGEN * randnumgen
#define LT(a, b)
Definition: portab.h:81
static int extStackGetOutEdgesStart(const EXTDATA *extdata, int stackpos)
const REDCOST *const redcostdata
unsigned char STP_Bool
Definition: portab.h:34
const int tree_maxnleaves
CSRDEPO *const msts_comp
#define SCIP_Bool
Definition: def.h:84
SCIP_Bool *const sdeq_edgesIsForbidden
struct initial_extension_component EXTCOMP
int *RESTRICT tail
Definition: graphdefs.h:223
CSRDEPO *const msts_levelbase
int *const extstack_start
SCIP_Real *const redcost_treenodeswaps
struct distance_data DISTDATA
SCIP_Real *const tree_bottleneckDistNode
PCDATA *const pcdata
int closenodes_totalsize
Definition: extreducedefs.h:94
SCIP_Bool graph_pc_isPc(const GRAPH *)
const SCIP_Bool *const node_isterm
SCIP_Bool sdeq_hasForbiddenEdges
struct pathroot_state PRSTATE
DCMST *const dcmst
SCIP_Bool *const redcost_noReversedTree
DISTDATA *const distdata
const int redcost_nlevels
#define STP_EXT_MAXGRAD
Definition: extreducedefs.h:42
static SCIP_Bool extIsAtInitialGenStar(const EXTDATA *extdata)
EXTRED_MODE
Definition: reducedefs.h:71
#define SCIP_Real
Definition: def.h:177
MLDISTS *const sds_vertical
MLDISTS *const sdsbias_vertical
MLDISTS *const sds_horizontal
int *const tree_deg
static int extStackGetTopRoot(const GRAPH *graph, const EXTDATA *extdata)
MLDISTS *const sdsbias_horizontal
int * pathroot_blocksizesmax
Definition: extreducedefs.h:89
SCIP_Bool * pathroot_isdirty
Definition: extreducedefs.h:91
includes various reduction methods for Steiner tree problems
SCIP_Real tree_cost
SCIP callable library.
const SCIP_Bool sdsbias_use
static SCIP_Bool extLeafIsExtendable(const GRAPH *graph, const SCIP_Bool *isterm, int leaf)
SCIP_Real *const tree_parentEdgeCost