Scippy

    SCIP

    Solving Constraint Integer Programs

    scip_cut.c
    Go to the documentation of this file.
    1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    2/* */
    3/* This file is part of the program and library */
    4/* SCIP --- Solving Constraint Integer Programs */
    5/* */
    6/* Copyright (c) 2002-2025 Zuse Institute Berlin (ZIB) */
    7/* */
    8/* Licensed under the Apache License, Version 2.0 (the "License"); */
    9/* you may not use this file except in compliance with the License. */
    10/* You may obtain a copy of the License at */
    11/* */
    12/* http://www.apache.org/licenses/LICENSE-2.0 */
    13/* */
    14/* Unless required by applicable law or agreed to in writing, software */
    15/* distributed under the License is distributed on an "AS IS" BASIS, */
    16/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
    17/* See the License for the specific language governing permissions and */
    18/* limitations under the License. */
    19/* */
    20/* You should have received a copy of the Apache-2.0 license */
    21/* along with SCIP; see the file LICENSE. If not visit scipopt.org. */
    22/* */
    23/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    24
    25/**@file scip_cut.c
    26 * @ingroup OTHER_CFILES
    27 * @brief public methods for cuts and aggregation rows
    28 * @author Tobias Achterberg
    29 * @author Timo Berthold
    30 * @author Gerald Gamrath
    31 * @author Leona Gottwald
    32 * @author Stefan Heinz
    33 * @author Gregor Hendel
    34 * @author Thorsten Koch
    35 * @author Alexander Martin
    36 * @author Marc Pfetsch
    37 * @author Michael Winkler
    38 * @author Kati Wolter
    39 *
    40 * @todo check all SCIP_STAGE_* switches, and include the new stages TRANSFORMED and INITSOLVE
    41 */
    42
    43/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
    44
    45#include "scip/cutpool.h"
    46#include "scip/debug.h"
    47#include "scip/lp.h"
    48#include "scip/prob.h"
    49#include "scip/pub_cutpool.h"
    50#include "scip/pub_lp.h"
    51#include "scip/pub_message.h"
    52#include "scip/scip_conflict.h"
    53#include "scip/scip_cut.h"
    54#include "scip/scip_numerics.h"
    55#include "scip/scip_tree.h"
    56#include "scip/sepastore.h"
    57#include "scip/set.h"
    58#include "scip/solve.h"
    59#include "scip/struct_lp.h"
    60#include "scip/struct_mem.h"
    61#include "scip/struct_scip.h"
    62#include "scip/struct_set.h"
    63#include "scip/tree.h"
    64
    65/** returns row's cutoff distance in the direction of the given primal solution
    66 *
    67 * @return the cutoff distance of the cut with respect to the LP solution in the direction of the given primal solution
    68 *
    69 * @pre This method can be called if @p scip is in one of the following stages:
    70 * - \ref SCIP_STAGE_SOLVING
    71 */
    73 SCIP* scip, /**< SCIP data structure */
    74 SCIP_SOL* sol, /**< solution to compute direction for cutoff distance; must not be NULL */
    75 SCIP_ROW* cut /**< separated cut */
    76 )
    77{
    78 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetCutLPSolCutoffDistance", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
    79
    80 assert(sol != NULL);
    81
    82 return SCIProwGetLPSolCutoffDistance(cut, scip->set, scip->stat, sol, scip->lp);
    83}
    84
    85/** returns efficacy of the cut with respect to the given primal solution or the current LP solution:
    86 * e = -feasibility/norm
    87 *
    88 * @return the efficacy of the cut with respect to the given primal solution or the current LP solution:
    89 * e = -feasibility/norm
    90 *
    91 * @pre This method can be called if @p scip is in one of the following stages:
    92 * - \ref SCIP_STAGE_SOLVING
    93 */
    95 SCIP* scip, /**< SCIP data structure */
    96 SCIP_SOL* sol, /**< primal CIP solution, or NULL for current LP solution */
    97 SCIP_ROW* cut /**< separated cut */
    98 )
    99{
    101
    102 if( sol == NULL )
    103 return SCIProwGetLPEfficacy(cut, scip->set, scip->stat, scip->lp);
    104 else
    105 return SCIProwGetSolEfficacy(cut, scip->set, scip->stat, sol);
    106}
    107
    108/** returns whether the cut's efficacy with respect to the given primal solution or the current LP solution is greater
    109 * than the minimal cut efficacy
    110 *
    111 * @return TRUE if the cut's efficacy with respect to the given primal solution or the current LP solution is greater
    112 * than the minimal cut efficacy, otherwise FALSE
    113 *
    114 * @pre This method can be called if @p scip is in one of the following stages:
    115 * - \ref SCIP_STAGE_SOLVING
    116 */
    118 SCIP* scip, /**< SCIP data structure */
    119 SCIP_SOL* sol, /**< primal CIP solution, or NULL for current LP solution */
    120 SCIP_ROW* cut /**< separated cut */
    121 )
    122{
    124
    125 if( sol == NULL )
    126 return SCIProwIsLPEfficacious(cut, scip->set, scip->stat, scip->lp, (SCIPtreeGetCurrentDepth(scip->tree) == 0));
    127 else
    128 return SCIProwIsSolEfficacious(cut, scip->set, scip->stat, sol, (SCIPtreeGetCurrentDepth(scip->tree) == 0));
    129}
    130
    131/** checks if the given cut's efficacy is larger than the minimal cut efficacy
    132 *
    133 * @return TRUE if the given cut's efficacy is larger than the minimal cut efficacy, otherwise FALSE
    134 */
    136 SCIP* scip, /**< SCIP data structure */
    137 SCIP_Real efficacy /**< efficacy of the cut */
    138 )
    139{
    140 assert(scip != NULL);
    141
    142 return SCIPsetIsEfficacious(scip->set, (SCIPtreeGetCurrentDepth(scip->tree) == 0), efficacy);
    143}
    144
    145/** calculates the efficacy norm of the given vector, which depends on the "separating/efficacynorm" parameter
    146 *
    147 * @return the efficacy norm of the given vector, which depends on the "separating/efficacynorm" parameter
    148 */
    150 SCIP* scip, /**< SCIP data structure */
    151 SCIP_Real* vals, /**< array of values */
    152 int nvals /**< number of values */
    153 )
    154{
    155 SCIP_Real norm;
    156 int i;
    157
    158 assert(scip != NULL);
    159 assert(scip->set != NULL);
    160
    161 norm = 0.0;
    162 switch( scip->set->sepa_efficacynorm )
    163 {
    164 case 'e':
    165 for( i = 0; i < nvals; ++i )
    166 norm += SQR(vals[i]);
    167 norm = sqrt(norm);
    168 break;
    169 case 'm':
    170 for( i = 0; i < nvals; ++i )
    171 {
    172 SCIP_Real absval;
    173
    174 absval = REALABS(vals[i]);
    175 norm = MAX(norm, absval);
    176 }
    177 break;
    178 case 's':
    179 for( i = 0; i < nvals; ++i )
    180 norm += REALABS(vals[i]);
    181 break;
    182 case 'd':
    183 for( i = 0; i < nvals; ++i )
    184 {
    185 if( !SCIPisZero(scip, vals[i]) )
    186 {
    187 norm = 1.0;
    188 break;
    189 }
    190 }
    191 break;
    192 default:
    193 SCIPerrorMessage("invalid efficacy norm parameter '%c'\n", scip->set->sepa_efficacynorm);
    194 assert(FALSE); /*lint !e506*/
    195 }
    196
    197 return norm;
    198}
    199
    200/** indicates whether a cut is applicable, i.e., will modify the LP when applied
    201 *
    202 * @pre This method can be called if @p scip is in one of the following stages:
    203 * - \ref SCIP_STAGE_SOLVING
    204 *
    205 * @return whether the cut is modifiable, not a bound change, or a bound change that changes bounds by at least epsilon
    206 */
    208 SCIP* scip, /**< SCIP data structure */
    209 SCIP_ROW* cut /**< separated cut */
    210 )
    211{
    213
    214 return SCIPsepastoreIsCutApplicable(scip->set, cut);
    215}
    216
    217/** adds row to separation storage
    218 *
    219 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
    220 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
    221 *
    222 * @pre This method can be called if @p scip is in one of the following stages:
    223 * - \ref SCIP_STAGE_SOLVING
    224 */
    226 SCIP* scip, /**< SCIP data structure */
    227 SCIP_ROW* row, /**< row */
    228 SCIP_Bool forcecut, /**< should the row be forced to enter the LP? */
    229 SCIP_Bool* infeasible /**< pointer to store whether row has been detected to be infeasible for local bounds */
    230 )
    231{
    233
    234 assert(SCIPtreeGetCurrentNode(scip->tree) != NULL);
    235
    236 SCIP_CALL( SCIPsepastoreAddCut(scip->sepastore, scip->mem->probmem, scip->set, scip->stat, scip->eventqueue,
    237 scip->eventfilter, scip->lp, row, forcecut, (SCIPtreeGetCurrentDepth(scip->tree) == 0), infeasible) );
    238
    239 /* possibly run conflict analysis */
    240 if ( *infeasible && SCIPprobAllColsInLP(scip->transprob, scip->set, scip->lp) && SCIPisConflictAnalysisApplicable(scip) )
    241 {
    242 SCIP_Real act;
    243 SCIP_VAR* var;
    244 SCIP_Real val;
    245 int ncols;
    246 int j;
    247
    248 /* initialize conflict analysis */
    250
    251 if ( ! SCIPisInfinity(scip, -row->lhs) )
    252 {
    253 act = SCIProwGetMaxActivity(row, scip->set, scip->stat);
    254 if ( SCIPisLT(scip, act, row->lhs) )
    255 {
    256 ncols = SCIProwGetNNonz(row);
    257 for (j = 0; j < ncols; ++j)
    258 {
    259 val = row->vals[j];
    260 if ( ! SCIPisZero(scip, val) )
    261 {
    262 var = SCIPcolGetVar(row->cols[j]);
    263 assert( var != NULL );
    264
    265 if ( val > 0.0 )
    266 {
    268 }
    269 else
    270 {
    272 }
    273 }
    274 }
    275 }
    276 }
    277 else if ( ! SCIPisInfinity(scip, row->rhs) )
    278 {
    279 act = SCIProwGetMinActivity(row, scip->set, scip->stat);
    280 if ( SCIPisGT(scip, act, row->rhs) )
    281 {
    282 ncols = SCIProwGetNNonz(row);
    283 for (j = 0; j < ncols; ++j)
    284 {
    285 val = row->vals[j];
    286 if ( ! SCIPisZero(scip, val) )
    287 {
    288 var = SCIPcolGetVar(row->cols[j]);
    289 assert( var != NULL );
    290
    291 if ( val > 0.0 )
    292 {
    294 }
    295 else
    296 {
    298 }
    299 }
    300 }
    301 }
    302 }
    303
    304 /* analyze the conflict */
    306 }
    307
    308 return SCIP_OKAY;
    309}
    310
    311/** checks if cut is already existing in global cutpool
    312 *
    313 * @return TRUE is returned if the cut is not already existing in the global cutpool, FALSE otherwise
    314 *
    315 * @pre This method can be called if @p scip is in one of the following stages:
    316 * - \ref SCIP_STAGE_SOLVING
    317 */
    319 SCIP* scip, /**< SCIP data structure */
    320 SCIP_ROW* row /**< cutting plane to add */
    321 )
    322{
    324
    325 return SCIPcutpoolIsCutNew(scip->cutpool, scip->set, row);
    326}
    327
    328/** if not already existing, adds row to global cut pool
    329 *
    330 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
    331 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
    332 *
    333 * @pre This method can be called if @p scip is in one of the following stages:
    334 * - \ref SCIP_STAGE_SOLVING
    335 */
    337 SCIP* scip, /**< SCIP data structure */
    338 SCIP_ROW* row /**< row to remove */
    339 )
    340{
    342
    343 SCIP_CALL( SCIPcutpoolAddRow(scip->cutpool, scip->mem->probmem, scip->set, scip->stat, scip->lp, row) );
    344
    345 return SCIP_OKAY;
    346}
    347
    348/** removes the row from the global cut pool
    349 *
    350 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
    351 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
    352 *
    353 * @pre This method can be called if @p scip is in one of the following stages:
    354 * - \ref SCIP_STAGE_SOLVING
    355 */
    357 SCIP* scip, /**< SCIP data structure */
    358 SCIP_ROW* row /**< cutting plane to add */
    359 )
    360{
    362
    363 SCIP_CALL( SCIPcutpoolDelRow(scip->cutpool, scip->mem->probmem, scip->set, scip->stat, scip->lp, row) );
    364
    365 return SCIP_OKAY;
    366}
    367
    368/** gets current cuts in the global cut pool
    369 *
    370 * @return the current cuts in the global cut pool
    371 *
    372 * @pre This method can be called if @p scip is in one of the following stages:
    373 * - \ref SCIP_STAGE_SOLVING
    374 * - \ref SCIP_STAGE_SOLVED
    375 * - \ref SCIP_STAGE_EXITSOLVE
    376 */
    378 SCIP* scip /**< SCIP data structure */
    379 )
    380{
    382
    383 return SCIPcutpoolGetCuts(scip->cutpool);
    384}
    385
    386/** gets current number of rows in the global cut pool
    387 *
    388 * @return the current number of rows in the global cut pool
    389 *
    390 * @pre This method can be called if @p scip is in one of the following stages:
    391 * - \ref SCIP_STAGE_SOLVING
    392 * - \ref SCIP_STAGE_SOLVED
    393 * - \ref SCIP_STAGE_EXITSOLVE
    394 */
    396 SCIP* scip /**< SCIP data structure */
    397 )
    398{
    400
    401 return SCIPcutpoolGetNCuts(scip->cutpool);
    402}
    403
    404/** gets the global cut pool used by SCIP
    405 *
    406 * @return the global cut pool used by SCIP
    407 *
    408 * @pre This method can be called if @p scip is in one of the following stages:
    409 * - \ref SCIP_STAGE_SOLVING
    410 * - \ref SCIP_STAGE_SOLVED
    411 * - \ref SCIP_STAGE_EXITSOLVE
    412 */
    414 SCIP* scip /**< SCIP data structure */
    415 )
    416{
    418
    419 return scip->cutpool;
    420}
    421
    422/** creates a cut pool
    423 *
    424 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
    425 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
    426 *
    427 * @pre This method can be called if @p scip is in one of the following stages:
    428 * - \ref SCIP_STAGE_TRANSFORMING
    429 * - \ref SCIP_STAGE_TRANSFORMED
    430 * - \ref SCIP_STAGE_INITPRESOLVE
    431 * - \ref SCIP_STAGE_PRESOLVING
    432 * - \ref SCIP_STAGE_EXITPRESOLVE
    433 * - \ref SCIP_STAGE_PRESOLVED
    434 * - \ref SCIP_STAGE_INITSOLVE
    435 * - \ref SCIP_STAGE_SOLVING
    436 */
    438 SCIP* scip, /**< SCIP data structure */
    439 SCIP_CUTPOOL** cutpool, /**< pointer to store cut pool */
    440 int agelimit /**< maximum age a cut can reach before it is deleted from the pool */
    441 )
    442{
    443 SCIP_CALL( SCIPcheckStage(scip, "SCIPcreateCutpool", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
    444
    445 SCIP_CALL( SCIPcutpoolCreate(cutpool, scip->mem->probmem, scip->set, agelimit, FALSE) );
    446
    447 return SCIP_OKAY;
    448}
    449
    450/** frees a cut pool
    451 *
    452 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
    453 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
    454 *
    455 * @pre This method can be called if @p scip is in one of the following stages:
    456 * - \ref SCIP_STAGE_TRANSFORMING
    457 * - \ref SCIP_STAGE_TRANSFORMED
    458 * - \ref SCIP_STAGE_INITPRESOLVE
    459 * - \ref SCIP_STAGE_PRESOLVING
    460 * - \ref SCIP_STAGE_EXITPRESOLVE
    461 * - \ref SCIP_STAGE_PRESOLVED
    462 * - \ref SCIP_STAGE_INITSOLVE
    463 * - \ref SCIP_STAGE_SOLVING
    464 * - \ref SCIP_STAGE_SOLVED
    465 * - \ref SCIP_STAGE_EXITSOLVE
    466 * - \ref SCIP_STAGE_FREETRANS
    467 */
    469 SCIP* scip, /**< SCIP data structure */
    470 SCIP_CUTPOOL** cutpool /**< pointer to store cut pool */
    471 )
    472{
    473 SCIP_CALL( SCIPcheckStage(scip, "SCIPfreeCutpool", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) );
    474
    475 SCIP_CALL( SCIPcutpoolFree(cutpool, scip->mem->probmem, scip->set, scip->lp) );
    476
    477 return SCIP_OKAY;
    478}
    479
    480/** if not already existing, adds row to a cut pool and captures it
    481 *
    482 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
    483 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
    484 *
    485 * @pre This method can be called if @p scip is in one of the following stages:
    486 * - \ref SCIP_STAGE_INITSOLVE
    487 * - \ref SCIP_STAGE_SOLVING
    488 */
    490 SCIP* scip, /**< SCIP data structure */
    491 SCIP_CUTPOOL* cutpool, /**< cut pool */
    492 SCIP_ROW* row /**< cutting plane to add */
    493 )
    494{
    496
    497 SCIP_CALL( SCIPcutpoolAddRow(cutpool, scip->mem->probmem, scip->set, scip->stat, scip->lp, row) );
    498
    499 return SCIP_OKAY;
    500}
    501
    502/** adds row to a cut pool and captures it; doesn't check for multiple cuts
    503 *
    504 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
    505 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
    506 *
    507 * @pre This method can be called if @p scip is in one of the following stages:
    508 * - \ref SCIP_STAGE_INITSOLVE
    509 * - \ref SCIP_STAGE_SOLVING
    510 */
    512 SCIP* scip, /**< SCIP data structure */
    513 SCIP_CUTPOOL* cutpool, /**< cut pool */
    514 SCIP_ROW* row /**< cutting plane to add */
    515 )
    516{
    517 SCIP_CALL( SCIPcheckStage(scip, "SCIPaddNewRowCutpool", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
    518
    519 SCIP_CALL( SCIPcutpoolAddNewRow(cutpool, scip->mem->probmem, scip->set, scip->stat, scip->lp, row) );
    520
    521 return SCIP_OKAY;
    522}
    523
    524/** removes the LP row from a cut pool
    525 *
    526 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
    527 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
    528 *
    529 * @pre This method can be called if @p scip is in one of the following stages:
    530 * - \ref SCIP_STAGE_INITSOLVE
    531 * - \ref SCIP_STAGE_SOLVING
    532 * - \ref SCIP_STAGE_SOLVED
    533 */
    535 SCIP* scip, /**< SCIP data structure */
    536 SCIP_CUTPOOL* cutpool, /**< cut pool */
    537 SCIP_ROW* row /**< row to remove */
    538 )
    539{
    541
    542 SCIP_CALL( SCIPcutpoolDelRow(cutpool, scip->mem->probmem, scip->set, scip->stat, scip->lp, row) );
    543
    544 return SCIP_OKAY;
    545}
    546
    547/** separates cuts from a cut pool
    548 *
    549 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
    550 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
    551 *
    552 * @pre This method can be called if @p scip is in one of the following stages:
    553 * - \ref SCIP_STAGE_SOLVING
    554 */
    556 SCIP* scip, /**< SCIP data structure */
    557 SCIP_CUTPOOL* cutpool, /**< cut pool */
    558 SCIP_RESULT* result /**< pointer to store the result of the separation call */
    559 )
    560{
    562
    563 assert(SCIPtreeGetCurrentNode(scip->tree) != NULL);
    564
    565 if( !SCIPtreeHasCurrentNodeLP(scip->tree) )
    566 {
    567 SCIPerrorMessage("cannot add cuts, because node LP is not processed\n");
    568 return SCIP_INVALIDCALL;
    569 }
    570
    571 SCIP_CALL( SCIPcutpoolSeparate(cutpool, scip->mem->probmem, scip->set, scip->stat, scip->eventqueue, scip->eventfilter,
    572 scip->lp, scip->sepastore, NULL, FALSE, (SCIPtreeGetCurrentDepth(scip->tree) == 0), result) );
    573
    574 return SCIP_OKAY;
    575}
    576
    577/** separates cuts w.r.t. given solution from a cut pool
    578 *
    579 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
    580 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
    581 *
    582 * @pre This method can be called if @p scip is in one of the following stages:
    583 * - \ref SCIP_STAGE_SOLVING
    584 */
    586 SCIP* scip, /**< SCIP data structure */
    587 SCIP_CUTPOOL* cutpool, /**< cut pool */
    588 SCIP_SOL* sol, /**< solution to be separated */
    589 SCIP_Bool pretendroot, /**< should the cut separators be called as if we are at the root node? */
    590 SCIP_RESULT* result /**< pointer to store the result of the separation call */
    591 )
    592{
    593 SCIP_CALL( SCIPcheckStage(scip, "SCIPseparateSolCutpool", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
    594
    595 assert(SCIPtreeGetCurrentNode(scip->tree) != NULL);
    596
    597 if( !SCIPtreeHasCurrentNodeLP(scip->tree) )
    598 {
    599 SCIPerrorMessage("cannot add cuts, because node LP is not processed\n");
    600 return SCIP_INVALIDCALL;
    601 }
    602
    603 SCIP_CALL( SCIPcutpoolSeparate(cutpool, scip->mem->probmem, scip->set, scip->stat, scip->eventqueue, scip->eventfilter,
    604 scip->lp, scip->sepastore, sol, FALSE, pretendroot, result) );
    605
    606 return SCIP_OKAY;
    607}
    608
    609/** if not already existing, adds row to delayed global cut pool
    610 *
    611 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
    612 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
    613 *
    614 * @pre This method can be called if @p scip is the stages \ref SCIP_STAGE_SOLVING
    615 */
    617 SCIP* scip, /**< SCIP data structure */
    618 SCIP_ROW* row /**< cutting plane to add */
    619 )
    620{
    621 SCIP_CALL( SCIPcheckStage(scip, "SCIPaddDelayedPoolCut", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
    622
    623 SCIP_CALL( SCIPcutpoolAddRow(scip->delayedcutpool, scip->mem->probmem, scip->set, scip->stat, scip->lp, row) );
    624
    625 return SCIP_OKAY;
    626}
    627
    628/** removes the row from the delayed global cut pool
    629 *
    630 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
    631 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
    632 *
    633 * @pre This method can be called if @p scip is the stages \ref SCIP_STAGE_SOLVING
    634 */
    636 SCIP* scip, /**< SCIP data structure */
    637 SCIP_ROW* row /**< cutting plane to add */
    638 )
    639{
    640 SCIP_CALL( SCIPcheckStage(scip, "SCIPdelDelayedPoolCut", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
    641
    642 SCIP_CALL( SCIPcutpoolDelRow(scip->delayedcutpool, scip->mem->probmem, scip->set, scip->stat, scip->lp, row) );
    643
    644 return SCIP_OKAY;
    645}
    646
    647/** gets current cuts in the delayed global cut pool
    648 *
    649 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
    650 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
    651 *
    652 * @pre This method can be called if @p scip is the stages \ref SCIP_STAGE_SOLVING
    653 */
    655 SCIP* scip /**< SCIP data structure */
    656 )
    657{
    659
    660 return SCIPcutpoolGetCuts(scip->delayedcutpool);
    661}
    662
    663/** gets current number of rows in the delayed global cut pool
    664 *
    665 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
    666 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
    667 *
    668 * @pre This method can be called if @p scip is the stages \ref SCIP_STAGE_SOLVING
    669 */
    671 SCIP* scip /**< SCIP data structure */
    672 )
    673{
    674 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNDelayedPoolCuts", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE) );
    675
    676 return SCIPcutpoolGetNCuts(scip->delayedcutpool);
    677}
    678
    679/** gets the delayed global cut pool used by SCIP
    680 *
    681 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
    682 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
    683 *
    684 * @pre This method can be called if @p scip is the stages \ref SCIP_STAGE_SOLVING
    685 */
    687 SCIP* scip /**< SCIP data structure */
    688 )
    689{
    690 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetDelayedGlobalCutpool", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE) );
    691
    692 return scip->delayedcutpool;
    693}
    694
    695/** separates the given primal solution or the current LP solution by calling the separators and constraint handlers'
    696 * separation methods;
    697 * the generated cuts are stored in the separation storage and can be accessed with the methods SCIPgetCuts() and
    698 * SCIPgetNCuts();
    699 * after evaluating the cuts, you have to call SCIPclearCuts() in order to remove the cuts from the
    700 * separation storage;
    701 * it is possible to call SCIPseparateSol() multiple times with different solutions and evaluate the found cuts
    702 * afterwards
    703 *
    704 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
    705 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
    706 *
    707 * @pre This method can be called if @p scip is in one of the following stages:
    708 * - \ref SCIP_STAGE_SOLVING
    709 */
    711 SCIP* scip, /**< SCIP data structure */
    712 SCIP_SOL* sol, /**< primal solution that should be separated, or NULL for LP solution */
    713 SCIP_Bool pretendroot, /**< should the cut separators be called as if we are at the root node? */
    714 SCIP_Bool allowlocal, /**< should the separator be asked to separate local cuts */
    715 SCIP_Bool onlydelayed, /**< should only separators be called that were delayed in the previous round? */
    716 SCIP_Bool* delayed, /**< pointer to store whether a separator was delayed */
    717 SCIP_Bool* cutoff /**< pointer to store whether the node can be cut off */
    718 )
    719{
    720 int actdepth;
    721
    723
    724 /* get current depth */
    725 actdepth = (pretendroot ? 0 : SCIPtreeGetCurrentDepth(scip->tree));
    726
    727 /* apply separation round */
    728 SCIP_CALL( SCIPseparationRound(scip->mem->probmem, scip->set, scip->messagehdlr, scip->stat, scip->eventqueue,
    729 scip->eventfilter, scip->transprob, scip->primal, scip->tree, scip->lp, scip->sepastore,
    730 sol, actdepth, allowlocal, onlydelayed, delayed, cutoff) );
    731
    732 return SCIP_OKAY;
    733}
    734
    735/** gets the array of cuts currently stored in the separation storage
    736 *
    737 * @return the array of cuts currently stored in the separation storage
    738 *
    739 * @pre This method can be called if @p scip is in one of the following stages:
    740 * - \ref SCIP_STAGE_PRESOLVED
    741 * - \ref SCIP_STAGE_SOLVING
    742 * - \ref SCIP_STAGE_SOLVED
    743 */
    745 SCIP* scip /**< SCIP data structure */
    746 )
    747{
    749
    750 return SCIPsepastoreGetCuts(scip->sepastore);
    751}
    752
    753/** get current number of cuts in the separation storage
    754 *
    755 * @return the current number of cuts in the separation storage
    756 *
    757 * @pre This method can be called if @p scip is in one of the following stages:
    758 * - \ref SCIP_STAGE_PRESOLVED
    759 * - \ref SCIP_STAGE_SOLVING
    760 * - \ref SCIP_STAGE_SOLVED
    761 */
    763 SCIP* scip /**< SCIP data structure */
    764 )
    765{
    767
    768 return SCIPsepastoreGetNCuts(scip->sepastore);
    769}
    770
    771/** clears the separation storage
    772 *
    773 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
    774 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
    775 *
    776 * @pre This method can be called if @p scip is in one of the following stages:
    777 * - \ref SCIP_STAGE_SOLVING
    778 */
    780 SCIP* scip /**< SCIP data structure */
    781 )
    782{
    784
    785 SCIP_CALL( SCIPsepastoreClearCuts(scip->sepastore, scip->mem->probmem, scip->set, scip->eventqueue, scip->eventfilter, scip->lp) );
    786
    787 return SCIP_OKAY;
    788}
    789
    790/** removes cuts that are inefficacious w.r.t. the current LP solution from separation storage without adding the cuts to the LP
    791 *
    792 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
    793 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
    794 *
    795 * @pre This method can be called if @p scip is in one of the following stages:
    796 * - \ref SCIP_STAGE_SOLVING
    797 */
    799 SCIP* scip /**< SCIP data structure */
    800 )
    801{
    802 SCIP_Bool isroot = FALSE;
    803
    804 SCIP_CALL( SCIPcheckStage(scip, "SCIPremoveInefficaciousCuts", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) );
    805
    806 if( SCIPtreeGetCurrentDepth(scip->tree) == 0 )
    807 isroot = TRUE;
    808
    809 SCIP_CALL( SCIPsepastoreRemoveInefficaciousCuts(scip->sepastore, scip->mem->probmem, scip->set, scip->stat,
    810 scip->eventqueue, scip->eventfilter, scip->lp, isroot, SCIP_EFFICIACYCHOICE_LP) );
    811
    812 return SCIP_OKAY;
    813}
    SCIP_RETCODE SCIPcutpoolSeparate(SCIP_CUTPOOL *cutpool, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_LP *lp, SCIP_SEPASTORE *sepastore, SCIP_SOL *sol, SCIP_Bool cutpoolisdelayed, SCIP_Bool root, SCIP_RESULT *result)
    Definition: cutpool.c:827
    SCIP_RETCODE SCIPcutpoolDelRow(SCIP_CUTPOOL *cutpool, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp, SCIP_ROW *row)
    Definition: cutpool.c:798
    SCIP_RETCODE SCIPcutpoolCreate(SCIP_CUTPOOL **cutpool, BMS_BLKMEM *blkmem, SCIP_SET *set, int agelimit, SCIP_Bool globalcutpool)
    Definition: cutpool.c:427
    SCIP_RETCODE SCIPcutpoolAddRow(SCIP_CUTPOOL *cutpool, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp, SCIP_ROW *row)
    Definition: cutpool.c:656
    SCIP_RETCODE SCIPcutpoolAddNewRow(SCIP_CUTPOOL *cutpool, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp, SCIP_ROW *row)
    Definition: cutpool.c:729
    SCIP_RETCODE SCIPcutpoolFree(SCIP_CUTPOOL **cutpool, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_LP *lp)
    Definition: cutpool.c:468
    SCIP_Bool SCIPcutpoolIsCutNew(SCIP_CUTPOOL *cutpool, SCIP_SET *set, SCIP_ROW *row)
    Definition: cutpool.c:593
    internal methods for storing cuts in a cut pool
    methods for debugging
    #define SCIPcheckStage(scip, method, init, problem, transforming, transformed, initpresolve, presolving, exitpresolve, presolved, initsolve, solving, solved, exitsolve, freetrans, freescip)
    Definition: debug.h:364
    #define NULL
    Definition: def.h:248
    #define SCIP_Bool
    Definition: def.h:91
    #define SCIP_Real
    Definition: def.h:156
    #define SQR(x)
    Definition: def.h:199
    #define TRUE
    Definition: def.h:93
    #define FALSE
    Definition: def.h:94
    #define MAX(x, y)
    Definition: def.h:220
    #define SCIP_CALL_ABORT(x)
    Definition: def.h:334
    #define REALABS(x)
    Definition: def.h:182
    #define SCIP_CALL(x)
    Definition: def.h:355
    SCIP_VAR * SCIPcolGetVar(SCIP_COL *col)
    Definition: lp.c:17425
    SCIP_RETCODE SCIPaddConflictLb(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx)
    SCIP_RETCODE SCIPinitConflictAnalysis(SCIP *scip, SCIP_CONFTYPE conftype, SCIP_Bool iscutoffinvolved)
    SCIP_RETCODE SCIPaddConflictUb(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx)
    SCIP_RETCODE SCIPanalyzeConflict(SCIP *scip, int validdepth, SCIP_Bool *success)
    SCIP_Bool SCIPisConflictAnalysisApplicable(SCIP *scip)
    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 SCIPaddPoolCut(SCIP *scip, SCIP_ROW *row)
    Definition: scip_cut.c:336
    SCIP_Real SCIPgetCutEfficacy(SCIP *scip, SCIP_SOL *sol, SCIP_ROW *cut)
    Definition: scip_cut.c:94
    SCIP_CUT ** SCIPcutpoolGetCuts(SCIP_CUTPOOL *cutpool)
    Definition: cutpool.c:1067
    SCIP_RETCODE SCIPdelDelayedPoolCut(SCIP *scip, SCIP_ROW *row)
    Definition: scip_cut.c:635
    SCIP_Real SCIPgetCutLPSolCutoffDistance(SCIP *scip, SCIP_SOL *sol, SCIP_ROW *cut)
    Definition: scip_cut.c:72
    SCIP_RETCODE SCIPdelRowCutpool(SCIP *scip, SCIP_CUTPOOL *cutpool, SCIP_ROW *row)
    Definition: scip_cut.c:534
    SCIP_RETCODE SCIPremoveInefficaciousCuts(SCIP *scip)
    Definition: scip_cut.c:798
    SCIP_RETCODE SCIPseparateCutpool(SCIP *scip, SCIP_CUTPOOL *cutpool, SCIP_RESULT *result)
    Definition: scip_cut.c:555
    SCIP_CUT ** SCIPgetDelayedPoolCuts(SCIP *scip)
    Definition: scip_cut.c:654
    SCIP_RETCODE SCIPaddRowCutpool(SCIP *scip, SCIP_CUTPOOL *cutpool, SCIP_ROW *row)
    Definition: scip_cut.c:489
    SCIP_Bool SCIPisCutNew(SCIP *scip, SCIP_ROW *row)
    Definition: scip_cut.c:318
    SCIP_Bool SCIPisCutEfficacious(SCIP *scip, SCIP_SOL *sol, SCIP_ROW *cut)
    Definition: scip_cut.c:117
    SCIP_CUTPOOL * SCIPgetGlobalCutpool(SCIP *scip)
    Definition: scip_cut.c:413
    SCIP_RETCODE SCIPseparateSolCutpool(SCIP *scip, SCIP_CUTPOOL *cutpool, SCIP_SOL *sol, SCIP_Bool pretendroot, SCIP_RESULT *result)
    Definition: scip_cut.c:585
    SCIP_Bool SCIPisEfficacious(SCIP *scip, SCIP_Real efficacy)
    Definition: scip_cut.c:135
    SCIP_Bool SCIPisCutApplicable(SCIP *scip, SCIP_ROW *cut)
    Definition: scip_cut.c:207
    SCIP_CUTPOOL * SCIPgetDelayedGlobalCutpool(SCIP *scip)
    Definition: scip_cut.c:686
    SCIP_RETCODE SCIPaddRow(SCIP *scip, SCIP_ROW *row, SCIP_Bool forcecut, SCIP_Bool *infeasible)
    Definition: scip_cut.c:225
    int SCIPgetNPoolCuts(SCIP *scip)
    Definition: scip_cut.c:395
    int SCIPcutpoolGetNCuts(SCIP_CUTPOOL *cutpool)
    Definition: cutpool.c:1077
    SCIP_ROW ** SCIPgetCuts(SCIP *scip)
    Definition: scip_cut.c:744
    SCIP_CUT ** SCIPgetPoolCuts(SCIP *scip)
    Definition: scip_cut.c:377
    SCIP_RETCODE SCIPclearCuts(SCIP *scip)
    Definition: scip_cut.c:779
    SCIP_RETCODE SCIPcreateCutpool(SCIP *scip, SCIP_CUTPOOL **cutpool, int agelimit)
    Definition: scip_cut.c:437
    SCIP_Real SCIPgetVectorEfficacyNorm(SCIP *scip, SCIP_Real *vals, int nvals)
    Definition: scip_cut.c:149
    int SCIPgetNDelayedPoolCuts(SCIP *scip)
    Definition: scip_cut.c:670
    int SCIPgetNCuts(SCIP *scip)
    Definition: scip_cut.c:762
    SCIP_RETCODE SCIPdelPoolCut(SCIP *scip, SCIP_ROW *row)
    Definition: scip_cut.c:356
    SCIP_RETCODE SCIPfreeCutpool(SCIP *scip, SCIP_CUTPOOL **cutpool)
    Definition: scip_cut.c:468
    SCIP_RETCODE SCIPaddNewRowCutpool(SCIP *scip, SCIP_CUTPOOL *cutpool, SCIP_ROW *row)
    Definition: scip_cut.c:511
    SCIP_RETCODE SCIPaddDelayedPoolCut(SCIP *scip, SCIP_ROW *row)
    Definition: scip_cut.c:616
    int SCIProwGetNNonz(SCIP_ROW *row)
    Definition: lp.c:17607
    SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisZero(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    int SCIPgetDepth(SCIP *scip)
    Definition: scip_tree.c:672
    SCIP_Real SCIProwGetMaxActivity(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
    Definition: lp.c:6849
    SCIP_Bool SCIProwIsLPEfficacious(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp, SCIP_Bool root)
    Definition: lp.c:7095
    SCIP_Real SCIProwGetSolEfficacy(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_SOL *sol)
    Definition: lp.c:7111
    SCIP_Real SCIProwGetLPSolCutoffDistance(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_SOL *sol, SCIP_LP *lp)
    Definition: lp.c:6997
    SCIP_Real SCIProwGetLPEfficacy(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp)
    Definition: lp.c:7054
    SCIP_Bool SCIProwIsSolEfficacious(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_SOL *sol, SCIP_Bool root)
    Definition: lp.c:7154
    SCIP_Real SCIProwGetMinActivity(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat)
    Definition: lp.c:6828
    internal methods for LP management
    SCIP_Bool SCIPprobAllColsInLP(SCIP_PROB *prob, SCIP_SET *set, SCIP_LP *lp)
    Definition: prob.c:2825
    internal methods for storing and manipulating the main problem
    public methods for storing cuts in a cut pool
    public methods for LP management
    public methods for message output
    #define SCIPerrorMessage
    Definition: pub_message.h:64
    public methods for conflict handler plugins and conflict analysis
    public methods for cuts and aggregation rows
    public methods for numerical tolerances
    public methods for the branch-and-bound tree
    SCIP_RETCODE SCIPsepastoreClearCuts(SCIP_SEPASTORE *sepastore, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_LP *lp)
    Definition: sepastore.c:1061
    int SCIPsepastoreGetNCuts(SCIP_SEPASTORE *sepastore)
    Definition: sepastore.c:1183
    SCIP_RETCODE SCIPsepastoreAddCut(SCIP_SEPASTORE *sepastore, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_LP *lp, SCIP_ROW *cut, SCIP_Bool forcecut, SCIP_Bool root, SCIP_Bool *infeasible)
    Definition: sepastore.c:439
    SCIP_RETCODE SCIPsepastoreRemoveInefficaciousCuts(SCIP_SEPASTORE *sepastore, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_LP *lp, SCIP_Bool root, SCIP_EFFICIACYCHOICE efficiacychoice)
    Definition: sepastore.c:1107
    SCIP_ROW ** SCIPsepastoreGetCuts(SCIP_SEPASTORE *sepastore)
    Definition: sepastore.c:1173
    SCIP_Bool SCIPsepastoreIsCutApplicable(SCIP_SET *set, SCIP_ROW *cut)
    Definition: sepastore.c:1164
    internal methods for storing separated cuts
    SCIP_Bool SCIPsetIsEfficacious(SCIP_SET *set, SCIP_Bool root, SCIP_Real efficacy)
    Definition: set.c:7447
    internal methods for global SCIP settings
    SCIP_RETCODE SCIPseparationRound(BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_PROB *prob, SCIP_PRIMAL *primal, SCIP_TREE *tree, SCIP_LP *lp, SCIP_SEPASTORE *sepastore, SCIP_SOL *sol, int actdepth, SCIP_Bool allowlocal, SCIP_Bool onlydelayed, SCIP_Bool *delayed, SCIP_Bool *cutoff)
    Definition: solve.c:2158
    internal methods for main solving loop and node processing
    SCIP_Real rhs
    Definition: struct_lp.h:208
    SCIP_Real * vals
    Definition: struct_lp.h:232
    SCIP_Real lhs
    Definition: struct_lp.h:207
    SCIP_COL ** cols
    Definition: struct_lp.h:230
    data structures for LP management
    datastructures for block memory pools and memory buffers
    SCIP main data structure.
    datastructures for global SCIP settings
    SCIP_NODE * SCIPtreeGetCurrentNode(SCIP_TREE *tree)
    Definition: tree.c:9462
    SCIP_Bool SCIPtreeHasCurrentNodeLP(SCIP_TREE *tree)
    Definition: tree.c:9496
    int SCIPtreeGetCurrentDepth(SCIP_TREE *tree)
    Definition: tree.c:9479
    internal methods for branch and bound tree
    @ SCIP_CONFTYPE_PROPAGATION
    Definition: type_conflict.h:62
    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_EFFICIACYCHOICE_LP