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-2024 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 int i;
112 int nvars;
113 SCIP_VAR** vars;
114 SCIPdebugMsg(scip, "catching events in " EVENTHDLR_NAME " eventhdlr\n");
115 /* notify SCIP that this event handler wants to react on global bound change events */
116 nvars = SCIPgetNVars(scip);
117 vars = SCIPgetVars(scip);
118 eventhdlrdata->storebounds = TRUE;
119 SCIP_CALL( SCIPboundstoreCreate(scip, &eventhdlrdata->boundstore, SCIPgetNOrigVars(scip)) );
120
121 SCIP_CALL( SCIPcatchEvent(scip, SCIP_EVENTTYPE_VARADDED, eventhdlr, NULL, &eventhdlrdata->filterpos) );
122 for( i = 0; i < nvars ; ++i )
123 {
125 }
126 }
127
128 return SCIP_OKAY;
129}
130
131/** deinitialization method of event handler (called before transformed problem is freed) */
132static
133SCIP_DECL_EVENTEXIT(eventExitGlobalbnd)
134{ /*lint --e{715}*/
135 SCIP_EVENTHDLRDATA* eventhdlrdata;
136
137 assert(scip != NULL);
138 assert(eventhdlr != NULL);
139 assert(strcmp(SCIPeventhdlrGetName(eventhdlr), EVENTHDLR_NAME) == 0);
140
141 eventhdlrdata = SCIPeventhdlrGetData(eventhdlr);
142 assert(eventhdlrdata != NULL);
143
144 /* notify SCIP that your event handler wants to drop the event type var added */
145 if( eventhdlrdata->filterpos >= 0 )
146 {
147 SCIP_CALL( SCIPdropEvent(scip, SCIP_EVENTTYPE_VARADDED, eventhdlr, NULL, eventhdlrdata->filterpos) );
148 eventhdlrdata->filterpos = -1;
149 SCIPboundstoreFree(scip, &eventhdlrdata->boundstore);
150 }
151
152 return SCIP_OKAY;
153}
154
155/** execution method of event handler */
156static
157SCIP_DECL_EVENTEXEC(eventExecGlobalbnd)
158{ /*lint --e{715}*/
159 SCIP_EVENTHDLRDATA* eventhdlrdata;
160 SCIP_VAR* var;
161 SCIP_Real newbound;
162 SCIP_BOUNDTYPE boundtype;
163 SCIP_Real constant;
164 SCIP_Real scalar;
165 SCIPdebugMsg(scip, "exec method of eventhdlr " EVENTHDLR_NAME "\n");
166 assert(eventhdlr != NULL);
167 assert(strcmp(SCIPeventhdlrGetName(eventhdlr), EVENTHDLR_NAME) == 0);
168 assert(event != NULL);
169 assert(scip != NULL);
170
171 eventhdlrdata = SCIPeventhdlrGetData(eventhdlr);
172 assert(eventhdlrdata != NULL);
173
174 var = SCIPeventGetVar(event);
175 switch( SCIPeventGetType(event) )
176 {
179 return SCIP_OKAY;
181 boundtype = SCIP_BOUNDTYPE_LOWER;
182 break;
184 boundtype = SCIP_BOUNDTYPE_UPPER;
185 break;
186 default:
187 SCIPABORT();
188 return SCIP_ERROR; /*lint !e527*/
189 }
190
191 if( !eventhdlrdata->storebounds )
192 return SCIP_OKAY;
193
194 newbound = SCIPeventGetNewbound(event);
195 constant = 0.0;
196 scalar = 1.0;
197 SCIP_CALL( SCIPvarGetOrigvarSum(&var, &scalar, &constant) );
198 if( var != NULL )
199 {
200 int varidx;
201
202 varidx = SCIPgetConcurrentVaridx(scip, var);
203
204 boundtype = scalar < 0.0 ? SCIPboundtypeOpposite(boundtype) : boundtype;
205 newbound = (newbound - constant) / scalar;
206
207 SCIP_CALL( SCIPboundstoreAdd(scip, eventhdlrdata->boundstore, varidx, newbound, boundtype) );
208 }
209 return SCIP_OKAY;
210}
211
212/** creates event handler for globalbnd event */
214 SCIP* scip /**< SCIP data structure */
215 )
216{
217 SCIP_EVENTHDLRDATA* eventhdlrdata;
218 SCIP_EVENTHDLR* eventhdlr;
219
220 /* create globalbnd event handler data */
221 eventhdlrdata = NULL;
222 SCIP_CALL( SCIPallocMemory(scip, &eventhdlrdata) );
223 eventhdlrdata->filterpos = -1;
224 eventhdlr = NULL;
225
226 /* include event handler into SCIP */
227
228 /* use SCIPincludeEventhdlrBasic() plus setter functions if you want to set callbacks one-by-one and your code should
229 * compile independent of new callbacks being added in future SCIP versions
230 */
232 eventExecGlobalbnd, eventhdlrdata) );
233 assert(eventhdlr != NULL);
234
235 /* set non fundamental callbacks via setter functions */
236 SCIP_CALL( SCIPsetEventhdlrFree(scip, eventhdlr, eventFreeGlobalbnd) );
237 SCIP_CALL( SCIPsetEventhdlrInit(scip, eventhdlr, eventInitGlobalbnd) );
238 SCIP_CALL( SCIPsetEventhdlrExit(scip, eventhdlr, eventExitGlobalbnd) );
239
240 return SCIP_OKAY;
241}
242
243
244/** gets the global bound changes stored in the eventhandler */
246 SCIP_EVENTHDLR* eventhdlr /**< the globalbound eventhandler */
247 )
248{
249 SCIP_EVENTHDLRDATA* eventhdlrdata;
250 assert(eventhdlr != NULL);
251 assert(strcmp(EVENTHDLR_NAME, SCIPeventhdlrGetName(eventhdlr)) == 0);
252
253 eventhdlrdata = SCIPeventhdlrGetData(eventhdlr);
254 assert(eventhdlrdata != NULL);
255
256 return eventhdlrdata->boundstore;
257}
258
259/** enables storing of bound changes */
261 SCIP_EVENTHDLR* eventhdlr /**< the globalbound eventhandler */
262 )
263{
264 SCIP_EVENTHDLRDATA* eventhdlrdata;
265
266 assert(eventhdlr != NULL);
267 assert(strcmp(EVENTHDLR_NAME, SCIPeventhdlrGetName(eventhdlr)) == 0);
268
269 eventhdlrdata = SCIPeventhdlrGetData(eventhdlr);
270 assert(eventhdlrdata != NULL);
271
272 eventhdlrdata->storebounds = TRUE;
273}
274
275/** disables storing of bound changes */
277 SCIP_EVENTHDLR* eventhdlr /**< the globalbound eventhandler */
278 )
279{
280 SCIP_EVENTHDLRDATA* eventhdlrdata;
281
282 assert(eventhdlr != NULL);
283 assert(strcmp(EVENTHDLR_NAME, SCIPeventhdlrGetName(eventhdlr)) == 0);
284
285 eventhdlrdata = SCIPeventhdlrGetData(eventhdlr);
286 assert(eventhdlrdata != NULL);
287
288 eventhdlrdata->storebounds = FALSE;
289}
290
291/** clears all bound changes stored in the eventhandler */
293 SCIP_EVENTHDLR* eventhdlr /**< the globalbound eventhandler */
294 )
295{
296 SCIP_EVENTHDLRDATA* eventhdlrdata;
297
298 assert(eventhdlr != NULL);
299 assert(strcmp(EVENTHDLR_NAME, SCIPeventhdlrGetName(eventhdlr)) == 0);
300
301 eventhdlrdata = SCIPeventhdlrGetData(eventhdlr);
302 assert(eventhdlrdata != NULL);
303
304 SCIPboundstoreClear(eventhdlrdata->boundstore);
305}
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:423
helper functions for concurrent scip solvers
#define NULL
Definition: def.h:266
#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:345
#define SCIP_CALL(x)
Definition: def.h:373
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:2605
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:17203
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:104
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:150
SCIP_RETCODE SCIPsetEventhdlrExit(SCIP *scip, SCIP_EVENTHDLR *eventhdlr, SCIP_DECL_EVENTEXIT((*eventexit)))
Definition: scip_event.c:178
SCIP_RETCODE SCIPsetEventhdlrInit(SCIP *scip, SCIP_EVENTHDLR *eventhdlr, SCIP_DECL_EVENTINIT((*eventinit)))
Definition: scip_event.c:164
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:354
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:286
SCIP_RETCODE SCIPdropEvent(SCIP *scip, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int filterpos)
Definition: scip_event.c:320
#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:12773
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