Scippy

SCIP

Solving Constraint Integer Programs

branch_stp.c
Go to the documentation of this file.
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2 /* */
3 /* This file is part of the program and library */
4 /* SCIP --- Solving Constraint Integer Programs */
5 /* */
6 /* Copyright (C) 2002-2015 Konrad-Zuse-Zentrum */
7 /* fuer Informationstechnik Berlin */
8 /* */
9 /* SCIP is distributed under the terms of the ZIB Academic License. */
10 /* */
11 /* You should have received a copy of the ZIB Academic License */
12 /* along with SCIP; see the file COPYING. If not email to scip@zib.de. */
13 /* */
14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15 /**@file branch_stp.c
16  * @brief Steiner vertex branching rule
17  * @author Daniel Rehfeldt
18  *
19  * The Steiner branching rule implemented in this file is described in
20  * "A Generic Approach to Solving the Steiner Tree Problem and Variants" by Daniel Rehfeldt.
21  * It includes and exludes Steiner vertices during branching.
22  *
23 */
24 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
25 
26 #include <assert.h>
27 #include <string.h>
28 #include "scip/branch_fullstrong.h"
29 #include "scip/cons_linear.h"
30 #include "scip/var.h"
31 #include "scip/set.h"
32 #include "scip/pub_tree.h"
33 #include "scip/struct_scip.h"
34 #include "scip/clock.h"
35 #include "grph.h"
36 #include "branch_stp.h"
37 #include "probdata_stp.h"
38 
39 #define BRANCHRULE_NAME "stp"
40 #define BRANCHRULE_DESC "stp branching on vertices"
41 #define BRANCHRULE_PRIORITY -1000000
42 #define BRANCHRULE_MAXDEPTH -1
43 #define BRANCHRULE_MAXBOUNDDIST 1.0
44 
45 
46 /*
47  * Data structures
48  */
49 
50 /** branching rule data */
52 {
53  int lastcand; /**< last evaluated candidate of last branching rule execution */
54 };
55 
56 
57 /*
58  * Local methods
59  */
60 
61 static
62 SCIP_RETCODE selectBranchingVertex(
63  SCIP* scip, /**< original SCIP data structure */
64  int* vertex /**< the vertex to branch on */
65  )
66 {
67  SCIP_PROBDATA* probdata;
68  SCIP_VAR** edgevars;
69  GRAPH* g;
70  SCIP_Real maxflow;
71  SCIP_Real* inflow;
72  int a;
73  int k;
74  int nnodes;
75  int branchvert;
76 
77  /* get problem data */
78  probdata = SCIPgetProbData(scip);
79  assert(probdata != NULL);
80 
81  /* get graph */
82  g = SCIPprobdataGetGraph(probdata);
83  assert(g != NULL);
84 
85  /* LP has not been solved */
86  if( !SCIPhasCurrentNodeLP(scip) || SCIPgetLPSolstat(scip) != SCIP_LPSOLSTAT_OPTIMAL )
87  {
88  *vertex = UNKNOWN;
89  return SCIP_OKAY;
90  }
91 
92  edgevars = SCIPprobdataGetEdgeVars(scip);
93  assert(edgevars != NULL);
94 
95  nnodes = g->knots;
96 
97  SCIP_CALL( SCIPallocBufferArray(scip, &inflow, nnodes) );
98 
99  branchvert = UNKNOWN;
100  maxflow = 1.0;
101  for( k = 0; k < nnodes; k++ )
102  {
103  inflow[k] = 0.0;
104  for( a = g->inpbeg[k]; a != EAT_LAST; a = g->ieat[a] )
105  inflow[k] += SCIPvarGetLPSol(edgevars[a]);
106 
107  if( !Is_term(g->term[k]) && SCIPisLT(scip, inflow[k], 1.0) && SCIPisLT(scip, fabs(inflow[k] - 0.5), maxflow) )
108  {
109  branchvert = k;
110  maxflow = fabs(inflow[k] - 0.5);
111  SCIPdebugMessage("new maxflow %f on vertex %d \n", inflow[k], branchvert );
112  }
113  }
114  SCIPdebugMessage("maxflow %f on vertex %d, term? %d \n", maxflow, branchvert, Is_term(g->term[branchvert]) );
115  (*vertex) = branchvert;
116 
117  SCIPfreeBufferArray(scip, &inflow);
118 
119  return SCIP_OKAY;
120 }
121 
122 /*
123  * Callback methods of branching rule
124  */
125 
126 /** copy method for branchrule plugins (called when SCIP copies plugins) */
127 static
128 SCIP_DECL_BRANCHCOPY(branchCopyStp)
129 { /*lint --e{715}*/
130  assert(scip != NULL);
131  assert(branchrule != NULL);
132  assert(strcmp(SCIPbranchruleGetName(branchrule), BRANCHRULE_NAME) == 0);
133 
134  /* call inclusion method of branchrule */
135  SCIP_CALL( SCIPincludeBranchruleStp(scip) ) ;
136 
137  return SCIP_OKAY;
138 }
139 
140 /** destructor of branching rule to free user data (called when SCIP is exiting) */
141 static
142 SCIP_DECL_BRANCHFREE(branchFreeStp)
143 { /*lint --e{715}*/
144  SCIP_BRANCHRULEDATA* branchruledata;
145 
146  /* free branching rule data */
147  branchruledata = SCIPbranchruleGetData(branchrule);
148  assert(branchruledata != NULL);
149 
150  SCIPfreeMemory(scip, &branchruledata);
151  SCIPbranchruleSetData(branchrule, NULL);
152 
153  return SCIP_OKAY;
154 }
155 
156 /** initialization method of branching rule (called after problem was transformed) */
157 static
158 SCIP_DECL_BRANCHINIT(branchInitStp)
159 { /*lint --e{715}*/
160  SCIP_BRANCHRULEDATA* branchruledata;
161 
162  branchruledata = SCIPbranchruleGetData(branchrule);
163  assert(branchruledata != NULL);
164 
165  branchruledata->lastcand = 0;
166 
167  return SCIP_OKAY;
168 }
169 
170 /** deinitialization method of branching rule (called before transformed problem is freed) */
171 static
172 SCIP_DECL_BRANCHEXIT(branchExitStp)
173 { /*lint --e{715}*/
174 #if 0
175  SCIP_BRANCHRULEDATA* branchruledata;
176 #endif
177  SCIPstatistic(int j = 0);
178 
179 #if 0
180  /* initialize branching rule data */
181  branchruledata = SCIPbranchruleGetData(branchrule);
182  assert(branchruledata != NULL);
183 #endif
184  return SCIP_OKAY;
185 }
186 
187 /** branching execution method for fractional LP solutions */
188 static
189 SCIP_DECL_BRANCHEXECLP(branchExeclpStp)
190 { /*lint --e{715}*/
191  SCIP_PROBDATA* probdata;
192  SCIP_CONS* consin;
193  SCIP_CONS* consout;
194  SCIP_NODE* vertexin;
195  SCIP_NODE* vertexout;
196  SCIP_VAR** edgevars;
197  SCIP_Real estimatein;
198  SCIP_Real estimateout;
199  GRAPH* g;
200  int e;
201  int branchvertex;
202 
203  assert(branchrule != NULL);
204  assert(strcmp(SCIPbranchruleGetName(branchrule), BRANCHRULE_NAME) == 0);
205  assert(scip != NULL);
206  assert(result != NULL);
207 
208  SCIPdebugMessage("Execlp method of Stp branching\n ");
209  estimatein = SCIPgetUpperbound(scip);
210  estimateout = SCIPgetUpperbound(scip);
211  *result = SCIP_DIDNOTRUN;
212 
213  /* get problem data */
214  probdata = SCIPgetProbData(scip);
215  assert(probdata != NULL);
216 
217  /* get graph */
218  g = SCIPprobdataGetGraph(probdata);
219  assert(g != NULL);
220 
221 
222  /* get vertex to branch on */
223  SCIP_CALL( selectBranchingVertex(scip, &branchvertex) );
224 
225  if( branchvertex == UNKNOWN )
226  {
227  SCIPdebugMessage("Branching did not run \n");
228  return SCIP_OKAY;
229  }
230 
231  edgevars = SCIPprobdataGetEdgeVars(scip);
232 
233  /* create constraints */
234  SCIP_CALL( SCIPcreateConsLinear(scip, &consin, "consin", 0,
235  NULL, NULL, 1.0, 1.0,
237 
238  SCIP_CALL( SCIPcreateConsLinear(scip, &consout, "consout", 0,
239  NULL, NULL, 0.0, 0.0,
241 
242  for( e = g->inpbeg[branchvertex]; e != EAT_LAST; e = g->ieat[e] )
243  {
244  SCIP_CALL( SCIPaddCoefLinear(scip, consin, edgevars[e], 1.0) );
245  SCIP_CALL( SCIPaddCoefLinear(scip, consout, edgevars[e], 1.0) );
246  SCIP_CALL( SCIPaddCoefLinear(scip, consout, edgevars[flipedge(e)], 1.0) );
247  }
248 
249  /* create the child nodes */
250  SCIP_CALL( SCIPcreateChild(scip, &vertexin, 1.0, estimatein) );
251 
252  SCIP_CALL( SCIPcreateChild(scip, &vertexout, 1.0, estimateout) );
253 
254  assert(vertexin != NULL);
255  assert(vertexout != NULL);
256 
257  SCIP_CALL( SCIPaddConsNode(scip, vertexin, consin, NULL) );
258  SCIP_CALL( SCIPaddConsNode(scip, vertexout, consout, NULL) );
259 
260  /* relase constraints */
261  SCIP_CALL( SCIPreleaseCons(scip, &consin) );
262  SCIP_CALL( SCIPreleaseCons(scip, &consout) );
263 
264  SCIPdebugMessage("Branched on stp vertex %d \n", branchvertex);
265 
266  *result = SCIP_BRANCHED;
267 
268 
269  return SCIP_OKAY;
270 }
271 
272 /*
273  * branching rule specific interface methods
274  */
275 
276 /** creates the multi-aggregated branching rule and includes it in SCIP */
278  SCIP* scip /**< SCIP data structure */
279  )
280 {
281  SCIP_BRANCHRULEDATA* branchruledata;
282  SCIP_BRANCHRULE* branchrule;
283 
284  /* create stp branching rule data */
285  SCIP_CALL( SCIPallocMemory(scip, &branchruledata) );
286  branchruledata->lastcand = 0;
287 
288  /* include branching rule */
289  SCIP_CALL( SCIPincludeBranchruleBasic(scip, &branchrule, BRANCHRULE_NAME, BRANCHRULE_DESC, BRANCHRULE_PRIORITY,
290  BRANCHRULE_MAXDEPTH, BRANCHRULE_MAXBOUNDDIST, branchruledata) );
291 
292  assert(branchrule != NULL);
293 
294  /* set non fundamental callbacks via setter functions */
295  SCIP_CALL( SCIPsetBranchruleCopy(scip, branchrule, branchCopyStp) );
296  SCIP_CALL( SCIPsetBranchruleFree(scip, branchrule, branchFreeStp) );
297  SCIP_CALL( SCIPsetBranchruleInit(scip, branchrule, branchInitStp) );
298  SCIP_CALL( SCIPsetBranchruleExit(scip, branchrule, branchExitStp) );
299  SCIP_CALL( SCIPsetBranchruleExecLp(scip, branchrule, branchExeclpStp) );
300 
301  return SCIP_OKAY;
302 }
#define Is_term(a)
Definition: grph.h:158
#define BRANCHRULE_PRIORITY
Definition: branch_stp.c:41
Definition: grph.h:55
#define TRUE
Definition: portab.h:34
static SCIP_DECL_BRANCHEXECLP(branchExeclpStp)
Definition: branch_stp.c:189
#define EAT_LAST
Definition: grph.h:31
SCIP_RETCODE SCIPincludeBranchruleStp(SCIP *scip)
Definition: branch_stp.c:277
#define BRANCHRULE_DESC
Definition: branch_stp.c:40
Problem data for stp problem.
static SCIP_DECL_BRANCHEXIT(branchExitStp)
Definition: branch_stp.c:172
GRAPH * SCIPprobdataGetGraph(SCIP_PROBDATA *probdata)
#define BRANCHRULE_NAME
Definition: branch_stp.c:39
#define FALSE
Definition: portab.h:37
static SCIP_DECL_BRANCHCOPY(branchCopyStp)
Definition: branch_stp.c:128
int * term
Definition: grph.h:69
int knots
Definition: grph.h:61
#define BRANCHRULE_MAXBOUNDDIST
Definition: branch_stp.c:43
int * inpbeg
Definition: grph.h:75
static SCIP_DECL_BRANCHINIT(branchInitStp)
Definition: branch_stp.c:158
SCIP_VAR ** SCIPprobdataGetEdgeVars(SCIP *scip)
#define UNKNOWN
Definition: grph.h:148
static SCIP_DECL_BRANCHFREE(branchFreeStp)
Definition: branch_stp.c:142
includes various files containing graph methods used for Steiner problems
#define BRANCHRULE_MAXDEPTH
Definition: branch_stp.c:42
Steiner vertex branching rule.
#define flipedge(edge)
Definition: grph.h:143
int * ieat
Definition: grph.h:99
static SCIP_RETCODE selectBranchingVertex(SCIP *scip, int *vertex)
Definition: branch_stp.c:62