Scippy

    SCIP

    Solving Constraint Integer Programs

    benders_default.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 benders_default.c
    26 * @ingroup DEFPLUGINS_BENDERS
    27 * @brief default Benders' decomposition plugin
    28 * @author Stephen J. Maher
    29 *
    30 * The default Benders' decomposition plugin is provided to simplify the interaction the Benders' decomposition
    31 * framework within SCIP. This plugin is included in the SCIP package by default. Using the default Benders'
    32 * decomposition plugin, a problem can be solved by Benders' decomposition by calling
    33 *
    34 * SCIPcreateBendersDefault(master problem, array of subproblems, number of subproblems)
    35 *
    36 * where "master problem" is a SCIP instance of the master problem, "array of subproblems" is an array of SCIP instances
    37 * that are the Benders' decomposition subproblems and "number of subproblems" is an integer indicating the number of
    38 * subproblems for this decomposition.
    39 *
    40 * A key feature of the default Benders' decomposition plugin is the automatic generation of the variable mapping
    41 * between the variables of the master problem and the subproblems.
    42 *
    43 * In the traditional application of Benders' decomposition, master problem variables are fixed to a solution value and
    44 * modify the RHS of the second stage constraints. The implementation within SCIP requires that a variable is created
    45 * in the subproblem for every master problem variable that appears in the subproblem constraints. This variable MUST
    46 * have the same name as the corresponding variable in the master problem. This name is used to automatically generate
    47 * the mapping between the master problem and the corresponding subproblem variables.
    48 *
    49 */
    50
    51/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
    52
    54#include "scip/bendersdefcuts.h"
    55#include "scip/pub_benders.h"
    56#include "scip/pub_message.h"
    57#include "scip/pub_misc.h"
    58#include "scip/pub_var.h"
    59#include "scip/scip.h"
    60
    61#define BENDERS_NAME "default"
    62#define BENDERS_DESC "default implementation of Benders' decomposition"
    63#define BENDERS_PRIORITY 0
    64#define BENDERS_CUTLP TRUE /**< should Benders' cut be generated for LP solutions */
    65#define BENDERS_CUTPSEUDO TRUE /**< should Benders' cut be generated for pseudo solutions */
    66#define BENDERS_CUTRELAX TRUE /**< should Benders' cut be generated for relaxation solutions */
    67#define BENDERS_SHAREAUXVARS FALSE /**< should this Benders' share the highest priority Benders' aux vars */
    68
    69
    70/*
    71 * Data structures
    72 */
    73
    74/** Benders' decomposition data */
    75struct SCIP_BendersData
    76{
    77 SCIP** subproblems; /**< the Benders' decomposition subproblems */
    78 SCIP_HASHMAP* mastervartosubindex;/**< hash map from the master variable to an index for the subproblemn variables */
    79 SCIP_HASHMAP* subvartomastervar; /**< hashmap from the subproblem variable to the master variable */
    80 SCIP_VAR*** subproblemvars; /**< the subproblem variables corresponding to master problem variables */
    81 int nmastervars; /**< the number of variables in the master problem */
    82 int nsubproblems; /**< the number of subproblems */
    83 SCIP_Bool subprobscreated; /**< flag to indicate that the Benders' decomposition Data was created */
    84 SCIP_Bool subprobscopied; /**< were the subproblems copied during the SCIP copy */
    85 SCIP_Bool mappingcreated; /**< flag to indicate whether the variable mapping has been created */
    86};
    87
    88
    89
    90
    91/*
    92 * Local methods
    93 */
    94
    95/** creates the Benders' decomposition data */
    96static
    98 SCIP* scip, /**< SCIP data structure */
    99 SCIP** subproblems, /**< the Benders' decomposition subproblems */
    100 SCIP_BENDERSDATA** bendersdata, /**< the Benders' decomposition data */
    101 int nsubproblems /**< the number of subproblems in the Benders' decomposition */
    102 )
    103{
    104 int i;
    105
    106 assert(scip != NULL);
    107 assert(subproblems != NULL);
    108
    109 (*bendersdata)->nsubproblems = nsubproblems;
    110
    111 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(*bendersdata)->subproblems, nsubproblems) );
    112
    113 /* Copying the subproblem to the Benders' decomposition data. */
    114 for( i = 0; i < nsubproblems; i++ )
    115 (*bendersdata)->subproblems[i] = subproblems[i];
    116
    117 (*bendersdata)->subprobscreated = TRUE;
    118
    119 return SCIP_OKAY;
    120}
    121
    122
    123/** Creates the variable mappings between the master problem and the corresponding variable in the subproblem.
    124 *
    125 * TODO: add the functionality to allow the user to provide an array of hashmaps for mapping between the master problem
    126 * variables and the corresponding subproblem variables.
    127 * TODO: check for uniqueness of names in this function.
    128 */
    129static
    131 SCIP* scip, /**< SCIP data structure */
    132 SCIP_BENDERS* benders /**< the Benders' decomposition structure */
    133 )
    134{
    135 SCIP_BENDERSDATA* bendersdata;
    136 SCIP_VAR** vars;
    137 int nsubproblems;
    138 int nvars;
    139 char varname[SCIP_MAXSTRLEN];
    140 int i;
    141 int j;
    142
    143 assert(scip != NULL);
    144 assert(benders != NULL);
    145
    146 bendersdata = SCIPbendersGetData(benders);
    147 assert(bendersdata != NULL);
    148
    149 nsubproblems = bendersdata->nsubproblems;
    150
    151 /* getting the master problem variable data */
    152 vars = SCIPgetVars(scip);
    153 nvars = SCIPgetNVars(scip);
    154
    155 bendersdata->nmastervars = nvars;
    156
    157 /* creating the hashmaps for the mapping between the master variables and the sub variables */
    158 SCIP_CALL( SCIPhashmapCreate(&bendersdata->mastervartosubindex, SCIPblkmem(scip), nvars) );
    159 SCIP_CALL( SCIPhashmapCreate(&bendersdata->subvartomastervar, SCIPblkmem(scip), nvars*nsubproblems) );
    160 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &bendersdata->subproblemvars, nsubproblems) );
    161 for( i = 0; i < nsubproblems; i++ )
    162 {
    163 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &bendersdata->subproblemvars[i], nvars) );
    164 }
    165
    166 /* this loop stores a mapping between the master problem variables and their counterpart in the subproblems. For each
    167 * master problem variable, the variable name is used to search for any corresponding variables in each of the
    168 * subproblems. If a corresponding variable exists, then a mapping is inserted into subvartomastervar and
    169 * mastervartosubvar hashmaps
    170 */
    171 for( i = 0; i < nvars; i++ )
    172 {
    173 SCIP_VAR* origvar;
    174 SCIP_VAR* subvar;
    175 SCIP_Real scalar;
    176 SCIP_Real constant;
    177 const char* origvarname;
    178 int charcount = SCIPgetSubscipDepth(scip)*2;
    179
    180 /* getting the original variable for the master variable
    181 * NOTE: This retrieved variable is the original variable. It may be a bug in regards to other parts of the code.
    182 * The process maps the subproblem variable to the original master variable. It was original supposed to be a
    183 * mapping between the subproblem variables and the transformed master variable.
    184 */
    185 origvar = vars[i];
    186 scalar = 1.0;
    187 constant = 0.0;
    188 SCIP_CALL( SCIPvarGetOrigvarSum(&origvar, &scalar, &constant) );
    189
    190 /* retrieving the var name */
    191 origvarname = SCIPvarGetName(origvar);
    192 (void) SCIPsnprintf(varname, SCIP_MAXSTRLEN, "%s", &origvarname[charcount]);
    193
    194 /* retrieving the subproblem variable for the given master variable */
    195 for( j = 0; j < nsubproblems; j++ )
    196 {
    197 /* find the corresponding subproblem variable for a given master problem variable using the variable name. */
    198 subvar = SCIPfindVar(bendersdata->subproblems[j], varname);
    199
    200 /* adding the subvariable to master variable mapping into the hash map */
    201 if( subvar != NULL )
    202 {
    203 SCIP_CALL( SCIPhashmapInsert(bendersdata->subvartomastervar, subvar, origvar) );
    204 }
    205
    206 /* storing the subproblem variable */
    207 bendersdata->subproblemvars[j][i] = subvar;
    208
    209 if( subvar != NULL )
    210 {
    211 SCIP_CALL( SCIPcaptureVar(bendersdata->subproblems[j], bendersdata->subproblemvars[j][i]) );
    212 }
    213 }
    214
    215 /* storing the mapping of the master variable to the variable index */
    216 SCIP_CALL( SCIPhashmapInsertInt(bendersdata->mastervartosubindex, vars[i], i) );
    217 }
    218
    219 bendersdata->mappingcreated = TRUE;
    220
    221 return SCIP_OKAY;
    222}
    223
    224
    225
    226/*
    227 * Callback methods for Benders' decomposition
    228 */
    229
    230/** copy method for Benders' decomposition plugins (called when SCIP copies plugins) */
    231static
    232SCIP_DECL_BENDERSCOPY(bendersCopyDefault)
    233{ /*lint --e{715}*/
    234 SCIP_BENDERSDATA* bendersdata; /* the source Benders' decomposition data */
    235
    236 assert(scip != NULL);
    237 assert(benders != NULL);
    238
    239 bendersdata = SCIPbendersGetData(benders);
    240
    241 /* including the Benders' decomposition in the target SCIP.
    242 * NOTE: this method uses the same subproblems as the main SCIP. In a parallel setting, this will not be thread safe.
    243 * It would be cleaner to copy the subproblems also.
    244 */
    246
    247 /* if the Benders' decomposition is active, then it must be created in the copy */
    248 if( SCIPbendersIsActive(benders) )
    249 {
    250 SCIP** subproblems;
    251 int i;
    252
    253 /* copying the subproblems if the threadsafe flag was set to TRUE */
    254 if( threadsafe )
    255 {
    256 /* allocating memory for the subproblems array */
    257 SCIP_CALL( SCIPallocBufferArray(scip, &subproblems, bendersdata->nsubproblems) );
    258
    259 for( i = 0; i < bendersdata->nsubproblems; i++ )
    260 {
    261 SCIP_Bool valid;
    262
    263 /* creating the SCIP instance for the subproblem */
    264 SCIP_CALL( SCIPcreate(&subproblems[i]) );
    265
    266 /* the original problem is copied so that the variable mappings are created correctly.
    267 * TODO: use a varmap to create the mappings for the copies
    268 */
    269 SCIP_CALL( SCIPcopyOrig(bendersdata->subproblems[i], subproblems[i], NULL, NULL, "", TRUE, FALSE, FALSE,
    270 &valid) );
    271 assert(valid);
    272 }
    273 }
    274 else
    275 subproblems = bendersdata->subproblems;
    276
    277 SCIP_CALL( SCIPcreateBendersDefault(scip, subproblems, bendersdata->nsubproblems) );
    278
    279 /* freeing the buffer memory for the subproblems */
    280 if( threadsafe )
    281 {
    282 SCIP_BENDERS* targetbenders;
    283 SCIP_BENDERSDATA* targetbendersdata;
    284
    285 targetbenders = SCIPfindBenders(scip, BENDERS_NAME);
    286 assert(targetbenders != NULL);
    287
    288 targetbendersdata = SCIPbendersGetData(targetbenders);
    289
    290 /* indicating that the subproblems have been copied */
    291 targetbendersdata->subprobscopied = TRUE;
    292
    293 SCIPfreeBufferArray(scip, &subproblems);
    294 }
    295 }
    296
    297 return SCIP_OKAY;
    298}
    299
    300/** destructor of Benders' decomposition to free user data (called when SCIP is exiting) */
    301/**! [SnippetBendersFreeDefault] */
    302static
    303SCIP_DECL_BENDERSFREE(bendersFreeDefault)
    304{ /*lint --e{715}*/
    305 SCIP_BENDERSDATA* bendersdata;
    306
    307 assert(scip != NULL);
    308 assert(benders != NULL);
    309
    310 bendersdata = SCIPbendersGetData(benders);
    311
    312 assert(bendersdata != NULL);
    313
    314 /* should have been freed in bendersExitDefault (if mappingcreated), or not been created at the first place */
    315 assert(bendersdata->subproblemvars == NULL);
    316 assert(bendersdata->subvartomastervar == NULL);
    317 assert(bendersdata->mastervartosubindex == NULL);
    318 assert(bendersdata->subproblems == NULL);
    319
    320 SCIPfreeBlockMemory(scip, &bendersdata);
    321
    322 return SCIP_OKAY;
    323}
    324/**! [SnippetBendersFreeDefault] */
    325
    326
    327/** initialization method of Benders' decomposition (called after problem was transformed) */
    328static
    329SCIP_DECL_BENDERSINIT(bendersInitDefault)
    330{ /*lint --e{715}*/
    331 assert(scip != NULL);
    332 assert(benders != NULL);
    333
    334 /* creating the variable mappings */
    336
    337 return SCIP_OKAY;
    338}
    339
    340/** deinitialization method of Benders' decomposition (called before transformed problem is freed and the Benders'
    341 * decomposition is active)
    342 */
    343static
    344SCIP_DECL_BENDERSEXIT(bendersExitDefault)
    345{
    346 SCIP_BENDERSDATA* bendersdata;
    347 int i;
    348 int j;
    349
    350 assert(scip != NULL);
    351 assert(benders != NULL);
    352
    353 bendersdata = SCIPbendersGetData(benders);
    354
    355 assert(bendersdata != NULL);
    356
    357 if( bendersdata->mappingcreated )
    358 {
    359 for( i = bendersdata->nsubproblems - 1; i >= 0; i-- )
    360 {
    361 for( j = 0; j < bendersdata->nmastervars; j++ )
    362 {
    363 if( bendersdata->subproblemvars[i][j] != NULL )
    364 {
    365 SCIP_CALL( SCIPreleaseVar(bendersdata->subproblems[i], &bendersdata->subproblemvars[i][j]) );
    366 }
    367 }
    368 SCIPfreeBlockMemoryArray(scip, &bendersdata->subproblemvars[i], bendersdata->nmastervars);
    369 }
    370 SCIPfreeBlockMemoryArray(scip, &bendersdata->subproblemvars, bendersdata->nsubproblems);
    371
    372 /* free hash map */
    373 SCIPhashmapFree(&bendersdata->subvartomastervar);
    374 SCIPhashmapFree(&bendersdata->mastervartosubindex);
    375 }
    376
    377 assert(bendersdata->subproblemvars == NULL);
    378 assert(bendersdata->subvartomastervar == NULL);
    379 assert(bendersdata->mastervartosubindex == NULL);
    380 if( bendersdata->subprobscreated )
    381 {
    382 /* if the subproblems were copied, then the copy needs to be freed */
    383 if( bendersdata->subprobscopied )
    384 {
    385 for( i = bendersdata->nsubproblems - 1; i >= 0; i-- )
    386 {
    387 SCIP_CALL( SCIPfree(&bendersdata->subproblems[i]) );
    388 }
    389 }
    390
    391 SCIPfreeBlockMemoryArray(scip, &bendersdata->subproblems, bendersdata->nsubproblems);
    392 }
    393
    394 return SCIP_OKAY;
    395}
    396
    397/** mapping method between the master problem variables and the subproblem variables of Benders' decomposition */
    398/**! [SnippetBendersGetvarDefault] */
    399static
    400SCIP_DECL_BENDERSGETVAR(bendersGetvarDefault)
    401{ /*lint --e{715}*/
    402 SCIP_BENDERSDATA* bendersdata;
    403 SCIP_VAR* origvar;
    404 SCIP_Real scalar;
    405 SCIP_Real constant;
    406
    407 assert(scip != NULL);
    408 assert(benders != NULL);
    409 assert(var != NULL);
    410 assert(mappedvar != NULL);
    411
    412 bendersdata = SCIPbendersGetData(benders);
    413
    414 if( probnumber == -1 )
    415 {
    416 origvar = var;
    417 /* The variable needs to be transformed back into an original variable. If the variable is already original, then
    418 * this function just returns the same variable
    419 */
    420 scalar = 1.0;
    421 constant = 0.0;
    422 SCIP_CALL( SCIPvarGetOrigvarSum(&origvar, &scalar, &constant) );
    423
    424 /* using the original variable, the master variable can be retrieved from the hash map */
    425 (*mappedvar) = (SCIP_VAR*) SCIPhashmapGetImage(bendersdata->subvartomastervar, origvar);
    426
    427 if( (*mappedvar) == NULL )
    428 (*mappedvar) = (SCIP_VAR*) SCIPhashmapGetImage(bendersdata->subvartomastervar, var);
    429 }
    430 else
    431 {
    432 int masterindex;
    433 /* The variable needs to be transformed back into an original variable. If the variable is already original, then
    434 * this function just returns the same variable
    435 */
    436
    437 /* we are requesting the subproblem variable for a master problem variable
    438 * The master problem variable is a transformed variable. The original variable is not required.
    439 * NOTE: Currently the original variable is being used. This may not be correct and should be the transformed
    440 * variable.
    441 */
    442 masterindex = SCIPhashmapGetImageInt(bendersdata->mastervartosubindex, var);
    443 (*mappedvar) = bendersdata->subproblemvars[probnumber][masterindex];
    444 }
    445
    446 return SCIP_OKAY;
    447}
    448/**! [SnippetBendersGetvarDefault] */
    449
    450/** the method for creating the Benders' decomposition subproblem. This method is called during the initialisation stage
    451 * (after the master problem was transformed)
    452 *
    453 * This method must create the SCIP instance for the subproblem and add the required variables and constraints. In
    454 * addition, the settings required for the solving the problem must be set here. However, some settings will be
    455 * overridden by the standard solving method included in the Benders' decomposition framework. If a special solving
    456 * method is desired, the user can implement the bendersSolvesubDefault callback.
    457 */
    458static
    459SCIP_DECL_BENDERSCREATESUB(bendersCreatesubDefault)
    460{ /*lint --e{715}*/
    461 SCIP_BENDERSDATA* bendersdata;
    462
    463 assert(scip != NULL);
    464 assert(benders != NULL);
    465
    466 bendersdata = SCIPbendersGetData(benders);
    467 assert(bendersdata != NULL);
    468
    469 /* adding the subproblem to the Benders' decomposition structure */
    470 SCIP_CALL( SCIPaddBendersSubproblem(scip, benders, bendersdata->subproblems[probnumber]) );
    471
    472 return SCIP_OKAY;
    473}
    474
    475
    476/*
    477 * Benders' decomposition specific interface methods
    478 */
    479
    480/** Creates a default Benders' decomposition algorithm and activates it in SCIP
    481 *
    482 * @note Every variable that appears in the subproblem constraints must be created in the corresponding subproblem with
    483 * the same name as in the master problem.
    484 *
    485 * @note The default Benders' decomposition implementation relies on unique variable names in the master problem and in
    486 * each of the subproblems. This is required because a variable mapping is made between the master problem variables and
    487 * the counterparts in the subproblems. This mapping is created using the variable names.
    488 */
    490 SCIP* scip, /**< SCIP data structure */
    491 SCIP** subproblems, /**< the Benders' decomposition subproblems */
    492 int nsubproblems /**< the number of subproblems in the Benders' decomposition */
    493 )
    494{
    495 SCIP_BENDERS* benders;
    496 SCIP_BENDERSDATA* bendersdata;
    497 int maxrestarts;
    498
    499 assert(scip != NULL);
    500 assert(subproblems != NULL);
    501 assert(nsubproblems > 0);
    502
    504 bendersdata = SCIPbendersGetData(benders);
    505
    506 /* turning restarts off */
    507 SCIP_CALL( SCIPgetIntParam(scip, "presolving/maxrestarts", &maxrestarts) );
    508 if( SCIPisParamFixed(scip, "presolving/maxrestarts") && maxrestarts != 0)
    509 {
    510 SCIPerrorMessage("The number of restarts is fixed to %d. The default Benders' decomposition requires the number"
    511 " of restarts to be 0.", maxrestarts);
    512 return SCIP_ERROR;
    513 }
    514 else
    515 {
    516 SCIP_CALL( SCIPsetIntParam(scip, "presolving/maxrestarts", 0) );
    517 SCIP_CALL( SCIPfixParam(scip, "presolving/maxrestarts") );
    518 }
    519
    520 SCIP_CALL( createBendersData(scip, subproblems, &bendersdata, nsubproblems) );
    521
    522 SCIP_CALL( SCIPactivateBenders(scip, benders, nsubproblems) );
    523
    524 return SCIP_OKAY;
    525}
    526
    527/** creates the default Benders' decomposition and includes it in SCIP */
    529 SCIP* scip /**< SCIP data structure */
    530 )
    531{
    532 SCIP_BENDERSDATA* bendersdata;
    533 SCIP_BENDERS* benders;
    534
    535 /* create default Benders' decomposition data */
    536 bendersdata = NULL;
    537
    538 SCIP_CALL( SCIPallocBlockMemory(scip, &bendersdata) );
    539 BMSclearMemory(bendersdata);
    540
    541 benders = NULL;
    542
    543 /* include Benders' decomposition */
    545 BENDERS_CUTPSEUDO, BENDERS_CUTRELAX, BENDERS_SHAREAUXVARS, bendersGetvarDefault, bendersCreatesubDefault,
    546 bendersdata) );
    547 assert(benders != NULL);
    548
    549 /* set non fundamental callbacks via setter functions */
    550 SCIP_CALL( SCIPsetBendersCopy(scip, benders, bendersCopyDefault) );
    551 SCIP_CALL( SCIPsetBendersFree(scip, benders, bendersFreeDefault) );
    552 SCIP_CALL( SCIPsetBendersInit(scip, benders, bendersInitDefault) );
    553 SCIP_CALL( SCIPsetBendersExit(scip, benders, bendersExitDefault) );
    554
    555 /* OPTIONAL: including the default cuts for Benders' decomposition */
    557
    558 return SCIP_OKAY;
    559}
    static SCIP_DECL_BENDERSEXIT(bendersExitDefault)
    static SCIP_RETCODE createVariableMappings(SCIP *scip, SCIP_BENDERS *benders)
    #define BENDERS_DESC
    static SCIP_DECL_BENDERSFREE(bendersFreeDefault)
    #define BENDERS_CUTLP
    #define BENDERS_NAME
    static SCIP_DECL_BENDERSGETVAR(bendersGetvarDefault)
    static SCIP_DECL_BENDERSINIT(bendersInitDefault)
    static SCIP_RETCODE createBendersData(SCIP *scip, SCIP **subproblems, SCIP_BENDERSDATA **bendersdata, int nsubproblems)
    #define BENDERS_PRIORITY
    static SCIP_DECL_BENDERSCREATESUB(bendersCreatesubDefault)
    #define BENDERS_CUTRELAX
    static SCIP_DECL_BENDERSCOPY(bendersCopyDefault)
    #define BENDERS_CUTPSEUDO
    #define BENDERS_SHAREAUXVARS
    default Benders' decomposition plugin
    SCIP_RETCODE SCIPincludeBendersDefaultCuts(SCIP *scip, SCIP_BENDERS *benders)
    #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 SCIPincludeBendersDefault(SCIP *scip)
    SCIP_RETCODE SCIPcopyOrig(SCIP *sourcescip, SCIP *targetscip, SCIP_HASHMAP *varmap, SCIP_HASHMAP *consmap, const char *suffix, SCIP_Bool enablepricing, SCIP_Bool threadsafe, SCIP_Bool passmessagehdlr, SCIP_Bool *valid)
    Definition: scip_copy.c:3044
    int SCIPgetSubscipDepth(SCIP *scip)
    Definition: scip_copy.c:2588
    SCIP_RETCODE SCIPfree(SCIP **scip)
    Definition: scip_general.c:402
    SCIP_RETCODE SCIPcreate(SCIP **scip)
    Definition: scip_general.c:370
    int SCIPgetNVars(SCIP *scip)
    Definition: scip_prob.c:2246
    SCIP_VAR ** SCIPgetVars(SCIP *scip)
    Definition: scip_prob.c:2201
    SCIP_VAR * SCIPfindVar(SCIP *scip, const char *name)
    Definition: scip_prob.c:3189
    void SCIPhashmapFree(SCIP_HASHMAP **hashmap)
    Definition: misc.c:3095
    int SCIPhashmapGetImageInt(SCIP_HASHMAP *hashmap, void *origin)
    Definition: misc.c:3304
    void * SCIPhashmapGetImage(SCIP_HASHMAP *hashmap, void *origin)
    Definition: misc.c:3284
    SCIP_RETCODE SCIPhashmapInsert(SCIP_HASHMAP *hashmap, void *origin, void *image)
    Definition: misc.c:3143
    SCIP_RETCODE SCIPhashmapCreate(SCIP_HASHMAP **hashmap, BMS_BLKMEM *blkmem, int mapsize)
    Definition: misc.c:3061
    SCIP_RETCODE SCIPhashmapInsertInt(SCIP_HASHMAP *hashmap, void *origin, int image)
    Definition: misc.c:3179
    SCIP_Bool SCIPisParamFixed(SCIP *scip, const char *name)
    Definition: scip_param.c:219
    SCIP_RETCODE SCIPsetIntParam(SCIP *scip, const char *name, int value)
    Definition: scip_param.c:487
    SCIP_RETCODE SCIPgetIntParam(SCIP *scip, const char *name, int *value)
    Definition: scip_param.c:269
    SCIP_RETCODE SCIPfixParam(SCIP *scip, const char *name)
    Definition: scip_param.c:367
    SCIP_RETCODE SCIPsetBendersFree(SCIP *scip, SCIP_BENDERS *benders, SCIP_DECL_BENDERSFREE((*bendersfree)))
    Definition: scip_benders.c:221
    SCIP_RETCODE SCIPsetBendersCopy(SCIP *scip, SCIP_BENDERS *benders, SCIP_DECL_BENDERSCOPY((*benderscopy)))
    Definition: scip_benders.c:197
    SCIP_RETCODE SCIPaddBendersSubproblem(SCIP *scip, SCIP_BENDERS *benders, SCIP *subproblem)
    Definition: scip_benders.c:771
    SCIP_BENDERS * SCIPfindBenders(SCIP *scip, const char *name)
    Definition: scip_benders.c:493
    SCIP_RETCODE SCIPactivateBenders(SCIP *scip, SCIP_BENDERS *benders, int nsubproblems)
    Definition: scip_benders.c:555
    SCIP_RETCODE SCIPincludeBendersBasic(SCIP *scip, SCIP_BENDERS **bendersptr, const char *name, const char *desc, int priority, SCIP_Bool cutlp, SCIP_Bool cutpseudo, SCIP_Bool cutrelax, SCIP_Bool shareauxvars, SCIP_DECL_BENDERSGETVAR((*bendersgetvar)), SCIP_DECL_BENDERSCREATESUB((*benderscreatesub)), SCIP_BENDERSDATA *bendersdata)
    Definition: scip_benders.c:151
    SCIP_RETCODE SCIPsetBendersExit(SCIP *scip, SCIP_BENDERS *benders, SCIP_DECL_BENDERSEXIT((*bendersexit)))
    Definition: scip_benders.c:269
    SCIP_Bool SCIPbendersIsActive(SCIP_BENDERS *benders)
    Definition: benders.c:2988
    SCIP_BENDERSDATA * SCIPbendersGetData(SCIP_BENDERS *benders)
    Definition: benders.c:5792
    SCIP_RETCODE SCIPsetBendersInit(SCIP *scip, SCIP_BENDERS *benders, SCIP_DECL_BENDERSINIT((*bendersinit)))
    Definition: scip_benders.c:245
    #define SCIPfreeBlockMemoryArray(scip, ptr, num)
    Definition: scip_mem.h:110
    BMS_BLKMEM * SCIPblkmem(SCIP *scip)
    Definition: scip_mem.c:57
    #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
    SCIP_RETCODE SCIPvarGetOrigvarSum(SCIP_VAR **var, SCIP_Real *scalar, SCIP_Real *constant)
    Definition: var.c:18320
    const char * SCIPvarGetName(SCIP_VAR *var)
    Definition: var.c:23267
    SCIP_RETCODE SCIPreleaseVar(SCIP *scip, SCIP_VAR **var)
    Definition: scip_var.c:1887
    SCIP_RETCODE SCIPcaptureVar(SCIP *scip, SCIP_VAR *var)
    Definition: scip_var.c:1853
    int SCIPsnprintf(char *t, int len, const char *s,...)
    Definition: misc.c:10827
    #define BMSclearMemory(ptr)
    Definition: memory.h:129
    public methods for Benders' decomposition
    public methods for message output
    #define SCIPerrorMessage
    Definition: pub_message.h:64
    public data structures and miscellaneous methods
    public methods for problem variables
    SCIP callable library.
    struct SCIP_BendersData SCIP_BENDERSDATA
    Definition: type_benders.h:94
    @ SCIP_OKAY
    Definition: type_retcode.h:42
    @ SCIP_ERROR
    Definition: type_retcode.h:43
    enum SCIP_Retcode SCIP_RETCODE
    Definition: type_retcode.h:63