Scippy

    SCIP

    Solving Constraint Integer Programs

    cutpool.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 cutpool.c
    26 * @ingroup OTHER_CFILES
    27 * @brief methods for storing cuts in a cut pool
    28 * @author Tobias Achterberg
    29 * @author Stefan Heinz
    30 * @author Gerald Gamrath
    31 * @author Marc Pfetsch
    32 * @author Kati Wolter
    33 */
    34
    35/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
    36
    37#include <assert.h>
    38
    39#include "scip/def.h"
    40#include "scip/set.h"
    41#include "scip/stat.h"
    42#include "scip/clock.h"
    43#include "scip/lp.h"
    44#include "scip/cons.h"
    45#include "scip/sepa.h"
    46#include "scip/sepastore.h"
    47#include "scip/cutpool.h"
    48#include "scip/pub_message.h"
    49#include "scip/pub_misc.h"
    50
    51#include "scip/struct_cutpool.h"
    52
    53
    54
    55/*
    56 * Hash functions
    57 */
    58
    59/** gets the hash key of a cut */
    60static
    62{ /*lint --e{715}*/
    63 SCIP_CUT* cut;
    64
    65 cut = (SCIP_CUT*)elem;
    66 assert(cut != NULL);
    67 assert(cut->row != NULL);
    68
    69 /* the key of a cut is the row */
    70 return cut->row;
    71}
    72
    73/** returns TRUE iff both cuts are identical */
    74static
    76{ /*lint --e{715}*/
    77 SCIP_ROW* row1;
    78 SCIP_ROW* row2;
    79 SCIP_Real row1scale;
    80 SCIP_Real row2scale;
    82
    83 row1 = (SCIP_ROW*)key1;
    84 row2 = (SCIP_ROW*)key2;
    85 assert(row1 != NULL);
    86 assert(row2 != NULL);
    87
    88 /* return true if the row is the same */
    89 if( row1 == row2 )
    90 return TRUE;
    91
    92 assert(row1->validminmaxidx);
    93 assert(row2->validminmaxidx);
    94
    95 /* compare the trivial characteristics of the rows */
    96 if( row1->len != row2->len
    97 || row1->minidx != row2->minidx
    98 || row1->maxidx != row2->maxidx
    99 )
    100 return FALSE;
    101
    102 set = (SCIP_SET*) userptr;
    103
    104 /* set scale for the rows such that the largest absolute coefficient is 1.0 */
    105 row1scale = 1.0 / SCIProwGetMaxval(row1, set);
    106 row2scale = 1.0 / SCIProwGetMaxval(row2, set);
    107
    108 /* check if scaled min value is feas equal first */
    109 if( !SCIPsetIsFeasEQ(set, row1scale * SCIProwGetMinval(row1, set),
    110 row2scale * SCIProwGetMinval(row2, set)) )
    111 return FALSE;
    112
    113 SCIProwSort(row1);
    114 assert(row1->lpcolssorted);
    115 assert(row1->nonlpcolssorted);
    116
    117 SCIProwSort(row2);
    118 assert(row2->lpcolssorted);
    119 assert(row2->nonlpcolssorted);
    120
    121 /* currently we are only handling rows which are completely linked or not linked at all */
    122 assert(row1->nunlinked == 0 || row1->nlpcols == 0);
    123 assert(row2->nunlinked == 0 || row2->nlpcols == 0);
    124
    125 /* set scale sign such that the rows are of the form ax <= b */
    126 if( SCIPsetIsInfinity(set, row1->rhs) )
    127 row1scale = -row1scale;
    128 if( SCIPsetIsInfinity(set, row2->rhs) )
    129 row2scale = -row2scale;
    130
    131 /* both rows have LP columns, or none of them has, or one has only LP colums and the other only non-LP columns,
    132 * so we can rely on the sorting of the columns
    133 */
    134 if( (row1->nlpcols == 0) == (row2->nlpcols == 0)
    135 || (row1->nlpcols == 0 && row2->nlpcols == row2->len)
    136 || (row1->nlpcols == row1->len && row2->nlpcols == 0) )
    137 {
    138 int i;
    139
    140 if( (row1->nlpcols == 0) == (row2->nlpcols == 0) )
    141 {
    142#ifndef NDEBUG
    143 /* in debug mode, we check that we can rely on the partition into LP columns and non-LP columns */
    144 int i2;
    145
    146 i = 0;
    147 i2 = row2->nlpcols;
    148 while( i < row1->nlpcols && i2 < row2->len )
    149 {
    150 assert(row1->cols[i] != row2->cols[i2]);
    151 if( row1->cols_index[i] < row2->cols_index[i2] )
    152 ++i;
    153 else
    154 {
    155 assert(row1->cols_index[i] > row2->cols_index[i2]);
    156 ++i2;
    157 }
    158 }
    159 assert(i == row1->nlpcols || i2 == row2->len);
    160
    161 i = row1->nlpcols;
    162 i2 = 0;
    163 while( i < row1->len && i2 < row2->nlpcols )
    164 {
    165 assert(row1->cols[i] != row2->cols[i2]);
    166 if( row1->cols_index[i] < row2->cols_index[i2] )
    167 ++i;
    168 else
    169 {
    170 assert(row1->cols_index[i] > row2->cols_index[i2]);
    171 ++i2;
    172 }
    173 }
    174 assert(i == row1->len || i2 == row2->nlpcols);
    175#endif
    176
    177 /* both rows are linked and the number of lpcolumns is not equal so they cannot be equal */
    178 if( row1->nlpcols != row2->nlpcols )
    179 return FALSE;
    180 }
    181
    182 /* compare the columns of the rows */
    183 for( i = 0; i < row1->len; ++i )
    184 {
    185 if( row1->cols_index[i] != row2->cols_index[i] )
    186 return FALSE;
    187 }
    188
    189 /* compare the coefficients of the rows */
    190 for( i = 0; i < row1->len; ++i )
    191 {
    192 if( !SCIPsetIsFeasEQ(set, row1scale * row1->vals[i], row2scale * row2->vals[i]) )
    193 return FALSE;
    194 }
    195 }
    196 /* one row has LP columns, but the other not, that could be because the one without was just created and isn't
    197 * linked yet; in this case, one column could be an LP column in one row and a non-LP column in the other row, so we
    198 * cannot rely on the partition; thus, we iteratively check whether the next column of row1 is either the next LP
    199 * column of row2 or the next non-LP column of row2 and the coefficients are equal
    200 */
    201 else
    202 {
    203 int i1;
    204 int ilp;
    205 int inlp;
    206
    207 /* ensure that row1 is the row without LP columns, switch the rows, if neccessary */
    208 if( row2->nlpcols == 0 )
    209 {
    210 SCIP_ROW* tmprow;
    211 SCIP_Real tmpscale;
    212
    213 tmprow = row2;
    214 row2 = row1;
    215 row1 = tmprow;
    216
    217 tmpscale = row2scale;
    218 row2scale = row1scale;
    219 row1scale = tmpscale;
    220 }
    221 assert(row1->nlpcols == 0 && row2->nlpcols > 0);
    222
    223 ilp = 0;
    224 inlp = row2->nlpcols;
    225
    226 /* compare the columns and coefficients of the rows */
    227 for( i1 = 0; i1 < row1->len; ++i1 )
    228 {
    229 /* current column of row1 is the current LP column of row2, check the coefficient */
    230 if( ilp < row2->nlpcols && row1->cols[i1] == row2->cols[ilp] )
    231 {
    232 if( !SCIPsetIsFeasEQ(set, row1scale * row1->vals[i1], row2scale * row2->vals[ilp]) )
    233 return FALSE;
    234 else
    235 ++ilp;
    236 }
    237 /* current column of row1 is the current non-LP column of row2, check the coefficient */
    238 else if( inlp < row2->len && row1->cols[i1] == row2->cols[inlp] )
    239 {
    240 if( !SCIPsetIsFeasEQ(set, row1scale * row1->vals[i1], row2scale * row2->vals[inlp]) )
    241 return FALSE;
    242 else
    243 ++inlp;
    244 }
    245 /* current column of row1 is neither the current LP column of row2, nor the current non-LP column of row 2 */
    246 else
    247 return FALSE;
    248 }
    249 }
    250
    251 return TRUE;
    252}
    253
    254static
    256{ /*lint --e{715}*/
    257 SCIP_ROW* row;
    258 int i;
    259 SCIP_Real scale;
    260 SCIP_SET* set;
    261 uint64_t hash;
    262
    263 set = (SCIP_SET*) userptr;
    264 row = (SCIP_ROW*)key;
    265 assert(row != NULL);
    266 assert(row->len > 0);
    267
    268 scale = 1.0 / SCIProwGetMaxval(row, set);
    269 if( SCIPsetIsInfinity(set, row->rhs) )
    270 scale = -scale;
    271
    272 hash = (uint64_t) (long) row->len;
    273
    274 for( i = 0; i < row->len; ++i )
    275 {
    276 SCIP_Real val = scale * row->vals[i];
    277
    278 hash += SCIPhashTwo(SCIPrealHashCode(val), row->cols_index[i]);
    279 }
    280
    281 return hash;
    282}
    283
    284
    285/*
    286 * dynamic memory arrays
    287 */
    288
    289/** resizes cuts array to be able to store at least num entries */
    290static
    292 SCIP_CUTPOOL* cutpool, /**< cut pool */
    293 SCIP_SET* set, /**< global SCIP settings */
    294 int num /**< minimal number of slots in array */
    295 )
    296{
    297 assert(cutpool != NULL);
    298 assert(set != NULL);
    299
    300 if( num > cutpool->cutssize )
    301 {
    302 int newsize;
    303
    304 newsize = SCIPsetCalcMemGrowSize(set, num);
    305 SCIP_ALLOC( BMSreallocMemoryArray(&cutpool->cuts, newsize) );
    306 cutpool->cutssize = newsize;
    307 }
    308 assert(num <= cutpool->cutssize);
    309
    310 return SCIP_OKAY;
    311}
    312
    313
    314
    315/*
    316 * Cut methods
    317 */
    318
    319/** creates a cut and captures the row */
    320static
    322 SCIP_CUT** cut, /**< pointer to store the cut */
    323 BMS_BLKMEM* blkmem, /**< block memory */
    324 SCIP_ROW* row /**< row this cut represents */
    325 )
    326{
    327 assert(cut != NULL);
    328 assert(blkmem != NULL);
    329 assert(row != NULL);
    330
    331 /* allocate cut memory */
    332 SCIP_ALLOC( BMSallocBlockMemory(blkmem, cut) );
    333 (*cut)->row = row;
    334 (*cut)->age = 0;
    335 (*cut)->processedlp = -1;
    336 (*cut)->processedlpsol = -1;
    337 (*cut)->pos = -1;
    338
    339 /* capture row */
    340 SCIProwCapture(row);
    341
    342 return SCIP_OKAY;
    343}
    344
    345/** frees a cut and releases the row */
    346static
    348 SCIP_CUT** cut, /**< pointer to store the cut */
    349 BMS_BLKMEM* blkmem, /**< block memory */
    350 SCIP_SET* set, /**< global SCIP settings */
    351 SCIP_LP* lp /**< current LP data */
    352 )
    353{
    354 assert(cut != NULL);
    355 assert(*cut != NULL);
    356 assert((*cut)->row != NULL);
    357 assert(blkmem != NULL);
    358
    359 /* release row */
    360 SCIP_CALL( SCIProwRelease(&(*cut)->row, blkmem, set, lp) );
    361
    362 /* free cut memory */
    363 BMSfreeBlockMemory(blkmem, cut);
    364
    365 return SCIP_OKAY;
    366}
    367
    368/** returns whether the cut's age exceeds the age limit */
    369static
    371 SCIP_CUT* cut, /**< cut to check */
    372 int agelimit /**< maximum age a cut can reach before it is deleted from the pool, or -1 */
    373 )
    374{
    375 assert(cut != NULL);
    376
    377 /* since agelimit can be -1 cast to unsigned before comparison, then it is the maximum unsigned value in that case */
    378 return (unsigned int)cut->age > (unsigned int)agelimit;
    379}
    380
    381/** gets the row of the cut */
    383 SCIP_CUT* cut /**< cut */
    384 )
    385{
    386 assert(cut != NULL);
    387
    388 return cut->row;
    389}
    390
    391/** gets the age of the cut: the number of consecutive cut pool separation rounds where the cut was neither in the LP nor violated */
    393 SCIP_CUT* cut /**< cut */
    394 )
    395{
    396 assert(cut != NULL);
    397
    398 return cut->age;
    399}
    400
    401/** returns the ratio of LPs where the row belonging to this cut was active in an LP solution, i.e.
    402 * where the age of its row has not been increased
    403 *
    404 * @see SCIPcutGetAge() to get the age of a cut
    405 */
    407 SCIP_CUT* cut /**< cut */
    408 )
    409{
    410 SCIP_Longint nlpsaftercreation;
    411 SCIP_Longint activeinlpcounter;
    412
    413 assert(cut != NULL);
    414 assert(cut->row != NULL);
    415
    416 nlpsaftercreation = SCIProwGetNLPsAfterCreation(cut->row);
    417 activeinlpcounter = SCIProwGetActiveLPCount(cut->row);
    418
    419 return (nlpsaftercreation > 0 ? activeinlpcounter / (SCIP_Real)nlpsaftercreation : 0.0);
    420}
    421
    422/*
    423 * Cutpool methods
    424 */
    425
    426/** creates cut pool */
    428 SCIP_CUTPOOL** cutpool, /**< pointer to store cut pool */
    429 BMS_BLKMEM* blkmem, /**< block memory */
    430 SCIP_SET* set, /**< global SCIP settings */
    431 int agelimit, /**< maximum age a cut can reach before it is deleted from the pool */
    432 SCIP_Bool globalcutpool /**< is this the global cut pool of SCIP? */
    433 )
    434{
    435 assert(cutpool != NULL);
    436 assert(agelimit >= -1);
    437
    438 SCIP_ALLOC( BMSallocMemory(cutpool) );
    439
    440 SCIP_CALL( SCIPclockCreate(&(*cutpool)->poolclock, SCIP_CLOCKTYPE_DEFAULT) );
    441
    442 SCIP_CALL( SCIPhashtableCreate(&(*cutpool)->hashtable, blkmem,
    444 hashGetKeyCut, hashKeyEqCut, hashKeyValCut, (void*) set) );
    445
    446 (*cutpool)->cuts = NULL;
    447 (*cutpool)->cutssize = 0;
    448 (*cutpool)->ncuts = 0;
    449 (*cutpool)->nremovablecuts = 0;
    450 (*cutpool)->agelimit = agelimit;
    451 (*cutpool)->processedlp = -1;
    452 (*cutpool)->processedlpsol = -1;
    453 (*cutpool)->processedlpefficacy = SCIP_INVALID;
    454 (*cutpool)->processedlpsolefficacy = SCIP_INVALID;
    455 (*cutpool)->firstunprocessed = 0;
    456 (*cutpool)->firstunprocessedsol = 0;
    457 (*cutpool)->maxncuts = 0;
    458 (*cutpool)->ncalls = 0;
    459 (*cutpool)->nrootcalls = 0;
    460 (*cutpool)->ncutsfound = 0;
    461 (*cutpool)->ncutsadded = 0;
    462 (*cutpool)->globalcutpool = globalcutpool;
    463
    464 return SCIP_OKAY;
    465}
    466
    467/** frees cut pool */
    469 SCIP_CUTPOOL** cutpool, /**< pointer to store cut pool */
    470 BMS_BLKMEM* blkmem, /**< block memory */
    471 SCIP_SET* set, /**< global SCIP settings */
    472 SCIP_LP* lp /**< current LP data */
    473 )
    474{
    475 assert(cutpool != NULL);
    476 assert(*cutpool != NULL);
    477
    478 /* remove all cuts from the pool */
    479 SCIP_CALL( SCIPcutpoolClear(*cutpool, blkmem, set, lp) );
    480
    481 /* free clock */
    482 SCIPclockFree(&(*cutpool)->poolclock);
    483
    484 /* free hash table */
    485 SCIPhashtableFree(&(*cutpool)->hashtable);
    486
    487 BMSfreeMemoryArrayNull(&(*cutpool)->cuts);
    488 BMSfreeMemory(cutpool);
    489
    490 return SCIP_OKAY;
    491}
    492
    493/** removes all rows from the cut pool */
    495 SCIP_CUTPOOL* cutpool, /**< cut pool */
    496 BMS_BLKMEM* blkmem, /**< block memory */
    497 SCIP_SET* set, /**< global SCIP settings */
    498 SCIP_LP* lp /**< current LP data */
    499 )
    500{
    501 int i;
    502
    503 assert(cutpool != NULL);
    504
    505 /* free cuts */
    507 for( i = 0; i < cutpool->ncuts; ++i )
    508 {
    509 if( cutpool->globalcutpool )
    510 cutpool->cuts[i]->row->inglobalcutpool = FALSE;
    511 SCIProwUnlock(cutpool->cuts[i]->row);
    512 SCIP_CALL( cutFree(&cutpool->cuts[i], blkmem, set, lp) );
    513 }
    514
    515 cutpool->ncuts = 0;
    516 cutpool->nremovablecuts = 0;
    517
    518 return SCIP_OKAY;
    519}
    520
    521/** removes the cut from the cut pool */
    522static
    524 SCIP_CUTPOOL* cutpool, /**< cut pool */
    525 BMS_BLKMEM* blkmem, /**< block memory */
    526 SCIP_SET* set, /**< global SCIP settings */
    527 SCIP_STAT* stat, /**< problem statistics data */
    528 SCIP_LP* lp, /**< current LP data */
    529 SCIP_CUT* cut /**< cut to remove */
    530 )
    531{
    532 int pos;
    533
    534 assert(cutpool != NULL);
    535 assert(cutpool->firstunprocessed <= cutpool->ncuts);
    536 assert(cutpool->firstunprocessedsol <= cutpool->ncuts);
    537 assert(blkmem != NULL);
    538 assert(stat != NULL);
    539 assert(cutpool->processedlp <= stat->lpcount);
    540 assert(cutpool->processedlpsol <= stat->lpcount);
    541 assert(cut != NULL);
    542 assert(cut->row != NULL);
    543
    544 pos = cut->pos;
    545 assert(0 <= pos && pos < cutpool->ncuts);
    546 assert(cutpool->cuts[pos] == cut);
    547
    548 /* decrease the number of removable cuts counter (row might have changed its removable status -> counting might not
    549 * be correct
    550 */
    551 if( SCIProwIsRemovable(cut->row) && cutpool->nremovablecuts > 0 )
    552 cutpool->nremovablecuts--;
    553
    554 /* if this is the global cut pool of SCIP, mark the row to not be member anymore */
    555 if( cutpool->globalcutpool )
    556 {
    557 assert(cut->row->inglobalcutpool);
    558 cut->row->inglobalcutpool = FALSE;
    559 }
    560
    561 /* remove the cut from the hash table */
    562 assert(SCIPhashtableExists(cutpool->hashtable, (void*)cut));
    563 SCIP_CALL( SCIPhashtableRemove(cutpool->hashtable, (void*)cut) );
    564 assert(! SCIPhashtableExists(cutpool->hashtable, (void*)cut));
    565
    566 /* unlock the row */
    567 SCIProwUnlock(cut->row);
    568
    569 /* free the cut */
    570 SCIP_CALL( cutFree(&cutpool->cuts[pos], blkmem, set, lp) );
    571
    572 --cutpool->ncuts;
    573 cutpool->firstunprocessed = MIN(cutpool->firstunprocessed, cutpool->ncuts);
    574 cutpool->firstunprocessedsol = MIN(cutpool->firstunprocessedsol, cutpool->ncuts);
    575
    576 /* move the last cut of the pool to the free position */
    577 if( pos < cutpool->ncuts )
    578 {
    579 cutpool->cuts[pos] = cutpool->cuts[cutpool->ncuts];
    580 cutpool->cuts[pos]->pos = pos;
    581 assert(cutpool->cuts[pos]->processedlp <= stat->lpcount);
    582 assert(cutpool->cuts[pos]->processedlpsol <= stat->lpcount);
    583 if( cutpool->cuts[pos]->processedlp < stat->lpcount )
    584 cutpool->firstunprocessed = MIN(cutpool->firstunprocessed, pos);
    585 if( cutpool->cuts[pos]->processedlpsol < stat->lpcount )
    586 cutpool->firstunprocessedsol = MIN(cutpool->firstunprocessedsol, pos);
    587 }
    588
    589 return SCIP_OKAY;
    590}
    591
    592/** checks if cut is already existing */
    594 SCIP_CUTPOOL* cutpool, /**< cut pool */
    595 SCIP_SET* set, /**< global SCIP settings */
    596 SCIP_ROW* row /**< cutting plane to add */
    597 )
    598{
    599 SCIP_CUT* othercut;
    600 assert(cutpool != NULL);
    601 assert(row != NULL);
    602
    603 if( row->len == 0 )
    604 {
    605 /* trivial cut is only new if it proves infeasibility */
    606 return SCIPsetIsFeasLT(set, row->constant, row->lhs) || SCIPsetIsFeasGT(set, row->constant, row->rhs);
    607 }
    608
    609 othercut = (SCIP_CUT*)SCIPhashtableRetrieve(cutpool->hashtable, (void*)row);
    610 /* check in hash table, if cut already exists in the pool */
    611 if( othercut == NULL )
    612 {
    613 return TRUE;
    614 }
    615 else if( othercut->row != row )
    616 {
    617 SCIP_ROW* otherrow = othercut->row;
    618 SCIP_Real otherrhs;
    619 SCIP_Real rhs;
    620 SCIP_Real scale;
    621 SCIP_Real otherscale;
    622
    623 /* since we are comparing the improvement with an absolute value, we apply a
    624 * scale to both rows such that the max absolute value is 1.0.
    625 * Then bring the cut into the form ax <= b
    626 */
    627 scale = 1.0 / SCIProwGetMaxval(row, set);
    628 otherscale = 1.0 / SCIProwGetMaxval(otherrow, set);
    629
    630 if( SCIPsetIsInfinity(set, otherrow->rhs) )
    631 {
    632 otherrhs = otherscale * (otherrow->constant - otherrow->lhs);
    633 }
    634 else
    635 {
    636 otherrhs = otherscale * (otherrow->rhs - otherrow->constant);
    637 }
    638
    639 if( SCIPsetIsInfinity(set, row->rhs) )
    640 {
    641 rhs = scale * (row->constant - row->lhs);
    642 }
    643 else
    644 {
    645 rhs = scale * (row->rhs - row->constant);
    646 }
    647
    648 if( SCIPsetIsFeasLT(set, rhs, otherrhs) )
    649 return TRUE;
    650 }
    651
    652 return FALSE;
    653}
    654
    655/** if not already existing, adds row to cut pool and captures it */
    657 SCIP_CUTPOOL* cutpool, /**< cut pool */
    658 BMS_BLKMEM* blkmem, /**< block memory */
    659 SCIP_SET* set, /**< global SCIP settings */
    660 SCIP_STAT* stat, /**< problem statistics data */
    661 SCIP_LP* lp, /**< current LP data */
    662 SCIP_ROW* row /**< cutting plane to add */
    663 )
    664{
    665 SCIP_CUT* othercut;
    666 assert(cutpool != NULL);
    667 assert(row != NULL);
    668
    669 if( row->len == 0 )
    670 return SCIP_OKAY;
    671
    672 /* ensure validity of minidx and maxidx for hash key comparison */
    673 (void)SCIProwGetMaxidx(row, set);
    674
    675 othercut = (SCIP_CUT*)SCIPhashtableRetrieve(cutpool->hashtable, (void*)row);
    676 /* check in hash table, if cut already exists in the pool */
    677 if( othercut == NULL )
    678 {
    679 SCIP_CALL( SCIPcutpoolAddNewRow(cutpool, blkmem, set, stat, lp, row) );
    680 }
    681 else
    682 {
    683 SCIP_ROW* otherrow = othercut->row;
    684 SCIP_Real otherrhs;
    685 SCIP_Real rhs;
    686 SCIP_Real scale;
    687 SCIP_Real otherscale;
    688
    689 /* since we are comparing the improvement with an absolute value, we apply a
    690 * scale to both rows such that the max absolute value is 1.0.
    691 * Then bring the cut into the form ax <= b
    692 */
    693 scale = 1.0 / SCIProwGetMaxval(row, set);
    694 otherscale = 1.0 / SCIProwGetMaxval(otherrow, set);
    695
    696 if( SCIPsetIsInfinity(set, otherrow->rhs) )
    697 {
    698 otherrhs = otherscale * (otherrow->constant - otherrow->lhs);
    699 }
    700 else
    701 {
    702 otherrhs = otherscale * (otherrow->rhs - otherrow->constant);
    703 }
    704
    705 if( SCIPsetIsInfinity(set, row->rhs) )
    706 {
    707 rhs = scale * (row->constant - row->lhs);
    708 }
    709 else
    710 {
    711 rhs = scale * (row->rhs - row->constant);
    712 }
    713
    714 if( SCIPsetIsFeasLT(set, rhs, otherrhs) )
    715 {
    716 SCIP_CALL( cutpoolDelCut(cutpool, blkmem, set, stat, lp, othercut) );
    717
    718 /* use recursion, since in rare cases new cut might compare equal to multiple other cuts
    719 * that do not compare equal themselve due to non-transitivity of epsilon comparisons
    720 */
    721 SCIP_CALL( SCIPcutpoolAddRow(cutpool, blkmem, set, stat, lp, row) );
    722 }
    723 }
    724
    725 return SCIP_OKAY;
    726}
    727
    728/** adds row to cut pool and captures it; doesn't check for multiple cuts */
    730 SCIP_CUTPOOL* cutpool, /**< cut pool */
    731 BMS_BLKMEM* blkmem, /**< block memory */
    732 SCIP_SET* set, /**< global SCIP settings */
    733 SCIP_STAT* stat, /**< problem statistics data */
    734 SCIP_LP* lp, /**< current LP data */
    735 SCIP_ROW* row /**< cutting plane to add */
    736 )
    737{
    738 SCIP_Real thisefficacy;
    739 SCIP_CUT* cut;
    740
    741 assert(cutpool != NULL);
    742 assert(row != NULL);
    743
    744 /* check, if row is modifiable or local */
    745 if( SCIProwIsModifiable(row) )
    746 {
    747 SCIPerrorMessage("cannot store modifiable row <%s> in a cut pool\n", SCIProwGetName(row));
    748 return SCIP_INVALIDDATA;
    749 }
    750 if( SCIProwIsLocal(row) )
    751 {
    752 SCIPerrorMessage("cannot store locally valid row <%s> in a cut pool\n", SCIProwGetName(row));
    753 return SCIP_INVALIDDATA;
    754 }
    755
    756 assert(!row->inglobalcutpool);
    757
    758 /* ensure validity of minidx and maxidx for hash key comparison */
    759 (void)SCIProwGetMaxidx(row, set);
    760
    761 /* create the cut */
    762 SCIP_CALL( cutCreate(&cut, blkmem, row) );
    763 cut->pos = cutpool->ncuts;
    764
    765 /* add cut to the pool */
    766 SCIP_CALL( cutpoolEnsureCutsMem(cutpool, set, cutpool->ncuts+1) );
    767 cutpool->cuts[cutpool->ncuts] = cut;
    768 cutpool->ncuts++;
    769 cutpool->ncutsfound++;
    770 cutpool->maxncuts = MAX(cutpool->maxncuts, cutpool->ncuts);
    771 if( SCIProwIsRemovable(row) )
    772 cutpool->nremovablecuts++;
    773
    774 assert(!SCIPhashtableExists(cutpool->hashtable, (void*)cut));
    775
    776 /* insert cut in the hash table */
    777 SCIP_CALL( SCIPhashtableInsert(cutpool->hashtable, (void*)cut) );
    778
    779 assert(SCIPhashtableExists(cutpool->hashtable, (void*)cut));
    780
    782 {
    783 thisefficacy = SCIProwGetLPEfficacy(row, set, stat, lp);
    784 stat->bestefficacy = MAX(thisefficacy, stat->bestefficacy);
    785 }
    786
    787 /* if this is the global cut pool of SCIP, mark the row to be member of the pool */
    788 if( cutpool->globalcutpool )
    789 row->inglobalcutpool = TRUE;
    790
    791 /* lock the row */
    792 SCIProwLock(row);
    793
    794 return SCIP_OKAY;
    795}
    796
    797/** removes the LP row from the cut pool */
    799 SCIP_CUTPOOL* cutpool, /**< cut pool */
    800 BMS_BLKMEM* blkmem, /**< block memory */
    801 SCIP_SET* set, /**< global SCIP settings */
    802 SCIP_STAT* stat, /**< problem statistics data */
    803 SCIP_LP* lp, /**< current LP data */
    804 SCIP_ROW* row /**< row to remove */
    805 )
    806{
    807 SCIP_CUT* cut;
    808
    809 assert(cutpool != NULL);
    810 assert(row != NULL);
    811
    812 /* find the cut in hash table */
    813 cut = (SCIP_CUT*)SCIPhashtableRetrieve(cutpool->hashtable, (void*)row);
    814 if( cut == NULL )
    815 {
    816 SCIPerrorMessage("row <%s> is not existing in cutpool %p\n", SCIProwGetName(row), (void*)cutpool);
    817 return SCIP_INVALIDDATA;
    818 }
    819
    820 SCIP_CALL( cutpoolDelCut(cutpool, blkmem, set, stat, lp, cut) );
    821
    822 return SCIP_OKAY;
    823}
    824
    825
    826/** separates cuts of the cut pool */
    828 SCIP_CUTPOOL* cutpool, /**< cut pool */
    829 BMS_BLKMEM* blkmem, /**< block memory */
    830 SCIP_SET* set, /**< global SCIP settings */
    831 SCIP_STAT* stat, /**< problem statistics data */
    832 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
    833 SCIP_EVENTFILTER* eventfilter, /**< event filter for global events */
    834 SCIP_LP* lp, /**< current LP data */
    835 SCIP_SEPASTORE* sepastore, /**< separation storage */
    836 SCIP_SOL* sol, /**< solution to be separated (or NULL for LP-solution) */
    837 SCIP_Bool cutpoolisdelayed, /**< is the cutpool delayed (count cuts found)? */
    838 SCIP_Bool root, /**< are we at the root node? */
    839 SCIP_RESULT* result /**< pointer to store the result of the separation call */
    840 )
    841{
    842 SCIP_CUT* cut;
    843 SCIP_Bool found;
    844 SCIP_Bool cutoff;
    845 SCIP_Real minefficacy;
    846 SCIP_Bool retest;
    847 int firstunproc;
    848 int oldncutsadded;
    849 int oldncutsfound;
    850 int nefficaciouscuts;
    851 int c;
    852
    853 assert(cutpool != NULL);
    854 assert(stat != NULL);
    855 assert(cutpool->processedlp <= stat->lpcount);
    856 assert(cutpool->processedlpsol <= stat->lpcount);
    857 assert(cutpool->firstunprocessed <= cutpool->ncuts);
    858 assert(cutpool->firstunprocessedsol <= cutpool->ncuts);
    859 assert(result != NULL);
    860
    861 *result = SCIP_DIDNOTRUN;
    862
    863 /* don't separate cut pool in the root node, if there are no removable cuts */
    864 if( root && cutpool->nremovablecuts == 0 )
    865 return SCIP_OKAY;
    866
    867 if ( sol == NULL )
    868 {
    869 if( cutpool->processedlp < stat->lpcount )
    870 cutpool->firstunprocessed = 0;
    871 if( cutpool->firstunprocessed == cutpool->ncuts )
    872 return SCIP_OKAY;
    873 firstunproc = cutpool->firstunprocessed;
    874 }
    875 else
    876 {
    877 if( cutpool->processedlpsol < stat->lpcount )
    878 cutpool->firstunprocessedsol = 0;
    879 if( cutpool->firstunprocessedsol == cutpool->ncuts )
    880 return SCIP_OKAY;
    881 firstunproc = cutpool->firstunprocessedsol;
    882 }
    883
    884 *result = SCIP_DIDNOTFIND;
    885 cutpool->ncalls++;
    886 if( root )
    887 cutpool->nrootcalls++;
    888 found = FALSE;
    889 if( set->sepa_filtercutpoolrel )
    890 minefficacy = stat->bestefficacy * stat->minefficacyfac;
    891 else
    892 minefficacy = root ? set->sepa_minefficacyroot : set->sepa_minefficacy;
    893
    894 if( sol == NULL )
    895 {
    896 retest = cutpool->processedlpefficacy > minefficacy;
    897 cutpool->processedlpefficacy = minefficacy;
    898 }
    899 else
    900 {
    901 retest = cutpool->processedlpsolefficacy > minefficacy;
    902 cutpool->processedlpsolefficacy = minefficacy;
    903 }
    904
    905 SCIPsetDebugMsg(set, "separating%s cut pool %p with %d cuts, beginning with cut %d\n", ( sol == NULL ) ? "" : " solution from", (void*)cutpool, cutpool->ncuts, firstunproc);
    906
    907 /* start timing */
    908 SCIPclockStart(cutpool->poolclock, set);
    909
    910 /* remember the current total number of found cuts */
    911 oldncutsfound = SCIPsepastoreGetNCuts(sepastore);
    912 oldncutsadded = SCIPsepastoreGetNCutsAdded(sepastore);
    913 nefficaciouscuts = 0;
    914
    915 /* process all unprocessed cuts in the pool */
    916 cutoff = FALSE;
    917 for( c = firstunproc; c < cutpool->ncuts; ++c )
    918 {
    919 SCIP_Longint proclp;
    920
    921 cut = cutpool->cuts[c];
    922 assert(cut != NULL);
    923 assert(cut->processedlp <= stat->lpcount);
    924 assert(cut->processedlpsol <= stat->lpcount);
    925 assert(cut->pos == c);
    926
    927 proclp = ( sol == NULL ) ? cut->processedlp : cut->processedlpsol;
    928
    929 if( retest || proclp < stat->lpcount )
    930 {
    931 SCIP_ROW* row;
    932
    933 if ( sol == NULL )
    934 cut->processedlp = stat->lpcount;
    935 else
    936 cut->processedlpsol = stat->lpcount;
    937
    938 row = cut->row;
    939 if( !SCIProwIsInLP(row) )
    940 {
    941 SCIP_Real efficacy;
    942
    943 /* if the cut is a bound change (i.e. a row with only one variable), add it as bound change instead of LP
    944 * row; hence, we want to remove the bound change cut from the SCIP cut pool
    945 */
    946 if( !SCIProwIsModifiable(row) && SCIProwGetNNonz(row) == 1 )
    947 {
    948 /* insert bound change cut into separation store which will force that cut;
    949 * fromcutpool is set for consistency.
    950 */
    951 row->fromcutpool = TRUE;
    952 SCIP_CALL( SCIPsepastoreAddCut(sepastore, blkmem, set, stat, eventqueue, eventfilter, lp, row, FALSE, root, &cutoff) );
    953 SCIP_CALL( cutpoolDelCut(cutpool, blkmem, set, stat, lp, cut) );
    954
    955 if ( cutoff )
    956 break;
    957
    958 continue;
    959 }
    960
    961 efficacy = sol == NULL ? SCIProwGetLPEfficacy(row, set, stat, lp) : SCIProwGetSolEfficacy(row, set, stat, sol);
    962 if( SCIPsetIsFeasPositive(set, efficacy) )
    963 ++nefficaciouscuts;
    964
    965 if( efficacy >= minefficacy )
    966 {
    967 /* insert cut in separation storage */
    968 row->fromcutpool = TRUE;
    969 SCIPsetDebugMsg(set, " -> separated cut <%s> from the cut pool (feasibility: %g)\n",
    970 SCIProwGetName(row), ( sol == NULL ) ? SCIProwGetLPFeasibility(row, set, stat, lp) : SCIProwGetSolFeasibility(row, set, stat, sol) );
    971 SCIP_CALL( SCIPsepastoreAddCut(sepastore, blkmem, set, stat, eventqueue, eventfilter, lp, row, FALSE, root, &cutoff) );
    972
    973 /* count cuts */
    974 if ( cutpoolisdelayed )
    975 {
    976 if ( SCIProwGetOriginSepa(row) != NULL )
    977 {
    978 SCIP_SEPA* sepa;
    979
    980 sepa = SCIProwGetOriginSepa(row);
    983 }
    984 else if ( SCIProwGetOriginConshdlr(row) != NULL )
    985 {
    986 SCIP_CONSHDLR* conshdlr;
    987
    988 conshdlr = SCIProwGetOriginConshdlr(row);
    990 }
    991 }
    992
    993 found = TRUE;
    994 cut->age = 0;
    995
    996 if ( cutoff )
    997 break;
    998 }
    999 else
    1000 {
    1001 cut->age++;
    1002 if( cutIsAged(cut, cutpool->agelimit) )
    1003 {
    1004 SCIP_CALL( cutpoolDelCut(cutpool, blkmem, set, stat, lp, cut) );
    1005 }
    1006 }
    1007 }
    1008 }
    1009 }
    1010
    1011 if ( sol == NULL )
    1012 {
    1013 cutpool->processedlp = stat->lpcount;
    1014 cutpool->firstunprocessed = cutpool->ncuts;
    1015 }
    1016 else
    1017 {
    1018 cutpool->processedlpsol = stat->lpcount;
    1019 cutpool->firstunprocessedsol = cutpool->ncuts;
    1020 }
    1021 /* update the number of found and added cuts */
    1022 cutpool->ncutsadded += SCIPsepastoreGetNCutsAdded(sepastore) - oldncutsadded; /*lint !e776*/
    1023
    1024 /* check whether efficacy threshold should be tightened or relaxed */
    1025 if( set->sepa_filtercutpoolrel && nefficaciouscuts > 0 )
    1026 {
    1027 int maxncuts = SCIPsetGetSepaMaxcuts(set, root);
    1028 int ncuts = SCIPsepastoreGetNCuts(sepastore) - oldncutsfound;
    1029
    1030 maxncuts = MIN(maxncuts, nefficaciouscuts);
    1031
    1032 if( ncuts > (0.5 * maxncuts) )
    1033 {
    1034 stat->ncutpoolfails = MIN(stat->ncutpoolfails - 1, -1);
    1035 }
    1036 else if( ncuts == 0 || (ncuts < (0.05 * maxncuts)) )
    1037 {
    1038 stat->ncutpoolfails = MAX(stat->ncutpoolfails + 1, 1);
    1039 }
    1040
    1041 if( stat->ncutpoolfails == (root ? 2 : 10) )
    1042 {
    1043 cutpool->firstunprocessed = 0;
    1044 cutpool->firstunprocessedsol = 0;
    1045 stat->minefficacyfac *= 0.5;
    1046 stat->ncutpoolfails = 0;
    1047 }
    1048 else if( stat->ncutpoolfails == -2 )
    1049 {
    1050 stat->minefficacyfac *= 1.2;
    1051 stat->ncutpoolfails = 0;
    1052 }
    1053 }
    1054
    1055 /* stop timing */
    1056 SCIPclockStop(cutpool->poolclock, set);
    1057
    1058 if ( cutoff )
    1059 *result = SCIP_CUTOFF;
    1060 else if( found )
    1061 *result = SCIP_SEPARATED;
    1062
    1063 return SCIP_OKAY;
    1064}
    1065
    1066/** gets array of cuts in the cut pool */
    1068 SCIP_CUTPOOL* cutpool /**< cut pool */
    1069 )
    1070{
    1071 assert(cutpool != NULL);
    1072
    1073 return cutpool->cuts;
    1074}
    1075
    1076/** gets number of cuts in the cut pool */
    1078 SCIP_CUTPOOL* cutpool /**< cut pool */
    1079 )
    1080{
    1081 assert(cutpool != NULL);
    1082
    1083 return cutpool->ncuts;
    1084}
    1085
    1086/** gets maximum number of cuts that were stored in the cut pool at the same time */
    1088 SCIP_CUTPOOL* cutpool /**< cut pool */
    1089 )
    1090{
    1091 assert(cutpool != NULL);
    1092
    1093 return cutpool->maxncuts;
    1094}
    1095
    1096/** gets time in seconds used for separating cuts from the pool */
    1098 SCIP_CUTPOOL* cutpool /**< cut pool */
    1099 )
    1100{
    1101 assert(cutpool != NULL);
    1102
    1103 return SCIPclockGetTime(cutpool->poolclock);
    1104}
    1105
    1106/** get number of times the cut pool was separated */
    1108 SCIP_CUTPOOL* cutpool /**< cut pool */
    1109 )
    1110{
    1111 assert(cutpool != NULL);
    1112
    1113 return cutpool->ncalls;
    1114}
    1115
    1116/** get number of times the cut pool was separated at the root */
    1118 SCIP_CUTPOOL* cutpool /**< cut pool */
    1119 )
    1120{
    1121 assert(cutpool != NULL);
    1122
    1123 return cutpool->nrootcalls;
    1124}
    1125
    1126/** get total number of cuts that were added to the cut pool */
    1128 SCIP_CUTPOOL* cutpool /**< cut pool */
    1129 )
    1130{
    1131 assert(cutpool != NULL);
    1132
    1133 return cutpool->ncutsfound;
    1134}
    1135
    1136/** get total number of cuts that were added from the cut pool to sepastore */
    1138 SCIP_CUTPOOL* cutpool /**< cut pool */
    1139 )
    1140{
    1141 assert(cutpool != NULL);
    1142
    1143 return cutpool->ncutsadded;
    1144}
    1145
    1146/** adds the maximum number of cuts that were stored in the pool;
    1147 * this is primarily used to keep statistics when SCIP performs a restart */
    1149 SCIP_CUTPOOL* cutpool, /**< cut pool */
    1150 SCIP_Longint ncuts /**< number of cuts to add */
    1151 )
    1152{
    1153 assert(cutpool != NULL);
    1154
    1155 cutpool->maxncuts += ncuts;
    1156}
    1157
    1158/** sets time in seconds used for separating cuts from the pool;
    1159 * this is primarily used to keep statistics when SCIP performs a restart */
    1161 SCIP_CUTPOOL* cutpool, /**< cut pool */
    1162 SCIP_Real time /**< poolclock time */
    1163 )
    1164{
    1165 assert(cutpool != NULL);
    1166
    1167 SCIPclockSetTime(cutpool->poolclock, time);
    1168}
    1169
    1170/** adds the number of times the cut pool was separated;
    1171 * this is primarily used to keep statistics when SCIP performs a restart */
    1173 SCIP_CUTPOOL* cutpool, /**< cut pool */
    1174 SCIP_Longint ncalls /**< ncalls */
    1175 )
    1176{
    1177 assert(cutpool != NULL);
    1178
    1179 cutpool->ncalls += ncalls;
    1180}
    1181
    1182/** adds the number of times the cut pool was separated at the root;
    1183 * this is primarily used to keep statistics when SCIP performs a restart */
    1185 SCIP_CUTPOOL* cutpool, /**< cut pool */
    1186 SCIP_Longint nrootcalls /**< nrootcalls */
    1187 )
    1188{
    1189 assert(cutpool != NULL);
    1190
    1191 cutpool->nrootcalls += nrootcalls;
    1192}
    1193
    1194/** adds the total number of cuts that were added to the pool;
    1195 * this is primarily used to keep statistics when SCIP performs a restart */
    1197 SCIP_CUTPOOL* cutpool, /**< cut pool */
    1198 SCIP_Longint ncutsfound /**< total number of cuts added to cut pool */
    1199 )
    1200{
    1201 assert(cutpool != NULL);
    1202
    1203 cutpool->ncutsfound += ncutsfound;
    1204}
    1205
    1206/** adds the total number of cuts that were separated from the pool;
    1207 * this is primarily used to keep statistics when SCIP performs a restart */
    1209 SCIP_CUTPOOL* cutpool, /**< cut pool */
    1210 SCIP_Longint ncutsadded /**< total number of cuts added from cut pool to sepastore */
    1211 )
    1212{
    1213 assert(cutpool != NULL);
    1214
    1215 cutpool->ncutsadded += ncutsadded;
    1216}
    void SCIPclockSetTime(SCIP_CLOCK *clck, SCIP_Real sec)
    Definition: clock.c:539
    void SCIPclockStop(SCIP_CLOCK *clck, SCIP_SET *set)
    Definition: clock.c:360
    void SCIPclockStart(SCIP_CLOCK *clck, SCIP_SET *set)
    Definition: clock.c:290
    SCIP_Real SCIPclockGetTime(SCIP_CLOCK *clck)
    Definition: clock.c:438
    void SCIPclockFree(SCIP_CLOCK **clck)
    Definition: clock.c:185
    SCIP_RETCODE SCIPclockCreate(SCIP_CLOCK **clck, SCIP_CLOCKTYPE clocktype)
    Definition: clock.c:170
    internal methods for clocks and timing issues
    void SCIPconshdlrIncNCutsFound(SCIP_CONSHDLR *conshdlr)
    Definition: cons.c:5072
    internal methods for constraints and constraint handlers
    void SCIPcutpoolAddNCutsFound(SCIP_CUTPOOL *cutpool, SCIP_Longint ncutsfound)
    Definition: cutpool.c:1196
    static SCIP_Bool cutIsAged(SCIP_CUT *cut, int agelimit)
    Definition: cutpool.c:370
    void SCIPcutpoolSetTime(SCIP_CUTPOOL *cutpool, SCIP_Real time)
    Definition: cutpool.c:1160
    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
    static SCIP_RETCODE cutCreate(SCIP_CUT **cut, BMS_BLKMEM *blkmem, SCIP_ROW *row)
    Definition: cutpool.c:321
    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
    static SCIP_DECL_HASHKEYEQ(hashKeyEqCut)
    Definition: cutpool.c:75
    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
    void SCIPcutpoolAddNCalls(SCIP_CUTPOOL *cutpool, SCIP_Longint ncalls)
    Definition: cutpool.c:1172
    static SCIP_DECL_HASHKEYVAL(hashKeyValCut)
    Definition: cutpool.c:255
    static SCIP_RETCODE cutFree(SCIP_CUT **cut, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_LP *lp)
    Definition: cutpool.c:347
    void SCIPcutpoolAddMaxNCuts(SCIP_CUTPOOL *cutpool, SCIP_Longint ncuts)
    Definition: cutpool.c:1148
    static SCIP_DECL_HASHGETKEY(hashGetKeyCut)
    Definition: cutpool.c:61
    static SCIP_RETCODE cutpoolEnsureCutsMem(SCIP_CUTPOOL *cutpool, SCIP_SET *set, int num)
    Definition: cutpool.c:291
    void SCIPcutpoolAddNCutsAdded(SCIP_CUTPOOL *cutpool, SCIP_Longint ncutsadded)
    Definition: cutpool.c:1208
    void SCIPcutpoolAddNRootCalls(SCIP_CUTPOOL *cutpool, SCIP_Longint nrootcalls)
    Definition: cutpool.c:1184
    SCIP_Bool SCIPcutpoolIsCutNew(SCIP_CUTPOOL *cutpool, SCIP_SET *set, SCIP_ROW *row)
    Definition: cutpool.c:593
    static SCIP_RETCODE cutpoolDelCut(SCIP_CUTPOOL *cutpool, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp, SCIP_CUT *cut)
    Definition: cutpool.c:523
    SCIP_RETCODE SCIPcutpoolClear(SCIP_CUTPOOL *cutpool, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_LP *lp)
    Definition: cutpool.c:494
    internal methods for storing cuts in a cut pool
    common defines and data types used in all packages of SCIP
    #define NULL
    Definition: def.h:248
    #define SCIP_Longint
    Definition: def.h:141
    #define SCIP_HASHSIZE_CUTPOOLS
    Definition: def.h:281
    #define SCIP_INVALID
    Definition: def.h:178
    #define SCIP_Bool
    Definition: def.h:91
    #define MIN(x, y)
    Definition: def.h:224
    #define SCIP_ALLOC(x)
    Definition: def.h:366
    #define SCIP_Real
    Definition: def.h:156
    #define TRUE
    Definition: def.h:93
    #define FALSE
    Definition: def.h:94
    #define MAX(x, y)
    Definition: def.h:220
    #define SCIP_HASHSIZE_CUTPOOLS_SMALL
    Definition: def.h:284
    #define SCIP_CALL(x)
    Definition: def.h:355
    void SCIPhashtableFree(SCIP_HASHTABLE **hashtable)
    Definition: misc.c:2348
    SCIP_Bool SCIPhashtableExists(SCIP_HASHTABLE *hashtable, void *element)
    Definition: misc.c:2647
    #define SCIPhashTwo(a, b)
    Definition: pub_misc.h:568
    SCIP_RETCODE SCIPhashtableCreate(SCIP_HASHTABLE **hashtable, BMS_BLKMEM *blkmem, int tablesize, SCIP_DECL_HASHGETKEY((*hashgetkey)), SCIP_DECL_HASHKEYEQ((*hashkeyeq)), SCIP_DECL_HASHKEYVAL((*hashkeyval)), void *userptr)
    Definition: misc.c:2298
    void * SCIPhashtableRetrieve(SCIP_HASHTABLE *hashtable, void *key)
    Definition: misc.c:2596
    void SCIPhashtableRemoveAll(SCIP_HASHTABLE *hashtable)
    Definition: misc.c:2743
    static INLINE uint32_t SCIPrealHashCode(double x)
    Definition: pub_misc.h:593
    SCIP_RETCODE SCIPhashtableRemove(SCIP_HASHTABLE *hashtable, void *element)
    Definition: misc.c:2665
    SCIP_RETCODE SCIPhashtableInsert(SCIP_HASHTABLE *hashtable, void *element)
    Definition: misc.c:2535
    SCIP_CUT ** SCIPcutpoolGetCuts(SCIP_CUTPOOL *cutpool)
    Definition: cutpool.c:1067
    SCIP_Longint SCIPcutpoolGetNRootCalls(SCIP_CUTPOOL *cutpool)
    Definition: cutpool.c:1117
    SCIP_Longint SCIPcutpoolGetNCutsFound(SCIP_CUTPOOL *cutpool)
    Definition: cutpool.c:1127
    SCIP_Real SCIPcutGetLPActivityQuot(SCIP_CUT *cut)
    Definition: cutpool.c:406
    SCIP_Real SCIPcutpoolGetTime(SCIP_CUTPOOL *cutpool)
    Definition: cutpool.c:1097
    int SCIPcutpoolGetNCuts(SCIP_CUTPOOL *cutpool)
    Definition: cutpool.c:1077
    SCIP_Longint SCIPcutpoolGetMaxNCuts(SCIP_CUTPOOL *cutpool)
    Definition: cutpool.c:1087
    SCIP_ROW * SCIPcutGetRow(SCIP_CUT *cut)
    Definition: cutpool.c:382
    SCIP_Longint SCIPcutpoolGetNCalls(SCIP_CUTPOOL *cutpool)
    Definition: cutpool.c:1107
    int SCIPcutGetAge(SCIP_CUT *cut)
    Definition: cutpool.c:392
    SCIP_Longint SCIPcutpoolGetNCutsAdded(SCIP_CUTPOOL *cutpool)
    Definition: cutpool.c:1137
    void SCIProwSort(SCIP_ROW *row)
    Definition: lp.c:6232
    SCIP_Bool SCIProwIsModifiable(SCIP_ROW *row)
    Definition: lp.c:17805
    SCIP_Longint SCIProwGetActiveLPCount(SCIP_ROW *row)
    Definition: lp.c:17939
    int SCIProwGetNNonz(SCIP_ROW *row)
    Definition: lp.c:17607
    SCIP_Bool SCIProwIsLocal(SCIP_ROW *row)
    Definition: lp.c:17795
    SCIP_CONSHDLR * SCIProwGetOriginConshdlr(SCIP_ROW *row)
    Definition: lp.c:17850
    SCIP_Longint SCIProwGetNLPsAfterCreation(SCIP_ROW *row)
    Definition: lp.c:17949
    void SCIProwLock(SCIP_ROW *row)
    Definition: lp.c:5594
    SCIP_Bool SCIProwIsRemovable(SCIP_ROW *row)
    Definition: lp.c:17815
    const char * SCIProwGetName(SCIP_ROW *row)
    Definition: lp.c:17745
    SCIP_SEPA * SCIProwGetOriginSepa(SCIP_ROW *row)
    Definition: lp.c:17870
    void SCIProwUnlock(SCIP_ROW *row)
    Definition: lp.c:5609
    SCIP_Bool SCIProwIsInLP(SCIP_ROW *row)
    Definition: lp.c:17917
    SCIP_Real SCIProwGetMaxval(SCIP_ROW *row, SCIP_SET *set)
    Definition: lp.c:6901
    SCIP_Real SCIProwGetLPFeasibility(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp)
    Definition: lp.c:6484
    void SCIProwCapture(SCIP_ROW *row)
    Definition: lp.c:5554
    SCIP_Real SCIProwGetSolFeasibility(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_SOL *sol)
    Definition: lp.c:6738
    SCIP_Real SCIProwGetSolEfficacy(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_SOL *sol)
    Definition: lp.c:7111
    int SCIProwGetMaxidx(SCIP_ROW *row, SCIP_SET *set)
    Definition: lp.c:6933
    SCIP_LPSOLSTAT SCIPlpGetSolstat(SCIP_LP *lp)
    Definition: lp.c:13420
    SCIP_Real SCIProwGetMinval(SCIP_ROW *row, SCIP_SET *set)
    Definition: lp.c:6917
    SCIP_Real SCIProwGetLPEfficacy(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp)
    Definition: lp.c:7054
    SCIP_RETCODE SCIProwRelease(SCIP_ROW **row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_LP *lp)
    Definition: lp.c:5567
    internal methods for LP management
    #define BMSfreeMemory(ptr)
    Definition: memory.h:145
    #define BMSfreeBlockMemory(mem, ptr)
    Definition: memory.h:465
    #define BMSallocBlockMemory(mem, ptr)
    Definition: memory.h:451
    #define BMSreallocMemoryArray(ptr, num)
    Definition: memory.h:127
    struct BMS_BlkMem BMS_BLKMEM
    Definition: memory.h:437
    #define BMSfreeMemoryArrayNull(ptr)
    Definition: memory.h:148
    #define BMSallocMemory(ptr)
    Definition: memory.h:118
    public methods for message output
    #define SCIPerrorMessage
    Definition: pub_message.h:64
    public data structures and miscellaneous methods
    void SCIPsepaIncNCutsAdded(SCIP_SEPA *sepa, SCIP_Bool fromcutpool)
    Definition: sepa.c:1006
    void SCIPsepaIncNCutsFoundAtNode(SCIP_SEPA *sepa)
    Definition: sepa.c:1062
    internal methods for separators
    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
    int SCIPsepastoreGetNCutsAdded(SCIP_SEPASTORE *sepastore)
    Definition: sepastore.c:1194
    internal methods for storing separated cuts
    SCIP_Bool SCIPsetIsFeasPositive(SCIP_SET *set, SCIP_Real val)
    Definition: set.c:7076
    int SCIPsetGetSepaMaxcuts(SCIP_SET *set, SCIP_Bool root)
    Definition: set.c:6233
    SCIP_Bool SCIPsetIsFeasGT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
    Definition: set.c:7017
    SCIP_Bool SCIPsetIsFeasEQ(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
    Definition: set.c:6945
    SCIP_Bool SCIPsetIsFeasLT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
    Definition: set.c:6969
    SCIP_Bool SCIPsetIsInfinity(SCIP_SET *set, SCIP_Real val)
    Definition: set.c:6515
    int SCIPsetCalcMemGrowSize(SCIP_SET *set, int num)
    Definition: set.c:6080
    internal methods for global SCIP settings
    #define SCIPsetDebugMsg
    Definition: set.h:1811
    internal methods for problem statistics
    SCIP_Longint processedlp
    SCIP_Longint processedlpsol
    SCIP_ROW * row
    SCIP_Longint ncalls
    SCIP_Longint ncutsfound
    SCIP_Longint ncutsadded
    SCIP_Longint processedlpsol
    SCIP_Real processedlpsolefficacy
    SCIP_Real processedlpefficacy
    SCIP_Longint processedlp
    SCIP_CUT ** cuts
    SCIP_Longint maxncuts
    int firstunprocessedsol
    SCIP_CLOCK * poolclock
    SCIP_Longint nrootcalls
    SCIP_HASHTABLE * hashtable
    SCIP_Bool globalcutpool
    int nlpcols
    Definition: struct_lp.h:240
    unsigned int lpcolssorted
    Definition: struct_lp.h:256
    unsigned int inglobalcutpool
    Definition: struct_lp.h:267
    SCIP_Real rhs
    Definition: struct_lp.h:208
    int nunlinked
    Definition: struct_lp.h:241
    unsigned int nonlpcolssorted
    Definition: struct_lp.h:257
    SCIP_Real * vals
    Definition: struct_lp.h:232
    unsigned int validminmaxidx
    Definition: struct_lp.h:259
    SCIP_Real lhs
    Definition: struct_lp.h:207
    int maxidx
    Definition: struct_lp.h:247
    SCIP_COL ** cols
    Definition: struct_lp.h:230
    SCIP_Real constant
    Definition: struct_lp.h:206
    int * cols_index
    Definition: struct_lp.h:231
    int minidx
    Definition: struct_lp.h:246
    int age
    Definition: struct_lp.h:252
    unsigned int fromcutpool
    Definition: struct_lp.h:254
    int len
    Definition: struct_lp.h:239
    SCIP_Real minefficacyfac
    Definition: struct_stat.h:161
    SCIP_Longint lpcount
    Definition: struct_stat.h:205
    int ncutpoolfails
    Definition: struct_stat.h:256
    SCIP_Real bestefficacy
    Definition: struct_stat.h:160
    datastructures for storing cuts in a cut pool
    Definition: heur_padm.c:135
    @ SCIP_CLOCKTYPE_DEFAULT
    Definition: type_clock.h:43
    @ SCIP_LPSOLSTAT_OPTIMAL
    Definition: type_lp.h:44
    @ 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
    enum SCIP_Result SCIP_RESULT
    Definition: type_result.h:61
    @ SCIP_INVALIDDATA
    Definition: type_retcode.h:52
    @ SCIP_OKAY
    Definition: type_retcode.h:42
    enum SCIP_Retcode SCIP_RETCODE
    Definition: type_retcode.h:63