SCIP

    Solving Constraint Integer Programs

    sepa_closecuts.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_closecuts.c
    26 * @ingroup DEFPLUGINS_SEPA
    27 * @brief closecuts meta separator
    28 * @author Marc Pfetsch
    29 *
    30 * This separator generates a convex combination of the current LP solution and either the best
    31 * primal feasible solution or an interior point of the LP relaxation. If the convex combination is
    32 * proper, the new point is closer to the convex hull of the feasible points. The separator then
    33 * calls all other separators to separate this point. The idea is that in this way possibly "deeper"
    34 * cuts are generated. Note, however, that the new point is not a basic solution, i.e., separators
    35 * relying basis information, e.g., Gomory cuts, will not work.
    36 *
    37 * The other cuts are generated via the sepasol() callbacks in constraints handlers or separators.
    38 *
    39 * This separator stops after a certain number (parameter @p maxunsuccessful) of unsuccessful
    40 * calls. It also inhibits the separation of the ordinary LP solution if it already generated enough
    41 * (parameter @p sepathreshold) cuts. The convex combination is determined via the parameter @p
    42 * sepacombvalue.
    43 *
    44 * In general, this separator makes sense if it is expected that there will be many separation
    45 * rounds and many cuts will be again deleted, because they are not active after a certain number of
    46 * rounds. In particular, branch-and-cut algorithms for combinatorial optimization problems form
    47 * good candidates.
    48 *
    49 * The idea seems to be first proposed in the context of the travelling salesman problem, see@par
    50 * The Traveling Salesman Problem: A Computational Study@n
    51 * David L. Applegate, Robert E. Bixby, Vasek Chvatal & William J. Cook@n
    52 * Princeton University Press 2006@n
    53 *
    54 * for more details. See also@par
    55 * Acceleration of cutting-plane and column generation algorithms: Applications to network design.@n
    56 * Walid Ben-Ameur, Jose Neto@n
    57 * Networks 49(1): 3-17 (2007).
    58 */
    59
    60/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
    61
    62#include "scip/pub_message.h"
    63#include "scip/pub_sepa.h"
    64#include "scip/pub_tree.h"
    65#include "scip/pub_var.h"
    66#include "scip/scip_branch.h"
    67#include "scip/scip_cut.h"
    68#include "scip/scip_general.h"
    69#include "scip/scip_lp.h"
    70#include "scip/scip_mem.h"
    71#include "scip/scip_message.h"
    72#include "scip/scip_numerics.h"
    73#include "scip/scip_param.h"
    74#include "scip/scip_prob.h"
    75#include "scip/scip_sepa.h"
    76#include "scip/scip_sol.h"
    78#include "scip/scip_timing.h"
    79#include "scip/scip_tree.h"
    80#include "scip/sepa_closecuts.h"
    81
    82
    83#define SEPA_NAME "closecuts"
    84#define SEPA_DESC "closecuts meta separator"
    85#define SEPA_PRIORITY 1000000
    86#define SEPA_FREQ -1
    87#define SEPA_MAXBOUNDDIST 1.0
    88#define SEPA_USESSUBSCIP FALSE /**< does the separator use a secondary SCIP instance? */
    89#define SEPA_DELAY FALSE /**< should separation method be delayed, if other separators found cuts? */
    90
    91
    92/* default values for parameters */
    93#define SCIP_DEFAULT_SEPARELINT TRUE /**< generate close cuts w.r.t. relative interior point (best solution otherwise)? */
    94#define SCIP_DEFAULT_SEPACOMBVALUE 0.30 /**< convex combination value for close cuts */
    95#define SCIP_DEFAULT_SEPATHRESHOLD 50 /**< threshold on number of generated cuts below which the ordinary separation is started */
    96#define SCIP_DEFAULT_INCLOBJCUTOFF FALSE /**< include the objective cutoff when computing the relative interior? */
    97#define SCIP_DEFAULT_RECOMPUTERELINT FALSE /**< recompute relative interior in each separation call? */
    98#define SCIP_DEFAULT_MAXUNSUCCESSFUL 0 /**< turn off separation in current node after unsuccessful calls (-1 never turn off) */
    99#define SCIP_DEFAULT_MAXLPITERFACTOR 10.0 /**< factor for maximal LP iterations in relative interior computation compared to node LP iterations */
    100
    101#define SCIP_MIN_LPITERS 100 /**< minimum number of allowed LP iterations in relative interior computation */
    102
    103
    104/** separator data */
    105struct SCIP_SepaData
    106{
    107 SCIP_Bool separelint; /**< generate close cuts w.r.t. relative interior point (best solution otherwise)? */
    108 SCIP_Bool triedRelint; /**< tried to compute relative interior */
    109 SCIP_Real sepacombvalue; /**< convex combination value for close cuts */
    110 int sepathreshold; /**< threshold on number of generated cuts below which the ordinary separation is started */
    111 SCIP_Bool inclobjcutoff; /**< include the objective cutoff when computing the relative interior? */
    112 SCIP_Bool recomputerelint; /**< recompute relative interior in each separation call? */
    113 int maxunsuccessful; /**< turn off separation in current node after unsuccessful calls (-1 never turn off) */
    114 SCIP_SOL* sepasol; /**< solution that can be used for generating close cuts */
    115 SCIP_Longint discardnode; /**< number of node for which separation is discarded */
    116 SCIP_Real maxlpiterfactor; /**< factor for maximal LP iterations in relative interior computation compared to node LP iterations */
    117 int nunsuccessful; /**< number of consecutive unsuccessful calls */
    118};
    119
    120
    121/** generate point for close cut separation
    122 *
    123 * The constructed point is the convex combination of the point stored in set->closesol and the
    124 * current LP solution. The convexity parameter is set->sepa_closecombvalue. If this parameter is
    125 * 0, the point coincides with the LP solution.
    126 */
    127static
    129 SCIP* scip, /**< SCIP data structure */
    130 SCIP_SEPADATA* sepadata, /**< separator data */
    131 SCIP_SOL** point /**< point to be generated (or NULL if unsuccessful) */
    132 )
    133{
    134 SCIP_VAR** vars;
    135 SCIP_VAR* var;
    136 SCIP_Real val;
    137 SCIP_Real alpha;
    138 SCIP_Real onealpha;
    139 SCIP_Real lb;
    140 SCIP_Real ub;
    141 int nvars;
    142 int i;
    143
    144 assert( scip != NULL );
    145 assert( point != NULL );
    146
    147 *point = NULL;
    148 if ( sepadata->sepasol == NULL )
    149 return SCIP_OKAY;
    150
    151 alpha = sepadata->sepacombvalue;
    152 if ( alpha < 0.001 )
    153 return SCIP_OKAY;
    154 onealpha = 1.0 - alpha;
    155
    156 /* create solution */
    157 SCIP_CALL( SCIPcreateSol(scip, point, NULL) );
    158
    159 /* generate convex combination */
    160 vars = SCIPgetVars(scip);
    161 nvars = SCIPgetNVars(scip);
    162 for (i = 0; i < nvars; ++i)
    163 {
    164 var = vars[i];
    165 val = alpha * SCIPgetSolVal(scip, sepadata->sepasol, var) + onealpha * SCIPvarGetLPSol(var);
    166
    167 /* If both the LP relaxation and the base point respect the variable bounds, the computed point will satisfy them
    168 * as well. However, variables might be fixed (e.g. by branching) since the time of the computation of the base
    169 * point. Thus, we adapt the value to lie inside the bounds in optimized mode. */
    170 lb = SCIPvarGetLbLocal(var);
    171 ub = SCIPvarGetUbLocal(var);
    172 val = MAX(val, lb);
    173 val = MIN(val, ub);
    174
    175 if ( ! SCIPisZero(scip, val) )
    176 {
    177 SCIP_CALL( SCIPsetSolVal(scip, *point, var, val) );
    178 }
    179 }
    180
    181 return SCIP_OKAY;
    182}
    183
    184
    185/*
    186 * Callback methods of separator
    187 */
    188
    189
    190/** copy method for separator plugins (called when SCIP copies plugins) */
    191static
    192SCIP_DECL_SEPACOPY(sepaCopyClosecuts)
    193{ /*lint --e{715}*/
    194 assert( scip != NULL );
    195 assert( sepa != NULL );
    196
    198
    199 /* call inclusion method of constraint handler */
    201
    202 return SCIP_OKAY;
    203}
    204
    205/** destructor of separator to free user data (called when SCIP is exiting) */
    206static
    207SCIP_DECL_SEPAFREE(sepaFreeClosecuts)
    208{ /*lint --e{715}*/
    209 SCIP_SEPADATA* sepadata;
    210
    211 assert( sepa != NULL );
    212
    214
    215 /* free separator data */
    216 sepadata = SCIPsepaGetData(sepa);
    217 assert( sepadata != NULL );
    218
    219 SCIPfreeBlockMemory(scip, &sepadata);
    220
    221 SCIPsepaSetData(sepa, NULL);
    222
    223 return SCIP_OKAY;
    224}
    225
    226
    227/** solving process deinitialization method of separator (called before branch and bound process data is freed) */
    228static
    229SCIP_DECL_SEPAEXITSOL(sepaExitsolClosecuts)
    230{ /*lint --e{715}*/
    231 SCIP_SEPADATA* sepadata;
    232
    233 assert( sepa != NULL );
    234
    236
    237 sepadata = SCIPsepaGetData(sepa);
    238 assert( sepadata != NULL );
    239
    240 if ( sepadata->separelint && sepadata->sepasol != NULL )
    241 {
    242 SCIP_CALL( SCIPfreeSol(scip, &sepadata->sepasol) );
    243 sepadata->triedRelint = FALSE;
    244 }
    245 sepadata->discardnode = -1;
    246 sepadata->nunsuccessful = 0;
    247
    248 return SCIP_OKAY;
    249}
    250
    251
    252/** LP solution separation method of separator */
    253static
    254SCIP_DECL_SEPAEXECLP(sepaExeclpClosecuts)
    255{ /*lint --e{715}*/
    256 SCIP_SEPADATA* sepadata;
    257 SCIP_Longint currentnodenumber;
    258 SCIP_SOL* point = NULL;
    259 SCIP_Bool isroot;
    260
    261 assert( sepa != NULL );
    262 assert( result != NULL );
    263
    265
    266 *result = SCIP_DIDNOTRUN;
    267
    268 /* only call separator, if LP has been solved (need LP to compute separation point) */
    270 return SCIP_OKAY;
    271
    272 /* only call separator, if there are fractional variables */
    273 if ( SCIPgetNLPBranchCands(scip) == 0 )
    274 return SCIP_OKAY;
    275
    276 /* exit if we stopped ... */
    277 if ( SCIPisStopped(scip) )
    278 return SCIP_OKAY;
    279
    280 /* get separation data */
    281 sepadata = SCIPsepaGetData(sepa);
    282 assert( sepadata != NULL );
    283
    284 /* exit if we already decided to discard the current node */
    285 currentnodenumber = SCIPnodeGetNumber(SCIPgetCurrentNode(scip));
    286 if ( sepadata->discardnode == currentnodenumber )
    287 return SCIP_OKAY;
    288
    289 SCIPdebugMsg(scip, "Separation method of closecuts separator.\n");
    290
    291 /* check whether we have to compute a relative interior point */
    292 if ( sepadata->separelint )
    293 {
    294 if ( sepadata->recomputerelint )
    295 {
    296 /* check if previous relative interior point should be forgotten, otherwise it is computed only once and the
    297 * same point is used for all nodes */
    298 if ( sepadata->sepasol != NULL )
    299 {
    300 SCIP_CALL( SCIPfreeSol(scip, &sepadata->sepasol) );
    301 sepadata->triedRelint = FALSE;
    302 }
    303 }
    304 else
    305 {
    306 /* skip execution, if we unsuccessfully tried to compute a relative interior point */
    307 if ( sepadata->sepasol == NULL && sepadata->triedRelint )
    308 return SCIP_OKAY;
    309 }
    310
    311 /* if relative interior point is not available ... */
    312 if ( sepadata->sepasol == NULL )
    313 {
    314 SCIP_Longint nlpiters;
    315 SCIP_Real timelimit;
    316 int iterlimit;
    317
    318 /* prepare time limit */
    319 SCIP_CALL( SCIPgetRealParam(scip, "limits/time", &timelimit) );
    320 if ( ! SCIPisInfinity(scip, timelimit) )
    321 timelimit -= SCIPgetSolvingTime(scip);
    322 /* exit if no time left */
    323 if ( timelimit <= 0.0 )
    324 return SCIP_OKAY;
    325
    326 /* determine iteration limit */
    327 if ( sepadata->maxlpiterfactor < 0.0 || SCIPisInfinity(scip, sepadata->maxlpiterfactor) )
    328 iterlimit = INT_MAX;
    329 else
    330 {
    331 /* determine iteration limit; the number of iterations in the root is only set after its solution, but the
    332 * total number of LP iterations is always updated.
    333 * here we use SCIPgetDepth instead of the depth argument passed to the callback because if we are not in
    334 * the root node but depth is 0 (i.e. if we want us to behave as if we are in the root node regarding
    335 * limits) then using the total number of iterations so far is a gross overestimation
    336 */
    337 if ( SCIPgetDepth(scip) == 0 )
    338 nlpiters = SCIPgetNLPIterations(scip);
    339 else
    340 nlpiters = SCIPgetNRootLPIterations(scip);
    341 iterlimit = (int)(sepadata->maxlpiterfactor * nlpiters);
    342 iterlimit = MAX(iterlimit, SCIP_MIN_LPITERS);
    343 assert(iterlimit > 0);
    344 }
    345
    346 SCIPverbMessage(scip, SCIP_VERBLEVEL_MINIMAL, 0, "Computing relative interior point (time limit: %g, iter limit: %d) ...\n", timelimit, iterlimit);
    347 SCIP_CALL( SCIPcomputeLPRelIntPoint(scip, TRUE, sepadata->inclobjcutoff, timelimit, iterlimit, &sepadata->sepasol) );
    348 sepadata->triedRelint = TRUE;
    349 }
    350 }
    351 else
    352 {
    353 /* get best solution (NULL if not present) */
    354 sepadata->sepasol = SCIPgetBestSol(scip);
    355 }
    356
    357 /* separate close cuts */
    358 if ( sepadata->sepasol != NULL )
    359 {
    360 SCIPdebugMsg(scip, "Generating close cuts ... (combination value: %f)\n", sepadata->sepacombvalue);
    361 *result = SCIP_DIDNOTFIND;
    362
    363 /* generate point to be separated */
    364 SCIP_CALL( generateCloseCutPoint(scip, sepadata, &point) );
    365
    366 /* apply a separation round to generated point */
    367 if ( point != NULL )
    368 {
    369 int noldcuts;
    370 SCIP_Bool delayed;
    371 SCIP_Bool cutoff;
    372
    373 noldcuts = SCIPgetNCuts(scip);
    374 isroot = (SCIP_Bool) (depth == 0);
    375
    376 /* separate solution via other separators */
    377 SCIP_CALL( SCIPseparateSol(scip, point, isroot, TRUE, FALSE, &delayed, &cutoff) );
    378
    379 SCIP_CALL( SCIPfreeSol(scip, &point) );
    380 assert( point == NULL );
    381
    382 /* the cuts might not violated by the current LP if the computed point is strange */
    384
    385 if ( cutoff )
    386 *result = SCIP_CUTOFF;
    387 else
    388 {
    389 if ( SCIPgetNCuts(scip) - noldcuts > sepadata->sepathreshold )
    390 {
    391 sepadata->nunsuccessful = 0;
    392 *result = SCIP_NEWROUND;
    393 }
    394 else
    395 {
    396 if ( SCIPgetNCuts(scip) > noldcuts )
    397 {
    398 sepadata->nunsuccessful = 0;
    399 *result = SCIP_SEPARATED;
    400 }
    401 else
    402 ++sepadata->nunsuccessful;
    403 }
    404 }
    405
    406 SCIPdebugMsg(scip, "Separated close cuts: %d (enoughcuts: %d, unsuccessful: %d).\n", SCIPgetNCuts(scip) - noldcuts,
    407 SCIPgetNCuts(scip) - noldcuts > sepadata->sepathreshold, sepadata->nunsuccessful);
    408
    409 if ( sepadata->maxunsuccessful >= 0 && sepadata->nunsuccessful > sepadata->maxunsuccessful )
    410 {
    411 SCIPdebugMsg(scip, "Turn off close cut separation, because of %d unsuccessful calls.\n", sepadata->nunsuccessful);
    412 sepadata->discardnode = currentnodenumber;
    413 sepadata->nunsuccessful = 0;
    414 }
    415 }
    416 }
    417
    418 return SCIP_OKAY;
    419}
    420
    421
    422/*
    423 * separator specific interface methods
    424 */
    425
    426/** creates the closecuts separator and includes it in SCIP */
    428 SCIP* scip /**< SCIP data structure */
    429 )
    430{
    431 SCIP_SEPADATA* sepadata;
    432 SCIP_SEPA* sepa;
    433
    434 /* create closecuts separator data */
    435 SCIP_CALL( SCIPallocBlockMemory(scip, &sepadata) );
    436 sepadata->sepasol = NULL;
    437 sepadata->discardnode = -1;
    438 sepadata->nunsuccessful = 0;
    439 sepadata->triedRelint = FALSE;
    440
    441 /* include separator */
    443 sepaExeclpClosecuts, NULL, sepadata) );
    444
    445 assert(sepa != NULL);
    446
    447 /* set non-NULL pointers to callback methods */
    448 SCIP_CALL( SCIPsetSepaCopy(scip, sepa, sepaCopyClosecuts) );
    449 SCIP_CALL( SCIPsetSepaFree(scip, sepa, sepaFreeClosecuts) );
    450 SCIP_CALL( SCIPsetSepaExitsol(scip, sepa, sepaExitsolClosecuts) );
    451
    452 /* add closecuts separator parameters */
    454 "separating/closecuts/separelint",
    455 "generate close cuts w.r.t. relative interior point (best solution otherwise)?",
    456 &sepadata->separelint, TRUE, SCIP_DEFAULT_SEPARELINT, NULL, NULL) );
    457
    459 "separating/closecuts/sepacombvalue",
    460 "convex combination value for close cuts",
    461 &sepadata->sepacombvalue, TRUE, SCIP_DEFAULT_SEPACOMBVALUE, 0.0, 1.0,
    462 NULL, NULL) );
    463
    465 "separating/closecuts/closethres",
    466 "threshold on number of generated cuts below which the ordinary separation is started",
    467 &sepadata->sepathreshold, TRUE, SCIP_DEFAULT_SEPATHRESHOLD, -1, INT_MAX, NULL, NULL) );
    468
    470 "separating/closecuts/inclobjcutoff",
    471 "include an objective cutoff when computing the relative interior?",
    472 &sepadata->inclobjcutoff, TRUE, SCIP_DEFAULT_INCLOBJCUTOFF, NULL, NULL) );
    473
    475 "separating/closecuts/recomputerelint",
    476 "recompute relative interior point in each separation call?",
    477 &sepadata->recomputerelint, TRUE, SCIP_DEFAULT_RECOMPUTERELINT, NULL, NULL) );
    478
    480 "separating/closecuts/maxunsuccessful",
    481 "turn off separation in current node after unsuccessful calls (-1 never turn off)",
    482 &sepadata->maxunsuccessful, TRUE, SCIP_DEFAULT_MAXUNSUCCESSFUL, -1, INT_MAX, NULL, NULL) );
    483
    485 "separating/closecuts/maxlpiterfactor",
    486 "factor for maximal LP iterations in relative interior computation compared to node LP iterations (negative for no limit)",
    487 &sepadata->maxlpiterfactor, TRUE, SCIP_DEFAULT_MAXLPITERFACTOR, -1.0, SCIP_REAL_MAX, NULL, NULL) );
    488
    489 return SCIP_OKAY;
    490}
    491
    492/** sets point to be used as base point for computing the point to be separated
    493 *
    494 * The point is only stored if separation of relative interior points is used. The solution is copied.
    495 */
    497 SCIP* scip, /**< SCIP data structure */
    498 SCIP_SOL* sol /**< base point solution */
    499 )
    500{
    501 SCIP_SEPA* sepa;
    502 SCIP_SEPADATA* sepadata;
    503
    504 assert( scip != NULL );
    505
    506 /* find separator */
    507 sepa = SCIPfindSepa(scip, SEPA_NAME);
    508 if ( sepa == NULL )
    509 {
    510 SCIPerrorMessage("Could not find separator <%s>.\n", SEPA_NAME);
    511 return SCIP_PLUGINNOTFOUND;
    512 }
    513
    515
    516 /* get sepadata */
    517 sepadata = SCIPsepaGetData(sepa);
    518 assert( sepadata != NULL );
    519
    520 /* store point if we have to separate relative interior points */
    521 if ( sepadata->separelint )
    522 {
    523 /* possibly free solution */
    524 if ( sepadata->sepasol != NULL )
    525 {
    526 SCIP_CALL( SCIPfreeSol(scip, &sepadata->sepasol) );
    527 }
    528
    529 /* copy and store solution */
    530 SCIP_CALL( SCIPcreateSolCopy(scip, &sepadata->sepasol, sol) );
    531 sepadata->triedRelint = TRUE;
    532 }
    533
    534 return SCIP_OKAY;
    535}
    #define NULL
    Definition: def.h:257
    #define SCIP_Longint
    Definition: def.h:150
    #define SCIP_REAL_MAX
    Definition: def.h:167
    #define SCIP_Bool
    Definition: def.h:100
    #define MIN(x, y)
    Definition: def.h:233
    #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 MAX(x, y)
    Definition: def.h:229
    #define SCIP_CALL(x)
    Definition: def.h:364
    SCIP_Bool SCIPisStopped(SCIP *scip)
    Definition: scip_general.c:767
    int SCIPgetNVars(SCIP *scip)
    Definition: scip_prob.c:2246
    SCIP_VAR ** SCIPgetVars(SCIP *scip)
    Definition: scip_prob.c:2201
    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_RETCODE SCIPaddIntParam(SCIP *scip, const char *name, const char *desc, int *valueptr, SCIP_Bool isadvanced, int defaultvalue, int minvalue, int maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
    Definition: scip_param.c:83
    SCIP_RETCODE SCIPaddRealParam(SCIP *scip, const char *name, const char *desc, SCIP_Real *valueptr, SCIP_Bool isadvanced, SCIP_Real defaultvalue, SCIP_Real minvalue, SCIP_Real maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
    Definition: scip_param.c:139
    SCIP_RETCODE SCIPgetRealParam(SCIP *scip, const char *name, SCIP_Real *value)
    Definition: scip_param.c:307
    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
    int SCIPgetNLPBranchCands(SCIP *scip)
    Definition: scip_branch.c:436
    SCIP_RETCODE SCIPseparateSol(SCIP *scip, SCIP_SOL *sol, SCIP_Bool pretendroot, SCIP_Bool allowlocal, SCIP_Bool onlydelayed, SCIP_Bool *delayed, SCIP_Bool *cutoff)
    Definition: scip_cut.c:710
    SCIP_RETCODE SCIPremoveInefficaciousCuts(SCIP *scip)
    Definition: scip_cut.c:798
    int SCIPgetNCuts(SCIP *scip)
    Definition: scip_cut.c:762
    SCIP_RETCODE SCIPcomputeLPRelIntPoint(SCIP *scip, SCIP_Bool relaxrows, SCIP_Bool inclobjcutoff, SCIP_Real timelimit, int iterlimit, SCIP_SOL **point)
    Definition: scip_lp.c:1103
    SCIP_LPSOLSTAT SCIPgetLPSolstat(SCIP *scip)
    Definition: scip_lp.c:174
    #define SCIPfreeBlockMemory(scip, ptr)
    Definition: scip_mem.h:108
    #define SCIPallocBlockMemory(scip, ptr)
    Definition: scip_mem.h:89
    SCIP_Longint SCIPnodeGetNumber(SCIP_NODE *node)
    Definition: tree.c:8513
    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_SEPA * SCIPfindSepa(SCIP *scip, const char *name)
    Definition: scip_sepa.c:253
    SCIP_RETCODE SCIPsetSepaExitsol(SCIP *scip, SCIP_SEPA *sepa, SCIP_DECL_SEPAEXITSOL((*sepaexitsol)))
    Definition: scip_sepa.c:237
    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_SOL * SCIPgetBestSol(SCIP *scip)
    Definition: scip_sol.c:2986
    SCIP_RETCODE SCIPcreateSol(SCIP *scip, SCIP_SOL **sol, SCIP_HEUR *heur)
    Definition: scip_sol.c:514
    SCIP_RETCODE SCIPcreateSolCopy(SCIP *scip, SCIP_SOL **sol, SCIP_SOL *sourcesol)
    Definition: scip_sol.c:882
    SCIP_RETCODE SCIPfreeSol(SCIP *scip, SCIP_SOL **sol)
    Definition: scip_sol.c:1250
    SCIP_RETCODE SCIPsetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var, SCIP_Real val)
    Definition: scip_sol.c:1569
    SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
    Definition: scip_sol.c:1763
    SCIP_Longint SCIPgetNRootLPIterations(SCIP *scip)
    SCIP_Longint SCIPgetNLPIterations(SCIP *scip)
    SCIP_Real SCIPgetSolvingTime(SCIP *scip)
    Definition: scip_timing.c:378
    SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisZero(SCIP *scip, SCIP_Real val)
    int SCIPgetDepth(SCIP *scip)
    Definition: scip_tree.c:672
    SCIP_NODE * SCIPgetCurrentNode(SCIP *scip)
    Definition: scip_tree.c:91
    SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
    Definition: var.c:24300
    SCIP_Real SCIPvarGetLPSol(SCIP_VAR *var)
    Definition: var.c:24696
    SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
    Definition: var.c:24266
    SCIP_RETCODE SCIPsetBasePointClosecuts(SCIP *scip, SCIP_SOL *sol)
    SCIP_RETCODE SCIPincludeSepaClosecuts(SCIP *scip)
    public methods for message output
    #define SCIPerrorMessage
    Definition: pub_message.h:64
    public methods for separators
    public methods for branch and bound tree
    public methods for problem variables
    public methods for branching rule plugins and branching
    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 separator plugins
    public methods for solutions
    public methods for querying solving statistics
    public methods for timing
    public methods for the branch-and-bound tree
    #define SEPA_PRIORITY
    #define SEPA_DELAY
    #define SEPA_DESC
    #define SCIP_DEFAULT_SEPACOMBVALUE
    #define SCIP_DEFAULT_INCLOBJCUTOFF
    #define SCIP_MIN_LPITERS
    #define SEPA_USESSUBSCIP
    #define SCIP_DEFAULT_RECOMPUTERELINT
    #define SCIP_DEFAULT_SEPARELINT
    static SCIP_DECL_SEPACOPY(sepaCopyClosecuts)
    #define SEPA_MAXBOUNDDIST
    #define SCIP_DEFAULT_MAXUNSUCCESSFUL
    #define SEPA_FREQ
    #define SEPA_NAME
    #define SCIP_DEFAULT_MAXLPITERFACTOR
    static SCIP_DECL_SEPAEXECLP(sepaExeclpClosecuts)
    static SCIP_DECL_SEPAEXITSOL(sepaExitsolClosecuts)
    static SCIP_RETCODE generateCloseCutPoint(SCIP *scip, SCIP_SEPADATA *sepadata, SCIP_SOL **point)
    static SCIP_DECL_SEPAFREE(sepaFreeClosecuts)
    #define SCIP_DEFAULT_SEPATHRESHOLD
    closecuts meta separator
    @ SCIP_LPSOLSTAT_OPTIMAL
    Definition: type_lp.h:44
    @ SCIP_VERBLEVEL_MINIMAL
    Definition: type_message.h:59
    @ 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_NEWROUND
    Definition: type_result.h:50
    @ SCIP_PLUGINNOTFOUND
    Definition: type_retcode.h:54
    @ 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