SCIP

    Solving Constraint Integer Programs

    sepa_impliedbounds.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 sepa_impliedbounds.c
    26 * @ingroup DEFPLUGINS_SEPA
    27 * @brief implied bounds separator
    28 * @author Kati Wolter
    29 * @author Tobias Achterberg
    30 */
    31
    32/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
    33
    35#include "scip/pub_implics.h"
    36#include "scip/pub_lp.h"
    37#include "scip/pub_message.h"
    38#include "scip/pub_misc.h"
    39#include "scip/pub_sepa.h"
    40#include "scip/pub_var.h"
    41#include "scip/scip_branch.h"
    42#include "scip/scip_cut.h"
    43#include "scip/scip_lp.h"
    44#include "scip/scip_mem.h"
    45#include "scip/scip_message.h"
    46#include "scip/scip_numerics.h"
    47#include "scip/scip_param.h"
    48#include "scip/scip_prob.h"
    49#include "scip/scip_sepa.h"
    50#include "scip/scip_sol.h"
    52#include "scip/scip_var.h"
    54
    55
    56#define SEPA_NAME "impliedbounds"
    57#define SEPA_DESC "implied bounds separator"
    58#define SEPA_PRIORITY -50
    59#define SEPA_FREQ 10
    60#define SEPA_MAXBOUNDDIST 1.0
    61#define SEPA_USESSUBSCIP FALSE /**< does the separator use a secondary SCIP instance? */
    62#define SEPA_DELAY FALSE /**< should separation method be delayed, if other separators found cuts? */
    63
    64#define RELCUTCOEFMAXRANGE 1.0 /**< maximal allowed range of cut coefficients, relative to 1/feastol */
    65#define DEFAULT_USETWOSIZECLIQUES TRUE /**< should violated inequalities for cliques with 2 variables be separated? */
    66
    67/** separator-specific data for the implied bounds separator */
    68struct SCIP_SepaData
    69{
    70 SCIP_Bool usetwosizecliques; /**< should violated inequalities for cliques with 2 variables be separated? */
    71};
    72
    73/*
    74 * Local methods
    75 */
    76
    77/** adds given cut with two variables, if it is violated */
    78static
    80 SCIP* scip, /**< SCIP data structure */
    81 SCIP_SEPA* sepa, /**< separator */
    82 SCIP_Real val1, /**< given coefficient of first variable */
    83 SCIP_VAR* var1, /**< given first variable */
    84 SCIP_Real solval1, /**< current LP solution value of first variable */
    85 SCIP_Real val2, /**< given coefficient of second variable */
    86 SCIP_VAR* var2, /**< given second variable */
    87 SCIP_Real solval2, /**< current LP solution value of second variable */
    88 SCIP_Real rhs, /**< given right hand side of the cut to add */
    89 SCIP_Bool* cutoff, /**< whether a cutoff has been detected */
    90 int* ncuts /**< pointer to update number of cuts added */
    91 )
    92{
    93 SCIP_Real activity;
    94
    95 assert(ncuts != NULL);
    96 assert(cutoff != NULL);
    97 *cutoff = FALSE;
    98
    99 /* calculate activity of cut */
    100 activity = val1 * solval1 + val2 * solval2;
    101 /*SCIPdebugMsg(scip, " -> %g<%s>[%g] + %g<%s>[%g] <= %g (act: %g)\n",
    102 val1, SCIPvarGetName(var1), solval1, val2, SCIPvarGetName(var2), solval2, rhs, activity);*/
    103
    104 /* check, if cut is violated */
    105 if( SCIPisEfficacious(scip, activity - rhs) )
    106 {
    107 SCIP_ROW* cut;
    108 char cutname[SCIP_MAXSTRLEN];
    109
    110 /* create cut */
    111 (void) SCIPsnprintf(cutname, SCIP_MAXSTRLEN, "implbd%" SCIP_LONGINT_FORMAT "_%d", SCIPgetNLPs(scip), *ncuts);
    112 SCIP_CALL( SCIPcreateEmptyRowSepa(scip, &cut, sepa, cutname, -SCIPinfinity(scip), rhs, FALSE, FALSE, TRUE) );
    114 SCIP_CALL( SCIPaddVarToRow(scip, cut, var1, val1) );
    115 SCIP_CALL( SCIPaddVarToRow(scip, cut, var2, val2) );
    117 /* set cut rank: for implied bounds we always set to 1 */
    118 SCIProwChgRank(cut, 1);
    119
    120#ifdef SCIP_DEBUG
    121 SCIPdebugMsg(scip, " -> found cut (activity = %g): ", activity);
    123#endif
    124
    126 (*ncuts)++;
    127
    128 /* release cut */
    129 SCIP_CALL( SCIPreleaseRow(scip, &cut) );
    130 }
    131
    132 return SCIP_OKAY;
    133}
    134
    135/** searches and adds implied bound cuts that are violated by the given solution value array */
    136static
    138 SCIP* scip, /**< SCIP data structure */
    139 SCIP_SEPA* sepa, /**< separator */
    140 SCIP_SOL* sol, /**< the solution that should be separated, or NULL for LP solution */
    141 SCIP_Real* solvals, /**< array with solution values of all problem variables */
    142 SCIP_VAR** fracvars, /**< array of fractional variables */
    143 SCIP_Real* fracvals, /**< solution values of fractional variables */
    144 int nfracs, /**< number of fractional variables */
    145 SCIP_Bool* cutoff, /**< whether a cutoff has been detected */
    146 int* ncuts /**< pointer to store the number of generated cuts */
    147 )
    148{
    149 SCIP_CLIQUE** cliques;
    150 SCIP_SEPADATA* sepadata;
    151 int ncliques;
    152 int i;
    153
    154 assert(solvals != NULL);
    155 assert(fracvars != NULL || nfracs == 0);
    156 assert(fracvals != NULL || nfracs == 0);
    157 assert(cutoff != NULL);
    158 assert(ncuts != NULL);
    159
    160 *cutoff = FALSE;
    161 *ncuts = 0;
    162 sepadata = SCIPsepaGetData(sepa);
    163 assert(sepadata != NULL);
    164
    165 SCIPdebugMsg(scip, "searching for implied bound cuts\n");
    166
    167 /* search binary variables for violated implications */
    168 for( i = 0; i < nfracs; i++ )
    169 {
    170 SCIP_BOUNDTYPE* impltypes;
    171 SCIP_Real* implbounds;
    172 SCIP_VAR** implvars;
    173 int nimpl;
    174 int j;
    175
    176 assert(fracvars != NULL);
    177 assert(fracvals != NULL);
    178
    179 /* only process binary variables */
    180 if( SCIPvarGetType(fracvars[i]) != SCIP_VARTYPE_BINARY || SCIPvarIsImpliedIntegral(fracvars[i]) )
    181 continue;
    182
    183 /* get implications of x == 1 */
    184 nimpl = SCIPvarGetNImpls(fracvars[i], TRUE);
    185 implvars = SCIPvarGetImplVars(fracvars[i], TRUE);
    186 impltypes = SCIPvarGetImplTypes(fracvars[i], TRUE);
    187 implbounds = SCIPvarGetImplBounds(fracvars[i], TRUE);
    188
    189 /*SCIPdebugMsg(scip, "%d implications for <%s>[%g] == 1\n", nimpl, SCIPvarGetName(fracvars[i]), fracvals[i]);*/
    190
    191 /* try to add cuts for implications of x == 1
    192 * x == 1 -> y <= p: y <= ub + x * (p - ub) <==> y + (ub - p) * x <= ub
    193 * x == 1 -> y >= p: y >= lb + x * (p - lb) <==> -y + (p - lb) * x <= -lb
    194 * with lb (ub) global lower (upper) bound of y
    195 */
    196 for( j = 0; j < nimpl; j++ )
    197 {
    198 SCIP_Real solval;
    199
    200 assert(implvars != NULL);
    201 assert(impltypes != NULL);
    202 assert(implbounds != NULL);
    203
    204 /* consider only implications with active implvar */
    205 if( SCIPvarGetProbindex(implvars[j]) < 0 )
    206 continue;
    207
    208 solval = solvals[SCIPvarGetProbindex(implvars[j])];
    209 if( impltypes[j] == SCIP_BOUNDTYPE_UPPER )
    210 {
    211 SCIP_Real ub;
    212
    213 /* implication x == 1 -> y <= p */
    214 ub = SCIPvarGetUbGlobal(implvars[j]);
    215
    216 /* consider only nonredundant and numerical harmless implications */
    217 if( SCIPisLE(scip, implbounds[j], ub) && (ub - implbounds[j]) * SCIPfeastol(scip) <= RELCUTCOEFMAXRANGE )
    218 {
    219 /* add cut if violated */
    220 SCIP_CALL( addCut(scip, sepa, 1.0, implvars[j], solval, (ub - implbounds[j]), fracvars[i], fracvals[i],
    221 ub, cutoff, ncuts) );
    222 if ( *cutoff )
    223 return SCIP_OKAY;
    224 }
    225 }
    226 else
    227 {
    228 SCIP_Real lb;
    229
    230 /* implication x == 1 -> y >= p */
    231 lb = SCIPvarGetLbGlobal(implvars[j]);
    232 assert(impltypes[j] == SCIP_BOUNDTYPE_LOWER);
    233
    234 /* consider only nonredundant and numerical harmless implications */
    235 if( SCIPisGE(scip, implbounds[j], lb) && (implbounds[j] - lb) * SCIPfeastol(scip) <= RELCUTCOEFMAXRANGE )
    236 {
    237 /* add cut if violated */
    238 SCIP_CALL( addCut(scip, sepa, -1.0, implvars[j], solval, (implbounds[j] - lb), fracvars[i], fracvals[i],
    239 -lb, cutoff, ncuts) );
    240 if ( *cutoff )
    241 return SCIP_OKAY;
    242 }
    243 }
    244 }
    245
    246 /* get implications of x == 0 */
    247 nimpl = SCIPvarGetNImpls(fracvars[i], FALSE);
    248 implvars = SCIPvarGetImplVars(fracvars[i], FALSE);
    249 impltypes = SCIPvarGetImplTypes(fracvars[i], FALSE);
    250 implbounds = SCIPvarGetImplBounds(fracvars[i], FALSE);
    251
    252 /*SCIPdebugMsg(scip, "%d implications for <%s>[%g] == 0\n", nimpl, SCIPvarGetName(fracvars[i]), fracvals[i]);*/
    253
    254 /* try to add cuts for implications of x == 0
    255 * x == 0 -> y <= p: y <= p + x * (ub - p) <==> y + (p - ub) * x <= p
    256 * x == 0 -> y >= p: y >= p + x * (lb - p) <==> -y + (lb - p) * x <= -p
    257 * with lb (ub) global lower (upper) bound of y
    258 */
    259 for( j = 0; j < nimpl; j++ )
    260 {
    261 SCIP_Real solval;
    262
    263 /* consider only implications with active implvar */
    264 if( SCIPvarGetProbindex(implvars[j]) < 0 )
    265 continue;
    266
    267 solval = solvals[SCIPvarGetProbindex(implvars[j])];
    268 if( impltypes[j] == SCIP_BOUNDTYPE_UPPER )
    269 {
    270 SCIP_Real ub;
    271
    272 /* implication x == 0 -> y <= p */
    273 ub = SCIPvarGetUbGlobal(implvars[j]);
    274
    275 /* consider only nonredundant and numerical harmless implications */
    276 if( SCIPisLE(scip, implbounds[j], ub) && (ub - implbounds[j]) * SCIPfeastol(scip) < RELCUTCOEFMAXRANGE )
    277 {
    278 /* add cut if violated */
    279 SCIP_CALL( addCut(scip, sepa, 1.0, implvars[j], solval, (implbounds[j] - ub), fracvars[i], fracvals[i],
    280 implbounds[j], cutoff, ncuts) );
    281 if ( *cutoff )
    282 return SCIP_OKAY;
    283 }
    284 }
    285 else
    286 {
    287 SCIP_Real lb;
    288
    289 /* implication x == 0 -> y >= p */
    290 lb = SCIPvarGetLbGlobal(implvars[j]);
    291 assert(impltypes[j] == SCIP_BOUNDTYPE_LOWER);
    292
    293 /* consider only nonredundant and numerical harmless implications */
    294 if( SCIPisGE(scip, implbounds[j], lb) && (implbounds[j] - lb) * SCIPfeastol(scip) < RELCUTCOEFMAXRANGE )
    295 {
    296 /* add cut if violated */
    297 SCIP_CALL( addCut(scip, sepa, -1.0, implvars[j], solval, (lb - implbounds[j]), fracvars[i], fracvals[i],
    298 -implbounds[j], cutoff, ncuts) );
    299 if ( *cutoff )
    300 return SCIP_OKAY;
    301 }
    302 }
    303 }
    304 }
    305
    306 /* stop separation here if cliques should not be separated */
    307 if( ! sepadata->usetwosizecliques )
    308 return SCIP_OKAY;
    309
    310 /* prepare clean clique data */
    312
    313 if( *cutoff )
    314 return SCIP_OKAY;
    315
    316 cliques = SCIPgetCliques(scip);
    317 ncliques = SCIPgetNCliques(scip);
    318
    319 /* loop over cliques of size 2 which are essentially implications and add cuts if they are violated */
    320 for( i = 0; i < ncliques; ++i )
    321 {
    322 SCIP_CLIQUE* clique;
    323 SCIP_VAR** clqvars;
    324 SCIP_Bool* clqvals;
    325 SCIP_Real rhs;
    326
    327 clique = cliques[i];
    328 /* only consider inequality cliques of size 2 */
    329 if( SCIPcliqueGetNVars(clique) != 2 || SCIPcliqueIsEquation(clique) )
    330 continue;
    331
    332 /* get variables and values of the clique */
    333 clqvars = SCIPcliqueGetVars(clique);
    334 clqvals = SCIPcliqueGetValues(clique);
    335
    336 /* clique variables should never be equal after clean up */
    337 assert(clqvars[0] != clqvars[1]);
    338
    339 /* calculate right hand side of clique inequality, which is initially 1 and decreased by 1 for every occurence of
    340 * a negated variable in the clique
    341 */
    342 rhs = 1.0;
    343 if( ! clqvals[0] )
    344 rhs -= 1.0;
    345 if( ! clqvals[1] )
    346 rhs -= 1.0;
    347
    348 /* Basic clique inequality is
    349 *
    350 * cx * x + (1-cx) (1-x) + cy * y + (1-cy) * (1-y) <= 1,
    351 *
    352 * where x and y are the two binary variables in the clique and cx and cy are their clique values, where a
    353 * clique value of 0 means that the negation of the variable should be part of the inequality.
    354 * Hence, exactly one of the two possible terms for x and y has a nonzero coefficient
    355 */
    356 SCIP_CALL( addCut(scip, sepa,
    357 clqvals[0] ? 1.0 : -1.0, clqvars[0], SCIPgetSolVal(scip, sol, clqvars[0]),
    358 clqvals[1] ? 1.0 : -1.0, clqvars[1], SCIPgetSolVal(scip, sol, clqvars[1]),
    359 rhs, cutoff, ncuts) );
    360
    361 /* terminate if cutoff was found */
    362 if( *cutoff )
    363 return SCIP_OKAY;
    364 }
    365
    366 return SCIP_OKAY;
    367}
    368
    369
    370/*
    371 * Callback methods of separator
    372 */
    373
    374/** copy method for separator plugins (called when SCIP copies plugins) */
    375static
    376SCIP_DECL_SEPACOPY(sepaCopyImpliedbounds)
    377{ /*lint --e{715}*/
    378 assert(scip != NULL);
    379 assert(sepa != NULL);
    380
    382
    383 /* call inclusion method of constraint handler */
    385
    386 return SCIP_OKAY;
    387}
    388
    389/** destructor of separator to free user data (called when SCIP is exiting) */
    390static
    391SCIP_DECL_SEPAFREE(sepaFreeImpliedbounds)
    392{ /*lint --e{715}*/
    393 SCIP_SEPADATA* sepadata;
    394
    395 assert(scip != NULL);
    396 assert(sepa != NULL);
    397
    399
    400 /* get separation data and free it */
    401 sepadata = SCIPsepaGetData(sepa);
    402 assert(sepadata != NULL);
    403 SCIPfreeBlockMemory(scip, &sepadata);
    404
    405 /* reset data pointer to NULL */
    406 SCIPsepaSetData(sepa, NULL);
    407
    408 return SCIP_OKAY;
    409}
    410
    411
    412/** LP solution separation method of separator */
    413static
    414SCIP_DECL_SEPAEXECLP(sepaExeclpImpliedbounds)
    415{ /*lint --e{715}*/
    416 SCIP_VAR** vars;
    417 SCIP_VAR** fracvars;
    418 SCIP_Real* solvals;
    419 SCIP_Real* fracvals;
    420 SCIP_Bool cutoff;
    421 int nvars;
    422 int nbinvars;
    423 int nfracs;
    424 int ncuts;
    425
    426 assert(sepa != NULL);
    427 assert(scip != NULL);
    428
    429 *result = SCIP_DIDNOTRUN;
    430
    431 /* gets active problem variables */
    432 SCIP_CALL( SCIPgetVarsData(scip, &vars, &nvars, &nbinvars, NULL, NULL, NULL) );
    433 if( nbinvars == 0 )
    434 return SCIP_OKAY;
    435
    436 /* get fractional problem variables */
    437 /* todo try out also separating fractional implicit integer variables */
    438 SCIP_CALL( SCIPgetLPBranchCands(scip, &fracvars, &fracvals, NULL, &nfracs, NULL, NULL) );
    439 if( nfracs == 0 )
    440 return SCIP_OKAY;
    441
    442 /* get solution values for all variables */
    443 SCIP_CALL( SCIPallocBufferArray(scip, &solvals, nvars) );
    444 SCIP_CALL( SCIPgetVarSols(scip, nvars, vars, solvals) );
    445
    446 /* call the cut separation */
    447 SCIP_CALL( separateCuts(scip, sepa, NULL, solvals, fracvars, fracvals, nfracs, &cutoff, &ncuts) );
    448
    449 /* adjust result code */
    450 if ( cutoff )
    451 *result = SCIP_CUTOFF;
    452 else if ( ncuts > 0 )
    453 *result = SCIP_SEPARATED;
    454 else
    455 *result = SCIP_DIDNOTFIND;
    456
    457 /* free temporary memory */
    458 SCIPfreeBufferArray(scip, &solvals);
    459
    460 return SCIP_OKAY;
    461}
    462
    463
    464/** arbitrary primal solution separation method of separator */
    465static
    466SCIP_DECL_SEPAEXECSOL(sepaExecsolImpliedbounds)
    467{ /*lint --e{715}*/
    468 SCIP_VAR** vars;
    469 SCIP_VAR** fracvars;
    470 SCIP_Real* solvals;
    471 SCIP_Real* fracvals;
    472 SCIP_Bool cutoff;
    473 int nvars;
    474 int nbinvars;
    475 int nfracs;
    476 int ncuts;
    477 int i;
    478
    479 assert(sepa != NULL);
    480 assert(scip != NULL);
    481
    482 *result = SCIP_DIDNOTRUN;
    483
    484 /* gets active problem variables */
    485 SCIP_CALL( SCIPgetVarsData(scip, &vars, &nvars, &nbinvars, NULL, NULL, NULL) );
    486 if( nbinvars == 0 )
    487 return SCIP_OKAY;
    488
    489 /* get solution values for all variables */
    490 SCIP_CALL( SCIPallocBufferArray(scip, &solvals, nvars) );
    491 SCIP_CALL( SCIPgetSolVals(scip, sol, nvars, vars, solvals) );
    492
    493 /* get binary problem variables that are fractional in given solution */
    494 SCIP_CALL( SCIPallocBufferArray(scip, &fracvars, nbinvars) );
    495 SCIP_CALL( SCIPallocBufferArray(scip, &fracvals, nbinvars) );
    496 nfracs = 0;
    497 for( i = 0; i < nbinvars; ++i )
    498 {
    499 if( !SCIPisFeasIntegral(scip, solvals[i]) )
    500 {
    501 fracvars[nfracs] = vars[i];
    502 fracvals[nfracs] = solvals[i];
    503 nfracs++;
    504 }
    505 }
    506
    507 /* call the cut separation */
    508 ncuts = 0;
    509 cutoff = FALSE;
    510
    511 if( nfracs > 0 )
    512 {
    513 SCIP_CALL( separateCuts(scip, sepa, sol, solvals, fracvars, fracvals, nfracs, &cutoff, &ncuts) );
    514 }
    515
    516 /* adjust result code */
    517 if ( cutoff )
    518 *result = SCIP_CUTOFF;
    519 else if ( ncuts > 0 )
    520 *result = SCIP_SEPARATED;
    521 else
    522 *result = SCIP_DIDNOTFIND;
    523
    524 /* free temporary memory */
    525 SCIPfreeBufferArray(scip, &fracvals);
    526 SCIPfreeBufferArray(scip, &fracvars);
    527 SCIPfreeBufferArray(scip, &solvals);
    528
    529 return SCIP_OKAY;
    530}
    531
    532
    533/*
    534 * separator specific interface methods
    535 */
    536
    537/** creates the impliedbounds separator and includes it in SCIP */
    539 SCIP* scip /**< SCIP data structure */
    540 )
    541{
    542 SCIP_SEPADATA* sepadata;
    543 SCIP_SEPA* sepa;
    544
    545 /* create impliedbounds separator data */
    546 SCIP_CALL( SCIPallocBlockMemory(scip, &sepadata) );
    547 assert(sepadata != NULL);
    548
    549 /* include separator */
    552 sepaExeclpImpliedbounds, sepaExecsolImpliedbounds,
    553 sepadata) );
    554 assert(sepa != NULL);
    555
    556 /* set non-NULL pointers to callback methods */
    557 SCIP_CALL( SCIPsetSepaCopy(scip, sepa, sepaCopyImpliedbounds) );
    558 SCIP_CALL( SCIPsetSepaFree(scip, sepa, sepaFreeImpliedbounds) );
    559
    560 /* add separator parameters */
    561 SCIP_CALL( SCIPaddBoolParam(scip, "separating/impliedbounds/usetwosizecliques",
    562 "should violated inequalities for cliques with 2 variables be separated?",
    563 &sepadata->usetwosizecliques, TRUE, DEFAULT_USETWOSIZECLIQUES, NULL, NULL) );
    564
    565 return SCIP_OKAY;
    566}
    #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 SCIPgetVarsData(SCIP *scip, SCIP_VAR ***vars, int *nvars, int *nbinvars, int *nintvars, int *nimplvars, int *ncontvars)
    Definition: scip_prob.c:2115
    #define SCIPdebugMsg
    Definition: scip_message.h:78
    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
    SCIP_RETCODE SCIPgetLPBranchCands(SCIP *scip, SCIP_VAR ***lpcands, SCIP_Real **lpcandssol, SCIP_Real **lpcandsfrac, int *nlpcands, int *npriolpcands, int *nfracimplvars)
    Definition: scip_branch.c:402
    SCIP_RETCODE SCIPaddPoolCut(SCIP *scip, SCIP_ROW *row)
    Definition: scip_cut.c:336
    SCIP_Bool SCIPisEfficacious(SCIP *scip, SCIP_Real efficacy)
    Definition: scip_cut.c:135
    #define SCIPallocBufferArray(scip, ptr, num)
    Definition: scip_mem.h:124
    #define SCIPfreeBufferArray(scip, ptr)
    Definition: scip_mem.h:136
    #define SCIPfreeBlockMemory(scip, ptr)
    Definition: scip_mem.h:108
    #define SCIPallocBlockMemory(scip, ptr)
    Definition: scip_mem.h:89
    SCIP_RETCODE SCIPcacheRowExtensions(SCIP *scip, SCIP_ROW *row)
    Definition: scip_lp.c:1581
    SCIP_RETCODE SCIPflushRowExtensions(SCIP *scip, SCIP_ROW *row)
    Definition: scip_lp.c:1604
    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_RETCODE SCIPcreateEmptyRowSepa(SCIP *scip, SCIP_ROW **row, SCIP_SEPA *sepa, const char *name, SCIP_Real lhs, SCIP_Real rhs, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool removable)
    Definition: scip_lp.c:1429
    void SCIProwChgRank(SCIP_ROW *row, int rank)
    Definition: lp.c:17928
    SCIP_RETCODE SCIPincludeSepaBasic(SCIP *scip, SCIP_SEPA **sepa, const char *name, const char *desc, int priority, int freq, SCIP_Real maxbounddist, SCIP_Bool usessubscip, SCIP_Bool delay, SCIP_DECL_SEPAEXECLP((*sepaexeclp)), SCIP_DECL_SEPAEXECSOL((*sepaexecsol)), SCIP_SEPADATA *sepadata)
    Definition: scip_sepa.c:115
    const char * SCIPsepaGetName(SCIP_SEPA *sepa)
    Definition: sepa.c:746
    SCIP_RETCODE SCIPsetSepaFree(SCIP *scip, SCIP_SEPA *sepa, SCIP_DECL_SEPAFREE((*sepafree)))
    Definition: scip_sepa.c:173
    SCIP_SEPADATA * SCIPsepaGetData(SCIP_SEPA *sepa)
    Definition: sepa.c:636
    void SCIPsepaSetData(SCIP_SEPA *sepa, SCIP_SEPADATA *sepadata)
    Definition: sepa.c:646
    SCIP_RETCODE SCIPsetSepaCopy(SCIP *scip, SCIP_SEPA *sepa, SCIP_DECL_SEPACOPY((*sepacopy)))
    Definition: scip_sepa.c:157
    SCIP_RETCODE SCIPgetSolVals(SCIP *scip, SCIP_SOL *sol, int nvars, SCIP_VAR **vars, SCIP_Real *vals)
    Definition: scip_sol.c:1844
    SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
    Definition: scip_sol.c:1763
    SCIP_Longint SCIPgetNLPs(SCIP *scip)
    SCIP_Real SCIPinfinity(SCIP *scip)
    SCIP_Bool SCIPisGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisFeasIntegral(SCIP *scip, SCIP_Real val)
    SCIP_Real SCIPfeastol(SCIP *scip)
    int SCIPvarGetNImpls(SCIP_VAR *var, SCIP_Bool varfixing)
    Definition: var.c:24600
    SCIP_Bool SCIPvarIsImpliedIntegral(SCIP_VAR *var)
    Definition: var.c:23530
    SCIP_CLIQUE ** SCIPgetCliques(SCIP *scip)
    Definition: scip_var.c:9566
    SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
    Definition: var.c:23485
    SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
    Definition: var.c:24174
    SCIP_VAR ** SCIPvarGetImplVars(SCIP_VAR *var, SCIP_Bool varfixing)
    Definition: var.c:24617
    int SCIPvarGetProbindex(SCIP_VAR *var)
    Definition: var.c:23694
    SCIP_RETCODE SCIPcleanupCliques(SCIP *scip, SCIP_Bool *infeasible)
    Definition: scip_var.c:9469
    SCIP_Real * SCIPvarGetImplBounds(SCIP_VAR *var, SCIP_Bool varfixing)
    Definition: var.c:24646
    int SCIPgetNCliques(SCIP *scip)
    Definition: scip_var.c:9512
    SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
    Definition: var.c:24152
    SCIP_RETCODE SCIPgetVarSols(SCIP *scip, int nvars, SCIP_VAR **vars, SCIP_Real *vals)
    Definition: scip_var.c:3071
    SCIP_BOUNDTYPE * SCIPvarGetImplTypes(SCIP_VAR *var, SCIP_Bool varfixing)
    Definition: var.c:24632
    SCIP_RETCODE SCIPincludeSepaImpliedbounds(SCIP *scip)
    int SCIPsnprintf(char *t, int len, const char *s,...)
    Definition: misc.c:10827
    SCIP_VAR ** SCIPcliqueGetVars(SCIP_CLIQUE *clique)
    Definition: implics.c:3384
    int SCIPcliqueGetNVars(SCIP_CLIQUE *clique)
    Definition: implics.c:3374
    SCIP_Bool * SCIPcliqueGetValues(SCIP_CLIQUE *clique)
    Definition: implics.c:3396
    SCIP_Bool SCIPcliqueIsEquation(SCIP_CLIQUE *clique)
    Definition: implics.c:3440
    memory allocation routines
    public methods for implications, variable bounds, and cliques
    public methods for LP management
    public methods for message output
    public data structures and miscellaneous methods
    public methods for separators
    public methods for problem variables
    public methods for branching rule plugins and branching
    public methods for cuts and aggregation rows
    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 separator plugins
    public methods for solutions
    public methods for querying solving statistics
    public methods for SCIP variables
    #define SEPA_PRIORITY
    #define SEPA_DELAY
    #define SEPA_DESC
    #define SEPA_USESSUBSCIP
    static SCIP_RETCODE separateCuts(SCIP *scip, SCIP_SEPA *sepa, SCIP_SOL *sol, SCIP_Real *solvals, SCIP_VAR **fracvars, SCIP_Real *fracvals, int nfracs, SCIP_Bool *cutoff, int *ncuts)
    static SCIP_RETCODE addCut(SCIP *scip, SCIP_SEPA *sepa, SCIP_Real val1, SCIP_VAR *var1, SCIP_Real solval1, SCIP_Real val2, SCIP_VAR *var2, SCIP_Real solval2, SCIP_Real rhs, SCIP_Bool *cutoff, int *ncuts)
    static SCIP_DECL_SEPAFREE(sepaFreeImpliedbounds)
    #define DEFAULT_USETWOSIZECLIQUES
    #define RELCUTCOEFMAXRANGE
    #define SEPA_MAXBOUNDDIST
    #define SEPA_FREQ
    #define SEPA_NAME
    static SCIP_DECL_SEPACOPY(sepaCopyImpliedbounds)
    static SCIP_DECL_SEPAEXECLP(sepaExeclpImpliedbounds)
    static SCIP_DECL_SEPAEXECSOL(sepaExecsolImpliedbounds)
    implied bounds separator
    @ SCIP_BOUNDTYPE_UPPER
    Definition: type_lp.h:58
    @ SCIP_BOUNDTYPE_LOWER
    Definition: type_lp.h:57
    enum SCIP_BoundType SCIP_BOUNDTYPE
    Definition: type_lp.h:60
    @ SCIP_DIDNOTRUN
    Definition: type_result.h:42
    @ SCIP_CUTOFF
    Definition: type_result.h:48
    @ SCIP_DIDNOTFIND
    Definition: type_result.h:44
    @ SCIP_SEPARATED
    Definition: type_result.h:49
    @ SCIP_OKAY
    Definition: type_retcode.h:42
    @ SCIP_INVALIDCALL
    Definition: type_retcode.h:51
    enum SCIP_Retcode SCIP_RETCODE
    Definition: type_retcode.h:63
    struct SCIP_SepaData SCIP_SEPADATA
    Definition: type_sepa.h:52
    @ SCIP_VARTYPE_BINARY
    Definition: type_var.h:64