Scippy

    SCIP

    Solving Constraint Integer Programs

    benderscut_nogood.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_nogood.c
    26 * @ingroup OTHER_CFILES
    27 * @brief Generates a no good cut for integer solutions that are infeasible for the subproblems
    28 * @author Stephen J. Maher
    29 */
    30
    31/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
    32
    34#include "scip/cons_linear.h"
    35#include "scip/pub_benderscut.h"
    36#include "scip/pub_benders.h"
    37#include "scip/pub_lp.h"
    38#include "scip/pub_message.h"
    39#include "scip/pub_misc.h"
    40#include "scip/pub_var.h"
    41#include "scip/scip_benders.h"
    42#include "scip/scip_cons.h"
    43#include "scip/scip_cut.h"
    44#include "scip/scip_general.h"
    45#include "scip/scip_lp.h"
    46#include "scip/scip_mem.h"
    47#include "scip/scip_message.h"
    48#include "scip/scip_numerics.h"
    49#include "scip/scip_param.h"
    50#include "scip/scip_prob.h"
    51#include "scip/scip_sol.h"
    52#include "scip/type_message.h"
    53#include <string.h>
    54
    55#define BENDERSCUT_NAME "nogood"
    56#define BENDERSCUT_DESC "no good Benders' decomposition integer cut"
    57#define BENDERSCUT_PRIORITY 500
    58#define BENDERSCUT_LPCUT FALSE
    59
    60
    61
    62#define SCIP_DEFAULT_ADDCUTS FALSE /** Should cuts be generated, instead of constraints */
    63
    64/*
    65 * Data structures
    66 */
    67
    68/** Benders' decomposition cuts data */
    69struct SCIP_BenderscutData
    70{
    71 SCIP_BENDERS* benders; /**< the Benders' decomposition data structure */
    72 int curriter; /**< the current Benders' decomposition subproblem solve iteration */
    73 SCIP_Bool addcuts; /**< should cuts be generated instead of constraints */
    74 SCIP_Bool cutadded; /**< has a cut been added in the current iteration. Only one cut per round */
    75 SCIP_Bool subprobsvalid; /**< is it valid to apply nogood cuts for this problem */
    76};
    77
    78
    79/*
    80 * Local methods
    81 */
    82
    83/** determines if the subproblems are valid for generating nogood cuts */
    84static
    86 SCIP_BENDERS* benders, /**< the benders' decomposition structure */
    87 SCIP_BENDERSCUT* benderscut /**< the benders' decomposition cut method */
    88 )
    89{
    90 SCIP_BENDERSCUTDATA* benderscutdata;
    91 int nmastervars;
    92 int nmasterbinvars;
    93 int i;
    94
    95 assert( benders != NULL );
    96 assert( benderscut != NULL );
    97 assert( strcmp(SCIPbenderscutGetName(benderscut), BENDERSCUT_NAME) == 0 );
    98
    99 /* getting the Benders' cut data */
    100 benderscutdata = SCIPbenderscutGetData(benderscut);
    101 assert( benderscutdata != NULL );
    102 assert(benderscutdata->benders == benders);
    103
    104 /* checking whether the nogood cut is valid for this subproblem */
    105 for( i = 0; i < SCIPbendersGetNSubproblems(benders); i++ )
    106 {
    107 /* it is only possible to generate the no-good cut for subproblems that only include binary master variables */
    108 SCIPbendersGetSubproblemMasterVarsData(benders, i, NULL, &nmastervars, &nmasterbinvars, NULL);
    109
    110 if( nmastervars != nmasterbinvars )
    111 {
    112 benderscutdata->subprobsvalid = FALSE;
    113 break;
    114 }
    115 }
    116}
    117
    118
    119/** compute no good cut */
    120static
    122 SCIP* masterprob, /**< the SCIP instance of the master problem */
    123 SCIP_BENDERS* benders, /**< the benders' decomposition structure */
    124 SCIP_SOL* sol, /**< primal CIP solution */
    125 SCIP_CONS* cons, /**< the constraint for the generated cut, can be NULL */
    126 SCIP_ROW* row, /**< the row for the generated cut, can be NULL */
    127 SCIP_Bool addcut /**< indicates whether a cut is created instead of a constraint */
    128 )
    129{
    130 SCIP_VAR** vars;
    131 int nvars;
    132 SCIP_Real lhs;
    133 int i;
    134#ifndef NDEBUG
    135 SCIP_Real verifycons;
    136#endif
    137
    138 assert(masterprob != NULL);
    139 assert(benders != NULL);
    140 assert(cons != NULL || addcut);
    141 assert(row != NULL || !addcut);
    142
    143 nvars = SCIPgetNVars(masterprob);
    144 vars = SCIPgetVars(masterprob);
    145
    146 /* adding the subproblem objective function value to the lhs */
    147 if( addcut )
    148 lhs = SCIProwGetLhs(row);
    149 else
    150 lhs = SCIPgetLhsLinear(masterprob, cons);
    151
    152 /* adding the violation to the lhs */
    153 lhs += 1.0;
    154
    155 /* looping over all master problem variables to update the coefficients in the computed cut. */
    156 for( i = 0; i < nvars; i++ )
    157 {
    158 SCIP_Real coef;
    159
    160 if( !SCIPvarIsBinary(vars[i]) )
    161 continue;
    162
    163 /* if the variable is on its upper bound, then the subproblem objective value is added to the cut */
    164 if( SCIPisFeasEQ(masterprob, SCIPgetSolVal(masterprob, sol, vars[i]), 1.0) )
    165 {
    166 coef = -1.0;
    167 lhs -= 1.0;
    168 }
    169 else
    170 coef = 1.0;
    171
    172 /* adding the variable to the cut. The coefficient is the subproblem objective value */
    173 if( addcut )
    174 {
    175 SCIP_CALL( SCIPaddVarToRow(masterprob, row, vars[i], coef) );
    176 }
    177 else
    178 {
    179 SCIP_CALL( SCIPaddCoefLinear(masterprob, cons, vars[i], coef) );
    180 }
    181 }
    182
    183 /* Update the lhs of the cut */
    184 if( addcut )
    185 {
    186 SCIP_CALL( SCIPchgRowLhs(masterprob, row, lhs) );
    187 }
    188 else
    189 {
    190 SCIP_CALL( SCIPchgLhsLinear(masterprob, cons, lhs) );
    191 }
    192
    193#ifndef NDEBUG
    194 if( addcut )
    195 verifycons = SCIPgetRowSolActivity(masterprob, row, sol);
    196 else
    197 verifycons = SCIPgetActivityLinear(masterprob, cons, sol);
    198#endif
    199
    200 assert(SCIPisFeasEQ(masterprob, verifycons, lhs - 1));
    201
    202 return SCIP_OKAY;
    203}
    204
    205
    206
    207/** generates and applies Benders' cuts */
    208static
    210 SCIP* masterprob, /**< the SCIP instance of the master problem */
    211 SCIP_BENDERS* benders, /**< the benders' decomposition */
    212 SCIP_BENDERSCUT* benderscut, /**< the benders' decomposition cut method */
    213 SCIP_SOL* sol, /**< primal CIP solution */
    214 SCIP_BENDERSENFOTYPE type, /**< the enforcement type calling this function */
    215 SCIP_RESULT* result /**< the result from solving the subproblems */
    216 )
    217{
    218 SCIP_BENDERSCUTDATA* benderscutdata;
    219 SCIP_CONSHDLR* consbenders;
    220 SCIP_CONS* cons;
    221 SCIP_ROW* row;
    222 char cutname[SCIP_MAXSTRLEN];
    223 SCIP_Bool addcut;
    224
    225 assert(masterprob != NULL);
    226 assert(benders != NULL);
    227 assert(benderscut != NULL);
    228 assert(result != NULL);
    229
    230 row = NULL;
    231 cons = NULL;
    232
    233 /* retrieving the Benders' cut data */
    234 benderscutdata = SCIPbenderscutGetData(benderscut);
    235
    236 /* if the cuts are generated prior to the solving stage, then rows can not be generated. So constraints must be
    237 * added to the master problem.
    238 */
    239 if( SCIPgetStage(masterprob) < SCIP_STAGE_INITSOLVE )
    240 addcut = FALSE;
    241 else
    242 addcut = benderscutdata->addcuts;
    243
    244 /* retrieving the Benders' decomposition constraint handler */
    245 consbenders = SCIPfindConshdlr(masterprob, "benders");
    246
    247 /* setting the name of the generated cut */
    248 (void) SCIPsnprintf(cutname, SCIP_MAXSTRLEN, "nogoodcut_%" SCIP_LONGINT_FORMAT, SCIPbenderscutGetNFound(benderscut) );
    249
    250 /* creating an empty row or constraint for the Benders' cut */
    251 if( addcut )
    252 {
    253 SCIP_CALL( SCIPcreateEmptyRowConshdlr(masterprob, &row, consbenders, cutname, 0.0, SCIPinfinity(masterprob), FALSE,
    254 FALSE, TRUE) );
    255 }
    256 else
    257 {
    258 SCIP_CALL( SCIPcreateConsBasicLinear(masterprob, &cons, cutname, 0, NULL, NULL, 0.0, SCIPinfinity(masterprob)) );
    259 SCIP_CALL( SCIPsetConsDynamic(masterprob, cons, TRUE) );
    260 SCIP_CALL( SCIPsetConsRemovable(masterprob, cons, TRUE) );
    261 }
    262
    263 /* computing the coefficients of the optimality cut */
    264 SCIP_CALL( computeNogoodCut(masterprob, benders, sol, cons, row, addcut) );
    265
    266 /* adding the constraint to the master problem */
    267 if( addcut )
    268 {
    269 SCIP_Bool infeasible;
    270
    272 {
    273 SCIP_CALL( SCIPaddRow(masterprob, row, FALSE, &infeasible) );
    274 assert(!infeasible);
    275 }
    276 else
    277 {
    279 SCIP_CALL( SCIPaddPoolCut(masterprob, row) );
    280 }
    281
    282#ifdef SCIP_DEBUG
    283 SCIP_CALL( SCIPprintRow(masterprob, row, NULL) );
    284 SCIPinfoMessage(masterprob, NULL, ";\n");
    285#endif
    286
    287 /* release the row */
    288 SCIP_CALL( SCIPreleaseRow(masterprob, &row) );
    289
    290 (*result) = SCIP_SEPARATED;
    291 }
    292 else
    293 {
    294 SCIP_CALL( SCIPaddCons(masterprob, cons) );
    295
    296 SCIPdebugPrintCons(masterprob, cons, NULL);
    297
    298 SCIP_CALL( SCIPreleaseCons(masterprob, &cons) );
    299
    300 (*result) = SCIP_CONSADDED;
    301 }
    302
    303 /* updating the cut added flag */
    304 benderscutdata->cutadded = TRUE;
    305
    306 return SCIP_OKAY;
    307}
    308
    309/*
    310 * Callback methods of Benders' decomposition cuts
    311 */
    312
    313/** destructor of Benders' decomposition cuts to free user data (called when SCIP is exiting) */
    314static
    315SCIP_DECL_BENDERSCUTFREE(benderscutFreeNogood)
    316{ /*lint --e{715}*/
    317 SCIP_BENDERSCUTDATA* benderscutdata;
    318
    319 assert( benderscut != NULL );
    320 assert( strcmp(SCIPbenderscutGetName(benderscut), BENDERSCUT_NAME) == 0 );
    321
    322 /* free Benders' cut data */
    323 benderscutdata = SCIPbenderscutGetData(benderscut);
    324 assert( benderscutdata != NULL );
    325
    326 SCIPfreeBlockMemory(scip, &benderscutdata);
    327
    328 SCIPbenderscutSetData(benderscut, NULL);
    329
    330 return SCIP_OKAY;
    331}
    332
    333
    334/** execution method of Benders' decomposition cuts */
    335static
    336SCIP_DECL_BENDERSCUTEXEC(benderscutExecNogood)
    337{ /*lint --e{715}*/
    338 SCIP* subproblem;
    339 SCIP_BENDERSCUTDATA* benderscutdata;
    340
    341 assert(scip != NULL);
    342 assert(benders != NULL);
    343 assert(benderscut != NULL);
    344 assert(result != NULL);
    345
    346 subproblem = SCIPbendersSubproblem(benders, probnumber);
    347
    348 if( subproblem == NULL )
    349 {
    350 SCIPdebugMsg(scip, "The subproblem %d is set to NULL. The <%s> Benders' decomposition cut can not be executed.\n",
    351 probnumber, BENDERSCUT_NAME);
    352
    353 (*result) = SCIP_DIDNOTRUN;
    354 return SCIP_OKAY;
    355 }
    356
    357 benderscutdata = SCIPbenderscutGetData(benderscut);
    358 assert(benderscutdata != NULL);
    359
    360 /* at the first iteration we check the validity of the subproblem for generating nogood cuts */
    361 if( benderscutdata->curriter == -1 )
    362 checkSubproblemValidity(benders, benderscut);
    363
    364 /* if the curriter is less than the number of Benders' decomposition calls, then we are in a new round.
    365 * So the cutadded flag must be set to FALSE
    366 */
    367 if( benderscutdata->curriter < SCIPbendersGetNCalls(benders) )
    368 {
    369 benderscutdata->curriter = SCIPbendersGetNCalls(benders);
    370 benderscutdata->cutadded = FALSE;
    371 }
    372
    373 /* if a cut has been added in this Benders' decomposition call, then no more must be added */
    374 if( benderscutdata->cutadded )
    375 return SCIP_OKAY;
    376
    377 /* it is only possible to generate nogood cuts if all linking variables are binary */
    378 if( !benderscutdata->subprobsvalid )
    379 {
    380 SCIPwarningMessage(scip, "The nogood cuts have been disabled because some linking variables are not binary.\n"
    381 "Since there is at least one non-convex subproblem, i.e. not LP or convex NLP, the problem will be solved heuristically.\n");
    382
    383 SCIPbenderscutSetEnabled(benderscut, FALSE);
    384
    385 return SCIP_OKAY;
    386 }
    387
    388 /* We can not rely on complete recourse for the subproblems. As such, the subproblems may be feasible for the LP, but
    389 * infeasible for the IP. As such, if one subproblem is infeasible, then a no good cut is generated.
    390 */
    391 if( SCIPgetStatus(subproblem) == SCIP_STATUS_INFEASIBLE )
    392 {
    393 /* generating a cut */
    394 SCIP_CALL( generateAndApplyBendersNogoodCut(scip, benders, benderscut, sol, type, result) );
    395 }
    396
    397 return SCIP_OKAY;
    398}
    399
    400
    401/*
    402 * Benders' decomposition cuts specific interface methods
    403 */
    404
    405/** creates the nogood Benders' decomposition cuts and includes it in SCIP */
    407 SCIP* scip, /**< SCIP data structure */
    408 SCIP_BENDERS* benders /**< Benders' decomposition */
    409 )
    410{
    411 SCIP_BENDERSCUTDATA* benderscutdata;
    412 SCIP_BENDERSCUT* benderscut;
    414
    415 assert(benders != NULL);
    416
    417 /* create nogood Benders' decomposition cuts data */
    418 SCIP_CALL( SCIPallocBlockMemory(scip, &benderscutdata) );
    419 benderscutdata->benders = benders;
    420 benderscutdata->curriter = -1;
    421 benderscutdata->cutadded = FALSE;
    422 benderscutdata->subprobsvalid = TRUE;
    423
    424 benderscut = NULL;
    425
    426 /* include Benders' decomposition cuts */
    428 BENDERSCUT_PRIORITY, BENDERSCUT_LPCUT, benderscutExecNogood, benderscutdata) );
    429
    430 assert(benderscut != NULL);
    431
    432 /* set non fundamental callbacks via setter functions */
    433 SCIP_CALL( SCIPsetBenderscutFree(scip, benderscut, benderscutFreeNogood) );
    434
    435 /* add nogood Benders' decomposition cuts parameters */
    436 (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "benders/%s/benderscut/%s/addcuts",
    439 "should cuts be generated and added to the cutpool instead of global constraints directly added to the problem.",
    440 &benderscutdata->addcuts, FALSE, SCIP_DEFAULT_ADDCUTS, NULL, NULL) );
    441
    442 return SCIP_OKAY;
    443}
    #define SCIP_DEFAULT_ADDCUTS
    #define BENDERSCUT_LPCUT
    static SCIP_RETCODE generateAndApplyBendersNogoodCut(SCIP *masterprob, SCIP_BENDERS *benders, SCIP_BENDERSCUT *benderscut, SCIP_SOL *sol, SCIP_BENDERSENFOTYPE type, SCIP_RESULT *result)
    #define BENDERSCUT_PRIORITY
    #define BENDERSCUT_DESC
    #define BENDERSCUT_NAME
    static SCIP_DECL_BENDERSCUTEXEC(benderscutExecNogood)
    static SCIP_RETCODE computeNogoodCut(SCIP *masterprob, SCIP_BENDERS *benders, SCIP_SOL *sol, SCIP_CONS *cons, SCIP_ROW *row, SCIP_Bool addcut)
    static void checkSubproblemValidity(SCIP_BENDERS *benders, SCIP_BENDERSCUT *benderscut)
    static SCIP_DECL_BENDERSCUTFREE(benderscutFreeNogood)
    Generates a no-good cut for solutions that are integer infeasible.
    Constraint handler for linear constraints in their most general form, .
    #define NULL
    Definition: def.h:255
    #define SCIP_MAXSTRLEN
    Definition: def.h:276
    #define SCIP_Bool
    Definition: def.h:98
    #define SCIP_Real
    Definition: def.h:163
    #define TRUE
    Definition: def.h:100
    #define FALSE
    Definition: def.h:101
    #define SCIP_LONGINT_FORMAT
    Definition: def.h:155
    #define SCIP_CALL(x)
    Definition: def.h:362
    SCIP_RETCODE SCIPincludeBenderscutNogood(SCIP *scip, SCIP_BENDERS *benders)
    SCIP_RETCODE SCIPaddCoefLinear(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real val)
    SCIP_Real SCIPgetLhsLinear(SCIP *scip, SCIP_CONS *cons)
    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_Real SCIPgetActivityLinear(SCIP *scip, SCIP_CONS *cons, SCIP_SOL *sol)
    SCIP_RETCODE SCIPchgLhsLinear(SCIP *scip, SCIP_CONS *cons, SCIP_Real lhs)
    SCIP_STATUS SCIPgetStatus(SCIP *scip)
    Definition: scip_general.c:562
    SCIP_STAGE SCIPgetStage(SCIP *scip)
    Definition: scip_general.c:444
    int SCIPgetNVars(SCIP *scip)
    Definition: scip_prob.c:2246
    SCIP_RETCODE SCIPaddCons(SCIP *scip, SCIP_CONS *cons)
    Definition: scip_prob.c:3274
    SCIP_VAR ** SCIPgetVars(SCIP *scip)
    Definition: scip_prob.c:2201
    void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
    Definition: scip_message.c:208
    #define SCIPdebugMsg
    Definition: scip_message.h:78
    void SCIPwarningMessage(SCIP *scip, const char *formatstr,...)
    Definition: scip_message.c:120
    SCIP_RETCODE SCIPaddBoolParam(SCIP *scip, const char *name, const char *desc, SCIP_Bool *valueptr, SCIP_Bool isadvanced, SCIP_Bool defaultvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
    Definition: scip_param.c:57
    const char * SCIPbendersGetName(SCIP_BENDERS *benders)
    Definition: benders.c:5966
    int SCIPbendersGetNSubproblems(SCIP_BENDERS *benders)
    Definition: benders.c:6010
    SCIP * SCIPbendersSubproblem(SCIP_BENDERS *benders, int probnumber)
    Definition: benders.c:6020
    void SCIPbendersGetSubproblemMasterVarsData(SCIP_BENDERS *benders, int probnumber, SCIP_VAR ***vars, int *nvars, int *nbinvars, int *nintvars)
    Definition: benders.c:6258
    int SCIPbendersGetNCalls(SCIP_BENDERS *benders)
    Definition: benders.c:6032
    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 SCIPsetBenderscutFree(SCIP *scip, SCIP_BENDERSCUT *benderscut, SCIP_DECL_BENDERSCUTFREE((*benderscutfree)))
    void SCIPbenderscutSetData(SCIP_BENDERSCUT *benderscut, SCIP_BENDERSCUTDATA *benderscutdata)
    Definition: benderscut.c:413
    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
    void SCIPbenderscutSetEnabled(SCIP_BENDERSCUT *benderscut, SCIP_Bool enabled)
    Definition: benderscut.c:593
    SCIP_CONSHDLR * SCIPfindConshdlr(SCIP *scip, const char *name)
    Definition: scip_cons.c:940
    SCIP_RETCODE SCIPsetConsDynamic(SCIP *scip, SCIP_CONS *cons, SCIP_Bool dynamic)
    Definition: scip_cons.c:1449
    SCIP_RETCODE SCIPsetConsRemovable(SCIP *scip, SCIP_CONS *cons, SCIP_Bool removable)
    Definition: scip_cons.c:1474
    SCIP_RETCODE SCIPreleaseCons(SCIP *scip, SCIP_CONS **cons)
    Definition: scip_cons.c:1173
    SCIP_RETCODE SCIPaddPoolCut(SCIP *scip, SCIP_ROW *row)
    Definition: scip_cut.c:336
    SCIP_RETCODE SCIPaddRow(SCIP *scip, SCIP_ROW *row, SCIP_Bool forcecut, SCIP_Bool *infeasible)
    Definition: scip_cut.c:225
    #define SCIPfreeBlockMemory(scip, ptr)
    Definition: scip_mem.h:108
    #define SCIPallocBlockMemory(scip, ptr)
    Definition: scip_mem.h:89
    SCIP_Real SCIProwGetLhs(SCIP_ROW *row)
    Definition: lp.c:17686
    SCIP_RETCODE SCIPchgRowLhs(SCIP *scip, SCIP_ROW *row, SCIP_Real lhs)
    Definition: scip_lp.c:1529
    SCIP_RETCODE SCIPcreateEmptyRowConshdlr(SCIP *scip, SCIP_ROW **row, SCIP_CONSHDLR *conshdlr, const char *name, SCIP_Real lhs, SCIP_Real rhs, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool removable)
    Definition: scip_lp.c:1367
    SCIP_RETCODE SCIPaddVarToRow(SCIP *scip, SCIP_ROW *row, SCIP_VAR *var, SCIP_Real val)
    Definition: scip_lp.c:1646
    SCIP_RETCODE SCIPprintRow(SCIP *scip, SCIP_ROW *row, FILE *file)
    Definition: scip_lp.c:2176
    SCIP_RETCODE SCIPreleaseRow(SCIP *scip, SCIP_ROW **row)
    Definition: scip_lp.c:1508
    SCIP_Real SCIPgetRowSolActivity(SCIP *scip, SCIP_ROW *row, SCIP_SOL *sol)
    Definition: scip_lp.c:2108
    SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
    Definition: scip_sol.c:1765
    SCIP_Real SCIPinfinity(SCIP *scip)
    SCIP_Bool SCIPisFeasEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPvarIsBinary(SCIP_VAR *var)
    Definition: var.c:23478
    int SCIPsnprintf(char *t, int len, const char *s,...)
    Definition: misc.c:10827
    static const char * paramname[]
    Definition: lpi_msk.c:5172
    public methods for Benders' decomposition
    public methods for Benders' decomposition cuts
    public methods for LP management
    public methods for message output
    #define SCIPdebugPrintCons(x, y, z)
    Definition: pub_message.h:102
    public data structures and miscellaneous methods
    public methods for problem variables
    public methods for Benders decomposition
    public methods for constraint handler plugins and constraints
    public methods for cuts and aggregation rows
    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 numerical tolerances
    public methods for SCIP parameter handling
    public methods for global and local (sub)problems
    public methods for solutions
    @ SCIP_BENDERSENFOTYPE_RELAX
    Definition: type_benders.h:52
    @ SCIP_BENDERSENFOTYPE_LP
    Definition: type_benders.h:51
    @ SCIP_BENDERSENFOTYPE_CHECK
    Definition: type_benders.h:54
    @ SCIP_BENDERSENFOTYPE_PSEUDO
    Definition: type_benders.h:53
    enum SCIP_BendersEnfoType SCIP_BENDERSENFOTYPE
    Definition: type_benders.h:56
    struct SCIP_BenderscutData SCIP_BENDERSCUTDATA
    type definitions for message output methods
    @ SCIP_DIDNOTRUN
    Definition: type_result.h:42
    @ SCIP_CONSADDED
    Definition: type_result.h:52
    @ SCIP_SEPARATED
    Definition: type_result.h:49
    enum SCIP_Result SCIP_RESULT
    Definition: type_result.h:61
    @ SCIP_OKAY
    Definition: type_retcode.h:42
    enum SCIP_Retcode SCIP_RETCODE
    Definition: type_retcode.h:63
    @ SCIP_STAGE_INITSOLVE
    Definition: type_set.h:52
    @ SCIP_STATUS_INFEASIBLE
    Definition: type_stat.h:44