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-2025 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);
    309 SCIP_CALL( SCIPcreateVarBasic(scip, &sqrvar, name, 0.0, SCIPinfinity(scip), coeff, SCIP_VARTYPE_CONTINUOUS) ); /*lint !e644*/
    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:248
    #define SCIP_MAXSTRLEN
    Definition: def.h:269
    #define SCIP_Bool
    Definition: def.h:91
    #define SCIP_Real
    Definition: def.h:156
    #define TRUE
    Definition: def.h:93
    #define FALSE
    Definition: def.h:94
    #define SCIP_CALL(x)
    Definition: def.h:355
    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:402
    SCIP_RETCODE SCIPcreate(SCIP **scip)
    Definition: scip_general.c:370
    SCIP_RETCODE SCIPaddVar(SCIP *scip, SCIP_VAR *var)
    Definition: scip_prob.c:1907
    SCIP_RETCODE SCIPsetProbDeltrans(SCIP *scip, SCIP_DECL_PROBDELTRANS((*probdeltrans)))
    Definition: scip_prob.c:244
    SCIP_RETCODE SCIPsetProbTrans(SCIP *scip, SCIP_DECL_PROBTRANS((*probtrans)))
    Definition: scip_prob.c:223
    SCIP_RETCODE SCIPsetProbDelorig(SCIP *scip, SCIP_DECL_PROBDELORIG((*probdelorig)))
    Definition: scip_prob.c:202
    SCIP_RETCODE SCIPaddCons(SCIP *scip, SCIP_CONS *cons)
    Definition: scip_prob.c:3274
    SCIP_RETCODE SCIPsetObjsense(SCIP *scip, SCIP_OBJSENSE objsense)
    Definition: scip_prob.c:1417
    SCIP_RETCODE SCIPcreateProbBasic(SCIP *scip, const char *name)
    Definition: scip_prob.c:182
    SCIP_RETCODE SCIPsetProbData(SCIP *scip, SCIP_PROBDATA *probdata)
    Definition: scip_prob.c:1189
    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:1173
    #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:1887
    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:184
    int SCIPsnprintf(char *t, int len, const char *s,...)
    Definition: misc.c:10827
    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:60
    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:64