Scippy

SCIP

Solving Constraint Integer Programs

pricer_stp.c
Go to the documentation of this file.
1 
2 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
3 /* */
4 /* This file is part of the program and library */
5 /* SCIP --- Solving Constraint Integer Programs */
6 /* */
7 /* Copyright (C) 2002-2015 Konrad-Zuse-Zentrum */
8 /* fuer Informationstechnik Berlin */
9 /* */
10 /* SCIP is distributed under the terms of the ZIB Academic License. */
11 /* */
12 /* You should have received a copy of the ZIB Academic License */
13 /* along with SCIP; see the file COPYING. If not email to scip@zib.de. */
14 /* */
15 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
16 
17 /**@file pricer_stp.c
18  * @brief stp variable pricer
19  * @author Daniel Rehfeldt
20  */
21 
22 #include <assert.h>
23 #include <string.h>
24 #include "scip/cons_linear.h"
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include "pricer_stp.h"
28 #include "grph.h"
29 
30 
31 #define PRICER_NAME "stp"
32 #define PRICER_DESC "pricer for stp"
33 #define PRICER_PRIORITY 1
34 #define PRICER_DELAY TRUE /* only call pricer if all problem variables have non-negative reduced costs */
35 
36 /*
37  * Data structures
38  */
39 
40 
41 /** variable pricer data */
43 {
44  SCIP* scip; /**< SCIP data structure */
45  SCIP_CONS** edgecons; /**< array containing all edge constraints */
46  SCIP_CONS** pathcons; /**< array containing all path constraints */
47  SCIP_Real* pi; /**< array of the dual solutions to the edge constraints*/
48  SCIP_Real* mi; /**< array of the dual solutions to the path constraint*/
49  SCIP_Real lowerbound; /**< lower bound computed by the pricer */
50  int* realterms; /**< array of all terminals except the root */
51  int* ncreatedvars; /**< array (1,...,realnterms); in ncreatedvars[t] the number of
52  created variables (during pricing) pertaining to terminal t is stored */
53  int root; /**< root node */
54  int nedges; /**< number of edges */
55  int realnterms; /**< number of terminals except the root */
56  SCIP_Bool bigt; /**< stores whether the 'T' model is being used */
57 };
58 
59 
60 /*
61  * Local methods
62  */
63 
64 
65 /*
66  * Callback methods of variable pricer
67  */
68 
69 /** copy method for pricer plugins (called when SCIP copies plugins) */
70 static
71 SCIP_DECL_PRICERCOPY(pricerCopyStp)
72 { /*lint --e{715}*/
73  SCIPdebugPrintf("pricerCopy \n");
74  assert(pricer != NULL);
75  assert(strcmp(SCIPpricerGetName(pricer), PRICER_NAME) == 0);
76 
77  return SCIP_OKAY;
78 }
79 
80 /** destructor of variable pricer to free user data (called when SCIP is exiting) */
81 static
82 SCIP_DECL_PRICERFREE(pricerFreeStp)
83 {
84  SCIP_PRICERDATA* pricerdata;
85  SCIPdebugPrintf("pricerfree \n");
86  assert(scip != NULL);
87 
88  /* get pricerdata */
89  pricerdata = SCIPpricerGetData(pricer);
90 
91  /* free memory for pricerdata*/
92  if ( pricerdata != NULL )
93  {
94  SCIPfreeMemory(scip, &pricerdata);
95  }
96 
97  SCIPpricerSetData(pricer, NULL);
98 
99  return SCIP_OKAY;
100 }
101 
102 /** initialization method of variable pricer (called after problem was transformed) */
103 static
104 SCIP_DECL_PRICERINIT(pricerInitStp)
105 {
106  SCIP_PRICERDATA* pricerdata;
107  SCIPdebugPrintf("pricer Init \n");
108  assert(scip != NULL);
109  assert(pricer != NULL);
110 
111  pricerdata = SCIPpricerGetData(pricer);
112  pricerdata->edgecons = SCIPprobdataGetEdgeConstraints(scip);
113  pricerdata->pathcons = SCIPprobdataGetPathConstraints(scip);
114  pricerdata->root = SCIPprobdataGetRoot(scip);
115  pricerdata->nedges = SCIPprobdataGetNEdges(scip);
116  pricerdata->realnterms = SCIPprobdataGetRNTerms(scip);
117  pricerdata->realterms = SCIPprobdataGetRTerms(scip);
118  pricerdata->bigt = SCIPprobdataIsBigt(scip);
119  pricerdata->lowerbound = 0;
120  return SCIP_OKAY;
121 }
122 
123 /** solving process initialization method of variable pricer (called when branch and bound process is about to begin) */
124 static
125 SCIP_DECL_PRICERINITSOL(pricerInitsolStp)
126 {
127  SCIP_PRICERDATA* pricerdata;
128  SCIPdebugPrintf("pricerinitsol \n");
129  assert(scip != NULL);
130  assert(pricer != NULL);
131 
132  pricerdata = SCIPpricerGetData(pricer);
133  assert(pricerdata != NULL);
134 
135  /* allocate memory */
136  if( !pricerdata->bigt )
137  {
138  SCIP_CALL( SCIPallocMemoryArray(scip, &(pricerdata->pi), SCIPprobdataGetNEdges(scip) * SCIPprobdataGetRNTerms(scip)) );
139  }
140  else
141  {
142  SCIP_CALL( SCIPallocMemoryArray(scip, &(pricerdata->pi), SCIPprobdataGetNEdges(scip)) );
143  }
144 
145  SCIP_CALL( SCIPallocMemoryArray(scip, &(pricerdata->mi), SCIPprobdataGetRNTerms(scip)) );
146  SCIP_CALL( SCIPallocMemoryArray(scip, &pricerdata->ncreatedvars, SCIPprobdataGetRNTerms(scip)) );
147  BMSclearMemoryArray(pricerdata->ncreatedvars, SCIPprobdataGetRNTerms(scip));
148 
149  return SCIP_OKAY;
150 }
151 
152 /** solving process deinitialization method of variable pricer (called before branch and bound process data is freed) */
153 static
154 SCIP_DECL_PRICEREXITSOL(pricerExitsolStp)
155 {
156  SCIP_PRICERDATA* pricerdata;
157 
158  assert(scip != NULL);
159  assert(pricer != NULL);
160 
161  pricerdata = SCIPpricerGetData(pricer);
162  assert(pricerdata != NULL);
163 
164  /* free memory */
165  SCIPfreeMemoryArray(scip, &(pricerdata->mi));
166  SCIPfreeMemoryArray(scip, &(pricerdata->pi));
167  SCIPfreeMemoryArray(scip, &pricerdata->ncreatedvars);
168 
169  return SCIP_OKAY;
170 }
171 
172 /** method for either Farkas or Redcost pricing */
173 static
174 SCIP_RETCODE pricing(
175  SCIP* scip, /**< SCIP data structure */
176  SCIP_PRICER* pricer, /**< pricer */
177  SCIP_Real* lowerbound, /**< lowerbound pointer */
178  SCIP_Bool farkas /**< TRUE: Farkas pricing; FALSE: Redcost pricing */
179  )
180 {
181  SCIP_PRICERDATA* pricerdata; /* the data of the pricer */
182  SCIP_PROBDATA* probdata;
183  GRAPH* graph;
184  SCIP_VAR* var;
185  PATH* path;
186  SCIP_Real* edgecosts; /* edgecosts of the current subproblem */
187  char varname[SCIP_MAXSTRLEN];
188  SCIP_Real newlowerbound = -SCIPinfinity(scip);
189  SCIP_Real redcost; /* reduced cost */
190  int tail;
191  int e;
192  int t;
193  int i;
194 
195  assert(scip != NULL);
196  assert(pricer != NULL);
197 
198  /* get pricer data */
199  pricerdata = SCIPpricerGetData(pricer);
200  assert(pricerdata != NULL);
201 
202  /* get problem data */
203  probdata = SCIPgetProbData(scip);
204  assert(probdata != NULL);
205 
206  SCIPdebugMessage("solstat=%d\n", SCIPgetLPSolstat(scip));
207 
208  if( !farkas && SCIPgetLPSolstat(scip) == SCIP_LPSOLSTAT_OPTIMAL )
209  newlowerbound = SCIPgetSolTransObj(scip, NULL);
210 
211  SCIPdebug( SCIP_CALL( SCIPprintSol(scip, NULL, NULL, FALSE) ) );
212 
213 # if 0
214  if ( pricerdata->lowerbound <= 4 )
215  {
216  char label[SCIP_MAXSTRLEN];
217  (void)SCIPsnprintf(label, SCIP_MAXSTRLEN, "X%g.gml", pricerdata->lowerbound);
218  SCIP_CALL( SCIPprobdataPrintGraph(scip, label , NULL, TRUE) );
219  pricerdata->lowerbound++;
220  }
221 #endif
222  /* get the graph*/
223  graph = SCIPprobdataGetGraph(probdata);
224 
225  /* get dual solutions and save them in mi and pi */
226  for( t = 0; t < pricerdata->realnterms; ++t )
227  {
228  if( farkas )
229  {
230  pricerdata->mi[t] = SCIPgetDualfarkasLinear(scip, pricerdata->pathcons[t]);
231  }
232  else
233  {
234  pricerdata->mi[t] = SCIPgetDualsolLinear(scip, pricerdata->pathcons[t]);
235  assert(!SCIPisNegative(scip, pricerdata->mi[t]));
236  }
237  }
238 
239  for( e = 0; e < pricerdata->nedges; ++e )
240  {
241  if( !pricerdata->bigt )
242  {
243  for( t = 0; t < pricerdata->realnterms; ++t )
244  {
245  if( farkas )
246  {
247  pricerdata->pi[t * pricerdata->nedges + e] = SCIPgetDualfarkasLinear(
248  scip, pricerdata->edgecons[t * pricerdata->nedges + e]);
249  }
250  else
251  {
252  pricerdata->pi[t * pricerdata->nedges + e] = SCIPgetDualsolLinear(
253  scip, pricerdata->edgecons[t * pricerdata->nedges + e]);
254  }
255  }
256  }
257  else
258  {
259  if( farkas )
260  {
261  pricerdata->pi[e] = SCIPgetDualfarkasLinear(
262  scip, pricerdata->edgecons[e]);
263  }
264  else
265  {
266  pricerdata->pi[e] = SCIPgetDualsolLinear(
267  scip, pricerdata->edgecons[e]);
268  }
269  }
270  }
271 
272  SCIP_CALL( SCIPallocMemoryArray(scip, &path, graph->knots) );
273  SCIP_CALL( SCIPallocMemoryArray(scip, &edgecosts, pricerdata->nedges) );
274 
275  if( pricerdata->bigt )
276  {
277  for( e = 0; e < pricerdata->nedges; ++e )
278  {
279  edgecosts[e] = (-pricerdata->pi[e]);
280  }
281  }
282  /* find shortest r-t (r root, t terminal) paths and create corresponding variables iff reduced cost < 0 */
283  for( t = 0; t < pricerdata->realnterms; ++t )
284  {
285  for( e = 0; e < pricerdata->nedges; ++e )
286  {
287  if( !pricerdata->bigt )
288  {
289  edgecosts[e] = (-pricerdata->pi[t * pricerdata->nedges + e]);
290  }
291 
292  assert(!SCIPisNegative(scip, edgecosts[e]));
293  }
294 
295  for( i = 0; i < graph->knots; i++ )
296  graph->mark[i] = 1;
297 
298  graph_path_exec(scip, graph, FSP_MODE, pricerdata->root, edgecosts, path);
299 
300  /* compute reduced cost of shortest path to terminal t */
301  redcost = 0.0;
302  tail = pricerdata->realterms[t];
303  while( tail != pricerdata->root )
304  {
305  redcost += edgecosts[path[tail].edge];
306  tail = graph->tail[path[tail].edge];
307  }
308  redcost -= pricerdata->mi[t];
309 
310  if( !farkas && SCIPgetLPSolstat(scip) == SCIP_LPSOLSTAT_OPTIMAL )
311  {
312  newlowerbound += redcost;
313  }
314  /* check if reduced cost < 0 */
315  if( SCIPisNegative(scip, redcost) )
316  {
317  /* create variable to the shortest path (having reduced cost < 0) */
318  var = NULL;
319  sprintf(varname, "PathVar%d_%d", t, pricerdata->ncreatedvars[t]);
320  ++(pricerdata->ncreatedvars[t]);
321 
322  SCIP_CALL( SCIPcreateVarBasic(scip, &var, varname, 0.0, SCIPinfinity(scip), 0.0, SCIP_VARTYPE_CONTINUOUS) );
323  SCIP_CALL( SCIPaddPricedVar(scip, var, -redcost) );
324  tail = pricerdata->realterms[t];
325  while( tail != pricerdata->root )
326  {
327  /* add variable to constraints */
328  if( !pricerdata->bigt )
329  {
330  SCIP_CALL( SCIPaddCoefLinear(scip, pricerdata->edgecons[t * pricerdata->nedges + path[tail].edge], var, 1.0) );
331  }
332  else
333  {
334  SCIP_CALL( SCIPaddCoefLinear(scip, pricerdata->edgecons[path[tail].edge], var, 1.0) );
335  }
336 
337  tail = graph->tail[path[tail].edge];
338  }
339  SCIP_CALL( SCIPaddCoefLinear(scip, pricerdata->pathcons[t], var, 1.0) );
340  }
341  }
342 
343  if( !farkas && SCIPgetLPSolstat(scip) == SCIP_LPSOLSTAT_OPTIMAL )
344  *lowerbound = newlowerbound;
345 
346  SCIPfreeMemoryArray(scip, &edgecosts);
347  SCIPfreeMemoryArray(scip, &path);
348 
349  return SCIP_OKAY;
350 }
351 
352 /** reduced cost pricing method of variable pricer for feasible LPs */
353 static
354 SCIP_DECL_PRICERREDCOST(pricerRedcostStp)
355 { /*lint --e{715}*/
356  SCIP_CALL( pricing(scip, pricer, lowerbound, FALSE) );
357 
358  /* set result pointer */
359  *result = SCIP_SUCCESS;
360  return SCIP_OKAY;
361 }
362 
363 /** Farkas pricing method of variable pricer for infeasible LPs */
364 static
365 SCIP_DECL_PRICERFARKAS(pricerFarkasStp)
366 { /*lint --e{715}*/
367  SCIP_CALL( pricing(scip, pricer, NULL, TRUE) );
368 
369  return SCIP_OKAY;
370 }
371 
372 /*
373  * variable pricer specific interface methods
374  */
375 
376 /** creates the stp variable pricer and includes it in SCIP */
377 SCIP_RETCODE SCIPincludePricerStp(
378  SCIP* scip /**< SCIP data structure */
379  )
380 {
381 
382  SCIP_PRICERDATA* pricerdata;
383  SCIP_PRICER* pricer;
384  SCIPdebugPrintf("include Pricer \n");
385 
386  /* create stp variable pricer data */
387  SCIP_CALL( SCIPallocMemory(scip, &pricerdata) );
388  pricerdata->scip = scip;
389 
390  /* include variable pricer */
391  pricer = NULL;
392  SCIP_CALL( SCIPincludePricerBasic(scip, &pricer, PRICER_NAME, PRICER_DESC, PRICER_PRIORITY, PRICER_DELAY,
393  pricerRedcostStp, pricerFarkasStp, pricerdata) );
394  assert(pricer != NULL);
395 
396  /* set non fundamental callbacks via setter functions */
397  SCIP_CALL( SCIPsetPricerCopy(scip, pricer, pricerCopyStp) );
398  SCIP_CALL( SCIPsetPricerFree(scip, pricer, pricerFreeStp) );
399  SCIP_CALL( SCIPsetPricerInit(scip, pricer, pricerInitStp) );
400  SCIP_CALL( SCIPsetPricerInitsol(scip, pricer, pricerInitsolStp) );
401  SCIP_CALL( SCIPsetPricerExitsol(scip, pricer, pricerExitsolStp) );
402 
403  return SCIP_OKAY;
404 }
stp variable pricer
Definition: grph.h:55
#define TRUE
Definition: portab.h:34
SCIP_RETCODE SCIPincludePricerStp(SCIP *scip)
Definition: pricer_stp.c:377
SCIP_CONS ** SCIPprobdataGetEdgeConstraints(SCIP *scip)
#define PRICER_PRIORITY
Definition: pricer_stp.c:33
#define PRICER_DELAY
Definition: pricer_stp.c:34
int * ncreatedvars
Definition: pricer_stp.c:51
signed int edge
Definition: grph.h:140
int SCIPprobdataGetNEdges(SCIP *scip)
static SCIP_DECL_PRICEREXITSOL(pricerExitsolStp)
Definition: pricer_stp.c:154
static SCIP_DECL_PRICERFARKAS(pricerFarkasStp)
Definition: pricer_stp.c:365
SCIP_Real * pi
Definition: pricer_stp.c:47
GRAPH * SCIPprobdataGetGraph(SCIP_PROBDATA *probdata)
static SCIP_DECL_PRICERCOPY(pricerCopyStp)
Definition: pricer_stp.c:71
#define FALSE
Definition: portab.h:37
int * SCIPprobdataGetRTerms(SCIP *scip)
int * mark
Definition: grph.h:71
SCIP_CONS ** SCIPprobdataGetPathConstraints(SCIP *scip)
int SCIPprobdataGetRNTerms(SCIP *scip)
SCIP_Bool SCIPprobdataIsBigt(SCIP *scip)
static SCIP_DECL_PRICERINIT(pricerInitStp)
Definition: pricer_stp.c:104
SCIP_RETCODE SCIPprobdataPrintGraph(SCIP *scip, const char *filename, SCIP_SOL *sol, SCIP_Bool printsol)
SCIP_CONS ** pathcons
Definition: pricer_stp.c:46
static SCIP_RETCODE pricing(SCIP *scip, SCIP_PRICER *pricer, SCIP_Real *lowerbound, SCIP_Bool farkas)
Definition: pricer_stp.c:174
static SCIP_DECL_PRICERFREE(pricerFreeStp)
Definition: pricer_stp.c:82
int * tail
Definition: grph.h:93
#define FSP_MODE
Definition: grph.h:153
#define PRICER_NAME
Definition: pricer_stp.c:31
int knots
Definition: grph.h:61
#define PRICER_DESC
Definition: pricer_stp.c:32
int SCIPprobdataGetRoot(SCIP *scip)
includes various files containing graph methods used for Steiner problems
SCIP_Real lowerbound
Definition: pricer_stp.c:49
SCIP_CONS ** edgecons
Definition: pricer_stp.c:45
SCIP_Real * mi
Definition: pricer_stp.c:48
SCIP_Bool bigt
Definition: pricer_stp.c:56
static SCIP_DECL_PRICERREDCOST(pricerRedcostStp)
Definition: pricer_stp.c:354
void graph_path_exec(SCIP *, const GRAPH *, int, int, SCIP_Real *, PATH *)
Definition: grphpath.c:453
static SCIP_DECL_PRICERINITSOL(pricerInitsolStp)
Definition: pricer_stp.c:125