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