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-2026 Zuse Institute Berlin (ZIB) */
    7/* */
    8/* Licensed under the Apache License, Version 2.0 (the "License"); */
    9/* you may not use this file except in compliance with the License. */
    10/* You may obtain a copy of the License at */
    11/* */
    12/* http://www.apache.org/licenses/LICENSE-2.0 */
    13/* */
    14/* Unless required by applicable law or agreed to in writing, software */
    15/* distributed under the License is distributed on an "AS IS" BASIS, */
    16/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
    17/* See the License for the specific language governing permissions and */
    18/* limitations under the License. */
    19/* */
    20/* You should have received a copy of the Apache-2.0 license */
    21/* along with SCIP; see the file LICENSE. If not visit scipopt.org. */
    22/* */
    23/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    24
    25/**@file 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
    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
    87
    88 eventhdlrdata = SCIPeventhdlrGetData(eventhdlr);
    89 assert(eventhdlrdata != NULL);
    90
    91 SCIPfreeMemory(scip, &eventhdlrdata);
    92 SCIPeventhdlrSetData(eventhdlr, NULL);
    93
    94 return SCIP_OKAY;
    95}
    96
    97/** initialization method of event handler (called after problem was transformed) */
    98static
    99SCIP_DECL_EVENTINIT(eventInitGlobalbnd)
    100{ /*lint --e{715}*/
    101 SCIP_EVENTHDLRDATA* eventhdlrdata;
    102
    103 assert(scip != NULL);
    104 assert(eventhdlr != NULL);
    105
    107
    108 eventhdlrdata = SCIPeventhdlrGetData(eventhdlr);
    109 assert(eventhdlrdata != NULL);
    110
    111 if( eventhdlrdata->filterpos < 0 && SCIPgetSubscipDepth(scip) == 0 && SCIPsyncstoreIsInitialized(SCIPgetSyncstore(scip)) )
    112 {
    113 SCIP_VAR** vars;
    114 int nvars;
    115 int i;
    116
    117 SCIPdebugMsg(scip, "catching events in " EVENTHDLR_NAME " eventhdlr\n");
    118
    119 /* notify SCIP that this event handler wants to react on global bound change events */
    120 nvars = SCIPgetNVars(scip);
    121 vars = SCIPgetVars(scip);
    122 eventhdlrdata->storebounds = TRUE;
    123 SCIP_CALL( SCIPboundstoreCreate(scip, &eventhdlrdata->boundstore, SCIPgetNOrigVars(scip)) );
    124
    125 SCIP_CALL( SCIPcatchEvent(scip, SCIP_EVENTTYPE_VARADDED, eventhdlr, NULL, &eventhdlrdata->filterpos) );
    126 for( i = 0; i < nvars ; ++i )
    127 {
    129 }
    130 }
    131
    132 return SCIP_OKAY;
    133}
    134
    135/** deinitialization method of event handler (called before transformed problem is freed) */
    136static
    137SCIP_DECL_EVENTEXIT(eventExitGlobalbnd)
    138{ /*lint --e{715}*/
    139 SCIP_EVENTHDLRDATA* eventhdlrdata;
    140
    141 assert(scip != NULL);
    142 assert(eventhdlr != NULL);
    143
    145
    146 eventhdlrdata = SCIPeventhdlrGetData(eventhdlr);
    147 assert(eventhdlrdata != NULL);
    148
    149 /* notify SCIP that your event handler wants to drop the event type var added */
    150 if( eventhdlrdata->filterpos >= 0 )
    151 {
    152 SCIP_CALL( SCIPdropEvent(scip, SCIP_EVENTTYPE_VARADDED, eventhdlr, NULL, eventhdlrdata->filterpos) );
    153 eventhdlrdata->filterpos = -1;
    154 SCIPboundstoreFree(scip, &eventhdlrdata->boundstore);
    155 }
    156
    157 return SCIP_OKAY;
    158}
    159
    160/** execution method of event handler */
    161static
    162SCIP_DECL_EVENTEXEC(eventExecGlobalbnd)
    163{ /*lint --e{715}*/
    164 SCIP_EVENTHDLRDATA* eventhdlrdata;
    165 SCIP_VAR* var;
    166 SCIP_Real newbound;
    167 SCIP_BOUNDTYPE boundtype;
    168 SCIP_Real constant;
    169 SCIP_Real scalar;
    170
    171 SCIPdebugMsg(scip, "exec method of eventhdlr " EVENTHDLR_NAME "\n");
    172
    173 assert(eventhdlr != NULL);
    174 assert(event != NULL);
    175 assert(scip != NULL);
    176
    178
    179 eventhdlrdata = SCIPeventhdlrGetData(eventhdlr);
    180 assert(eventhdlrdata != NULL);
    181
    182 var = SCIPeventGetVar(event);
    183 switch( SCIPeventGetType(event) )
    184 {
    187 return SCIP_OKAY;
    189 boundtype = SCIP_BOUNDTYPE_LOWER;
    190 break;
    192 boundtype = SCIP_BOUNDTYPE_UPPER;
    193 break;
    194 default:
    195 SCIPABORT();
    196 return SCIP_ERROR; /*lint !e527*/
    197 }
    198
    199 if( !eventhdlrdata->storebounds )
    200 return SCIP_OKAY;
    201
    202 newbound = SCIPeventGetNewbound(event);
    203 constant = 0.0;
    204 scalar = 1.0;
    205 SCIP_CALL( SCIPvarGetOrigvarSum(&var, &scalar, &constant) );
    206 if( var != NULL )
    207 {
    208 int varidx;
    209
    210 varidx = SCIPgetConcurrentVaridx(scip, var);
    211 if( varidx >= 0 )
    212 {
    213 boundtype = scalar < 0.0 ? SCIPboundtypeOpposite(boundtype) : boundtype;
    214 newbound = (newbound - constant) / scalar;
    215
    216 SCIP_CALL( SCIPboundstoreAdd(scip, eventhdlrdata->boundstore, varidx, newbound, boundtype) );
    217 }
    218 }
    219 return SCIP_OKAY;
    220}
    221
    222/** creates event handler for globalbnd event */
    224 SCIP* scip /**< SCIP data structure */
    225 )
    226{
    227 SCIP_EVENTHDLRDATA* eventhdlrdata = NULL;
    228 SCIP_EVENTHDLR* eventhdlr = NULL;
    229
    230 /* create globalbnd event handler data */
    231 SCIP_CALL( SCIPallocMemory(scip, &eventhdlrdata) );
    232 eventhdlrdata->filterpos = -1;
    233
    234 /* include event handler into SCIP */
    235
    236 /* use SCIPincludeEventhdlrBasic() plus setter functions if you want to set callbacks one-by-one and your code should
    237 * compile independent of new callbacks being added in future SCIP versions
    238 */
    240 eventExecGlobalbnd, eventhdlrdata) );
    241 assert(eventhdlr != NULL);
    242
    243 /* set non fundamental callbacks via setter functions */
    244 SCIP_CALL( SCIPsetEventhdlrFree(scip, eventhdlr, eventFreeGlobalbnd) );
    245 SCIP_CALL( SCIPsetEventhdlrInit(scip, eventhdlr, eventInitGlobalbnd) );
    246 SCIP_CALL( SCIPsetEventhdlrExit(scip, eventhdlr, eventExitGlobalbnd) );
    247
    248 return SCIP_OKAY;
    249}
    250
    251
    252/** gets the global bound changes stored in the eventhandler */
    254 SCIP_EVENTHDLR* eventhdlr /**< the globalbound eventhandler */
    255 )
    256{
    257 SCIP_EVENTHDLRDATA* eventhdlrdata;
    258 assert(eventhdlr != NULL);
    259
    261
    262 eventhdlrdata = SCIPeventhdlrGetData(eventhdlr);
    263 assert(eventhdlrdata != NULL);
    264
    265 return eventhdlrdata->boundstore;
    266}
    267
    268/** enables storing of bound changes */
    270 SCIP_EVENTHDLR* eventhdlr /**< the globalbound eventhandler */
    271 )
    272{
    273 SCIP_EVENTHDLRDATA* eventhdlrdata;
    274
    275 assert(eventhdlr != NULL);
    276 eventhdlrdata = SCIPeventhdlrGetData(eventhdlr);
    277 assert(eventhdlrdata != NULL);
    278
    279 eventhdlrdata->storebounds = TRUE;
    280}
    281
    282/** disables storing of bound changes */
    284 SCIP_EVENTHDLR* eventhdlr /**< the globalbound eventhandler */
    285 )
    286{
    287 SCIP_EVENTHDLRDATA* eventhdlrdata;
    288
    289 assert(eventhdlr != NULL);
    290 eventhdlrdata = SCIPeventhdlrGetData(eventhdlr);
    291 assert(eventhdlrdata != NULL);
    292
    293 eventhdlrdata->storebounds = FALSE;
    294}
    295
    296/** clears all bound changes stored in the eventhandler */
    298 SCIP_EVENTHDLR* eventhdlr /**< the globalbound eventhandler */
    299 )
    300{
    301 SCIP_EVENTHDLRDATA* eventhdlrdata;
    302
    303 assert(eventhdlr != NULL);
    304 eventhdlrdata = SCIPeventhdlrGetData(eventhdlr);
    305 assert(eventhdlrdata != NULL);
    306
    307 SCIPboundstoreClear(eventhdlrdata->boundstore);
    308}
    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:152
    the interface of the bound store data structure
    int SCIPgetConcurrentVaridx(SCIP *scip, SCIP_VAR *var)
    Definition: concurrent.c:434
    helper functions for concurrent scip solvers
    #define NULL
    Definition: def.h:257
    #define SCIP_Bool
    Definition: def.h:100
    #define SCIP_STRINGEQ(name, reference, retcode)
    Definition: def.h:454
    #define SCIP_Real
    Definition: def.h:165
    #define TRUE
    Definition: def.h:102
    #define FALSE
    Definition: def.h:103
    #define SCIPABORT()
    Definition: def.h:336
    #define SCIP_CALL(x)
    Definition: def.h:364
    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:2589
    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:18365
    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_INVALIDCALL
    Definition: type_retcode.h:51
    @ SCIP_ERROR
    Definition: type_retcode.h:43
    enum SCIP_Retcode SCIP_RETCODE
    Definition: type_retcode.h:63