Scippy

SCIP

Solving Constraint Integer Programs

probdata_scflp.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 scipopt.org. */
13 /* */
14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15 
16 /**@file probdata_scflp.c
17  * @brief Problem data for Stochastic Capacitated Facility Location problem
18  * @author Stephen J. Maher
19  *
20  * This file handles the main problem data used in that project. For more details see \ref SCFLP_PROBLEMDATA page.
21  *
22  * @page SCFLP_SOLVEPROB Solving the deterministic equivalent
23  *
24  * The probdata_scflp.c is used to store the global problem data and build the monolithic MIP and decomposed problems.
25  * First, the structure of the problem data is describe. This is followed by a description of how to solve the problem
26  * directly using SCIP or using Benders' decomposition.
27  *
28  * @section SCFLP_PROBLEMDATA The global problem data
29  *
30  * The problem data is accessible in all plugins. The function SCIPgetProbData() returns the pointer to that structure.
31  * We use this data structure to store all the information of the SCFLP. Since this structure is not visible in the
32  * other plugins, we implemented setter and getter functions to access this data. The problem data structure
33  * SCIP_ProbData is shown below.
34  *
35  * \code
36  * ** @brief Problem data which is accessible in all places
37  * *
38  * * This problem data is used to store the input of the cap instance, all variables which are created, and all
39  * * constraints. In addition, the probdata stores the data structures for the decomposed problem. This permits the
40  * * use of Benders' decomposition to solve the stochastic program.
41  * *
42  * struct SCIP_ProbData
43  * {
44  * SCIP** subproblems; **< the Benders' decomposition subproblems * SCIP_VAR**
45  * SCIP_VAR** facilityvars; **< all variables representing facilities *
46  * SCIP_VAR*** subfacilityvars; **< duplicates of the facility variables in the subproblems *
47  * SCIP_VAR**** customervars; **< all variables representing the satisfaction of demand per scenario *
48  * SCIP_CONS*** capconss; **< capacity constraints per facility per scenario *
49  * SCIP_CONS*** demandconss; **< demand constraints per customer per scenario *
50  * SCIP_CONS* sufficientcap; **< ensuring sufficient capacity is provided to satisfy demand (relatively complete recourse) *
51  * SCIP_Real** costs; **< the transportation costs to a customer from a facility *
52  * SCIP_Real** demands; **< the customer demands per scenario *
53  * SCIP_Real* capacity; **< the capacity of each facility *
54  * SCIP_Real* fixedcost; **< the fixed cost of opening each facility *
55  * int ncustomers; **< the number of customers *
56  * int nfacilities; **< the number of facilities *
57  * int nscenarios; **< the number of scenarios *
58  * SCIP_Bool usebenders; **< whether Benders' decomposition is used *
59  * };
60  * \endcode
61  *
62  * The function SCIPprobdataCreate() manages the creation of the SCFLP instance in SCIP. There are two types of
63  * formulations that can be produced in this example. The first is the monolithic deterministic equivalent. The second
64  * is the reformulated problem that decomposes the stochastic problem by scenarios. This alternative formulations is
65  * solved using Benders' decomposition. Depending on the solution method, some members of SCIP_ProbData will be unused.
66  * For example, subproblems and subfacilityvars are only used when Benders' decomposition is applied to solve the SCFLP.
67  *
68  * The probdata_scflp.c also provide interface methods to the global problem data. A list of all interface methods can be
69  * found in probdata_scflp.h.
70  *
71  * @section SCFLP_DETEQUIV Directly solving the deterministic equivalent using SCIP
72  *
73  * Within probdata_scflp.c, both the monolithic determinstic equivalent or the decomposed problem can be built within
74  * SCIP. The monolithic deterministic equivalent involve a since SCIP instances that is solved directly as a MIP. The
75  * problem that is build in SCIP is given in \ref SCFLP_DETEQUIVMODEL.
76  *
77  * @section SCFLP_BENDERS Solving the SCFLP using Benders' decomposition
78  *
79  * The model that is used to build the decomposed problem is given in \ref SCFLP_BENDERSMODEL. In this example, the
80  * default Benders' decomposition plugin is used to employ the Benders' decomposition framework, see
81  * src/scip/benders_default.h. Before calling SCIPcreateBendersDefault() to invoke the Benders' decomposition framework,
82  * the SCIP instances for the master problem and the subproblems must be created.
83  *
84  * The SCIP instance for the master problem includes only the first stage variables (the facility variables \f$x_{i}\f$)
85  * and the first stage constraints. Note, the auxiliary variables are not added to the master problem by the user, nor
86  * are any Benders' decomposition cuts.
87  *
88  * For each subproblem \f$s\f$, the SCIP instance is formulated with the second stage variables (the customer variables
89  * \f$y^{s}_{ij}\f$) and the second stage constraints. Also, the first stage variables are created for each scenario.
90  * These variables are copies of the master variables from the master SCIP instances and must be created by calling
91  * SCIPcreateVarBasic() or SCIPcreateVar(). The master problem variable copies that are created in the subproblem SCIP
92  * instances must have an objective coefficient of 0.0. This is inline with the classical application of Benders'
93  * decomposition.
94  *
95  * IMPORTANT: the master variables that are created for the subproblem SCIP instances must have the same name as the
96  * corresponding master variables in the master problem SCIP instance. This is because the mapping between the master
97  * and subproblem variables relies on the variable names. This mapping is used for setting up the subproblems to
98  * evaluate solutions from the master problem and generating Benders' cuts.
99  *
100  * Once the master and subproblem SCIP instances are created, the Benders' decomposition is invoked by calling the
101  * interface function SCIPcreateBendersDefault(). The parameters for this function are a SCIP instance for the master
102  * problem, an array of SCIP instances for the subproblems and the number of subproblems.
103  *
104  * The Benders' decomposition framework involves the use of constraint handlers within SCIP, src/scip/cons_benders.h and
105  * src/scip/cons_benderslp.h. In order to solve the master problem by adding Benders' cuts, src/scip/cons_benders.h and
106  * src/scip/cons_benderslp.h must be activated. This is done by setting the parameter "constraints/benders/active" and
107  * "constraints/benderslp/active" to TRUE.
108  *
109  * NOTE: it is not necessary to activate src/scip/cons_benderslp.h. The purpose of this constraint handler is to
110  * generate Benders' decomposition cut from solutions to the LP relaxation in the root node. These solutions are
111  * fractional, since the enforcement priority of benderslp is higher than the integer constraint handler. The benderslp
112  * constraint handler allows the user to employ the multi-phase algorithm of McDaniel and Devine (1977).
113  *
114  * McDaniel D, Devine M. A modified Benders’ partitioning algorithm for mixed integer programming. Management Science
115  * 1977;24(2):312–9
116  */
117 
118 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
119 
120 #include <string.h>
121 
122 #include "probdata_scflp.h"
123 
124 #include "scip/scip.h"
125 #include "scip/scipdefplugins.h"
126 
127 #define DEFAULT_SCALINGFACTOR 5000.0
128 
129 /** @brief Problem data which is accessible in all places
130  *
131  * This problem data is used to store the input of the SCFLP, all variables which are created, and all constraints.
132  */
133 struct SCIP_ProbData
134 {
135  SCIP** subproblems; /**< the Benders' decomposition subproblems */
136  SCIP_VAR** facilityvars; /**< all variables representing facilities */
137  SCIP_VAR*** subfacilityvars; /**< duplicates of the facility variables in the subproblems */
138  SCIP_VAR**** customervars; /**< all variables representing the satisfaction of demand per scenario */
139  SCIP_CONS*** capconss; /**< capacity constraints per facility per scenario */
140  SCIP_CONS*** demandconss; /**< demand constraints per customer per scenario */
141  SCIP_CONS* sufficientcap; /**< ensuring sufficient capacity is provided to satisfy demand (relatively complete recourse) */
142  SCIP_Real** costs; /**< the transportation costs to a customer from a facility */
143  SCIP_Real** demands; /**< the customer demands per scenario */
144  SCIP_Real* capacity; /**< the capacity of each facility */
145  SCIP_Real* fixedcost; /**< the fixed cost of opening each facility */
146  int ncustomers; /**< the number of customers */
147  int nfacilities; /**< the number of facilities */
148 
149  /* probdata parameters */
150  int nscenarios; /**< the number of scenarios */
151  SCIP_Bool usebenders; /**< whether Benders' decomposition is used */
152  SCIP_Bool quadcosts; /**< should the problem be formulated with quadratic costs */
153 };
154 
155 
156 
157 /**@name Local methods
158  *
159  * @{
160  */
161 
162 /** creates the original problem */
163 static
165  SCIP* scip, /**< SCIP data structure */
166  SCIP_VAR** facilityvars, /**< all variables representing facilities */
167  SCIP_VAR**** customervars, /**< all variables representing the satisfaction of demand */
168  SCIP_CONS*** capconss, /**< capacity constraints per facility */
169  SCIP_CONS*** demandconss, /**< demand constraints per customer */
170  SCIP_CONS** sufficientcap, /**< ensuring sufficient capacity is provided to satisfy demand */
171  SCIP_Real** costs, /**< the transportation costs from a facility to a customer */
172  SCIP_Real** demands, /**< the customer demands */
173  SCIP_Real* capacity, /**< the capacity of each facility */
174  SCIP_Real* fixedcost, /**< the fixed cost of opening a facility */
175  int ncustomers, /**< the number of customers */
176  int nfacilities, /**< the number of facilities */
177  int nscenarios, /**< the number of scenarios */
178  SCIP_Bool quadcosts /**< should the problem be formulated with quadratic costs */
179  )
180 {
181  SCIP_CONS* cons;
182  SCIP_VAR* var;
183  SCIP_VAR* sqrvar;
184  SCIP_Real maxdemand;
185  SCIP_Real coeff;
186  SCIP_Real custcoeff;
187  SCIP_Real one = 1.0;
188  SCIP_Real minusone = -1.0;
189  int i;
190  int j;
191  int k;
192  char name[SCIP_MAXSTRLEN];
193 
194 
195  assert(scip != NULL);
196 
197  /* adding the sufficient capacity constraints */
198  maxdemand = 0;
199  for( i = 0; i < nscenarios; i++)
200  {
201  SCIP_Real sumdemand = 0;
202  for( j = 0; j < ncustomers; j++ )
203  sumdemand += demands[j][i];
204 
205  if( sumdemand > maxdemand )
206  maxdemand = sumdemand;
207  }
208 
209  (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "sufficientcapacity");
210  SCIP_CALL( SCIPcreateConsBasicLinear(scip, sufficientcap, name, 0, NULL, NULL, maxdemand, SCIPinfinity(scip)) );
211 
212  SCIP_CALL( SCIPaddCons(scip, (*sufficientcap)) );
213 
214  /* adds the capacity constraints to the scenario */
215  for( i = 0; i < nfacilities; i++ )
216  {
217  for( j = 0; j < nscenarios; j++ )
218  {
219  (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "capacity_%d_%d", i, j);
220  SCIP_CALL( SCIPcreateConsBasicLinear(scip, &cons, name, 0, NULL, NULL, -SCIPinfinity(scip), 0.0) );
221 
222  SCIP_CALL( SCIPaddCons(scip, cons) );
223 
224  capconss[i][j] = cons;
225  }
226  }
227 
228  /* adds the demand constraints to the scenario */
229  for( i = 0; i < ncustomers; i++ )
230  {
231  for( j = 0; j < nscenarios; j++ )
232  {
233  (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "demand_%d_%d", i, j);
234  SCIP_CALL( SCIPcreateConsBasicLinear(scip, &cons, name, 0, NULL, NULL, demands[i][j], SCIPinfinity(scip)) );
235 
236  SCIP_CALL( SCIPaddCons(scip, cons) );
237 
238  demandconss[i][j] = cons;
239  }
240  }
241 
242  for( i = 0; i < nfacilities; i++ )
243  {
244  (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "facility_%d", i);
245  SCIP_CALL( SCIPcreateVarBasic(scip, &var, name, 0.0, 1.0, fixedcost[i], SCIP_VARTYPE_BINARY) );
246 
247  SCIP_CALL( SCIPaddVar(scip, var) );
248 
249  /* storing the variable in the facility variable list */
250  facilityvars[i] = var;
251 
252  /* adding the variable to the capacity constraints */
253  for( j = 0; j < nscenarios; j++ )
254  SCIP_CALL( SCIPaddCoefLinear(scip, capconss[i][j], var, -capacity[i]) );
255 
256  /* adding the variable to the sufficient capacity constraints */
257  SCIP_CALL( SCIPaddCoefLinear(scip, (*sufficientcap), var, capacity[i]) );
258  }
259 
260  /* adding the customer variables to the scenario */
261  for( i = 0; i < ncustomers; i++ )
262  {
263  for( j = 0; j < nfacilities; j++ )
264  {
265  for( k = 0; k < nscenarios; k++ )
266  {
267  custcoeff = costs[i][j]/(SCIP_Real)nscenarios;
268 
269  /* if the quadratic costs are used, then the customer coefficient is zero and the quadratic costs are scaled
270  * by 10,000. */
271  if( quadcosts )
272  {
273  coeff = custcoeff / DEFAULT_SCALINGFACTOR;
274  custcoeff = 0.0;
275  }
276 
277  (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "customer(%d,%d,%d)", i, j, k);
278  SCIP_CALL( SCIPcreateVarBasic(scip, &var, name, 0.0, SCIPinfinity(scip), custcoeff,
280 
281  SCIP_CALL( SCIPaddVar(scip, var) );
282 
283  /* storing the customer variable in the list */
284  customervars[i][j][k] = var;
285 
286  if( costs[i][j] > 0 )
287  {
288  /* adding the variable to the capacity constraints */
289  SCIP_CALL( SCIPaddCoefLinear(scip, capconss[j][k], customervars[i][j][k], 1.0) );
290 
291  /* adding the variable to the demand constraints */
292  SCIP_CALL( SCIPaddCoefLinear(scip, demandconss[i][k], customervars[i][j][k], 1.0) );
293 
294  /* if the quadratic costs are used, then variables representing the square of the customer supply
295  * must be added
296  */
297  if( quadcosts )
298  {
299  (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "customersqr(%d,%d,%d)", i, j, k);
300  SCIP_CALL( SCIPcreateVarBasic(scip, &sqrvar, name, 0.0, SCIPinfinity(scip), coeff, SCIP_VARTYPE_CONTINUOUS) );
301 
302  SCIP_CALL( SCIPaddVar(scip, sqrvar) );
303 
304  /* add constraint var^2 <= sqrvar */
305  (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "customersqrcons(%d,%d,%d)", i, j, k);
306  SCIP_CALL( SCIPcreateConsQuadraticNonlinear(scip, &cons, name, 1, &sqrvar, &minusone, 1, &var, &var,
307  &one, -SCIPinfinity(scip), 0.0, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
308 
309  SCIP_CALL( SCIPaddCons(scip, cons) );
310 
311  SCIP_CALL( SCIPreleaseCons(scip, &cons) );
312  SCIP_CALL( SCIPreleaseVar(scip, &sqrvar) );
313  }
314  }
315  }
316  }
317  }
318 
319  return SCIP_OKAY;
320 }
321 
322 /** creates the Benders' decomposition master problem */
323 static
325  SCIP* scip, /**< SCIP data structure */
326  SCIP_VAR** facilityvars, /**< all variables representing facilities */
327  SCIP_CONS** sufficientcap, /**< ensuring sufficient capacity is provided to satisfy demand */
328  SCIP_Real* capacity, /**< the capacity of each facility */
329  SCIP_Real* fixedcost, /**< the fixed cost of opening a facility */
330  SCIP_Real** demands, /**< the customer demands */
331  int ncustomers, /**< the number of customers */
332  int nfacilities, /**< the number of facilities */
333  int nscenarios /**< the number of scenarios */
334  )
335 {
336  SCIP_VAR* var;
337  SCIP_Real maxdemand;
338  int i;
339  int j;
340  char name[SCIP_MAXSTRLEN];
341  assert(scip != NULL);
342 
344  "Creating the master problem\n============\n");
345 
346  /* adding the sufficient capacity constraints */
347  maxdemand = 0;
348  for( i = 0; i < nscenarios; i++)
349  {
350  SCIP_Real sumdemand = 0;
351  for( j = 0; j < ncustomers; j++ )
352  sumdemand += demands[j][i];
353 
354  if( sumdemand > maxdemand )
355  maxdemand = sumdemand;
356  }
357 
358  (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "sufficientcapacity");
359  SCIP_CALL( SCIPcreateConsBasicLinear(scip, sufficientcap, name, 0, NULL, NULL, maxdemand, SCIPinfinity(scip)) );
360 
361  SCIP_CALL( SCIPaddCons(scip, (*sufficientcap)) );
362 
363  /* adding the facility variables */
364  for( i = 0; i < nfacilities; i++ )
365  {
366  (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "facility_%d", i);
367  SCIP_CALL( SCIPcreateVarBasic(scip, &var, name, 0.0, 1.0, fixedcost[i], SCIP_VARTYPE_BINARY) );
368 
369  SCIP_CALL( SCIPaddVar(scip, var) );
370 
371  /* storing the variable in the facility variable list */
372  facilityvars[i] = var;
373 
374  /* adding the variable to the sufficient capacity constraints */
375  SCIP_CALL( SCIPaddCoefLinear(scip, (*sufficientcap), var, capacity[i]) );
376  }
377 
379  "master problem has %d binary variables and 1 constraint\n\n", nfacilities);
380 
381  return SCIP_OKAY;
382 }
383 
384 /** creates the scenario subproblems */
385 static
387  SCIP* scip, /**< SCIP data structure */
388  SCIP** subproblems, /**< the Benders' decomposition subproblems */
389  SCIP_VAR** facilityvars, /**< all variables representing facilities */
390  SCIP_VAR*** subfacilityvars, /**< the copies of the facility variables in the subproblems */
391  SCIP_VAR**** customervars, /**< all variables representing the satisfaction of demand */
392  SCIP_CONS*** capconss, /**< capacity constraints per facility */
393  SCIP_CONS*** demandconss, /**< demand constraints per customer */
394  SCIP_Real** costs, /**< the transportation costs from a facility to a customer */
395  SCIP_Real** demands, /**< the customer demands */
396  SCIP_Real* capacity, /**< the capacity of each facility */
397  SCIP_Real* fixedcost, /**< the fixed cost of opening a facility */
398  int ncustomers, /**< the number of customers */
399  int nfacilities, /**< the number of facilities */
400  int nscenarios, /**< the number of scenarios */
401  SCIP_Bool quadcosts /**< should the problem be formulated with quadratic costs */
402  )
403 {
404  SCIP_CONS* cons;
405  SCIP_VAR* var;
406  SCIP_VAR* sqrvar;
407  SCIP_Real coeff;
408  SCIP_Real custcoeff;
409  SCIP_Real one = 1.0;
410  SCIP_Real minusone = -1.0;
411  int i;
412  int j;
413  int k;
414  char name[SCIP_MAXSTRLEN];
415 
416 
417  assert(scip != NULL);
418 
420  "Creating the subproblems\n============\n");
421 
422  /* adds the capacity constraints to the scenario */
423  for( i = 0; i < nfacilities; i++ )
424  {
425  for( j = 0; j < nscenarios; j++ )
426  {
427  (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "capacity_%d_%d", i, j);
428  SCIP_CALL( SCIPcreateConsBasicLinear(subproblems[j], &cons, name, 0, NULL, NULL, -SCIPinfinity(subproblems[j]), 0.0) );
429 
430  SCIP_CALL( SCIPaddCons(subproblems[j], cons) );
431 
432  capconss[i][j] = cons;
433  }
434  }
435 
436  /* adds the demand constraints to the scenario */
437  for( i = 0; i < ncustomers; i++ )
438  {
439  for( j = 0; j < nscenarios; j++ )
440  {
441  (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "demand_%d_%d", i, j);
442  SCIP_CALL( SCIPcreateConsBasicLinear(subproblems[j], &cons, name, 0, NULL, NULL, demands[i][j], SCIPinfinity(subproblems[j])) );
443 
444  SCIP_CALL( SCIPaddCons(subproblems[j], cons) );
445 
446  demandconss[i][j] = cons;
447  }
448  }
449 
450  for( i = 0; i < nfacilities; i++ )
451  {
452  for( j = 0; j < nscenarios; j++ )
453  {
454  (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "facility_%d", i);
455  SCIP_CALL( SCIPcreateVarBasic(subproblems[j], &var, name, 0.0, 1.0, 0.0, SCIP_VARTYPE_CONTINUOUS) );
456 
457  SCIP_CALL( SCIPaddVar(subproblems[j], var) );
458 
459  /* storing the variable in the facility variable list */
460  subfacilityvars[i][j] = var;
461 
462  /* adding the variable to the capacity constraints */
463  SCIP_CALL( SCIPaddCoefLinear(subproblems[j], capconss[i][j], subfacilityvars[i][j], -capacity[i]) );
464  }
465  }
466 
467  /* adding the customer variables to the scenario */
468  for( i = 0; i < ncustomers; i++ )
469  {
470  for( j = 0; j < nfacilities; j++ )
471  {
472  for( k = 0; k < nscenarios; k++ )
473  {
474  custcoeff = costs[i][j]/(SCIP_Real)nscenarios;
475 
476  /* if the quadratic costs are used, then the customer coefficient is zero and the quadratic costs are scaled
477  * by 10,000. */
478  if( quadcosts )
479  {
480  coeff = custcoeff / 10000.0;
481  custcoeff = 0.0;
482  }
483 
484  (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "customer(%d,%d,%d)", i, j, k);
485  SCIP_CALL( SCIPcreateVarBasic(subproblems[k], &var, name, 0.0, SCIPinfinity(subproblems[k]), custcoeff,
487 
488  SCIP_CALL( SCIPaddVar(subproblems[k], var) );
489 
490  /* storing the customer variable in the list */
491  customervars[i][j][k] = var;
492 
493  if( costs[i][j] > 0 )
494  {
495  /* adding the variable to the capacity constraints */
496  SCIP_CALL( SCIPaddCoefLinear(subproblems[k], capconss[j][k], customervars[i][j][k], 1.0) );
497 
498  /* adding the variable to the demand constraints */
499  SCIP_CALL( SCIPaddCoefLinear(subproblems[k], demandconss[i][k], customervars[i][j][k], 1.0) );
500 
501 
502  /* if the quadratic costs are used, then variables representing the square of the customer supply
503  * must be added
504  */
505  if( quadcosts )
506  {
507  coeff = costs[i][j]/(SCIP_Real)nscenarios / DEFAULT_SCALINGFACTOR;
508  (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "customersqr(%d,%d,%d)", i, j, k);
509  SCIP_CALL( SCIPcreateVarBasic(subproblems[k], &sqrvar, name, 0.0, SCIPinfinity(subproblems[k]), coeff, SCIP_VARTYPE_CONTINUOUS) );
510 
511  SCIP_CALL( SCIPaddVar(subproblems[k], sqrvar) );
512 
513  /* add constraint var^2 <= sqrvar */
514  (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "customersqrcons(%d,%d,%d)", i, j, k);
515  SCIP_CALL( SCIPcreateConsQuadraticNonlinear(subproblems[k], &cons, name, 1, &sqrvar, &minusone, 1, &var, &var, &one, -SCIPinfinity(subproblems[k]), 0.0, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
516 
517  SCIP_CALL( SCIPaddCons(subproblems[k], cons) );
518 
519  SCIP_CALL( SCIPreleaseCons(subproblems[k], &cons) );
520  SCIP_CALL( SCIPreleaseVar(subproblems[k], &sqrvar) );
521  }
522  }
523  }
524  }
525  }
526 
528  "%d subproblems have been created.\neach subproblem has %d continuous variables and %d constraint\n\n",
529  nscenarios, ncustomers*nfacilities + nfacilities, nfacilities + ncustomers);
530 
531  return SCIP_OKAY;
532 }
533 
534 
535 /** creates problem data */
536 static
538  SCIP* scip, /**< SCIP data structure */
539  SCIP_PROBDATA** probdata, /**< pointer to problem data */
540  SCIP** subproblems, /**< the Benders' decomposition subproblems */
541  SCIP_VAR** facilityvars, /**< all variables representing facilities */
542  SCIP_VAR*** subfacilityvars, /**< the copies of the facility variables in the subproblems */
543  SCIP_VAR**** customervars, /**< all variables representing the satisfaction of demand */
544  SCIP_CONS*** capconss, /**< capacity constraints per facility per scenario */
545  SCIP_CONS*** demandconss, /**< demand constraints per customer per scenario */
546  SCIP_CONS* sufficientcap, /**< ensuring sufficient capacity is provided to satisfy demand */
547  SCIP_Real** costs, /**< the transportation costs to a customer from a facility */
548  SCIP_Real** demands, /**< the customer demands per scenario */
549  SCIP_Real* capacity, /**< the capacity of each facility */
550  SCIP_Real* fixedcost, /**< the fixed cost of opening a facility */
551  int ncustomers, /**< the number of customers */
552  int nfacilities, /**< the number of facilities */
553  int nscenarios, /**< the number of scenarios */
554  SCIP_Bool usebenders, /**< whether Benders' decomposition is used */
555  SCIP_Bool quadcosts /**< should the problem be formulated with quadratic costs */
556  )
557 {
558  int i;
559  int j;
560 
561  assert(scip != NULL);
562  assert(probdata != NULL);
563 
564  /* allocate memory */
565  SCIP_CALL( SCIPallocBlockMemory(scip, probdata) );
566 
567  /* copying the subproblem information */
568  if( usebenders )
569  {
570  SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*probdata)->subproblems, subproblems, nscenarios) );
571 
572  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(*probdata)->subfacilityvars, nfacilities) );
573  for( i = 0; i < nfacilities; i++ )
574  SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*probdata)->subfacilityvars[i], subfacilityvars[i], nscenarios) );
575  }
576 
577  /* copy variable arrays */
578  SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*probdata)->facilityvars, facilityvars, nfacilities) );
579  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(*probdata)->customervars, ncustomers) );
580  for( i = 0; i < ncustomers; i++ )
581  {
582  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(*probdata)->customervars[i], nfacilities) );
583  for( j = 0; j < nfacilities; j++ )
584  SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*probdata)->customervars[i][j], customervars[i][j],
585  nscenarios) );
586  }
587 
588  /* duplicate the constraint arrays */
589  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(*probdata)->capconss, nfacilities) );
590  for( i = 0; i < nfacilities; i++ )
591  SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*probdata)->capconss[i], capconss[i], nscenarios) );
592 
593  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(*probdata)->demandconss, ncustomers) );
594  for( i = 0; i < ncustomers; i++ )
595  SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*probdata)->demandconss[i], demandconss[i], nscenarios) );
596 
597  /* duplicate the data arrays */
598  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(*probdata)->demands, ncustomers) );
599  for( i = 0; i < ncustomers; i++ )
600  SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*probdata)->demands[i], demands[i], nscenarios) );
601 
602  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(*probdata)->costs, ncustomers) );
603  for( i = 0; i < ncustomers; i++ )
604  SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*probdata)->costs[i], costs[i], nfacilities) );
605 
606  SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*probdata)->capacity, capacity, nfacilities) );
607  SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*probdata)->fixedcost, fixedcost, nfacilities) );
608 
609  (*probdata)->sufficientcap = sufficientcap;
610  (*probdata)->ncustomers = ncustomers;
611  (*probdata)->nfacilities = nfacilities;
612  (*probdata)->nscenarios = nscenarios;
613  (*probdata)->usebenders = usebenders;
614  (*probdata)->quadcosts = quadcosts;
615 
616  return SCIP_OKAY;
617 }
618 
619 /** frees the memory of the given problem data */
620 static
622  SCIP* scip, /**< SCIP data structure */
623  SCIP_PROBDATA** probdata /**< pointer to problem data */
624  )
625 {
626  int i;
627  int j;
628  int k;
629 
630  assert(scip != NULL);
631  assert(probdata != NULL);
632 
633 #if 1
634  /* release all variables */
635  for( i = 0; i < (*probdata)->nfacilities; i++ )
636  SCIP_CALL( SCIPreleaseVar(scip, &(*probdata)->facilityvars[i]) );
637 
638  for( i = 0; i < (*probdata)->nscenarios; i++ )
639  {
640  SCIP* varscip;
641  if( (*probdata)->usebenders )
642  varscip = (*probdata)->subproblems[i];
643  else
644  varscip = scip;
645 
646  for( j = 0; j < (*probdata)->nfacilities; j++ )
647  {
648  for( k = 0; k < (*probdata)->ncustomers; k++ )
649  SCIP_CALL( SCIPreleaseVar(varscip, &(*probdata)->customervars[k][j][i]) );
650  }
651  }
652 
653  /* release all constraints */
654  for( i = 0; i < (*probdata)->nscenarios; ++i )
655  {
656  SCIP* consscip;
657  if( (*probdata)->usebenders )
658  consscip = (*probdata)->subproblems[i];
659  else
660  consscip = scip;
661 
662  for( j = 0; j < (*probdata)->ncustomers; j++ )
663  SCIP_CALL( SCIPreleaseCons(consscip, &(*probdata)->demandconss[j][i]) );
664  }
665 
666  for( i = 0; i < (*probdata)->nscenarios; ++i )
667  {
668  SCIP* consscip;
669  if( (*probdata)->usebenders )
670  consscip = (*probdata)->subproblems[i];
671  else
672  consscip = scip;
673 
674  for( j = 0; j < (*probdata)->nfacilities; ++j )
675  SCIP_CALL( SCIPreleaseCons(consscip, &(*probdata)->capconss[j][i]) );
676  }
677 
678  SCIP_CALL( SCIPreleaseCons(scip, &(*probdata)->sufficientcap) );
679 #endif
680 
681  /* free memory of arrays */
682  SCIPfreeBlockMemoryArray(scip, &(*probdata)->fixedcost, (*probdata)->nfacilities);
683  SCIPfreeBlockMemoryArray(scip, &(*probdata)->capacity, (*probdata)->nfacilities);
684 
685  for( i = (*probdata)->ncustomers - 1; i >= 0; i-- )
686  SCIPfreeBlockMemoryArray(scip, &(*probdata)->costs[i], (*probdata)->nfacilities);
687  SCIPfreeBlockMemoryArray(scip, &(*probdata)->costs, (*probdata)->ncustomers);
688 
689  for( i = (*probdata)->ncustomers - 1; i >= 0; i-- )
690  SCIPfreeBlockMemoryArray(scip, &(*probdata)->demands[i], (*probdata)->nscenarios);
691  SCIPfreeBlockMemoryArray(scip, &(*probdata)->demands, (*probdata)->ncustomers);
692 
693  /* freeing the constraint memory arrays */
694  for( i = (*probdata)->ncustomers - 1; i >= 0; i-- )
695  SCIPfreeBlockMemoryArray(scip, &(*probdata)->demandconss[i], (*probdata)->nscenarios);
696  SCIPfreeBlockMemoryArray(scip, &(*probdata)->demandconss, (*probdata)->ncustomers);
697 
698  for( i = (*probdata)->nfacilities - 1; i >= 0; i-- )
699  SCIPfreeBlockMemoryArray(scip, &(*probdata)->capconss[i], (*probdata)->nscenarios);
700  SCIPfreeBlockMemoryArray(scip, &(*probdata)->capconss, (*probdata)->nfacilities);
701 
702  /* freeing the variable memory arrays */
703  for( i = (*probdata)->ncustomers - 1; i >= 0; i-- )
704  {
705  for( j = (*probdata)->nfacilities - 1; j >= 0; j-- )
706  SCIPfreeBlockMemoryArray(scip, &(*probdata)->customervars[i][j], (*probdata)->nscenarios);
707 
708  SCIPfreeBlockMemoryArray(scip, &(*probdata)->customervars[i], (*probdata)->nfacilities);
709  }
710  SCIPfreeBlockMemoryArray(scip, &(*probdata)->customervars, (*probdata)->ncustomers);
711 
712  SCIPfreeBlockMemoryArray(scip, &(*probdata)->facilityvars, (*probdata)->nfacilities);
713 
714  /* freeing the subproblem information */
715  if( (*probdata)->usebenders )
716  {
717  /* freeing the sub facility variables */
718  for( i = 0; i < (*probdata)->nscenarios; i++ )
719  {
720  for( j = 0; j < (*probdata)->nfacilities; j++ )
721  SCIP_CALL( SCIPreleaseVar((*probdata)->subproblems[i], &(*probdata)->subfacilityvars[j][i]) );
722  }
723 
724  for( i = (*probdata)->nfacilities - 1; i >= 0; i-- )
725  SCIPfreeBlockMemoryArray(scip, &(*probdata)->subfacilityvars[i], (*probdata)->nscenarios);
726 
727  SCIPfreeBlockMemoryArray(scip, &(*probdata)->subfacilityvars, (*probdata)->nfacilities);
728 
729  for( i = (*probdata)->nscenarios - 1; i >= 0 ; i-- )
730  SCIP_CALL( SCIPfree(&(*probdata)->subproblems[i]) );
731  SCIPfreeBlockMemoryArray(scip, &(*probdata)->subproblems, (*probdata)->nscenarios);
732  }
733 
734  /* free probdata */
735  SCIPfreeBlockMemory(scip, probdata);
736 
737  return SCIP_OKAY;
738 }
739 
740 /**@} */
741 
742 /**@name Callback methods of problem data
743  *
744  * @{
745  */
746 
747 /** frees user data of original problem (called when the original problem is freed) */
748 static
749 SCIP_DECL_PROBDELORIG(probdelorigScflp)
750 {
751  assert(scip != NULL);
752  assert(probdata != NULL);
753 
754  SCIPdebugMsg(scip, "free original problem data\n");
755 
756  SCIP_CALL( probdataFree(scip, probdata) );
757 
758  return SCIP_OKAY;
759 }
760 
761 /** creates user data of transformed problem by transforming the original user problem data
762  * (called after problem was transformed) */
763 static
764 SCIP_DECL_PROBTRANS(probtransScflp)
765 {
766  SCIPdebugMsg(scip, "transforming problem data\n");
767 
768  return SCIP_OKAY;
769 }
770 
771 /** frees user data of transformed problem (called when the transformed problem is freed) */
772 static
773 SCIP_DECL_PROBDELTRANS(probdeltransScflp)
774 {
775  SCIPdebugMsg(scip, "free transformed problem data\n");
776 
777  return SCIP_OKAY;
778 }
779 
780 /**@} */
781 
782 
783 /**@name Interface methods
784  *
785  * @{
786  */
787 
788 /** sets up the problem data */
790  SCIP* scip, /**< SCIP data structure */
791  const char* probname, /**< problem name */
792  SCIP_Real** costs, /**< the transportation costs from a facility to a customer */
793  SCIP_Real** demands, /**< the customer demands */
794  SCIP_Real* capacity, /**< the capacity of each facility */
795  SCIP_Real* fixedcost, /**< the fixed cost of opening a facility */
796  int ncustomers, /**< the number of customers */
797  int nfacilities, /**< the number of facilities */
798  int nscenarios, /**< the number of Benders' decomposition scenarios */
799  SCIP_Bool usebenders, /**< whether Benders' decomposition is used */
800  SCIP_Bool quadcosts /**< should the problem be formulated with quadratic costs */
801  )
802 {
803  SCIP** subproblems;
804  SCIP_PROBDATA* probdata;
805  SCIP_CONS*** demandconss;
806  SCIP_CONS*** capconss;
807  SCIP_CONS* sufficientcap;
808  SCIP_VAR** facilityvars;
809  SCIP_VAR*** subfacilityvars;
810  SCIP_VAR**** customervars;
811  int i;
812  int j;
813 
814  assert(scip != NULL);
815 
816  /* create problem in SCIP and add non-NULL callbacks via setter functions */
817  SCIP_CALL( SCIPcreateProbBasic(scip, probname) );
818 
819  SCIP_CALL( SCIPsetProbDelorig(scip, probdelorigScflp) );
820  SCIP_CALL( SCIPsetProbTrans(scip, probtransScflp) );
821  SCIP_CALL( SCIPsetProbDeltrans(scip, probdeltransScflp) );
822 
823  /* set objective sense */
825 
826  SCIP_CALL( SCIPallocBufferArray(scip, &demandconss, ncustomers) );
827  for( i = 0; i < ncustomers; i++ )
828  SCIP_CALL( SCIPallocBufferArray(scip, &demandconss[i], nscenarios) );
829  SCIP_CALL( SCIPallocBufferArray(scip, &capconss, nfacilities) );
830  for( i = 0; i < nfacilities; i++ )
831  SCIP_CALL( SCIPallocBufferArray(scip, &capconss[i], nscenarios) );
832 
833  SCIP_CALL( SCIPallocBufferArray(scip, &facilityvars, nfacilities) );
834  SCIP_CALL( SCIPallocBufferArray(scip, &customervars, ncustomers) );
835  for( i = 0; i < ncustomers; i++ )
836  {
837  SCIP_CALL( SCIPallocBufferArray(scip, &customervars[i], nfacilities) );
838  for( j = 0; j < nfacilities; j++ )
839  SCIP_CALL( SCIPallocBufferArray(scip, &customervars[i][j], nscenarios) );
840  }
841 
842  sufficientcap = NULL;
843 
844  subproblems = NULL;
845  subfacilityvars = NULL;
846 
847  /* if quadratic costs are used, then the costs are scaled by 10,000. The user must be informed about this scaling */
848  if( quadcosts )
849  {
850  SCIPinfoMessage(scip, NULL, "The problem will be formulated with quadratic costs. "
851  "The input costs will be scaled by %g\n\n", DEFAULT_SCALINGFACTOR);
852  }
853 
854  if( usebenders )
855  {
856  char subprobname[SCIP_MAXSTRLEN];
857 
858  /* allocting the memory for the subproblem specific information */
859  SCIP_CALL( SCIPallocBufferArray(scip, &subproblems, nscenarios) );
860  SCIP_CALL( SCIPallocBufferArray(scip, &subfacilityvars, nfacilities) );
861  for( i = 0; i < nfacilities; i++ )
862  SCIP_CALL( SCIPallocBufferArray(scip, &subfacilityvars[i], nscenarios) );
863 
864  /* creating the subproblems */
865  for( i = 0; i < nscenarios; i++ )
866  {
867  SCIP_CALL( SCIPcreate(&subproblems[i]) );
868 
869  /* include default SCIP plugins */
870  SCIP_CALL( SCIPincludeDefaultPlugins(subproblems[i]) );
871 
872  (void) SCIPsnprintf(subprobname, SCIP_MAXSTRLEN, "sub_%s_%d", probname, i);
873  SCIP_CALL( SCIPcreateProbBasic(subproblems[i], subprobname) );
874  }
875 
876  /* creating the master problem */
877  SCIP_CALL( createMasterproblem(scip, facilityvars, &sufficientcap, capacity, fixedcost, demands, ncustomers,
878  nfacilities, nscenarios) );
879  SCIP_CALL( createSubproblems(scip, subproblems, facilityvars, subfacilityvars, customervars, capconss,
880  demandconss, costs, demands, capacity, fixedcost, ncustomers, nfacilities, nscenarios, quadcosts) );
881 
882  /* including the Benders' decomposition plugin */
883  SCIP_CALL( SCIPcreateBendersDefault(scip, subproblems, nscenarios) );
884 
885  /* activating the Benders' decomposition constraint handlers */
886  SCIP_CALL( SCIPsetBoolParam(scip, "constraints/benders/active", TRUE) );
887  SCIP_CALL( SCIPsetBoolParam(scip, "constraints/benderslp/active", TRUE) );
888 
889  SCIP_CALL( SCIPsetIntParam(scip, "constraints/benders/maxprerounds", 1) );
890  SCIP_CALL( SCIPsetIntParam(scip, "presolving/maxrounds", 1) );
891  }
892  else
893  {
894  /* creating the original problem */
895  SCIP_CALL( createOriginalproblem(scip, facilityvars, customervars, capconss, demandconss, &sufficientcap, costs,
896  demands, capacity, fixedcost, ncustomers, nfacilities, nscenarios, quadcosts) );
897  }
898 
899  /* create problem data */
900  SCIP_CALL( probdataCreate(scip, &probdata, subproblems, facilityvars, subfacilityvars, customervars, capconss,
901  demandconss, sufficientcap, costs, demands, capacity, fixedcost, ncustomers, nfacilities, nscenarios,
902  usebenders, quadcosts) );
903 
904  /* set user problem data */
905  SCIP_CALL( SCIPsetProbData(scip, probdata) );
906 
907  /* free local buffer arrays */
908  if( usebenders )
909  {
910  SCIPfreeBufferArray(scip, &subproblems);
911 
912  for( i = nfacilities - 1; i >= 0; i-- )
913  SCIPfreeBufferArray(scip, &subfacilityvars[i]);
914  SCIPfreeBufferArray(scip, &subfacilityvars);
915  }
916 
917  for( i = ncustomers - 1; i >= 0; i-- )
918  {
919  for( j = nfacilities - 1; j >= 0; j-- )
920  SCIPfreeBufferArray(scip, &customervars[i][j]);
921  SCIPfreeBufferArray(scip, &customervars[i]);
922  }
923  SCIPfreeBufferArray(scip, &customervars);
924  SCIPfreeBufferArray(scip, &facilityvars);
925 
926  for( i = nfacilities - 1; i >= 0; i-- )
927  SCIPfreeBufferArray(scip, &capconss[i]);
928  SCIPfreeBufferArray(scip, &capconss);
929 
930  for( i = ncustomers - 1; i >= 0; i-- )
931  SCIPfreeBufferArray(scip, &demandconss[i]);
932  SCIPfreeBufferArray(scip, &demandconss);
933 
934  return SCIP_OKAY;
935 }
936 
937 /** returns the number of facilities */
939  SCIP_PROBDATA* probdata /**< problem data */
940  )
941 {
942  assert(probdata != NULL);
943 
944  return probdata->nfacilities;
945 }
946 
947 /** returns the number of customers */
949  SCIP_PROBDATA* probdata /**< problem data */
950  )
951 {
952  assert(probdata != NULL);
953 
954  return probdata->ncustomers;
955 }
956 
957 /** returns the facility variables */
959  SCIP_PROBDATA* probdata /**< problem data */
960  )
961 {
962  assert(probdata != NULL);
963 
964  return probdata->facilityvars;
965 }
966 
967 /**@} */
#define SCIPfreeBlockMemoryArray(scip, ptr, num)
Definition: scip_mem.h:101
#define SCIPallocBlockMemoryArray(scip, ptr, num)
Definition: scip_mem.h:84
SCIP_RETCODE SCIPcreateConsBasicLinear(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_Real *vals, SCIP_Real lhs, SCIP_Real rhs)
#define SCIP_MAXSTRLEN
Definition: def.h:293
#define DEFAULT_SCALINGFACTOR
SCIP_RETCODE SCIPprobdataCreate(SCIP *scip, const char *probname, SCIP_Real **costs, SCIP_Real **demands, SCIP_Real *capacity, SCIP_Real *fixedcost, int ncustomers, int nfacilities, int nscenarios, SCIP_Bool usebenders, SCIP_Bool quadcosts)
SCIP_RETCODE SCIPreleaseVar(SCIP *scip, SCIP_VAR **var)
Definition: scip_var.c:1245
#define FALSE
Definition: def.h:87
SCIP_Real SCIPinfinity(SCIP *scip)
SCIP_RETCODE SCIPcreateBendersDefault(SCIP *scip, SCIP **subproblems, int nsubproblems)
SCIP_VERBLEVEL SCIPgetVerbLevel(SCIP *scip)
Definition: scip_message.c:240
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition: misc.c:10755
#define TRUE
Definition: def.h:86
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:54
int SCIPprobdataGetNCustomers(SCIP_PROBDATA *probdata)
SCIP_RETCODE SCIPsetProbData(SCIP *scip, SCIP_PROBDATA *probdata)
Definition: scip_prob.c:1012
static SCIP_DECL_PROBDELORIG(probdelorigScflp)
SCIP_RETCODE SCIPcreateVarBasic(SCIP *scip, SCIP_VAR **var, const char *name, SCIP_Real lb, SCIP_Real ub, SCIP_Real obj, SCIP_VARTYPE vartype)
Definition: scip_var.c:185
#define SCIPfreeBlockMemory(scip, ptr)
Definition: scip_mem.h:99
SCIP_MESSAGEHDLR * SCIPgetMessagehdlr(SCIP *scip)
Definition: scip_message.c:79
#define SCIPfreeBufferArray(scip, ptr)
Definition: scip_mem.h:127
SCIP_RETCODE SCIPcreate(SCIP **scip)
Definition: scip_general.c:283
#define SCIPdebugMsg
Definition: scip_message.h:69
SCIP_RETCODE SCIPaddCoefLinear(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real val)
void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
Definition: scip_message.c:199
SCIP_RETCODE SCIPcreateProbBasic(SCIP *scip, const char *name)
Definition: scip_prob.c:170
static SCIP_DECL_PROBTRANS(probtransScflp)
int SCIPprobdataGetNFacilities(SCIP_PROBDATA *probdata)
#define SCIPduplicateBlockMemoryArray(scip, ptr, source, num)
Definition: scip_mem.h:96
SCIP_RETCODE SCIPsetObjsense(SCIP *scip, SCIP_OBJSENSE objsense)
Definition: scip_prob.c:1240
static SCIP_RETCODE createSubproblems(SCIP *scip, SCIP **subproblems, SCIP_VAR **facilityvars, SCIP_VAR ***subfacilityvars, SCIP_VAR ****customervars, SCIP_CONS ***capconss, SCIP_CONS ***demandconss, SCIP_Real **costs, SCIP_Real **demands, SCIP_Real *capacity, SCIP_Real *fixedcost, int ncustomers, int nfacilities, int nscenarios, SCIP_Bool quadcosts)
void SCIPmessagePrintVerbInfo(SCIP_MESSAGEHDLR *messagehdlr, SCIP_VERBLEVEL verblevel, SCIP_VERBLEVEL msgverblevel, const char *formatstr,...)
Definition: message.c:669
SCIP_RETCODE SCIPaddCons(SCIP *scip, SCIP_CONS *cons)
Definition: scip_prob.c:2768
SCIP_RETCODE SCIPsetBoolParam(SCIP *scip, const char *name, SCIP_Bool value)
Definition: scip_param.c:420
SCIP_RETCODE SCIPcreateConsQuadraticNonlinear(SCIP *scip, SCIP_CONS **cons, const char *name, int nlinvars, SCIP_VAR **linvars, SCIP_Real *lincoefs, int nquadterms, SCIP_VAR **quadvars1, SCIP_VAR **quadvars2, SCIP_Real *quadcoefs, SCIP_Real lhs, SCIP_Real rhs, 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)
#define NULL
Definition: lpi_spx1.cpp:155
#define SCIP_CALL(x)
Definition: def.h:384
Problem data for Stochastic Capacitated Facility Location problem.
static SCIP_RETCODE createOriginalproblem(SCIP *scip, SCIP_VAR **facilityvars, SCIP_VAR ****customervars, SCIP_CONS ***capconss, SCIP_CONS ***demandconss, SCIP_CONS **sufficientcap, SCIP_Real **costs, SCIP_Real **demands, SCIP_Real *capacity, SCIP_Real *fixedcost, int ncustomers, int nfacilities, int nscenarios, SCIP_Bool quadcosts)
#define SCIPallocBufferArray(scip, ptr, num)
Definition: scip_mem.h:115
#define SCIP_Bool
Definition: def.h:84
SCIP_RETCODE SCIPsetProbTrans(SCIP *scip, SCIP_DECL_PROBTRANS((*probtrans)))
Definition: scip_prob.c:211
SCIP_RETCODE SCIPincludeDefaultPlugins(SCIP *scip)
static SCIP_RETCODE probdataFree(SCIP *scip, SCIP_PROBDATA **probdata)
SCIP_RETCODE SCIPsetIntParam(SCIP *scip, const char *name, int value)
Definition: scip_param.c:478
SCIP_VAR ** SCIPprobdataGetFacilityVars(SCIP_PROBDATA *probdata)
static SCIP_DECL_PROBDELTRANS(probdeltransScflp)
struct SCIP_ProbData SCIP_PROBDATA
Definition: type_prob.h:44
SCIP_RETCODE SCIPaddVar(SCIP *scip, SCIP_VAR *var)
Definition: scip_prob.c:1666
SCIP_RETCODE SCIPreleaseCons(SCIP *scip, SCIP_CONS **cons)
Definition: scip_cons.c:1110
static SCIP_RETCODE probdataCreate(SCIP *scip, SCIP_PROBDATA **probdata, SCIP **subproblems, SCIP_VAR **facilityvars, SCIP_VAR ***subfacilityvars, SCIP_VAR ****customervars, SCIP_CONS ***capconss, SCIP_CONS ***demandconss, SCIP_CONS *sufficientcap, SCIP_Real **costs, SCIP_Real **demands, SCIP_Real *capacity, SCIP_Real *fixedcost, int ncustomers, int nfacilities, int nscenarios, SCIP_Bool usebenders, SCIP_Bool quadcosts)
#define SCIP_Real
Definition: def.h:177
static SCIP_RETCODE createMasterproblem(SCIP *scip, SCIP_VAR **facilityvars, SCIP_CONS **sufficientcap, SCIP_Real *capacity, SCIP_Real *fixedcost, SCIP_Real **demands, int ncustomers, int nfacilities, int nscenarios)
SCIP_RETCODE SCIPsetProbDeltrans(SCIP *scip, SCIP_DECL_PROBDELTRANS((*probdeltrans)))
Definition: scip_prob.c:232
SCIP_RETCODE SCIPsetProbDelorig(SCIP *scip, SCIP_DECL_PROBDELORIG((*probdelorig)))
Definition: scip_prob.c:190
SCIPallocBlockMemory(scip, subsol))
default SCIP plugins
SCIP callable library.
SCIP_RETCODE SCIPfree(SCIP **scip)
Definition: scip_general.c:315