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-2017 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 email to scip@zib.de. */
13 /* */
14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15 
16 /**@file event_globalbnd.c
17  * @brief eventhandler for storing all global bound changes
18  * @author Robert Lion Gottwald
19  *
20  * the bound changes are stored so that they can be shared with other threads
21  * in a concurrent solve.
22  */
23 
24 /*--+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
25 
26 #include "scip/event_globalbnd.h"
27 #include "scip/pub_misc.h"
28 #include "scip/concurrent.h"
29 #include "scip/boundstore.h"
30 #include "scip/syncstore.h"
31 #include <string.h>
32 
33 #define EVENTHDLR_NAME "globalbnd"
34 #define EVENTHDLR_DESC "event handler for globalbnd event"
35 
36 
37 /*
38  * Data structures
39  */
40 
41 
42 
43 /** event handler data */
44 struct SCIP_EventhdlrData
45 {
46  int filterpos;
47  SCIP_Bool storebounds;
48  SCIP_BOUNDSTORE* boundstore;
49 };
50 
51 /*
52  * Local methods
53  */
54 
55 /*
56  * Callback methods of event handler
57  */
58 
59 /** destructor of event handler to free user data (called when SCIP is exiting) */
60 static
61 SCIP_DECL_EVENTFREE(eventFreeGlobalbnd)
62 { /*lint --e{715}*/
63  SCIP_EVENTHDLRDATA* eventhdlrdata;
64 
65  assert(scip != NULL);
66  assert(eventhdlr != NULL);
67  assert(strcmp(SCIPeventhdlrGetName(eventhdlr), EVENTHDLR_NAME) == 0);
68 
69  eventhdlrdata = SCIPeventhdlrGetData(eventhdlr);
70  assert(eventhdlrdata != NULL);
71 
72  SCIPfreeMemory(scip, &eventhdlrdata);
73  SCIPeventhdlrSetData(eventhdlr, NULL);
74 
75  return SCIP_OKAY;
76 }
77 
78 /** initialization method of event handler (called after problem was transformed) */
79 static
80 SCIP_DECL_EVENTINIT(eventInitGlobalbnd)
81 { /*lint --e{715}*/
82  SCIP_EVENTHDLRDATA* eventhdlrdata;
83 
84  assert(scip != NULL);
85  assert(eventhdlr != NULL);
86  assert(strcmp(SCIPeventhdlrGetName(eventhdlr), EVENTHDLR_NAME) == 0);
87 
88  eventhdlrdata = SCIPeventhdlrGetData(eventhdlr);
89  assert(eventhdlrdata != NULL);
90 
91  if( eventhdlrdata->filterpos < 0 && SCIPgetSubscipDepth(scip) == 0 && SCIPsyncstoreIsInitialized(SCIPgetSyncstore(scip)) )
92  {
93  int i;
94  int nvars;
95  SCIP_VAR** vars;
96  SCIPdebugMsg(scip, "catching events in " EVENTHDLR_NAME " eventhdlr\n");
97  /* notify SCIP that this event handler wants to react on global bound change events */
98  nvars = SCIPgetNVars(scip);
99  vars = SCIPgetVars(scip);
100  eventhdlrdata->storebounds = TRUE;
101  SCIP_CALL( SCIPboundstoreCreate(scip, &eventhdlrdata->boundstore, SCIPgetNOrigVars(scip)) );
102 
103  SCIP_CALL( SCIPcatchEvent(scip, SCIP_EVENTTYPE_VARADDED, eventhdlr, NULL, &eventhdlrdata->filterpos) );
104  for( i = 0; i < nvars ; ++i )
105  {
106  SCIP_CALL( SCIPcatchVarEvent(scip, vars[i], SCIP_EVENTTYPE_GBDCHANGED, eventhdlr, NULL, NULL) );
107  }
108  }
109 
110  return SCIP_OKAY;
111 }
112 
113 /** deinitialization method of event handler (called before transformed problem is freed) */
114 static
115 SCIP_DECL_EVENTEXIT(eventExitGlobalbnd)
116 { /*lint --e{715}*/
117  SCIP_EVENTHDLRDATA* eventhdlrdata;
118 
119  assert(scip != NULL);
120  assert(eventhdlr != NULL);
121  assert(strcmp(SCIPeventhdlrGetName(eventhdlr), EVENTHDLR_NAME) == 0);
122 
123  eventhdlrdata = SCIPeventhdlrGetData(eventhdlr);
124  assert(eventhdlrdata != NULL);
125 
126  /* notify SCIP that your event handler wants to drop the event type var added */
127  if( eventhdlrdata->filterpos >= 0 )
128  {
129  SCIP_CALL( SCIPdropEvent(scip, SCIP_EVENTTYPE_VARADDED, eventhdlr, NULL, eventhdlrdata->filterpos) );
130  eventhdlrdata->filterpos = -1;
131  SCIPboundstoreFree(scip, &eventhdlrdata->boundstore);
132  }
133 
134  return SCIP_OKAY;
135 }
136 
137 /** execution method of event handler */
138 static
139 SCIP_DECL_EVENTEXEC(eventExecGlobalbnd)
140 { /*lint --e{715}*/
141  SCIP_EVENTHDLRDATA* eventhdlrdata;
142  SCIP_VAR* var;
143  SCIP_Real newbound;
144  SCIP_BOUNDTYPE boundtype;
145  SCIP_Real constant;
146  SCIP_Real scalar;
147  SCIPdebugMsg(scip, "exec method of eventhdlr " EVENTHDLR_NAME "\n");
148  assert(eventhdlr != NULL);
149  assert(strcmp(SCIPeventhdlrGetName(eventhdlr), EVENTHDLR_NAME) == 0);
150  assert(event != NULL);
151  assert(scip != NULL);
152 
153  eventhdlrdata = SCIPeventhdlrGetData(eventhdlr);
154  assert(eventhdlrdata != NULL);
155 
156  var = SCIPeventGetVar(event);
157  switch( SCIPeventGetType(event) )
158  {
160  SCIP_CALL( SCIPcatchVarEvent(scip, var, SCIP_EVENTTYPE_GBDCHANGED, eventhdlr, NULL, NULL) );
161  return SCIP_OKAY;
163  boundtype = SCIP_BOUNDTYPE_LOWER;
164  break;
166  boundtype = SCIP_BOUNDTYPE_UPPER;
167  break;
168  default:
169  SCIPABORT();
170  return SCIP_ERROR; /*lint !e527*/
171  }
172 
173  if( !eventhdlrdata->storebounds )
174  return SCIP_OKAY;
175 
176  newbound = SCIPeventGetNewbound(event);
177  constant = 0.0;
178  scalar = 1.0;
179  SCIP_CALL( SCIPvarGetOrigvarSum(&var, &scalar, &constant) );
180  if( var != NULL )
181  {
182  int varidx;
183 
184  varidx = SCIPgetConcurrentVaridx(scip, var);
185 
186  boundtype = scalar < 0.0 ? SCIPboundtypeOpposite(boundtype) : boundtype;
187  newbound = (newbound - constant) / scalar;
188 
189  SCIP_CALL( SCIPboundstoreAdd(scip, eventhdlrdata->boundstore, varidx, newbound, boundtype) );
190  }
191  return SCIP_OKAY;
192 }
193 
194 /** creates event handler for globalbnd event */
196  SCIP* scip /**< SCIP data structure */
197  )
198 {
199  SCIP_EVENTHDLRDATA* eventhdlrdata;
200  SCIP_EVENTHDLR* eventhdlr;
201 
202  /* create globalbnd event handler data */
203  eventhdlrdata = NULL;
204  SCIP_CALL( SCIPallocMemory(scip, &eventhdlrdata) );
205  eventhdlrdata->filterpos = -1;
206  eventhdlr = NULL;
207 
208  /* include event handler into SCIP */
209 
210  /* use SCIPincludeEventhdlrBasic() plus setter functions if you want to set callbacks one-by-one and your code should
211  * compile independent of new callbacks being added in future SCIP versions
212  */
214  eventExecGlobalbnd, eventhdlrdata) );
215  assert(eventhdlr != NULL);
216 
217  /* set non fundamental callbacks via setter functions */
218  SCIP_CALL( SCIPsetEventhdlrFree(scip, eventhdlr, eventFreeGlobalbnd) );
219  SCIP_CALL( SCIPsetEventhdlrInit(scip, eventhdlr, eventInitGlobalbnd) );
220  SCIP_CALL( SCIPsetEventhdlrExit(scip, eventhdlr, eventExitGlobalbnd) );
221 
222  return SCIP_OKAY;
223 }
224 
225 
226 /** gets the global bound changes stored in the eventhandler */
228  SCIP_EVENTHDLR* eventhdlr /**< the globalbound eventhandler */
229  )
230 {
231  SCIP_EVENTHDLRDATA* eventhdlrdata;
232  assert(eventhdlr != NULL);
233  assert(strcmp(EVENTHDLR_NAME, SCIPeventhdlrGetName(eventhdlr)) == 0);
234 
235  eventhdlrdata = SCIPeventhdlrGetData(eventhdlr);
236  assert(eventhdlrdata != NULL);
237 
238  return eventhdlrdata->boundstore;
239 }
240 
241 /** enables storing of bound changes */
243  SCIP_EVENTHDLR* eventhdlr /**< the globalbound eventhandler */
244  )
245 {
246  SCIP_EVENTHDLRDATA* eventhdlrdata;
247 
248  assert(eventhdlr != NULL);
249  assert(strcmp(EVENTHDLR_NAME, SCIPeventhdlrGetName(eventhdlr)) == 0);
250 
251  eventhdlrdata = SCIPeventhdlrGetData(eventhdlr);
252  assert(eventhdlrdata != NULL);
253 
254  eventhdlrdata->storebounds = TRUE;
255 }
256 
257 /** disables storing of bound changes */
259  SCIP_EVENTHDLR* eventhdlr /**< the globalbound eventhandler */
260  )
261 {
262  SCIP_EVENTHDLRDATA* eventhdlrdata;
263 
264  assert(eventhdlr != NULL);
265  assert(strcmp(EVENTHDLR_NAME, SCIPeventhdlrGetName(eventhdlr)) == 0);
266 
267  eventhdlrdata = SCIPeventhdlrGetData(eventhdlr);
268  assert(eventhdlrdata != NULL);
269 
270  eventhdlrdata->storebounds = FALSE;
271 }
272 
273 /** clears all bound changes stored in the eventhandler */
275  SCIP_EVENTHDLR* eventhdlr /**< the globalbound eventhandler */
276  )
277 {
278  SCIP_EVENTHDLRDATA* eventhdlrdata;
279 
280  assert(eventhdlr != NULL);
281  assert(strcmp(EVENTHDLR_NAME, SCIPeventhdlrGetName(eventhdlr)) == 0);
282 
283  eventhdlrdata = SCIPeventhdlrGetData(eventhdlr);
284  assert(eventhdlrdata != NULL);
285 
286  SCIPboundstoreClear(eventhdlrdata->boundstore);
287 }
enum SCIP_BoundType SCIP_BOUNDTYPE
Definition: type_lp.h:50
SCIP_RETCODE SCIPcatchVarEvent(SCIP *scip, SCIP_VAR *var, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int *filterpos)
Definition: scip.c:41220
static SCIP_DECL_EVENTEXEC(eventExecGlobalbnd)
SCIP_RETCODE SCIPsetEventhdlrExit(SCIP *scip, SCIP_EVENTHDLR *eventhdlr, SCIP_DECL_EVENTEXIT((*eventexit)))
Definition: scip.c:8685
eventhdlr for storing all global bound changes
int SCIPgetNOrigVars(SCIP *scip)
Definition: scip.c:12246
void SCIPeventGlobalbndDisableBoundStorage(SCIP_EVENTHDLR *eventhdlr)
SCIP_RETCODE SCIPincludeEventhdlrBasic(SCIP *scip, SCIP_EVENTHDLR **eventhdlrptr, const char *name, const char *desc, SCIP_DECL_EVENTEXEC((*eventexec)), SCIP_EVENTHDLRDATA *eventhdlrdata)
Definition: scip.c:8611
struct SCIP_EventhdlrData SCIP_EVENTHDLRDATA
Definition: type_event.h:138
#define FALSE
Definition: def.h:64
const char * SCIPeventhdlrGetName(SCIP_EVENTHDLR *eventhdlr)
Definition: event.c:278
int SCIPgetSubscipDepth(SCIP *scip)
Definition: scip.c:3542
#define EVENTHDLR_DESC
#define TRUE
Definition: def.h:63
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:53
#define SCIP_EVENTTYPE_GLBCHANGED
Definition: type_event.h:61
static SCIP_DECL_EVENTEXIT(eventExitGlobalbnd)
#define SCIPdebugMsg
Definition: scip.h:455
void SCIPeventhdlrSetData(SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTHDLRDATA *eventhdlrdata)
Definition: event.c:298
SCIP_Real SCIPeventGetNewbound(SCIP_EVENT *event)
Definition: event.c:1162
#define SCIPallocMemory(scip, ptr)
Definition: scip.h:22551
SCIP_BOUNDTYPE SCIPboundtypeOpposite(SCIP_BOUNDTYPE boundtype)
Definition: lp.c:16392
SCIP_Bool SCIPsyncstoreIsInitialized(SCIP_SYNCSTORE *syncstore)
Definition: syncstore.c:776
SCIP_RETCODE SCIPsetEventhdlrFree(SCIP *scip, SCIP_EVENTHDLR *eventhdlr, SCIP_DECL_EVENTFREE((*eventfree)))
Definition: scip.c:8657
void SCIPboundstoreFree(SCIP *scip, SCIP_BOUNDSTORE **boundstore)
Definition: boundstore.c:51
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
SCIP_RETCODE SCIPsetEventhdlrInit(SCIP *scip, SCIP_EVENTHDLR *eventhdlr, SCIP_DECL_EVENTINIT((*eventinit)))
Definition: scip.c:8671
void SCIPeventGlobalbndClearBoundChanges(SCIP_EVENTHDLR *eventhdlr)
the interface of the boundstore structure
void SCIPeventGlobalbndEnableBoundStorage(SCIP_EVENTHDLR *eventhdlr)
#define SCIP_CALL(x)
Definition: def.h:350
the function declarations for the synchronization store
public data structures and miscellaneous methods
SCIP_VAR * SCIPeventGetVar(SCIP_EVENT *event)
Definition: event.c:982
#define SCIP_Bool
Definition: def.h:61
SCIP_RETCODE SCIPcatchEvent(SCIP *scip, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int *filterpos)
Definition: scip.c:41152
SCIP_BOUNDSTORE * SCIPeventGlobalbndGetBoundChanges(SCIP_EVENTHDLR *eventhdlr)
SCIP_EVENTTYPE SCIPeventGetType(SCIP_EVENT *event)
Definition: event.c:959
SCIP_SYNCSTORE * SCIPgetSyncstore(SCIP *scip)
Definition: scip.c:42011
int SCIPgetConcurrentVaridx(SCIP *scip, SCIP_VAR *var)
Definition: concurrent.c:413
SCIP_RETCODE SCIPdropEvent(SCIP *scip, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int filterpos)
Definition: scip.c:41186
#define EVENTHDLR_NAME
static SCIP_DECL_EVENTFREE(eventFreeGlobalbnd)
#define SCIP_EVENTTYPE_GBDCHANGED
Definition: type_event.h:103
SCIP_RETCODE SCIPvarGetOrigvarSum(SCIP_VAR **var, SCIP_Real *scalar, SCIP_Real *constant)
Definition: var.c:12184
helper functions for concurrent scip solvers
int SCIPgetNVars(SCIP *scip)
Definition: scip.c:11806
#define SCIPfreeMemory(scip, ptr)
Definition: scip.h:22567
SCIP_VAR ** SCIPgetVars(SCIP *scip)
Definition: scip.c:11761
#define SCIP_Real
Definition: def.h:149
SCIP_RETCODE SCIPboundstoreCreate(SCIP *scip, SCIP_BOUNDSTORE **boundstore, int nvars)
Definition: boundstore.c:30
#define SCIP_EVENTTYPE_GUBCHANGED
Definition: type_event.h:62
static SCIP_DECL_EVENTINIT(eventInitGlobalbnd)
SCIP_EVENTHDLRDATA * SCIPeventhdlrGetData(SCIP_EVENTHDLR *eventhdlr)
Definition: event.c:288
#define SCIPABORT()
Definition: def.h:322
#define SCIP_EVENTTYPE_VARADDED
Definition: type_event.h:56
void SCIPboundstoreClear(SCIP_BOUNDSTORE *boundstore)
Definition: boundstore.c:137