Scippy

    SCIP

    Solving Constraint Integer Programs

    event_globalbnd.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 event_globalbnd.c
    26 * @ingroup DEFPLUGINS_EVENT
    27 * @brief eventhandler for storing all global bound changes
    28 * @author Leona Gottwald
    29 *
    30 * the bound changes are stored so that they can be shared with other threads
    31 * in a concurrent solve.
    32 */
    33
    34/*--+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
    35
    37#include "scip/boundstore.h"
    38#include "scip/concurrent.h"
    40#include "scip/pub_event.h"
    41#include "scip/pub_lp.h"
    42#include "scip/pub_message.h"
    43#include "scip/pub_var.h"
    45#include "scip/scip_copy.h"
    46#include "scip/scip_event.h"
    47#include "scip/scip_mem.h"
    48#include "scip/scip_message.h"
    49#include "scip/scip_prob.h"
    50#include "scip/syncstore.h"
    51#include <string.h>
    52
    53#define EVENTHDLR_NAME "globalbnd"
    54#define EVENTHDLR_DESC "event handler for globalbnd event"
    55
    56
    57/*
    58 * Data structures
    59 */
    60
    61/** event handler data */
    62struct SCIP_EventhdlrData
    63{
    64 int filterpos;
    65 SCIP_Bool storebounds;
    66 SCIP_BOUNDSTORE* boundstore;
    67};
    68
    69/*
    70 * Local methods
    71 */
    72
    73/*
    74 * Callback methods of event handler
    75 */
    76
    77/** destructor of event handler to free user data (called when SCIP is exiting) */
    78static
    79SCIP_DECL_EVENTFREE(eventFreeGlobalbnd)
    80{ /*lint --e{715}*/
    81 SCIP_EVENTHDLRDATA* eventhdlrdata;
    82
    83 assert(scip != NULL);
    84 assert(eventhdlr != NULL);
    85 assert(strcmp(SCIPeventhdlrGetName(eventhdlr), EVENTHDLR_NAME) == 0);
    86
    87 eventhdlrdata = SCIPeventhdlrGetData(eventhdlr);
    88 assert(eventhdlrdata != NULL);
    89
    90 SCIPfreeMemory(scip, &eventhdlrdata);
    91 SCIPeventhdlrSetData(eventhdlr, NULL);
    92
    93 return SCIP_OKAY;
    94}
    95
    96/** initialization method of event handler (called after problem was transformed) */
    97static
    98SCIP_DECL_EVENTINIT(eventInitGlobalbnd)
    99{ /*lint --e{715}*/
    100 SCIP_EVENTHDLRDATA* eventhdlrdata;
    101
    102 assert(scip != NULL);
    103 assert(eventhdlr != NULL);
    104 assert(strcmp(SCIPeventhdlrGetName(eventhdlr), EVENTHDLR_NAME) == 0);
    105
    106 eventhdlrdata = SCIPeventhdlrGetData(eventhdlr);
    107 assert(eventhdlrdata != NULL);
    108
    109 if( eventhdlrdata->filterpos < 0 && SCIPgetSubscipDepth(scip) == 0 && SCIPsyncstoreIsInitialized(SCIPgetSyncstore(scip)) )
    110 {
    111 SCIP_VAR** vars;
    112 int nvars;
    113 int i;
    114
    115 SCIPdebugMsg(scip, "catching events in " EVENTHDLR_NAME " eventhdlr\n");
    116
    117 /* notify SCIP that this event handler wants to react on global bound change events */
    118 nvars = SCIPgetNVars(scip);
    119 vars = SCIPgetVars(scip);
    120 eventhdlrdata->storebounds = TRUE;
    121 SCIP_CALL( SCIPboundstoreCreate(scip, &eventhdlrdata->boundstore, SCIPgetNOrigVars(scip)) );
    122
    123 SCIP_CALL( SCIPcatchEvent(scip, SCIP_EVENTTYPE_VARADDED, eventhdlr, NULL, &eventhdlrdata->filterpos) );
    124 for( i = 0; i < nvars ; ++i )
    125 {
    127 }
    128 }
    129
    130 return SCIP_OKAY;
    131}
    132
    133/** deinitialization method of event handler (called before transformed problem is freed) */
    134static
    135SCIP_DECL_EVENTEXIT(eventExitGlobalbnd)
    136{ /*lint --e{715}*/
    137 SCIP_EVENTHDLRDATA* eventhdlrdata;
    138
    139 assert(scip != NULL);
    140 assert(eventhdlr != NULL);
    141 assert(strcmp(SCIPeventhdlrGetName(eventhdlr), EVENTHDLR_NAME) == 0);
    142
    143 eventhdlrdata = SCIPeventhdlrGetData(eventhdlr);
    144 assert(eventhdlrdata != NULL);
    145
    146 /* notify SCIP that your event handler wants to drop the event type var added */
    147 if( eventhdlrdata->filterpos >= 0 )
    148 {
    149 SCIP_CALL( SCIPdropEvent(scip, SCIP_EVENTTYPE_VARADDED, eventhdlr, NULL, eventhdlrdata->filterpos) );
    150 eventhdlrdata->filterpos = -1;
    151 SCIPboundstoreFree(scip, &eventhdlrdata->boundstore);
    152 }
    153
    154 return SCIP_OKAY;
    155}
    156
    157/** execution method of event handler */
    158static
    159SCIP_DECL_EVENTEXEC(eventExecGlobalbnd)
    160{ /*lint --e{715}*/
    161 SCIP_EVENTHDLRDATA* eventhdlrdata;
    162 SCIP_VAR* var;
    163 SCIP_Real newbound;
    164 SCIP_BOUNDTYPE boundtype;
    165 SCIP_Real constant;
    166 SCIP_Real scalar;
    167
    168 SCIPdebugMsg(scip, "exec method of eventhdlr " EVENTHDLR_NAME "\n");
    169
    170 assert(eventhdlr != NULL);
    171 assert(strcmp(SCIPeventhdlrGetName(eventhdlr), EVENTHDLR_NAME) == 0);
    172 assert(event != NULL);
    173 assert(scip != NULL);
    174
    175 eventhdlrdata = SCIPeventhdlrGetData(eventhdlr);
    176 assert(eventhdlrdata != NULL);
    177
    178 var = SCIPeventGetVar(event);
    179 switch( SCIPeventGetType(event) )
    180 {
    183 return SCIP_OKAY;
    185 boundtype = SCIP_BOUNDTYPE_LOWER;
    186 break;
    188 boundtype = SCIP_BOUNDTYPE_UPPER;
    189 break;
    190 default:
    191 SCIPABORT();
    192 return SCIP_ERROR; /*lint !e527*/
    193 }
    194
    195 if( !eventhdlrdata->storebounds )
    196 return SCIP_OKAY;
    197
    198 newbound = SCIPeventGetNewbound(event);
    199 constant = 0.0;
    200 scalar = 1.0;
    201 SCIP_CALL( SCIPvarGetOrigvarSum(&var, &scalar, &constant) );
    202 if( var != NULL )
    203 {
    204 int varidx;
    205
    206 varidx = SCIPgetConcurrentVaridx(scip, var);
    207 if( varidx >= 0 )
    208 {
    209 boundtype = scalar < 0.0 ? SCIPboundtypeOpposite(boundtype) : boundtype;
    210 newbound = (newbound - constant) / scalar;
    211
    212 SCIP_CALL( SCIPboundstoreAdd(scip, eventhdlrdata->boundstore, varidx, newbound, boundtype) );
    213 }
    214 }
    215 return SCIP_OKAY;
    216}
    217
    218/** creates event handler for globalbnd event */
    220 SCIP* scip /**< SCIP data structure */
    221 )
    222{
    223 SCIP_EVENTHDLRDATA* eventhdlrdata = NULL;
    224 SCIP_EVENTHDLR* eventhdlr = NULL;
    225
    226 /* create globalbnd event handler data */
    227 SCIP_CALL( SCIPallocMemory(scip, &eventhdlrdata) );
    228 eventhdlrdata->filterpos = -1;
    229
    230 /* include event handler into SCIP */
    231
    232 /* use SCIPincludeEventhdlrBasic() plus setter functions if you want to set callbacks one-by-one and your code should
    233 * compile independent of new callbacks being added in future SCIP versions
    234 */
    236 eventExecGlobalbnd, eventhdlrdata) );
    237 assert(eventhdlr != NULL);
    238
    239 /* set non fundamental callbacks via setter functions */
    240 SCIP_CALL( SCIPsetEventhdlrFree(scip, eventhdlr, eventFreeGlobalbnd) );
    241 SCIP_CALL( SCIPsetEventhdlrInit(scip, eventhdlr, eventInitGlobalbnd) );
    242 SCIP_CALL( SCIPsetEventhdlrExit(scip, eventhdlr, eventExitGlobalbnd) );
    243
    244 return SCIP_OKAY;
    245}
    246
    247
    248/** gets the global bound changes stored in the eventhandler */
    250 SCIP_EVENTHDLR* eventhdlr /**< the globalbound eventhandler */
    251 )
    252{
    253 SCIP_EVENTHDLRDATA* eventhdlrdata;
    254 assert(eventhdlr != NULL);
    255 assert(strcmp(EVENTHDLR_NAME, SCIPeventhdlrGetName(eventhdlr)) == 0);
    256
    257 eventhdlrdata = SCIPeventhdlrGetData(eventhdlr);
    258 assert(eventhdlrdata != NULL);
    259
    260 return eventhdlrdata->boundstore;
    261}
    262
    263/** enables storing of bound changes */
    265 SCIP_EVENTHDLR* eventhdlr /**< the globalbound eventhandler */
    266 )
    267{
    268 SCIP_EVENTHDLRDATA* eventhdlrdata;
    269
    270 assert(eventhdlr != NULL);
    271 assert(strcmp(EVENTHDLR_NAME, SCIPeventhdlrGetName(eventhdlr)) == 0);
    272
    273 eventhdlrdata = SCIPeventhdlrGetData(eventhdlr);
    274 assert(eventhdlrdata != NULL);
    275
    276 eventhdlrdata->storebounds = TRUE;
    277}
    278
    279/** disables storing of bound changes */
    281 SCIP_EVENTHDLR* eventhdlr /**< the globalbound eventhandler */
    282 )
    283{
    284 SCIP_EVENTHDLRDATA* eventhdlrdata;
    285
    286 assert(eventhdlr != NULL);
    287 assert(strcmp(EVENTHDLR_NAME, SCIPeventhdlrGetName(eventhdlr)) == 0);
    288
    289 eventhdlrdata = SCIPeventhdlrGetData(eventhdlr);
    290 assert(eventhdlrdata != NULL);
    291
    292 eventhdlrdata->storebounds = FALSE;
    293}
    294
    295/** clears all bound changes stored in the eventhandler */
    297 SCIP_EVENTHDLR* eventhdlr /**< the globalbound eventhandler */
    298 )
    299{
    300 SCIP_EVENTHDLRDATA* eventhdlrdata;
    301
    302 assert(eventhdlr != NULL);
    303 assert(strcmp(EVENTHDLR_NAME, SCIPeventhdlrGetName(eventhdlr)) == 0);
    304
    305 eventhdlrdata = SCIPeventhdlrGetData(eventhdlr);
    306 assert(eventhdlrdata != NULL);
    307
    308 SCIPboundstoreClear(eventhdlrdata->boundstore);
    309}
    SCIP_RETCODE SCIPboundstoreAdd(SCIP *scip, SCIP_BOUNDSTORE *boundstore, int varidx, SCIP_Real newbound, SCIP_BOUNDTYPE boundtype)
    Definition: boundstore.c:75
    void SCIPboundstoreFree(SCIP *scip, SCIP_BOUNDSTORE **boundstore)
    Definition: boundstore.c:60
    SCIP_RETCODE SCIPboundstoreCreate(SCIP *scip, SCIP_BOUNDSTORE **boundstore, int nvars)
    Definition: boundstore.c:39
    void SCIPboundstoreClear(SCIP_BOUNDSTORE *boundstore)
    Definition: boundstore.c:146
    the interface of the boundstore structure
    int SCIPgetConcurrentVaridx(SCIP *scip, SCIP_VAR *var)
    Definition: concurrent.c:434
    helper functions for concurrent scip solvers
    #define NULL
    Definition: def.h:248
    #define SCIP_Bool
    Definition: def.h:91
    #define SCIP_Real
    Definition: def.h:156
    #define TRUE
    Definition: def.h:93
    #define FALSE
    Definition: def.h:94
    #define SCIPABORT()
    Definition: def.h:327
    #define SCIP_CALL(x)
    Definition: def.h:355
    void SCIPeventGlobalbndClearBoundChanges(SCIP_EVENTHDLR *eventhdlr)
    static SCIP_DECL_EVENTFREE(eventFreeGlobalbnd)
    static SCIP_DECL_EVENTEXEC(eventExecGlobalbnd)
    static SCIP_DECL_EVENTEXIT(eventExitGlobalbnd)
    SCIP_RETCODE SCIPincludeEventHdlrGlobalbnd(SCIP *scip)
    void SCIPeventGlobalbndEnableBoundStorage(SCIP_EVENTHDLR *eventhdlr)
    SCIP_BOUNDSTORE * SCIPeventGlobalbndGetBoundChanges(SCIP_EVENTHDLR *eventhdlr)
    static SCIP_DECL_EVENTINIT(eventInitGlobalbnd)
    #define EVENTHDLR_DESC
    void SCIPeventGlobalbndDisableBoundStorage(SCIP_EVENTHDLR *eventhdlr)
    #define EVENTHDLR_NAME
    eventhdlr for storing all global bound changes
    int SCIPgetSubscipDepth(SCIP *scip)
    Definition: scip_copy.c:2588
    int SCIPgetNVars(SCIP *scip)
    Definition: scip_prob.c:2246
    SCIP_VAR ** SCIPgetVars(SCIP *scip)
    Definition: scip_prob.c:2201
    int SCIPgetNOrigVars(SCIP *scip)
    Definition: scip_prob.c:2838
    #define SCIPdebugMsg
    Definition: scip_message.h:78
    SCIP_BOUNDTYPE SCIPboundtypeOpposite(SCIP_BOUNDTYPE boundtype)
    Definition: lp.c:17597
    SCIP_RETCODE SCIPincludeEventhdlrBasic(SCIP *scip, SCIP_EVENTHDLR **eventhdlrptr, const char *name, const char *desc, SCIP_DECL_EVENTEXEC((*eventexec)), SCIP_EVENTHDLRDATA *eventhdlrdata)
    Definition: scip_event.c:111
    const char * SCIPeventhdlrGetName(SCIP_EVENTHDLR *eventhdlr)
    Definition: event.c:396
    SCIP_EVENTHDLRDATA * SCIPeventhdlrGetData(SCIP_EVENTHDLR *eventhdlr)
    Definition: event.c:406
    void SCIPeventhdlrSetData(SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTHDLRDATA *eventhdlrdata)
    Definition: event.c:416
    SCIP_RETCODE SCIPsetEventhdlrFree(SCIP *scip, SCIP_EVENTHDLR *eventhdlr, SCIP_DECL_EVENTFREE((*eventfree)))
    Definition: scip_event.c:157
    SCIP_RETCODE SCIPsetEventhdlrExit(SCIP *scip, SCIP_EVENTHDLR *eventhdlr, SCIP_DECL_EVENTEXIT((*eventexit)))
    Definition: scip_event.c:185
    SCIP_RETCODE SCIPsetEventhdlrInit(SCIP *scip, SCIP_EVENTHDLR *eventhdlr, SCIP_DECL_EVENTINIT((*eventinit)))
    Definition: scip_event.c:171
    SCIP_EVENTTYPE SCIPeventGetType(SCIP_EVENT *event)
    Definition: event.c:1194
    SCIP_RETCODE SCIPcatchVarEvent(SCIP *scip, SCIP_VAR *var, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int *filterpos)
    Definition: scip_event.c:367
    SCIP_VAR * SCIPeventGetVar(SCIP_EVENT *event)
    Definition: event.c:1217
    SCIP_Real SCIPeventGetNewbound(SCIP_EVENT *event)
    Definition: event.c:1415
    SCIP_RETCODE SCIPcatchEvent(SCIP *scip, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int *filterpos)
    Definition: scip_event.c:293
    SCIP_RETCODE SCIPdropEvent(SCIP *scip, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int filterpos)
    Definition: scip_event.c:333
    #define SCIPallocMemory(scip, ptr)
    Definition: scip_mem.h:60
    #define SCIPfreeMemory(scip, ptr)
    Definition: scip_mem.h:78
    SCIP_SYNCSTORE * SCIPgetSyncstore(SCIP *scip)
    SCIP_RETCODE SCIPvarGetOrigvarSum(SCIP_VAR **var, SCIP_Real *scalar, SCIP_Real *constant)
    Definition: var.c:18320
    memory allocation routines
    public methods for managing events
    public methods for LP management
    public methods for message output
    public methods for problem variables
    public methods for concurrent solving mode
    public methods for problem copies
    public methods for event handler plugins and event handlers
    public methods for memory management
    public methods for message handling
    public methods for global and local (sub)problems
    SCIP_Bool SCIPsyncstoreIsInitialized(SCIP_SYNCSTORE *syncstore)
    Definition: syncstore.c:795
    the function declarations for the synchronization store
    #define SCIP_EVENTTYPE_GUBCHANGED
    Definition: type_event.h:76
    #define SCIP_EVENTTYPE_GBDCHANGED
    Definition: type_event.h:122
    struct SCIP_EventhdlrData SCIP_EVENTHDLRDATA
    Definition: type_event.h:160
    #define SCIP_EVENTTYPE_GLBCHANGED
    Definition: type_event.h:75
    #define SCIP_EVENTTYPE_VARADDED
    Definition: type_event.h:70
    @ SCIP_BOUNDTYPE_UPPER
    Definition: type_lp.h:58
    @ SCIP_BOUNDTYPE_LOWER
    Definition: type_lp.h:57
    enum SCIP_BoundType SCIP_BOUNDTYPE
    Definition: type_lp.h:60
    @ SCIP_OKAY
    Definition: type_retcode.h:42
    @ SCIP_ERROR
    Definition: type_retcode.h:43
    enum SCIP_Retcode SCIP_RETCODE
    Definition: type_retcode.h:63