Scippy

    SCIP

    Solving Constraint Integer Programs

    scip_presol.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_presol.c
    26 * @ingroup OTHER_CFILES
    27 * @brief public methods for presolving plugins
    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/debug.h"
    46#include "scip/presol.h"
    47#include "scip/pub_message.h"
    48#include "scip/scip_presol.h"
    49#include "scip/set.h"
    50#include "scip/struct_mem.h"
    51#include "scip/struct_scip.h"
    52#include "scip/struct_set.h"
    53#include "scip/struct_stat.h"
    54
    55/** creates a presolver and includes it in SCIP.
    56 *
    57 * @pre This method can be called if SCIP is in one of the following stages:
    58 * - \ref SCIP_STAGE_INIT
    59 * - \ref SCIP_STAGE_PROBLEM
    60 *
    61 * @note method has all presolver callbacks as arguments and is thus changed every time a new
    62 * callback is added
    63 * in future releases; consider using SCIPincludePresolBasic() and setter functions
    64 * if you seek for a method which is less likely to change in future releases
    65 */
    67 SCIP* scip, /**< SCIP data structure */
    68 const char* name, /**< name of presolver */
    69 const char* desc, /**< description of presolver */
    70 int priority, /**< priority of the presolver (>= 0: before, < 0: after constraint handlers) */
    71 int maxrounds, /**< maximal number of presolving rounds the presolver participates in (-1: no limit) */
    72 SCIP_PRESOLTIMING timing, /**< timing mask of the presolver */
    73 SCIP_DECL_PRESOLCOPY ((*presolcopy)), /**< copy method of presolver or NULL if you don't want to copy your plugin into sub-SCIPs */
    74 SCIP_DECL_PRESOLFREE ((*presolfree)), /**< destructor of presolver to free user data (called when SCIP is exiting) */
    75 SCIP_DECL_PRESOLINIT ((*presolinit)), /**< initialization method of presolver (called after problem was transformed) */
    76 SCIP_DECL_PRESOLEXIT ((*presolexit)), /**< deinitialization method of presolver (called before transformed problem is freed) */
    77 SCIP_DECL_PRESOLINITPRE((*presolinitpre)),/**< presolving initialization method of presolver (called when presolving is about to begin) */
    78 SCIP_DECL_PRESOLEXITPRE((*presolexitpre)),/**< presolving deinitialization method of presolver (called after presolving has been finished) */
    79 SCIP_DECL_PRESOLEXEC ((*presolexec)), /**< execution method of presolver */
    80 SCIP_PRESOLDATA* presoldata /**< presolver data */
    81 )
    82{
    83 SCIP_PRESOL* presol;
    84
    86
    87 /* check whether presolver is already present */
    88 if( SCIPfindPresol(scip, name) != NULL )
    89 {
    90 SCIPerrorMessage("presolver <%s> already included.\n", name);
    91 return SCIP_INVALIDDATA;
    92 }
    93
    94 SCIP_CALL( SCIPpresolCreate(&presol, scip->set, scip->messagehdlr, scip->mem->setmem, name, desc, priority,
    95 maxrounds, timing, presolcopy,
    96 presolfree, presolinit, presolexit, presolinitpre, presolexitpre, presolexec, presoldata) );
    97 SCIP_CALL( SCIPsetIncludePresol(scip->set, presol) );
    98
    99 return SCIP_OKAY;
    100}
    101
    102/** creates a presolver and includes it in SCIP with its fundamental callback. All non-fundamental (or optional)
    103 * callbacks as, e.g., init and exit callbacks, will be set to NULL. Optional callbacks can be set via specific setter
    104 * functions. These are SCIPsetPresolCopy(), SCIPsetPresolFree(), SCIPsetPresolInit(), SCIPsetPresolExit(),
    105 * SCIPsetPresolInitpre(), and SCIPsetPresolExitPre().
    106 *
    107 * @pre This method can be called if SCIP is in one of the following stages:
    108 * - \ref SCIP_STAGE_INIT
    109 * - \ref SCIP_STAGE_PROBLEM
    110 *
    111 * @note if you want to set all callbacks with a single method call, consider using SCIPincludePresol() instead
    112 */
    114 SCIP* scip, /**< SCIP data structure */
    115 SCIP_PRESOL** presolptr, /**< reference to presolver, or NULL */
    116 const char* name, /**< name of presolver */
    117 const char* desc, /**< description of presolver */
    118 int priority, /**< priority of the presolver (>= 0: before, < 0: after constraint handlers) */
    119 int maxrounds, /**< maximal number of presolving rounds the presolver participates in (-1: no limit) */
    120 SCIP_PRESOLTIMING timing, /**< timing mask of the presolver */
    121 SCIP_DECL_PRESOLEXEC ((*presolexec)), /**< execution method of presolver */
    122 SCIP_PRESOLDATA* presoldata /**< presolver data */
    123 )
    124{
    125 SCIP_PRESOL* presol;
    126
    127 SCIP_CALL( SCIPcheckStage(scip, "SCIPincludePresolBasic", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
    128
    129 /* check whether presolver is already present */
    130 if( SCIPfindPresol(scip, name) != NULL )
    131 {
    132 SCIPerrorMessage("presolver <%s> already included.\n", name);
    133 return SCIP_INVALIDDATA;
    134 }
    135
    136 SCIP_CALL( SCIPpresolCreate(&presol, scip->set, scip->messagehdlr, scip->mem->setmem, name, desc, priority, maxrounds, timing,
    137 NULL,
    138 NULL, NULL, NULL, NULL, NULL, presolexec, presoldata) );
    139 SCIP_CALL( SCIPsetIncludePresol(scip->set, presol) );
    140
    141 if( presolptr != NULL )
    142 *presolptr = presol;
    143
    144 return SCIP_OKAY;
    145}
    146
    147/** sets copy method of presolver */
    149 SCIP* scip, /**< SCIP data structure */
    150 SCIP_PRESOL* presol, /**< presolver */
    151 SCIP_DECL_PRESOLCOPY ((*presolcopy)) /**< copy method of presolver or NULL if you don't want to copy your plugin into sub-SCIPs */
    152 )
    153{
    155
    156 assert(presol != NULL);
    157
    158 SCIPpresolSetCopy(presol, presolcopy);
    159
    160 return SCIP_OKAY;
    161}
    162
    163/** sets destructor method of presolver */
    165 SCIP* scip, /**< SCIP data structure */
    166 SCIP_PRESOL* presol, /**< presolver */
    167 SCIP_DECL_PRESOLFREE ((*presolfree)) /**< destructor of presolver */
    168 )
    169{
    171
    172 assert(presol != NULL);
    173
    174 SCIPpresolSetFree(presol, presolfree);
    175
    176 return SCIP_OKAY;
    177}
    178
    179/** sets initialization method of presolver */
    181 SCIP* scip, /**< SCIP data structure */
    182 SCIP_PRESOL* presol, /**< presolver */
    183 SCIP_DECL_PRESOLINIT ((*presolinit)) /**< initialize presolver */
    184 )
    185{
    187
    188 assert(presol != NULL);
    189
    190 SCIPpresolSetInit(presol, presolinit);
    191
    192 return SCIP_OKAY;
    193}
    194
    195/** sets deinitialization method of presolver */
    197 SCIP* scip, /**< SCIP data structure */
    198 SCIP_PRESOL* presol, /**< presolver */
    199 SCIP_DECL_PRESOLEXIT ((*presolexit)) /**< deinitialize presolver */
    200 )
    201{
    203
    204 assert(presol != NULL);
    205
    206 SCIPpresolSetExit(presol, presolexit);
    207
    208 return SCIP_OKAY;
    209}
    210
    211/** sets solving process initialization method of presolver */
    213 SCIP* scip, /**< SCIP data structure */
    214 SCIP_PRESOL* presol, /**< presolver */
    215 SCIP_DECL_PRESOLINITPRE ((*presolinitpre))/**< solving process initialization method of presolver */
    216 )
    217{
    218 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetPresolInitpre", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
    219
    220 assert(presol != NULL);
    221
    222 SCIPpresolSetInitpre(presol, presolinitpre);
    223
    224 return SCIP_OKAY;
    225}
    226
    227/** sets solving process deinitialization method of presolver */
    229 SCIP* scip, /**< SCIP data structure */
    230 SCIP_PRESOL* presol, /**< presolver */
    231 SCIP_DECL_PRESOLEXITPRE ((*presolexitpre))/**< solving process deinitialization method of presolver */
    232 )
    233{
    234 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetPresolExitpre", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
    235
    236 assert(presol != NULL);
    237
    238 SCIPpresolSetExitpre(presol, presolexitpre);
    239
    240 return SCIP_OKAY;
    241}
    242
    243/** returns the presolver of the given name, or NULL if not existing */
    245 SCIP* scip, /**< SCIP data structure */
    246 const char* name /**< name of presolver */
    247 )
    248{
    249 assert(scip != NULL);
    250 assert(scip->set != NULL);
    251 assert(name != NULL);
    252
    253 return SCIPsetFindPresol(scip->set, name);
    254}
    255
    256/** returns the array of currently available presolvers */
    258 SCIP* scip /**< SCIP data structure */
    259 )
    260{
    261 assert(scip != NULL);
    262 assert(scip->set != NULL);
    263
    265
    266 return scip->set->presols;
    267}
    268
    269/** returns the number of currently available presolvers */
    271 SCIP* scip /**< SCIP data structure */
    272 )
    273{
    274 assert(scip != NULL);
    275 assert(scip->set != NULL);
    276
    277 return scip->set->npresols;
    278}
    279
    280/** sets the priority of a presolver */
    282 SCIP* scip, /**< SCIP data structure */
    283 SCIP_PRESOL* presol, /**< presolver */
    284 int priority /**< new priority of the presolver */
    285 )
    286{
    287 assert(scip != NULL);
    288 assert(scip->set != NULL);
    289
    290 SCIPpresolSetPriority(presol, scip->set, priority);
    291
    292 return SCIP_OKAY;
    293}
    294
    295/** returns the number of presolve rounds (current or last presolve) */
    297 SCIP* scip /**< SCIP data structure */
    298 )
    299{
    300 assert(scip != NULL);
    301 assert(scip->stat != NULL);
    302
    303 return scip->stat->npresolrounds;
    304}
    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 TRUE
    Definition: def.h:93
    #define FALSE
    Definition: def.h:94
    #define SCIP_CALL(x)
    Definition: def.h:355
    SCIP_RETCODE SCIPincludePresol(SCIP *scip, const char *name, const char *desc, int priority, int maxrounds, SCIP_PRESOLTIMING timing, SCIP_DECL_PRESOLCOPY((*presolcopy)), SCIP_DECL_PRESOLFREE((*presolfree)), SCIP_DECL_PRESOLINIT((*presolinit)), SCIP_DECL_PRESOLEXIT((*presolexit)), SCIP_DECL_PRESOLINITPRE((*presolinitpre)), SCIP_DECL_PRESOLEXITPRE((*presolexitpre)), SCIP_DECL_PRESOLEXEC((*presolexec)), SCIP_PRESOLDATA *presoldata)
    Definition: scip_presol.c:66
    SCIP_RETCODE SCIPsetPresolExitpre(SCIP *scip, SCIP_PRESOL *presol, SCIP_DECL_PRESOLEXITPRE((*presolexitpre)))
    Definition: scip_presol.c:228
    SCIP_RETCODE SCIPsetPresolInit(SCIP *scip, SCIP_PRESOL *presol, SCIP_DECL_PRESOLINIT((*presolinit)))
    Definition: scip_presol.c:180
    SCIP_PRESOL ** SCIPgetPresols(SCIP *scip)
    Definition: scip_presol.c:257
    SCIP_RETCODE SCIPsetPresolFree(SCIP *scip, SCIP_PRESOL *presol, SCIP_DECL_PRESOLFREE((*presolfree)))
    Definition: scip_presol.c:164
    SCIP_RETCODE SCIPsetPresolPriority(SCIP *scip, SCIP_PRESOL *presol, int priority)
    Definition: scip_presol.c:281
    SCIP_RETCODE SCIPsetPresolExit(SCIP *scip, SCIP_PRESOL *presol, SCIP_DECL_PRESOLEXIT((*presolexit)))
    Definition: scip_presol.c:196
    SCIP_PRESOL * SCIPfindPresol(SCIP *scip, const char *name)
    Definition: scip_presol.c:244
    int SCIPgetNPresols(SCIP *scip)
    Definition: scip_presol.c:270
    SCIP_RETCODE SCIPsetPresolCopy(SCIP *scip, SCIP_PRESOL *presol, SCIP_DECL_PRESOLCOPY((*presolcopy)))
    Definition: scip_presol.c:148
    SCIP_RETCODE SCIPincludePresolBasic(SCIP *scip, SCIP_PRESOL **presolptr, const char *name, const char *desc, int priority, int maxrounds, SCIP_PRESOLTIMING timing, SCIP_DECL_PRESOLEXEC((*presolexec)), SCIP_PRESOLDATA *presoldata)
    Definition: scip_presol.c:113
    SCIP_RETCODE SCIPsetPresolInitpre(SCIP *scip, SCIP_PRESOL *presol, SCIP_DECL_PRESOLINITPRE((*presolinitpre)))
    Definition: scip_presol.c:212
    int SCIPgetNPresolRounds(SCIP *scip)
    Definition: scip_presol.c:296
    void SCIPpresolSetExitpre(SCIP_PRESOL *presol, SCIP_DECL_PRESOLEXITPRE((*presolexitpre)))
    Definition: presol.c:604
    void SCIPpresolSetPriority(SCIP_PRESOL *presol, SCIP_SET *set, int priority)
    Definition: presol.c:665
    void SCIPpresolSetExit(SCIP_PRESOL *presol, SCIP_DECL_PRESOLEXIT((*presolexit)))
    Definition: presol.c:582
    void SCIPpresolSetInitpre(SCIP_PRESOL *presol, SCIP_DECL_PRESOLINITPRE((*presolinitpre)))
    Definition: presol.c:593
    SCIP_RETCODE SCIPpresolCreate(SCIP_PRESOL **presol, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, BMS_BLKMEM *blkmem, const char *name, const char *desc, int priority, int maxrounds, SCIP_PRESOLTIMING timing, SCIP_DECL_PRESOLCOPY((*presolcopy)), SCIP_DECL_PRESOLFREE((*presolfree)), SCIP_DECL_PRESOLINIT((*presolinit)), SCIP_DECL_PRESOLEXIT((*presolexit)), SCIP_DECL_PRESOLINITPRE((*presolinitpre)), SCIP_DECL_PRESOLEXITPRE((*presolexitpre)), SCIP_DECL_PRESOLEXEC((*presolexec)), SCIP_PRESOLDATA *presoldata)
    Definition: presol.c:181
    void SCIPpresolSetCopy(SCIP_PRESOL *presol, SCIP_DECL_PRESOLCOPY((*presolcopy)))
    Definition: presol.c:549
    void SCIPpresolSetFree(SCIP_PRESOL *presol, SCIP_DECL_PRESOLFREE((*presolfree)))
    Definition: presol.c:560
    void SCIPpresolSetInit(SCIP_PRESOL *presol, SCIP_DECL_PRESOLINIT((*presolinit)))
    Definition: presol.c:571
    internal methods for presolvers
    public methods for message output
    #define SCIPerrorMessage
    Definition: pub_message.h:64
    public methods for presolving plugins
    void SCIPsetSortPresols(SCIP_SET *set)
    Definition: set.c:4381
    SCIP_RETCODE SCIPsetIncludePresol(SCIP_SET *set, SCIP_PRESOL *presol)
    Definition: set.c:4338
    SCIP_PRESOL * SCIPsetFindPresol(SCIP_SET *set, const char *name)
    Definition: set.c:4361
    internal methods for global SCIP settings
    datastructures for block memory pools and memory buffers
    SCIP main data structure.
    datastructures for global SCIP settings
    datastructures for problem statistics
    #define SCIP_DECL_PRESOLCOPY(x)
    Definition: type_presol.h:60
    struct SCIP_PresolData SCIP_PRESOLDATA
    Definition: type_presol.h:51
    #define SCIP_DECL_PRESOLFREE(x)
    Definition: type_presol.h:68
    #define SCIP_DECL_PRESOLINITPRE(x)
    Definition: type_presol.h:98
    #define SCIP_DECL_PRESOLEXITPRE(x)
    Definition: type_presol.h:116
    #define SCIP_DECL_PRESOLINIT(x)
    Definition: type_presol.h:76
    #define SCIP_DECL_PRESOLEXIT(x)
    Definition: type_presol.h:84
    #define SCIP_DECL_PRESOLEXEC(x)
    Definition: type_presol.h:167
    @ SCIP_INVALIDDATA
    Definition: type_retcode.h:52
    @ SCIP_OKAY
    Definition: type_retcode.h:42
    enum SCIP_Retcode SCIP_RETCODE
    Definition: type_retcode.h:63
    unsigned int SCIP_PRESOLTIMING
    Definition: type_timing.h:61