Scippy

SCIP

Solving Constraint Integer Programs

cons_stpcomponents.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 cons_stpcomponents.c
17  * @brief Component constraint handler for Steiner problems
18  * @author Daniel Rehfeldt
19  *
20  * This file checks for biconnected components and solves them separately.
21  *
22  *
23  *
24  */
25 
26 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
27 //#define SCIP_DEBUG
28 #include <assert.h>
29 #include <string.h>
30 
31 #include "cons_stpcomponents.h"
32 #include "scip/scip.h"
33 #include "bidecomposition.h"
34 #include "prop_stp.h"
35 #include "substpsolver.h"
36 #include "graph.h"
37 #include "solstp.h"
38 
39 /**@name Constraint handler properties
40  *
41  * @{
42  */
43 
44 #define CONSHDLR_NAME "stpcomponents"
45 #define CONSHDLR_DESC "steiner tree components constraint handler"
46 #define CONSHDLR_SEPAPRIORITY -1 /**< priority of the constraint handler for separation */
47 #define CONSHDLR_ENFOPRIORITY -1 /**< priority of the constraint handler for constraint enforcing */
48 #define CONSHDLR_CHECKPRIORITY -1 /**< priority of the constraint handler for checking feasibility */
49 #define CONSHDLR_SEPAFREQ -1 /**< frequency for separating cuts; zero means to separate only in the root node */
50 #define CONSHDLR_PROPFREQ 0 /**< frequency for propagating domains; zero means only preprocessing propagation */
51 #define CONSHDLR_EAGERFREQ -1 /**< frequency for using all instead of only the useful constraints in separation,
52  * propagation and enforcement, -1 for no eager evaluations, 0 for first only */
53 #define CONSHDLR_DELAYSEPA FALSE /**< should separation method be delayed, if other separators found cuts? */
54 #define CONSHDLR_DELAYPROP FALSE /**< should propagation method be delayed, if other propagators found reductions? */
55 #define CONSHDLR_NEEDSCONS FALSE /**< should the constraint handler be skipped, if no constraints are available? */
56 
57 
58 #define CONSHDLR_PROP_TIMING SCIP_PROPTIMING_BEFORELP // SCIP_PROPTIMING_DURINGLPLOOP // SCIP_PROPTIMING_BEFORELP
59 #define DECOMP_MAXCOMPRATIO 0.95
60 #define DECOMP_MINNNODES 10
61 
62 
63 /**@} */
64 
65 /*
66  * Data structures
67  */
68 
69 
70 /** @brief Constraint data for \ref cons_stp.c "Stp" constraints */
71 struct SCIP_ConsData
72 {
73  GRAPH* graph; /**< graph data structure */
74 };
75 
76 
77 /** @brief Constraint handler data for \ref cons_stp.c "Stp" constraint handler */
78 struct SCIP_ConshdlrData
79 {
80  CUTNODES* cutnodes;
81  BIDECOMP* bidecomposition;
82  SCIP_Bool probDecompIsReady; /**< decomposition available?*/
83  SCIP_Bool probWasDecomposed; /**< already decomposed? */
84 };
85 
86 
87 /** sub-solution */
88 typedef struct sub_solution
89 {
90  int* subedgesSol; /**< solution: UNKNOWN/CONNECT */
91  int nsubedges; /**< number of edges of subproblem */
93 
94 
95 /*
96  * Local methods
97  */
98 
99 
100 
101 /** gets optimal sub-problem solution */
102 static
104  SUBSTP* substp, /**< sub-problem data structure */
105  SUBSOL* subcomp /**< component */
106  )
107 {
108  SCIP_CALL( substpsolver_getSolution(substp, subcomp->subedgesSol) );
109 
110  return SCIP_OKAY;
111 }
112 
113 
114 /** fixes original edges */
115 static
117  SCIP* scip, /**< SCIP data structure */
118  const SUBINOUT* subinout, /**< helper for problem mapping */
119  SUBSOL* subsol /**< solution */
120  )
121 {
122  SCIP_VAR** orgvars = SCIPprobdataGetVars(scip);
123  const int* const subedgesSol = subsol->subedgesSol;
124  const int* const subedgesToOrg = graph_subinoutGetSubToOrgEdgeMap(subinout);
125  const int nsubedges = subsol->nsubedges;
126  SCIP_Bool success;
127 #ifndef NDEBUG
128  GRAPH* orggraph = SCIPprobdataGetGraph2(scip);
129 #endif
130  assert(orggraph);
131  assert(orgvars);
132  assert(subedgesSol && subedgesToOrg);
133  assert(nsubedges > 0);
134 
135  for( int i = 0; i < nsubedges; i++ )
136  {
137  const int orgedge = subedgesToOrg[i];
138  assert(graph_edge_isInRange(orggraph, orgedge));
139 
140  if( subedgesSol[i] == CONNECT )
141  {
142 #ifdef SCIP_DEBUG
143  SCIPdebugMessage("fix to 1: ");
145 #endif
146  SCIP_CALL( SCIPStpFixEdgeVarTo1(scip, orgvars[orgedge], &success) );
147  }
148  else
149  {
150 #ifdef SCIP_DEBUG
151  SCIPdebugMessage("fix to 0: ");
153 #endif
154  assert(subedgesSol[i] == UNKNOWN);
155  SCIP_CALL( SCIPStpFixEdgeVarTo0(scip, orgvars[orgedge], &success) );
156  }
157  }
158 
159  return SCIP_OKAY;
160 }
161 
162 
163 /** initializes */
164 static
166  SCIP* scip, /**< sub-SCIP data structure */
167  const SUBSTP* substp, /**< sub problem */
168  SUBSOL** subsolution /**< to initialize */
169  )
170 {
171  SUBSOL* subsol;
172 
173  assert(scip && substp);
174 
175  SCIP_CALL( SCIPallocMemory(scip, subsolution) );
176  subsol = *subsolution;
177 
178  subsol->nsubedges = substpsolver_getNsubedges(substp);
179  assert(subsol->nsubedges >= 2);
180 
181  SCIP_CALL( SCIPallocMemoryArray(scip, &(subsol->subedgesSol), subsol->nsubedges) );
182 
183  return SCIP_OKAY;
184 }
185 
186 
187 /** exits */
188 static
189 void subsolFree(
190  SCIP* subscip, /**< sub-SCIP data structure */
191  SUBSOL** subsolution /**< to initialize */
192  )
193 {
194  SUBSOL* subsol;
195 
196  assert(subsolution);
197  subsol = *subsolution;
198  assert(subsol);
199 
200  SCIPfreeMemoryArray(subscip, &(subsol->subedgesSol));
201  SCIPfreeMemory(subscip, subsolution);
202 }
203 
204 
205 /** fixes original edges with sub-solution */
206 static
208  SCIP* scip, /**< SCIP data structure */
209  const SUBINOUT* subinout, /**< sub-problem insertion/extraction data structure */
210  SUBSTP* substp /**< sub-problem data structure */
211  )
212 {
213  SUBSOL* subcomp;
214 
215  assert(scip && subinout && substp);
216 
217  SCIP_CALL( subsolInit(scip, substp, &subcomp) );
218  SCIP_CALL( subsolGet(substp, subcomp) );
219  SCIP_CALL( subsolFixOrgEdges(scip, subinout, subcomp) );
220 
221  subsolFree(scip, &subcomp);
222 
223  return SCIP_OKAY;
224 }
225 
226 /** is promising? */
227 static
229  const GRAPH* g, /**< graph data structure */
230  const BIDECOMP* bidecomp /**< bidecomposition data structure */
231  )
232 {
233  if( g->knots < DECOMP_MINNNODES )
234  {
235  return FALSE;
236  }
237  else
238  {
239  const SCIP_Real maxcompratio = DECOMP_MAXCOMPRATIO;
240  const SCIP_Real maxratio = bidecomposition_getMaxcompNodeRatio(bidecomp);
241 
242  assert(GT(maxratio, 0.0));
243 
244  return (maxratio < maxcompratio);
245  }
246 }
247 
248 
249 /** gets subgraph */
250 static
252  SCIP* scip, /**< SCIP data structure */
253  const BIDECOMP* bidecomp, /**< all-components storage */
254  int compindex, /**< component index */
255  GRAPH* orggraph, /**< graph data structure */
256  GRAPH** subgraph /**< subgraph */
257  )
258 {
259 /*
260  SCIP_CALL( graph_copy(scip, orggraph, subgraph) );
261  (*subgraph)->is_packed = FALSE;
262  return SCIP_OKAY;
263 */
264  int subroot;
265  GRAPH* subg;
266  SUBINOUT* subinout = bidecomp->subinout;
267  assert(graph_valid(scip, orggraph));
268 
269  bidecomposition_markSub(bidecomp, compindex, orggraph);
270  SCIP_CALL( graph_subgraphExtract(scip, orggraph, subinout, subgraph) );
271  subg = *subgraph;
272 
273 #ifdef SCIP_DEBUG
274  SCIPdebugMessage("original nodes of connected components: \n");
275 
276  for( int i = 0; i < orggraph->knots; i++ )
277  {
278  if( orggraph->mark[i] )
279  graph_knot_printInfo(orggraph, i);
280  }
281 #endif
282 
283  SCIP_CALL( bidecomposition_getMarkedSubRoot(scip, bidecomp, orggraph, subg, &subroot) );
284  assert(graph_knot_isInRange(subg, subroot));
285  assert(Is_term(subg->term[subroot]));
286  subg->source = subroot;
287 
288  return SCIP_OKAY;
289 }
290 
291 
292 /** solves subproblem */
293 static
295  SCIP* scip, /**< SCIP data structure */
296  const BIDECOMP* bidecomp, /**< all-components storage */
297  int compindex, /**< component index */
298  GRAPH* orggraph, /**< graph data structure */
299  SCIP_Bool* success /**< solved? */
300  )
301 {
302  SUBINOUT* subinout;
303  SUBSTP* substp;
304  GRAPH* subgraph;
305 
306  assert(scip && orggraph && bidecomp && success);
307  assert(graph_subinoutUsesNewHistory(bidecomp->subinout));
308 
309  *success = TRUE;
310  subinout = bidecomp->subinout;
311 
312  if( bidecomposition_componentIsTrivial(bidecomp, compindex) )
313  {
314  SCIPdebugMessage("trivial component, skip! \n");
315  return SCIP_OKAY;
316  }
317 
318  SCIPdebugMessage("building subproblem... \n");
319 
320  SCIP_CALL( decomposeGetSubgraph(scip, bidecomp, compindex, orggraph, &subgraph) );
321 
322  /* NOTE: subgraph will be moved into substp! */
323  SCIP_CALL( substpsolver_init(scip, subgraph, &substp) );
325  orggraph, substp) );
326 
327  {
328  int verblevel;
329  SCIP_CALL( SCIPgetIntParam(scip, "display/verblevel", &verblevel) );
330  if( verblevel == 0 )
331  SCIP_CALL( substpsolver_setMute(substp) );
332  }
333 
334  SCIP_CALL( substpsolver_solve(scip, substp, success) );
335 
336  if( *success )
337  {
338  /* here we basically fix the entire sub-problem */
339  SCIP_CALL( subcompFixOrgEdges(scip, subinout, substp) );
340  }
341 
342  graph_subinoutClean(scip, subinout);
343  substpsolver_free(scip, &substp);
344 
345  return SCIP_OKAY;
346 }
347 
348 
349 /** tries to decompose and solve */
350 static
352  SCIP* scip, /**< SCIP data structure */
353  BIDECOMP* bidecomp, /**< bidecomposition data structure */
354  CUTNODES* cutnodes, /**< cut nodes data structure */
355  GRAPH* orggraph, /**< graph to decompose */
356  SCIP_Bool* success /**< decomposed? */
357  )
358 {
359  assert(bidecomp && cutnodes && success);
360  assert(graph_valid(scip, orggraph));
361  assert(*success == FALSE);
362 
363  SCIP_CALL( bidecomposition_initSubInOut(scip, orggraph, bidecomp) );
364  SCIP_CALL( graph_subinoutActivateEdgeMap(orggraph, bidecomp->subinout) );
366 
367  printf("solving problem by decomposition (%d components) \n", bidecomp->nbicomps);
368 
369  *success = TRUE;
370 
371  /* solve each biconnected component individually */
372  for( int i = 0; i < bidecomp->nbicomps; i++ )
373  {
374  SCIP_CALL( decomposeSolveSub(scip, bidecomp, i, orggraph, success) );
375 
376  if( *success == FALSE )
377  {
378  printf("could not solve component %d; aborting decomposition now \n", i);
379  break;
380  }
381  }
382 
383  return SCIP_OKAY;
384 }
385 
386 
387 /** initializes for conshdlrdata */
388 static
390  SCIP* scip, /**< SCIP data structure */
391  SCIP_CONSHDLRDATA* conshdlrdata, /**< cosntraint handler data */
392  GRAPH* orggraph, /**< graph to decompose */
393  SCIP_Bool* isPromsing /**< promising decomposition? */
394  )
395 {
396  BIDECOMP* bidecomp;
397  CUTNODES* cutnodes;
398 
399  assert(scip && conshdlrdata && orggraph && isPromsing);
400  assert(!conshdlrdata->cutnodes);
401  assert(!conshdlrdata->bidecomposition);
402  assert(graph_typeIsSpgLike(orggraph) && "only SPG decomposition supported yet");
403 
404  *isPromsing = FALSE;
405 
406  if( orggraph->terms == 1 )
407  {
408  SCIPdebugMessage("only one terminal...don't decompose \n");
409  return SCIP_OKAY;
410  }
411 
412  graph_mark(orggraph);
413 
414  if( !bidecomposition_isPossible(orggraph) )
415  {
416  SCIPdebugMessage("graph is too large...don't decompose \n");
417  return SCIP_OKAY;
418  }
419 
420  SCIP_CALL( bidecomposition_cutnodesInit(scip, orggraph, &cutnodes) );
421  conshdlrdata->cutnodes = cutnodes;
422  bidecomposition_cutnodesCompute(orggraph, cutnodes);
423 
424  if( cutnodes->biconn_ncomps > 0 )
425  {
426  SCIP_CALL( bidecomposition_init(scip, cutnodes, orggraph, &bidecomp) );
427  conshdlrdata->bidecomposition = bidecomp;
428 
429  *isPromsing = decomposeIsPromising(orggraph, bidecomp);
430  }
431 
432  return SCIP_OKAY;
433 }
434 
435 
436 
437 /** tries to decompose and solve */
438 static
439 void freeDecompose(
440  SCIP* scip, /**< SCIP data structure */
441  SCIP_CONSHDLRDATA* conshdlrdata /**< constraint handler data */
442  )
443 {
444  assert(scip && conshdlrdata);
445 
446  if( conshdlrdata->cutnodes )
447  {
448  bidecomposition_cutnodesFree(scip, &(conshdlrdata->cutnodes));
449  }
450 
451  if( conshdlrdata->bidecomposition )
452  {
453  bidecomposition_free(scip, &(conshdlrdata->bidecomposition));
454  }
455 }
456 
457 /** decomposes and solves */
458 static
460  SCIP* scip, /**< SCIP data structure */
461  SCIP_CONSHDLRDATA* conshdlrdata, /**< constraints handler data */
462  SCIP_Bool* success /**< decomposed? */
463  )
464 {
465  GRAPH* orggraph = SCIPprobdataGetGraph2(scip);
466 
467  assert(conshdlrdata && success);
468  assert(conshdlrdata->bidecomposition && conshdlrdata->cutnodes);
469  assert(orggraph->terms > 1);
470  assert(decomposeIsPromising(orggraph, conshdlrdata->bidecomposition));
471  assert(graph_typeIsSpgLike(orggraph) && "only SPG bidecomposition supported yet");
472  assert(conshdlrdata->cutnodes->biconn_ncomps > 0);
473 
474  *success = FALSE;
475  graph_mark(orggraph);
476 
477  SCIP_CALL( decomposeExec(scip, conshdlrdata->bidecomposition, conshdlrdata->cutnodes, orggraph, success) );
478 
479  return SCIP_OKAY;
480 }
481 
482 
483 /*
484  * Callbacks
485  */
486 
487 /** copy method for constraint handler plugins (called when SCIP copies plugins) */
488 static
489 SCIP_DECL_CONSHDLRCOPY(conshdlrCopyStpcomponents)
490 { /*lint --e{715}*/
491  assert(scip != NULL);
492  assert(conshdlr != NULL);
493  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
494 
495  /* call inclusion method of constraint handler */
497 
498  *valid = TRUE;
499 
500  return SCIP_OKAY;
501 }
502 
503 /** destructor of constraint handler to free constraint handler data (called when SCIP is exiting) */
504 static
505 SCIP_DECL_CONSFREE(consFreeStpcomponents)
506 { /*lint --e{715}*/
507  SCIP_CONSHDLRDATA* conshdlrdata;
508 
509  assert(scip != NULL);
510  assert(conshdlr != NULL);
511  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
512 
513  /* free constraint handler data */
514  conshdlrdata = SCIPconshdlrGetData(conshdlr);
515  assert(conshdlrdata != NULL);
516 
517  SCIPfreeMemory(scip, &conshdlrdata);
518 
519  SCIPconshdlrSetData(conshdlr, NULL);
520 
521  return SCIP_OKAY;
522 }
523 
524 /** solving process initialization method of constraint handler (called when branch and bound process is about to begin) */
525 static
526 SCIP_DECL_CONSINITSOL(consInitsolStpcomponents)
527 { /*lint --e{715}*/
528 
529 
530  return SCIP_OKAY;
531 }
532 
533 static
534 SCIP_DECL_CONSEXITSOL(consExitsolStpcomponents)
535 { /*lint --e{715}*/
536  SCIP_CONSHDLRDATA* conshdlrdata;
537 
538  conshdlrdata = SCIPconshdlrGetData(conshdlr);
539  assert(conshdlrdata);
540 
541  freeDecompose(scip, conshdlrdata);
542 
543  return SCIP_OKAY;
544 }
545 
546 /** frees specific constraint data */
547 static
548 SCIP_DECL_CONSDELETE(consDeleteStpcomponents)
549 { /*lint --e{715}*/
550  assert(conshdlr != NULL);
551  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
552  assert(consdata != NULL);
553  assert(*consdata != NULL);
554 
555  SCIPfreeBlockMemory(scip, consdata);
556 
557  return SCIP_OKAY;
558 }
559 
560 /** transforms constraint data into data belonging to the transformed problem */
561 static
562 SCIP_DECL_CONSTRANS(consTransStpcomponents)
563 { /*lint --e{715}*/
564  SCIP_CONSDATA* sourcedata;
565  SCIP_CONSDATA* targetdata;
566 
567  assert(conshdlr != NULL);
568  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
569  assert(SCIPgetStage(scip) == SCIP_STAGE_TRANSFORMING);
570  assert(sourcecons != NULL);
571  assert(targetcons != NULL);
572 
573  sourcedata = SCIPconsGetData(sourcecons);
574  assert(sourcedata != NULL);
575 
576  /* create constraint data for target constraint */
577  SCIP_CALL( SCIPallocBlockMemory(scip, &targetdata) );
578 
579  targetdata->graph = sourcedata->graph;
580 
581  /* create target constraint */
582  SCIP_CALL( SCIPcreateCons(scip, targetcons, SCIPconsGetName(sourcecons), conshdlr, targetdata,
583  SCIPconsIsInitial(sourcecons), SCIPconsIsSeparated(sourcecons), SCIPconsIsEnforced(sourcecons),
584  SCIPconsIsChecked(sourcecons), SCIPconsIsPropagated(sourcecons),
585  SCIPconsIsLocal(sourcecons), SCIPconsIsModifiable(sourcecons),
586  SCIPconsIsDynamic(sourcecons), SCIPconsIsRemovable(sourcecons), SCIPconsIsStickingAtNode(sourcecons)) );
587 
588  return SCIP_OKAY;
589 }
590 
591 /** LP initialization method of constraint handler (called before the initial LP relaxation at a node is solved) */
592 static
593 SCIP_DECL_CONSINITLP(consInitlpStpcomponents)
594 { /*lint --e{715}*/
595 
596 
597  return SCIP_OKAY;
598 }
599 
600 /** domain propagation method of constraint handler */
601 static
602 SCIP_DECL_CONSPROP(consPropStpcomponents)
603 { /*lint --e{715}*/
604  SCIP_CONSHDLRDATA* conshdlrdata = SCIPconshdlrGetData(conshdlr);
605  GRAPH* graph = SCIPprobdataGetGraph2(scip);
606  SCIP_Bool success;
607 
608  assert(conshdlrdata);
609  assert(graph);
610 
611  *result = SCIP_DIDNOTRUN;
612 
613  if( SCIPisStopped(scip) )
614  return SCIP_OKAY;
615 
616  if( graph->terms == 1 )
617  return SCIP_OKAY;
618 
619  if( !graph_typeIsSpgLike(graph) )
620  return SCIP_OKAY;
621 
622  if( !conshdlrdata->probDecompIsReady )
623  return SCIP_OKAY;
624 
625  assert(!conshdlrdata->probWasDecomposed);
626 
627  *result = SCIP_DIDNOTFIND;
628 
629  SCIP_CALL( divideAndConquer(scip, conshdlrdata, &success) );
630 
631  if( success )
632  {
633  printf("problem solved by bidecomposition \n");
634  conshdlrdata->probWasDecomposed = TRUE;
635  }
636 
637  return SCIP_OKAY;
638 }
639 
640 
641 /** variable rounding lock method of constraint handler */
642 static
643 SCIP_DECL_CONSLOCK(consLockStpcomponents)
644 { /*lint --e{715}*/
645  return SCIP_OKAY;
646 }
647 
648 
649 #define consEnfolpStpcomponents NULL
650 #define consEnfopsStpcomponents NULL
651 #define consCheckStpcomponents NULL
653 /*
654  * Interface methods
655  */
656 
657 
658 /** sets the data for bidecomposition up */
660  SCIP* scip, /**< SCIP data structure */
661  GRAPH* graph /**< graph data */
662  )
663 {
664  SCIP_CONSHDLR* conshdlr = NULL;
665  SCIP_CONSHDLRDATA* conshdlrdata;
666  SCIP_Bool isPromising = FALSE;
667 
668  assert(scip && graph);
669 
670  conshdlr = SCIPfindConshdlr(scip, "stpcomponents");
671  conshdlrdata = SCIPconshdlrGetData(conshdlr);
672  assert(conshdlrdata);
673 
674  SCIP_CALL( initDecompose(scip, conshdlrdata, graph, &isPromising) );
675 
676  conshdlrdata->probDecompIsReady = isPromising;
677 
678  if( !isPromising )
679  {
680  freeDecompose(scip, conshdlrdata);
681  }
682 
683  return SCIP_OKAY;
684 }
685 
686 
687 /** is a promising bidecomposition available? */
689  SCIP* scip /**< SCIP data structure */
690  )
691 {
692  SCIP_CONSHDLR* conshdlr = NULL;
693  SCIP_CONSHDLRDATA* conshdlrdata;
694 
695  assert(scip);
696 
697  conshdlr = SCIPfindConshdlr(scip, "stpcomponents");
698  conshdlrdata = SCIPconshdlrGetData(conshdlr);
699  assert(conshdlrdata);
700 
701  return conshdlrdata->probDecompIsReady;
702 }
703 
704 /** creates the handler for stp constraints and includes it in SCIP */
706  SCIP* scip /**< SCIP data structure */
707  )
708 {
709  SCIP_CONSHDLRDATA* conshdlrdata;
710  SCIP_CONSHDLR* conshdlr;
711 
712  /* create stp constraint handler data */
713  SCIP_CALL( SCIPallocMemory(scip, &conshdlrdata) );
714  conshdlrdata->cutnodes = NULL;
715  conshdlrdata->bidecomposition = NULL;
716  conshdlrdata->probWasDecomposed = FALSE;
717  conshdlrdata->probDecompIsReady = FALSE;
718 
719  conshdlr = NULL;
720  /* include constraint handler */
724  conshdlrdata) );
725  assert(conshdlr != NULL);
726 
727  SCIP_CALL( SCIPsetConshdlrCopy(scip, conshdlr, conshdlrCopyStpcomponents, NULL) );
728  SCIP_CALL( SCIPsetConshdlrDelete(scip, conshdlr, consDeleteStpcomponents) );
729  SCIP_CALL( SCIPsetConshdlrTrans(scip, conshdlr, consTransStpcomponents) );
730  SCIP_CALL( SCIPsetConshdlrInitsol(scip, conshdlr, consInitsolStpcomponents) );
731  SCIP_CALL( SCIPsetConshdlrExitsol(scip, conshdlr, consExitsolStpcomponents) );
732 
733  SCIP_CALL( SCIPsetConshdlrInitlp(scip, conshdlr, consInitlpStpcomponents) );
734  SCIP_CALL( SCIPsetConshdlrProp(scip, conshdlr, consPropStpcomponents, CONSHDLR_PROPFREQ, CONSHDLR_DELAYPROP,
736  SCIP_CALL( SCIPsetConshdlrFree(scip, conshdlr, consFreeStpcomponents) );
737 
738  return SCIP_OKAY;
739 }
void SCIPconshdlrSetData(SCIP_CONSHDLR *conshdlr, SCIP_CONSHDLRDATA *conshdlrdata)
Definition: cons.c:4205
SCIP_RETCODE SCIPsetConshdlrDelete(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSDELETE((*consdelete)))
Definition: scip_cons.c:563
static SCIP_RETCODE decomposeGetSubgraph(SCIP *scip, const BIDECOMP *bidecomp, int compindex, GRAPH *orggraph, GRAPH **subgraph)
SCIP_STAGE SCIPgetStage(SCIP *scip)
Definition: scip_general.c:356
SCIP_Bool SCIPconsIsDynamic(SCIP_CONS *cons)
Definition: cons.c:8344
SCIP_RETCODE SCIPsetConshdlrTrans(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSTRANS((*constrans)))
Definition: scip_cons.c:586
int source
Definition: graphdefs.h:195
SCIP_RETCODE SCIPStpFixEdgeVarTo1(SCIP *scip, SCIP_VAR *edgevar, SCIP_Bool *success)
Definition: prop_stp.c:2443
SCIP_Bool bidecomposition_isPossible(const GRAPH *g)
#define Is_term(a)
Definition: graphdefs.h:102
SCIP_CONSHDLR * SCIPfindConshdlr(SCIP *scip, const char *name)
Definition: scip_cons.c:877
SCIP_RETCODE graph_subinoutActivateEdgeMap(const GRAPH *, SUBINOUT *)
Definition: graph_sub.c:769
#define SCIPfreeMemoryArray(scip, ptr)
Definition: scip_mem.h:71
SCIP_Bool graph_valid(SCIP *, const GRAPH *)
Definition: graph_base.c:1480
static void freeDecompose(SCIP *scip, SCIP_CONSHDLRDATA *conshdlrdata)
int terms
Definition: graphdefs.h:192
SCIP_RETCODE substpsolver_setMute(SUBSTP *substp)
Definition: substpsolver.c:525
SCIP_Bool graph_subinoutUsesNewHistory(const SUBINOUT *)
Definition: graph_sub.c:848
SCIP_VAR ** SCIPprobdataGetVars(SCIP *scip)
static SCIP_RETCODE divideAndConquer(SCIP *scip, SCIP_CONSHDLRDATA *conshdlrdata, SCIP_Bool *success)
#define SCIPallocMemoryArray(scip, ptr, num)
Definition: scip_mem.h:55
void graph_mark(GRAPH *)
Definition: graph_base.c:1130
includes methods for Steiner tree problem solutions
#define consEnfopsStpcomponents
void graph_knot_printInfo(const GRAPH *, int)
Definition: graph_stats.c:151
#define FALSE
Definition: def.h:87
static SCIP_RETCODE subsolGet(SUBSTP *substp, SUBSOL *subcomp)
SCIP_RETCODE SCIPincludeConshdlrBasic(SCIP *scip, SCIP_CONSHDLR **conshdlrptr, const char *name, const char *desc, int enfopriority, int chckpriority, int eagerfreq, SCIP_Bool needscons, SCIP_DECL_CONSENFOLP((*consenfolp)), SCIP_DECL_CONSENFOPS((*consenfops)), SCIP_DECL_CONSCHECK((*conscheck)), SCIP_DECL_CONSLOCK((*conslock)), SCIP_CONSHDLRDATA *conshdlrdata)
Definition: scip_cons.c:166
void graph_subinoutActivateNewHistory(SUBINOUT *)
Definition: graph_sub.c:788
#define TRUE
Definition: def.h:86
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:54
includes various files containing graph methods used for Steiner tree problems
SCIP_Bool SCIPconsIsStickingAtNode(SCIP_CONS *cons)
Definition: cons.c:8364
static SCIP_DECL_CONSINITLP(consInitlpStpcomponents)
void bidecomposition_free(SCIP *scip, BIDECOMP **bidecomposition)
#define CONSHDLR_DESC
static SCIP_RETCODE initDecompose(SCIP *scip, SCIP_CONSHDLRDATA *conshdlrdata, GRAPH *orggraph, SCIP_Bool *isPromsing)
#define CONSHDLR_NEEDSCONS
#define SCIPfreeBlockMemory(scip, ptr)
Definition: scip_mem.h:99
#define SCIPdebugMessage
Definition: pub_message.h:87
SCIP_Bool SCIPStpcomponentsAllowsDecomposition(SCIP *scip)
#define consEnfolpStpcomponents
SCIP_RETCODE substpsolver_init(SCIP *scip, GRAPH *subgraph, SUBSTP **substp)
Definition: substpsolver.c:313
SCIP_Bool SCIPconsIsRemovable(SCIP_CONS *cons)
Definition: cons.c:8354
SCIP_RETCODE SCIPsetConshdlrInitlp(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSINITLP((*consinitlp)))
Definition: scip_cons.c:609
several decomposition methods for Steiner tree problems
static SCIP_DECL_CONSINITSOL(consInitsolStpcomponents)
SCIP_RETCODE SCIPcreateCons(SCIP *scip, SCIP_CONS **cons, const char *name, SCIP_CONSHDLR *conshdlr, SCIP_CONSDATA *consdata, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
Definition: scip_cons.c:934
int *RESTRICT mark
Definition: graphdefs.h:198
Components constraint handler for Steiner problems.
#define CONSHDLR_CHECKPRIORITY
SCIP_RETCODE SCIPsetConshdlrInitsol(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSINITSOL((*consinitsol)))
Definition: scip_cons.c:429
SCIP_RETCODE SCIPStpFixEdgeVarTo0(SCIP *scip, SCIP_VAR *edgevar, SCIP_Bool *success)
Definition: prop_stp.c:2419
static SCIP_RETCODE subsolInit(SCIP *scip, const SUBSTP *substp, SUBSOL **subsolution)
#define consCheckStpcomponents
static SCIP_DECL_CONSTRANS(consTransStpcomponents)
SCIP_RETCODE SCIPsetConshdlrCopy(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSHDLRCOPY((*conshdlrcopy)), SCIP_DECL_CONSCOPY((*conscopy)))
Definition: scip_cons.c:332
SCIP_RETCODE substpsolver_transferHistory(const int *edgeMapToOrg, GRAPH *orggraph, SUBSTP *substp)
Definition: substpsolver.c:404
void bidecomposition_markSub(const BIDECOMP *bidecomp, int compindex, GRAPH *g)
void bidecomposition_cutnodesCompute(const GRAPH *g, CUTNODES *cutnodes)
const char * SCIPconshdlrGetName(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4175
static SCIP_DECL_CONSDELETE(consDeleteStpcomponents)
struct sub_solution SUBSOL
const char * SCIPconsGetName(SCIP_CONS *cons)
Definition: cons.c:8085
SCIP_Bool SCIPconsIsPropagated(SCIP_CONS *cons)
Definition: cons.c:8304
static SCIP_DECL_CONSLOCK(consLockStpcomponents)
SCIP_RETCODE SCIPsetConshdlrFree(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSFREE((*consfree)))
Definition: scip_cons.c:357
static SCIP_DECL_CONSPROP(consPropStpcomponents)
SCIP_CONSHDLRDATA * SCIPconshdlrGetData(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4195
SCIP_RETCODE graph_subgraphExtract(SCIP *, GRAPH *, SUBINOUT *, GRAPH **)
Definition: graph_sub.c:712
#define NULL
Definition: lpi_spx1.cpp:155
#define DECOMP_MAXCOMPRATIO
SCIP_Real bidecomposition_getMaxcompNodeRatio(const BIDECOMP *bidecomp)
Solver for Steiner tree (sub-) problems.
SCIP_RETCODE SCIPgetIntParam(SCIP *scip, const char *name, int *value)
Definition: scip_param.c:260
int knots
Definition: graphdefs.h:190
#define SCIP_CALL(x)
Definition: def.h:384
static SCIP_RETCODE decomposeExec(SCIP *scip, BIDECOMP *bidecomp, CUTNODES *cutnodes, GRAPH *orggraph, SCIP_Bool *success)
#define CONSHDLR_PROP_TIMING
SCIP_Bool SCIPconsIsLocal(SCIP_CONS *cons)
Definition: cons.c:8324
struct SCIP_ConsData SCIP_CONSDATA
Definition: type_cons.h:56
#define CONSHDLR_ENFOPRIORITY
SCIP_RETCODE bidecomposition_cutnodesInit(SCIP *scip, const GRAPH *g, CUTNODES **cutnodes)
propagator for Steiner tree problems, using the LP reduced costs
static SCIP_RETCODE subcompFixOrgEdges(SCIP *scip, const SUBINOUT *subinout, SUBSTP *substp)
static SCIP_RETCODE decomposeSolveSub(SCIP *scip, const BIDECOMP *bidecomp, int compindex, GRAPH *orggraph, SCIP_Bool *success)
#define GT(a, b)
Definition: portab.h:84
#define SCIP_Bool
Definition: def.h:84
SCIP_RETCODE bidecomposition_initSubInOut(SCIP *scip, const GRAPH *g, BIDECOMP *bidecomposition)
SCIP_RETCODE substpsolver_getSolution(SUBSTP *substp, int *edgesol)
Definition: substpsolver.c:500
SCIP_Bool SCIPconsIsChecked(SCIP_CONS *cons)
Definition: cons.c:8284
SCIP_Bool SCIPconsIsInitial(SCIP_CONS *cons)
Definition: cons.c:8254
static SCIP_DECL_CONSHDLRCOPY(conshdlrCopyStpcomponents)
int *RESTRICT term
Definition: graphdefs.h:196
void graph_edge_printInfo(const GRAPH *, int)
Definition: graph_stats.c:133
#define DECOMP_MINNNODES
void bidecomposition_cutnodesFree(SCIP *scip, CUTNODES **cutnodes)
#define CONNECT
Definition: graphdefs.h:87
static SCIP_DECL_CONSEXITSOL(consExitsolStpcomponents)
#define SCIPfreeMemory(scip, ptr)
Definition: scip_mem.h:69
static SCIP_DECL_CONSFREE(consFreeStpcomponents)
static void subsolFree(SCIP *subscip, SUBSOL **subsolution)
SCIP_CONSDATA * SCIPconsGetData(SCIP_CONS *cons)
Definition: cons.c:8115
SCIP_Bool graph_edge_isInRange(const GRAPH *, int)
Definition: graph_stats.c:110
void graph_subinoutClean(SCIP *, SUBINOUT *)
Definition: graph_sub.c:882
static SCIP_RETCODE subsolFixOrgEdges(SCIP *scip, const SUBINOUT *subinout, SUBSOL *subsol)
const int * graph_subinoutGetSubToOrgEdgeMap(const SUBINOUT *)
Definition: graph_sub.c:812
#define SCIP_Real
Definition: def.h:177
SCIP_Bool SCIPconsIsModifiable(SCIP_CONS *cons)
Definition: cons.c:8334
SCIP_Bool SCIPisStopped(SCIP *scip)
Definition: scip_general.c:694
SCIP_Bool SCIPconsIsEnforced(SCIP_CONS *cons)
Definition: cons.c:8274
SCIP_Bool SCIPconsIsSeparated(SCIP_CONS *cons)
Definition: cons.c:8264
int substpsolver_getNsubedges(const SUBSTP *substp)
Definition: substpsolver.c:488
static SCIP_Bool decomposeIsPromising(const GRAPH *g, const BIDECOMP *bidecomp)
void substpsolver_free(SCIP *scip, SUBSTP **substp)
Definition: substpsolver.c:380
static DPSUBSOL ** subsol
#define CONSHDLR_NAME
#define SCIPallocMemory(scip, ptr)
Definition: scip_mem.h:51
SCIP_Bool graph_knot_isInRange(const GRAPH *, int)
Definition: graph_node.c:52
#define UNKNOWN
Definition: sepa_mcf.c:4095
struct SCIP_ConshdlrData SCIP_CONSHDLRDATA
Definition: type_cons.h:55
SCIPallocBlockMemory(scip, subsol))
SCIP_Bool bidecomposition_componentIsTrivial(const BIDECOMP *bidecomp, int compindex)
SCIP_RETCODE bidecomposition_getMarkedSubRoot(SCIP *scip, const BIDECOMP *bidecomp, const GRAPH *orggraph, const GRAPH *subgraph, int *subroot)
SCIP_RETCODE substpsolver_solve(SCIP *scip, SUBSTP *substp, SCIP_Bool *success)
Definition: substpsolver.c:452
SCIP_Bool graph_typeIsSpgLike(const GRAPH *)
Definition: graph_stats.c:57
SCIP_RETCODE SCIPsetConshdlrExitsol(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSEXITSOL((*consexitsol)))
Definition: scip_cons.c:453
GRAPH * SCIPprobdataGetGraph2(SCIP *scip)
#define CONSHDLR_DELAYPROP
SCIP_RETCODE SCIPincludeConshdlrStpcomponents(SCIP *scip)
SCIP_RETCODE bidecomposition_init(SCIP *scip, const CUTNODES *cutnodes, const GRAPH *g, BIDECOMP **bidecomposition)
SCIP callable library.
SCIP_RETCODE SCIPStpcomponentsSetUp(SCIP *scip, GRAPH *graph)
#define CONSHDLR_PROPFREQ
#define CONSHDLR_EAGERFREQ
SCIP_RETCODE SCIPsetConshdlrProp(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPROP((*consprop)), int propfreq, SCIP_Bool delayprop, SCIP_PROPTIMING proptiming)
Definition: scip_cons.c:266