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:262
#define SCIP_Bool
Definition: def.h:91
#define SCIP_Real
Definition: def.h:172
#define TRUE
Definition: def.h:93
#define FALSE
Definition: def.h:94
#define SCIPABORT()
Definition: def.h:341
#define SCIP_CALL(x)
Definition: def.h:369
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:2607
int SCIPgetNVars(SCIP *scip)
Definition: scip_prob.c:1992
SCIP_VAR ** SCIPgetVars(SCIP *scip)
Definition: scip_prob.c:1947
int SCIPgetNOrigVars(SCIP *scip)
Definition: scip_prob.c:2432
#define SCIPdebugMsg
Definition: scip_message.h:78
SCIP_BOUNDTYPE SCIPboundtypeOpposite(SCIP_BOUNDTYPE boundtype)
Definition: lp.c:17232
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:324
SCIP_EVENTHDLRDATA * SCIPeventhdlrGetData(SCIP_EVENTHDLR *eventhdlr)
Definition: event.c:334
void SCIPeventhdlrSetData(SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTHDLRDATA *eventhdlrdata)
Definition: event.c:344
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:1030
SCIP_RETCODE SCIPcatchVarEvent(SCIP *scip, SCIP_VAR *var, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int *filterpos)
Definition: scip_event.c:361
SCIP_VAR * SCIPeventGetVar(SCIP_EVENT *event)
Definition: event.c:1053
SCIP_Real SCIPeventGetNewbound(SCIP_EVENT *event)
Definition: event.c:1242
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:327
#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:12792
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:120
struct SCIP_EventhdlrData SCIP_EVENTHDLRDATA
Definition: type_event.h:155
#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:57
@ SCIP_BOUNDTYPE_LOWER
Definition: type_lp.h:56
enum SCIP_BoundType SCIP_BOUNDTYPE
Definition: type_lp.h:59
@ SCIP_OKAY
Definition: type_retcode.h:42
@ SCIP_ERROR
Definition: type_retcode.h:43
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:63