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