SCIP

    Solving Constraint Integer Programs

    benderscut_feasalt.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-2026 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 benderscut_feasalt.c
    26 * @brief Alternative feasibility cuts for Benders' decomposition
    27 * @author Stephen J. Maher
    28 */
    29
    30/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
    31
    32#include "scip/pub_expr.h"
    34#include "scip/benderscut_opt.h"
    35#include "scip/cons_linear.h"
    36#include "scip/pub_benderscut.h"
    37#include "scip/pub_benders.h"
    38#include "scip/pub_lp.h"
    39#include "scip/pub_message.h"
    40#include "scip/pub_misc.h"
    42#include "scip/pub_nlp.h"
    43#include "scip/pub_var.h"
    44#include "scip/scip_benders.h"
    45#include "scip/scip_cons.h"
    46#include "scip/scip_general.h"
    47#include "scip/scip_lp.h"
    48#include "scip/scip_mem.h"
    49#include "scip/scip_message.h"
    50#include "scip/scip_nlp.h"
    51#include "scip/scip_nlpi.h"
    52#include "scip/scip_numerics.h"
    53#include "scip/scip_param.h"
    54#include "scip/scip_prob.h"
    56#include "scip/scip_timing.h"
    57#include "scip/scip_var.h"
    58
    59#define BENDERSCUT_NAME "feasalt"
    60#define BENDERSCUT_DESC "Alternative feasibility cuts for Benders' decomposition"
    61#define BENDERSCUT_PRIORITY 10001
    62#define BENDERSCUT_LPCUT TRUE
    63
    64#define SCIP_DEFAULT_DISPLAYFREQ 20
    65#define SLACKVAR_NAME "##bendersslackvar" /** the name for the Benders' slack variables added to each
    66 * constraints in the subproblems */
    67
    68struct SCIP_BenderscutData
    69{
    70 SCIP_NLPI* nlpi; /**< nlpi used to create the nlpi problem */
    71 SCIP_NLPIPROBLEM* nlpiprob; /**< nlpi problem representing the convex NLP relaxation */
    72 SCIP_HASHMAP* var2idx; /**< mapping the variable to the index in the NLPI problem */
    73 SCIP_HASHMAP* row2idx; /**< mapping the rows to the index in the NLPI problem */
    74 SCIP_VAR** nlpivars; /**< the variables in the NLPI problem */
    75 SCIP_NLROW** nlpirows; /**< the rows in the NLPI problem */
    76 int nlpinvars; /**< the number of variables in the NPLI problem */
    77 int nlpinrows; /**< the number of rows in the NLPI problem */
    78 int nlpinslackvars; /**< the number of slack variables in the NLPI problem */
    79 int nlpiprobsubprob; /**< the index of the subproblem that the nonlinear problem belongs to */
    80
    81 SCIP_Real* slackvarlbs; /**< an array of zeros for the slack variable lower bounds*/
    82 SCIP_Real* slackvarubs; /**< an array of infinity for the slack variable upper bounds*/
    83 int* slackvarinds; /**< array of indices for the slack variables */
    84};
    85
    86/*
    87 * Local methods
    88 */
    89
    90/** frees the non linear problem */
    91static
    93 SCIP* masterprob, /**< the SCIP instance of the master problem */
    94 SCIP* subproblem, /**< the SCIP instance of the pricing problem */
    95 SCIP_BENDERSCUT* benderscut /**< the Benders' decomposition structure */
    96 )
    97{
    98 SCIP_BENDERSCUTDATA* benderscutdata;
    99
    100 assert(masterprob != NULL);
    101 assert(subproblem != NULL);
    102 assert(benderscut != NULL);
    103
    104 benderscutdata = SCIPbenderscutGetData(benderscut);
    105 assert(benderscutdata != NULL);
    106
    107 if( benderscutdata->nlpiprob != NULL )
    108 {
    109 assert(benderscutdata->nlpi != NULL);
    110
    111 SCIPfreeBlockMemoryArray(masterprob, &benderscutdata->slackvarinds, benderscutdata->nlpinvars);
    112 SCIPfreeBlockMemoryArray(masterprob, &benderscutdata->slackvarubs, benderscutdata->nlpinvars);
    113 SCIPfreeBlockMemoryArray(masterprob, &benderscutdata->slackvarlbs, benderscutdata->nlpinvars);
    114 SCIPfreeBlockMemoryArray(masterprob, &benderscutdata->nlpirows, benderscutdata->nlpinrows);
    115 SCIPfreeBlockMemoryArray(masterprob, &benderscutdata->nlpivars, benderscutdata->nlpinvars);
    116 SCIPhashmapFree(&benderscutdata->row2idx);
    117 SCIPhashmapFree(&benderscutdata->var2idx);
    118
    119 SCIP_CALL( SCIPfreeNlpiProblem(subproblem, benderscutdata->nlpi, &benderscutdata->nlpiprob) );
    120
    121 benderscutdata->nlpinslackvars = 0;
    122 benderscutdata->nlpinrows = 0;
    123 benderscutdata->nlpinvars = 0;
    124
    125 benderscutdata->nlpi = NULL;
    126 }
    127
    128 return SCIP_OKAY;
    129}
    130
    131/** solves the auxiliary feasibility subproblem.
    132 *
    133 * @note: the variable fixings need to be setup before calling this function
    134 */
    135static
    137 SCIP* scip, /**< SCIP data structure */
    138 SCIP_BENDERSCUTDATA* benderscutdata, /**< Benders' cut data */
    139 SCIP_Bool* success /**< returns whether solving the feasibility problem was successful */
    140 )
    141{
    142 SCIP_NLPSOLSTAT nlpsolstat;
    143
    144 assert(scip != NULL);
    145 assert(benderscutdata != NULL);
    146
    147 (*success) = TRUE;
    148
    149 SCIP_CALL( SCIPsolveNlpi(scip, benderscutdata->nlpi, benderscutdata->nlpiprob, .iterlimit = 3000) ); /*lint !e666*/
    150 SCIPdebugMsg(scip, "NLP solstat = %d\n", SCIPgetNlpiSolstat(scip, benderscutdata->nlpi, benderscutdata->nlpiprob));
    151
    152 nlpsolstat = SCIPgetNlpiSolstat(scip, benderscutdata->nlpi, benderscutdata->nlpiprob);
    153
    154 /* if the feasibility NLP is not feasible, then it is not possible to generate a Benders' cut. This is also an error,
    155 * since the NLP should always be feasible. In debug mode, an ABORT will be thrown.
    156 */
    157 if( nlpsolstat > SCIP_NLPSOLSTAT_FEASIBLE )
    158 (*success) = FALSE;
    159
    160 return SCIP_OKAY;
    161}
    162
    163/** builds the non-linear problem to resolve to generate a cut for the infeasible subproblem */
    164static
    166 SCIP* masterprob, /**< the SCIP instance of the master problem */
    167 SCIP* subproblem, /**< the SCIP instance of the pricing problem */
    168 SCIP_BENDERSCUT* benderscut /**< the benders' decomposition cut method */
    169 )
    170{
    171 SCIP_BENDERSCUTDATA* benderscutdata;
    172 SCIP_Real* obj;
    173 int i;
    174
    175 assert(masterprob != NULL);
    176
    177 benderscutdata = SCIPbenderscutGetData(benderscut);
    178 assert(benderscutdata != NULL);
    179
    180 /* first freeing the non-linear problem if it exists */
    181 SCIP_CALL( freeNonlinearProblem(masterprob, subproblem, benderscut) );
    182
    183 assert(benderscutdata->nlpi == NULL);
    184 assert(benderscutdata->nlpiprob == NULL);
    185
    186 benderscutdata->nlpinvars = SCIPgetNVars(subproblem);
    187 benderscutdata->nlpinrows = SCIPgetNNLPNlRows(subproblem);
    188 benderscutdata->nlpi = SCIPgetNlpis(subproblem)[0];
    189 assert(benderscutdata->nlpi != NULL);
    190
    191 SCIP_CALL( SCIPhashmapCreate(&benderscutdata->var2idx, SCIPblkmem(masterprob), benderscutdata->nlpinvars) );
    192 SCIP_CALL( SCIPhashmapCreate(&benderscutdata->row2idx, SCIPblkmem(masterprob), benderscutdata->nlpinrows) );
    193
    194 SCIP_CALL( SCIPduplicateBlockMemoryArray(masterprob, &benderscutdata->nlpivars, SCIPgetVars(subproblem),
    195 benderscutdata->nlpinvars) ); /*lint !e666*/
    196 SCIP_CALL( SCIPduplicateBlockMemoryArray(masterprob, &benderscutdata->nlpirows, SCIPgetNLPNlRows(subproblem),
    197 benderscutdata->nlpinrows) ); /*lint !e666*/
    198
    199 SCIP_CALL( SCIPcreateNlpiProblemFromNlRows(subproblem, benderscutdata->nlpi, &benderscutdata->nlpiprob, "benders-feascutalt-nlp",
    200 SCIPgetNLPNlRows(subproblem), benderscutdata->nlpinrows, benderscutdata->var2idx, benderscutdata->row2idx, NULL, SCIPinfinity(subproblem), FALSE,
    201 FALSE) );
    202
    203 /* storing the slack variable bounds and indices */
    204 SCIP_CALL( SCIPallocBufferArray(masterprob, &obj, benderscutdata->nlpinvars) );
    205
    206 SCIP_CALL( SCIPallocBlockMemoryArray(masterprob, &benderscutdata->slackvarlbs, benderscutdata->nlpinvars) );
    207 SCIP_CALL( SCIPallocBlockMemoryArray(masterprob, &benderscutdata->slackvarubs, benderscutdata->nlpinvars) );
    208 SCIP_CALL( SCIPallocBlockMemoryArray(masterprob, &benderscutdata->slackvarinds, benderscutdata->nlpinvars) );
    209 benderscutdata->nlpinslackvars = 0;
    210 for( i = 0; i < benderscutdata->nlpinvars; i++ )
    211 {
    212 if( strstr(SCIPvarGetName(benderscutdata->nlpivars[i]), SLACKVAR_NAME) )
    213 {
    214 benderscutdata->slackvarlbs[benderscutdata->nlpinslackvars] = 0.0;
    215 benderscutdata->slackvarubs[benderscutdata->nlpinslackvars] = SCIPinfinity(subproblem);
    216 benderscutdata->slackvarinds[benderscutdata->nlpinslackvars] = SCIPhashmapGetImageInt(benderscutdata->var2idx,
    217 (void*)benderscutdata->nlpivars[i]);
    218
    219 obj[benderscutdata->nlpinslackvars] = 1.0;
    220
    221 benderscutdata->nlpinslackvars++;
    222 }
    223 }
    224
    225 /* setting the objective function */
    226 SCIP_CALL( SCIPsetNlpiObjective(subproblem, benderscutdata->nlpi, benderscutdata->nlpiprob, benderscutdata->nlpinslackvars,
    227 benderscutdata->slackvarinds, obj, NULL, 0.0) );
    228
    229 /* unfixing the slack variables */
    230 SCIP_CALL( SCIPchgNlpiVarBounds(subproblem, benderscutdata->nlpi, benderscutdata->nlpiprob, benderscutdata->nlpinslackvars,
    231 benderscutdata->slackvarinds, benderscutdata->slackvarlbs, benderscutdata->slackvarubs) );
    232
    233 SCIPfreeBufferArray(masterprob, &obj);
    234
    235 return SCIP_OKAY;
    236}
    237
    238/** updates the non-linear problem that is resolved to generate a cut for the infeasible subproblem */
    239static
    241 SCIP* subproblem, /**< the SCIP instance of the pricing problem */
    242 SCIP_BENDERSCUT* benderscut /**< the benders' decomposition cut method */
    243 )
    244{
    245 SCIP_BENDERSCUTDATA* benderscutdata;
    246
    247 assert(subproblem != NULL);
    248 assert(benderscut != NULL);
    249
    250 benderscutdata = SCIPbenderscutGetData(benderscut);
    251 assert(benderscutdata != NULL);
    252 assert(benderscutdata->nlpi != NULL);
    253 assert(benderscutdata->nlpiprob != NULL);
    254 assert(benderscutdata->var2idx != NULL);
    255 assert(benderscutdata->row2idx != NULL);
    256
    257 /* setting the variable bounds to that from the current subproblem */
    258 SCIP_CALL( SCIPupdateNlpiProblem(subproblem, benderscutdata->nlpi, benderscutdata->nlpiprob, benderscutdata->var2idx,
    259 benderscutdata->nlpivars, benderscutdata->nlpinvars, SCIPinfinity(subproblem)) );
    260
    261 /* unfixing the slack variables */
    262 SCIP_CALL( SCIPchgNlpiVarBounds(subproblem, benderscutdata->nlpi, benderscutdata->nlpiprob, benderscutdata->nlpinslackvars,
    263 benderscutdata->slackvarinds, benderscutdata->slackvarlbs, benderscutdata->slackvarubs) );
    264
    265 return SCIP_OKAY;
    266}
    267
    268/** generates and applies Benders' cuts */
    269static
    271 SCIP* masterprob, /**< the SCIP instance of the master problem */
    272 SCIP* subproblem, /**< the SCIP instance of the pricing problem */
    273 SCIP_BENDERS* benders, /**< the benders' decomposition */
    274 SCIP_BENDERSCUT* benderscut, /**< the benders' decomposition cut method */
    275 SCIP_SOL* sol, /**< primal CIP solution */
    276 int probnumber, /**< the number of the pricing problem */
    277 SCIP_BENDERSENFOTYPE type, /**< the enforcement type calling this function */
    278 SCIP_RESULT* result /**< the result from solving the subproblems */
    279 )
    280{
    281 SCIP_BENDERSCUTDATA* benderscutdata;
    282 SCIP_Real* primalvals;
    283 SCIP_Real* consdualvals;
    284 SCIP_Real* varlbdualvals;
    285 SCIP_Real* varubdualvals;
    286 SCIP_Real obj;
    287 char cutname[SCIP_MAXSTRLEN];
    288 SCIP_Bool success;
    289#ifdef SCIP_EVENMOREDEBUG
    290 int i;
    291#endif
    292
    293 assert(masterprob != NULL);
    294 assert(subproblem != NULL);
    295 assert(benders != NULL);
    296 assert(result != NULL);
    297
    298 benderscutdata = SCIPbenderscutGetData(benderscut);
    299 assert(benderscutdata != NULL);
    300
    301 /* creating or updating the NLPI problem */
    302 if( benderscutdata->nlpiprob == NULL || benderscutdata->nlpiprobsubprob != probnumber )
    303 {
    304 SCIP_CALL( createAuxiliaryNonlinearSubproblem(masterprob, subproblem, benderscut) );
    305 benderscutdata->nlpiprobsubprob = probnumber;
    306 }
    307 else
    308 {
    309 SCIP_CALL( updateAuxiliaryNonlinearSubproblem(subproblem, benderscut) );
    310 }
    311
    312 /* solving the NLPI problem to get the minimum infeasible solution */
    313 SCIP_CALL( solveFeasibilityNonlinearSubproblem(subproblem, benderscutdata, &success) );
    314
    315 if( !success )
    316 {
    317 (*result) = SCIP_DIDNOTFIND;
    318 SCIPdebugMsg(masterprob, "Error in generating Benders' feasibility cut for problem %d. "
    319 "The feasibility subproblem failed to solve with a feasible solution.\n", probnumber);
    320 return SCIP_OKAY;
    321 }
    322
    323 /* getting the solution from the NLPI problem */
    324 SCIP_CALL( SCIPgetNlpiSolution(subproblem, benderscutdata->nlpi, benderscutdata->nlpiprob, &primalvals, &consdualvals,
    325 &varlbdualvals, &varubdualvals, &obj) );
    326
    327#ifdef SCIP_EVENMOREDEBUG
    328 SCIPdebugMsg(masterprob, "NLP Feasibility problem solution.\n");
    329 SCIPdebugMsg(masterprob, "Objective: %g.\n", obj);
    330 for( i = 0; i < benderscutdata->nlpinvars; i++ )
    331 {
    332 int varindex;
    333 SCIP_Real solval;
    334 if( SCIPhashmapExists(benderscutdata->var2idx, benderscutdata->nlpivars[i]) )
    335 {
    336 varindex = SCIPhashmapGetImageInt(benderscutdata->var2idx, benderscutdata->nlpivars[i]);
    337 solval = primalvals[varindex];
    338
    339 if( !SCIPisZero(masterprob, solval) )
    340 {
    341 SCIPdebugMsg(masterprob, "%s (obj: %g): %20g\n", SCIPvarGetName(benderscutdata->nlpivars[i]),
    342 SCIPvarGetObj(benderscutdata->nlpivars[i]), solval);
    343 }
    344 }
    345 }
    346#endif
    347
    348 /* setting the name of the generated cut */
    349 (void) SCIPsnprintf(cutname, SCIP_MAXSTRLEN, "altfeasibilitycut_%d_%" SCIP_LONGINT_FORMAT, probnumber,
    350 SCIPbenderscutGetNFound(benderscut) );
    351
    352 /* generating a Benders' decomposition cut using the classical optimality cut methods */
    353 SCIP_CALL( SCIPgenerateAndApplyBendersOptCut(masterprob, subproblem, benders, benderscut,
    354 sol, probnumber, cutname, obj, primalvals, consdualvals, varlbdualvals, varubdualvals, benderscutdata->row2idx,
    355 benderscutdata->var2idx, type, FALSE, TRUE, result) );
    356
    357 if( (*result) == SCIP_CONSADDED )
    358 {
    359 if( SCIPisInfinity(masterprob, -SCIPgetDualbound(masterprob))
    361 {
    362 if( SCIPgetStage(masterprob) == SCIP_STAGE_SOLVING )
    363 {
    366 "Benders' Decomposition: Master problem LP is infeasible. Added %" SCIP_LONGINT_FORMAT " feasibility cuts.\n",
    367 SCIPbenderscutGetNFound(benderscut));
    368 }
    369 }
    370 SCIPdebugMsg(masterprob, "Constraint <%s> has been added to the master problem.\n", cutname);
    371 }
    372
    373 return SCIP_OKAY;
    374}
    375
    376/*
    377 * Callback methods of Benders' decomposition cuts
    378 */
    379
    380/** deinitialization method of Benders' decomposition cuts (called before transformed problem is freed) */
    381static
    382SCIP_DECL_BENDERSCUTEXIT(benderscutExitFeasalt)
    383{ /*lint --e{715}*/
    384 assert( benderscut != NULL );
    385
    387
    388 return SCIP_OKAY;
    389}
    390
    391/** destructor of the Benders' decomposition cut to free user data (called when SCIP is exiting) */
    392static
    393SCIP_DECL_BENDERSCUTFREE(benderscutFreeFeasalt)
    394{ /*lint --e{715}*/
    395 SCIP_BENDERSCUTDATA* benderscutdata;
    396
    397 assert(scip != NULL);
    398 assert(benderscut != NULL);
    399
    400 benderscutdata = SCIPbenderscutGetData(benderscut);
    401 assert(benderscutdata != NULL);
    402
    403 SCIPfreeBlockMemory(scip, &benderscutdata);
    404
    405 return SCIP_OKAY;
    406}
    407
    408/** execution method of Benders' decomposition cuts */
    409static
    410SCIP_DECL_BENDERSCUTEXEC(benderscutExecFeasalt)
    411{ /*lint --e{715}*/
    412 SCIP* subproblem;
    413 SCIP_Bool nlprelaxation;
    414
    415 assert(scip != NULL);
    416 assert(benders != NULL);
    417 assert(benderscut != NULL);
    418 assert(result != NULL);
    419 assert(probnumber >= 0 && probnumber < SCIPbendersGetNSubproblems(benders));
    420
    421 subproblem = SCIPbendersSubproblem(benders, probnumber);
    422
    423 if( subproblem == NULL )
    424 {
    425 SCIPdebugMsg(scip, "The subproblem %d is set to NULL. The <%s> Benders' decomposition cut can not be executed.\n",
    426 probnumber, BENDERSCUT_NAME);
    427
    428 (*result) = SCIP_DIDNOTRUN;
    429 return SCIP_OKAY;
    430 }
    431
    432 /* setting a flag to indicate whether the NLP relaxation should be used to generate cuts */
    433 nlprelaxation = SCIPisNLPConstructed(subproblem) && SCIPgetNNlpis(subproblem)
    435
    436 /* only generate feasibility cuts if the subproblem LP or NLP is infeasible,
    437 * since we use the farkas proof from the LP or the dual solution of the NLP to construct the feasibility cut
    438 */
    439 if( SCIPgetStage(subproblem) == SCIP_STAGE_SOLVING &&
    440 (nlprelaxation && (SCIPgetNLPSolstat(subproblem) == SCIP_NLPSOLSTAT_LOCINFEASIBLE || SCIPgetNLPSolstat(subproblem) == SCIP_NLPSOLSTAT_GLOBINFEASIBLE)) )
    441 {
    442 /* generating a cut for a given subproblem */
    443 SCIP_CALL( generateAndApplyBendersCuts(scip, subproblem, benders, benderscut, sol, probnumber, type, result) );
    444
    445 /* TODO this was in benderscutExitFeasalt, but freeNonlinearProblem now needs subproblem, which didn't seem to be easily available there */
    446 /* freeing the non-linear problem information */
    447 SCIP_CALL( freeNonlinearProblem(scip, subproblem, benderscut) );
    448 }
    449
    450 return SCIP_OKAY;
    451}
    452
    453
    454/*
    455 * Benders' decomposition cuts specific interface methods
    456 */
    457
    458/** creates the Alternative Feasibility Benders' decomposition cuts and includes it in SCIP */
    460 SCIP* scip, /**< SCIP data structure */
    461 SCIP_BENDERS* benders /**< Benders' decomposition */
    462 )
    463{
    464 SCIP_BENDERSCUT* benderscut;
    465 SCIP_BENDERSCUTDATA* benderscutdata;
    466
    467 assert(benders != NULL);
    468
    469 benderscut = NULL;
    470
    471 SCIP_CALL( SCIPallocBlockMemory(scip, &benderscutdata) );
    472 BMSclearMemory(benderscutdata);
    473 benderscutdata->nlpiprobsubprob = -1;
    474
    475 /* include Benders' decomposition cuts */
    477 BENDERSCUT_PRIORITY, BENDERSCUT_LPCUT, benderscutExecFeasalt, benderscutdata) );
    478
    479 /* set non fundamental callbacks via setter functions */
    480 SCIP_CALL( SCIPsetBenderscutFree(scip, benderscut, benderscutFreeFeasalt) );
    481 SCIP_CALL( SCIPsetBenderscutExit(scip, benderscut, benderscutExitFeasalt) );
    482
    483 assert(benderscut != NULL);
    484
    485 return SCIP_OKAY;
    486}
    #define BENDERSCUT_LPCUT
    static SCIP_DECL_BENDERSCUTEXIT(benderscutExitFeasalt)
    static SCIP_RETCODE createAuxiliaryNonlinearSubproblem(SCIP *masterprob, SCIP *subproblem, SCIP_BENDERSCUT *benderscut)
    #define BENDERSCUT_PRIORITY
    #define BENDERSCUT_DESC
    #define BENDERSCUT_NAME
    static SCIP_DECL_BENDERSCUTFREE(benderscutFreeFeasalt)
    #define SLACKVAR_NAME
    static SCIP_RETCODE solveFeasibilityNonlinearSubproblem(SCIP *scip, SCIP_BENDERSCUTDATA *benderscutdata, SCIP_Bool *success)
    static SCIP_RETCODE updateAuxiliaryNonlinearSubproblem(SCIP *subproblem, SCIP_BENDERSCUT *benderscut)
    static SCIP_DECL_BENDERSCUTEXEC(benderscutExecFeasalt)
    #define SCIP_DEFAULT_DISPLAYFREQ
    static SCIP_RETCODE freeNonlinearProblem(SCIP *masterprob, SCIP *subproblem, SCIP_BENDERSCUT *benderscut)
    static SCIP_RETCODE generateAndApplyBendersCuts(SCIP *masterprob, SCIP *subproblem, SCIP_BENDERS *benders, SCIP_BENDERSCUT *benderscut, SCIP_SOL *sol, int probnumber, SCIP_BENDERSENFOTYPE type, SCIP_RESULT *result)
    Alternative feasibility cuts for Benders' decomposition.
    Generates a standard Benders' decomposition optimality cut.
    Constraint handler for linear constraints in their most general form, .
    #define NULL
    Definition: def.h:257
    #define SCIP_MAXSTRLEN
    Definition: def.h:278
    #define SCIP_Bool
    Definition: def.h:100
    #define SCIP_STRINGEQ(name, reference, retcode)
    Definition: def.h:454
    #define SCIP_Real
    Definition: def.h:165
    #define TRUE
    Definition: def.h:102
    #define FALSE
    Definition: def.h:103
    #define SCIP_LONGINT_FORMAT
    Definition: def.h:157
    #define SCIP_CALL(x)
    Definition: def.h:364
    SCIP_RETCODE SCIPgenerateAndApplyBendersOptCut(SCIP *masterprob, SCIP *subproblem, SCIP_BENDERS *benders, SCIP_BENDERSCUT *benderscut, SCIP_SOL *sol, int probnumber, char *cutname, SCIP_Real objective, SCIP_Real *primalvals, SCIP_Real *consdualvals, SCIP_Real *varlbdualvals, SCIP_Real *varubdualvals, SCIP_HASHMAP *row2idx, SCIP_HASHMAP *var2idx, SCIP_BENDERSENFOTYPE type, SCIP_Bool addcut, SCIP_Bool feasibilitycut, SCIP_RESULT *result)
    SCIP_RETCODE SCIPincludeBenderscutFeasalt(SCIP *scip, SCIP_BENDERS *benders)
    SCIP_STAGE SCIPgetStage(SCIP *scip)
    Definition: scip_general.c:444
    int SCIPgetNVars(SCIP *scip)
    Definition: scip_prob.c:2246
    SCIP_VAR ** SCIPgetVars(SCIP *scip)
    Definition: scip_prob.c:2201
    void SCIPhashmapFree(SCIP_HASHMAP **hashmap)
    Definition: misc.c:3095
    int SCIPhashmapGetImageInt(SCIP_HASHMAP *hashmap, void *origin)
    Definition: misc.c:3304
    SCIP_RETCODE SCIPhashmapCreate(SCIP_HASHMAP **hashmap, BMS_BLKMEM *blkmem, int mapsize)
    Definition: misc.c:3061
    SCIP_Bool SCIPhashmapExists(SCIP_HASHMAP *hashmap, void *origin)
    Definition: misc.c:3466
    void SCIPverbMessage(SCIP *scip, SCIP_VERBLEVEL msgverblevel, FILE *file, const char *formatstr,...)
    Definition: scip_message.c:225
    #define SCIPdebugMsg
    Definition: scip_message.h:78
    SCIP_BENDERSSUBTYPE SCIPbendersGetSubproblemType(SCIP_BENDERS *benders, int probnumber)
    Definition: benders.c:6442
    int SCIPbendersGetNSubproblems(SCIP_BENDERS *benders)
    Definition: benders.c:6029
    SCIP * SCIPbendersSubproblem(SCIP_BENDERS *benders, int probnumber)
    Definition: benders.c:6039
    SCIP_RETCODE SCIPincludeBenderscutBasic(SCIP *scip, SCIP_BENDERS *benders, SCIP_BENDERSCUT **benderscutptr, const char *name, const char *desc, int priority, SCIP_Bool islpcut, SCIP_DECL_BENDERSCUTEXEC((*benderscutexec)), SCIP_BENDERSCUTDATA *benderscutdata)
    SCIP_RETCODE SCIPsetBenderscutExit(SCIP *scip, SCIP_BENDERSCUT *benderscut, SCIP_DECL_BENDERSCUTEXIT((*benderscutexit)))
    SCIP_RETCODE SCIPsetBenderscutFree(SCIP *scip, SCIP_BENDERSCUT *benderscut, SCIP_DECL_BENDERSCUTFREE((*benderscutfree)))
    const char * SCIPbenderscutGetName(SCIP_BENDERSCUT *benderscut)
    Definition: benderscut.c:492
    SCIP_BENDERSCUTDATA * SCIPbenderscutGetData(SCIP_BENDERSCUT *benderscut)
    Definition: benderscut.c:403
    SCIP_Longint SCIPbenderscutGetNFound(SCIP_BENDERSCUT *benderscut)
    Definition: benderscut.c:543
    #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
    #define SCIPduplicateBlockMemoryArray(scip, ptr, source, num)
    Definition: scip_mem.h:105
    SCIP_RETCODE SCIPupdateNlpiProblem(SCIP *scip, SCIP_NLPI *nlpi, SCIP_NLPIPROBLEM *nlpiprob, SCIP_HASHMAP *var2nlpiidx, SCIP_VAR **nlpivars, int nlpinvars, SCIP_Real cutoffbound)
    Definition: scip_nlpi.c:735
    #define SCIPsolveNlpi(scip, nlpi,...)
    Definition: scip_nlpi.h:208
    SCIP_RETCODE SCIPcreateNlpiProblemFromNlRows(SCIP *scip, SCIP_NLPI *nlpi, SCIP_NLPIPROBLEM **nlpiprob, const char *name, SCIP_NLROW **nlrows, int nnlrows, SCIP_HASHMAP *var2idx, SCIP_HASHMAP *nlrow2idx, SCIP_Real *nlscore, SCIP_Real cutoffbound, SCIP_Bool setobj, SCIP_Bool onlyconvex)
    Definition: scip_nlpi.c:449
    int SCIPgetNNlpis(SCIP *scip)
    Definition: scip_nlpi.c:205
    SCIP_NLPI ** SCIPgetNlpis(SCIP *scip)
    Definition: scip_nlpi.c:192
    SCIP_Bool SCIPisNLPConstructed(SCIP *scip)
    Definition: scip_nlp.c:110
    SCIP_NLPSOLSTAT SCIPgetNLPSolstat(SCIP *scip)
    Definition: scip_nlp.c:574
    int SCIPgetNNLPNlRows(SCIP *scip)
    Definition: scip_nlp.c:341
    SCIP_NLROW ** SCIPgetNLPNlRows(SCIP *scip)
    Definition: scip_nlp.c:319
    SCIP_Real SCIPgetDualbound(SCIP *scip)
    SCIP_RETCODE SCIPprintDisplayLine(SCIP *scip, FILE *file, SCIP_VERBLEVEL verblevel, SCIP_Bool endline)
    SCIP_Real SCIPinfinity(SCIP *scip)
    SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisZero(SCIP *scip, SCIP_Real val)
    SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
    Definition: var.c:23932
    const char * SCIPvarGetName(SCIP_VAR *var)
    Definition: var.c:23299
    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 Benders' decomposition cuts
    public functions to work with algebraic expressions
    public methods for LP management
    public methods for message output
    public data structures and miscellaneous methods
    internal miscellaneous methods for linear constraints
    public methods for NLP management
    public methods for problem variables
    public methods for Benders decomposition
    public methods for constraint handler plugins and constraints
    general public methods
    public methods for the LP relaxation, rows and columns
    public methods for memory management
    public methods for message handling
    public methods for nonlinear relaxation
    public methods for NLPI solver interfaces
    public methods for numerical tolerances
    public methods for SCIP parameter handling
    public methods for global and local (sub)problems
    public methods for querying solving statistics
    public methods for timing
    public methods for SCIP variables
    @ SCIP_BENDERSSUBTYPE_CONVEXDIS
    Definition: type_benders.h:79
    enum SCIP_BendersEnfoType SCIP_BENDERSENFOTYPE
    Definition: type_benders.h:56
    struct SCIP_BenderscutData SCIP_BENDERSCUTDATA
    @ SCIP_VERBLEVEL_NORMAL
    Definition: type_message.h:60
    enum SCIP_NlpSolStat SCIP_NLPSOLSTAT
    Definition: type_nlpi.h:168
    @ SCIP_NLPSOLSTAT_GLOBINFEASIBLE
    Definition: type_nlpi.h:164
    @ SCIP_NLPSOLSTAT_LOCINFEASIBLE
    Definition: type_nlpi.h:163
    @ SCIP_NLPSOLSTAT_FEASIBLE
    Definition: type_nlpi.h:162
    @ SCIP_DIDNOTRUN
    Definition: type_result.h:42
    @ SCIP_DIDNOTFIND
    Definition: type_result.h:44
    @ SCIP_CONSADDED
    Definition: type_result.h:52
    enum SCIP_Result SCIP_RESULT
    Definition: type_result.h:61
    @ SCIP_OKAY
    Definition: type_retcode.h:42
    @ SCIP_INVALIDCALL
    Definition: type_retcode.h:51
    enum SCIP_Retcode SCIP_RETCODE
    Definition: type_retcode.h:63
    @ SCIP_STAGE_SOLVING
    Definition: type_set.h:53