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-2019 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 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 "blockmemshell/memory.h"
27 #include "scip/boundstore.h"
28 #include "scip/concurrent.h"
29 #include "scip/event_globalbnd.h"
30 #include "scip/pub_event.h"
31 #include "scip/pub_lp.h"
32 #include "scip/pub_message.h"
33 #include "scip/pub_var.h"
34 #include "scip/scip_concurrent.h"
35 #include "scip/scip_copy.h"
36 #include "scip/scip_event.h"
37 #include "scip/scip_mem.h"
38 #include "scip/scip_message.h"
39 #include "scip/scip_prob.h"
40 #include "scip/syncstore.h"
41 #include <string.h>
42 
43 #define EVENTHDLR_NAME "globalbnd"
44 #define EVENTHDLR_DESC "event handler for globalbnd event"
45 
46 
47 /*
48  * Data structures
49  */
50 
51 /** event handler data */
52 struct SCIP_EventhdlrData
53 {
54  int filterpos;
55  SCIP_Bool storebounds;
56  SCIP_BOUNDSTORE* boundstore;
57 };
58 
59 /*
60  * Local methods
61  */
62 
63 /*
64  * Callback methods of event handler
65  */
66 
67 /** destructor of event handler to free user data (called when SCIP is exiting) */
68 static
69 SCIP_DECL_EVENTFREE(eventFreeGlobalbnd)
70 { /*lint --e{715}*/
71  SCIP_EVENTHDLRDATA* eventhdlrdata;
72 
73  assert(scip != NULL);
74  assert(eventhdlr != NULL);
75  assert(strcmp(SCIPeventhdlrGetName(eventhdlr), EVENTHDLR_NAME) == 0);
76 
77  eventhdlrdata = SCIPeventhdlrGetData(eventhdlr);
78  assert(eventhdlrdata != NULL);
79 
80  SCIPfreeMemory(scip, &eventhdlrdata);
81  SCIPeventhdlrSetData(eventhdlr, NULL);
82 
83  return SCIP_OKAY;
84 }
85 
86 /** initialization method of event handler (called after problem was transformed) */
87 static
88 SCIP_DECL_EVENTINIT(eventInitGlobalbnd)
89 { /*lint --e{715}*/
90  SCIP_EVENTHDLRDATA* eventhdlrdata;
91 
92  assert(scip != NULL);
93  assert(eventhdlr != NULL);
94  assert(strcmp(SCIPeventhdlrGetName(eventhdlr), EVENTHDLR_NAME) == 0);
95 
96  eventhdlrdata = SCIPeventhdlrGetData(eventhdlr);
97  assert(eventhdlrdata != NULL);
98 
99  if( eventhdlrdata->filterpos < 0 && SCIPgetSubscipDepth(scip) == 0 && SCIPsyncstoreIsInitialized(SCIPgetSyncstore(scip)) )
100  {
101  int i;
102  int nvars;
103  SCIP_VAR** vars;
104  SCIPdebugMsg(scip, "catching events in " EVENTHDLR_NAME " eventhdlr\n");
105  /* notify SCIP that this event handler wants to react on global bound change events */
106  nvars = SCIPgetNVars(scip);
107  vars = SCIPgetVars(scip);
108  eventhdlrdata->storebounds = TRUE;
109  SCIP_CALL( SCIPboundstoreCreate(scip, &eventhdlrdata->boundstore, SCIPgetNOrigVars(scip)) );
110 
111  SCIP_CALL( SCIPcatchEvent(scip, SCIP_EVENTTYPE_VARADDED, eventhdlr, NULL, &eventhdlrdata->filterpos) );
112  for( i = 0; i < nvars ; ++i )
113  {
115  }
116  }
117 
118  return SCIP_OKAY;
119 }
120 
121 /** deinitialization method of event handler (called before transformed problem is freed) */
122 static
123 SCIP_DECL_EVENTEXIT(eventExitGlobalbnd)
124 { /*lint --e{715}*/
125  SCIP_EVENTHDLRDATA* eventhdlrdata;
126 
127  assert(scip != NULL);
128  assert(eventhdlr != NULL);
129  assert(strcmp(SCIPeventhdlrGetName(eventhdlr), EVENTHDLR_NAME) == 0);
130 
131  eventhdlrdata = SCIPeventhdlrGetData(eventhdlr);
132  assert(eventhdlrdata != NULL);
133 
134  /* notify SCIP that your event handler wants to drop the event type var added */
135  if( eventhdlrdata->filterpos >= 0 )
136  {
137  SCIP_CALL( SCIPdropEvent(scip, SCIP_EVENTTYPE_VARADDED, eventhdlr, NULL, eventhdlrdata->filterpos) );
138  eventhdlrdata->filterpos = -1;
139  SCIPboundstoreFree(scip, &eventhdlrdata->boundstore);
140  }
141 
142  return SCIP_OKAY;
143 }
144 
145 /** execution method of event handler */
146 static
147 SCIP_DECL_EVENTEXEC(eventExecGlobalbnd)
148 { /*lint --e{715}*/
149  SCIP_EVENTHDLRDATA* eventhdlrdata;
150  SCIP_VAR* var;
151  SCIP_Real newbound;
152  SCIP_BOUNDTYPE boundtype;
153  SCIP_Real constant;
154  SCIP_Real scalar;
155  SCIPdebugMsg(scip, "exec method of eventhdlr " EVENTHDLR_NAME "\n");
156  assert(eventhdlr != NULL);
157  assert(strcmp(SCIPeventhdlrGetName(eventhdlr), EVENTHDLR_NAME) == 0);
158  assert(event != NULL);
159  assert(scip != NULL);
160 
161  eventhdlrdata = SCIPeventhdlrGetData(eventhdlr);
162  assert(eventhdlrdata != NULL);
163 
164  var = SCIPeventGetVar(event);
165  switch( SCIPeventGetType(event) )
166  {
169  return SCIP_OKAY;
171  boundtype = SCIP_BOUNDTYPE_LOWER;
172  break;
174  boundtype = SCIP_BOUNDTYPE_UPPER;
175  break;
176  default:
177  SCIPABORT();
178  return SCIP_ERROR; /*lint !e527*/
179  }
180 
181  if( !eventhdlrdata->storebounds )
182  return SCIP_OKAY;
183 
184  newbound = SCIPeventGetNewbound(event);
185  constant = 0.0;
186  scalar = 1.0;
187  SCIP_CALL( SCIPvarGetOrigvarSum(&var, &scalar, &constant) );
188  if( var != NULL )
189  {
190  int varidx;
191 
192  varidx = SCIPgetConcurrentVaridx(scip, var);
193 
194  boundtype = scalar < 0.0 ? SCIPboundtypeOpposite(boundtype) : boundtype;
195  newbound = (newbound - constant) / scalar;
196 
197  SCIP_CALL( SCIPboundstoreAdd(scip, eventhdlrdata->boundstore, varidx, newbound, boundtype) );
198  }
199  return SCIP_OKAY;
200 }
201 
202 /** creates event handler for globalbnd event */
204  SCIP* scip /**< SCIP data structure */
205  )
206 {
207  SCIP_EVENTHDLRDATA* eventhdlrdata;
208  SCIP_EVENTHDLR* eventhdlr;
209 
210  /* create globalbnd event handler data */
211  eventhdlrdata = NULL;
212  SCIP_CALL( SCIPallocMemory(scip, &eventhdlrdata) );
213  eventhdlrdata->filterpos = -1;
214  eventhdlr = NULL;
215 
216  /* include event handler into SCIP */
217 
218  /* use SCIPincludeEventhdlrBasic() plus setter functions if you want to set callbacks one-by-one and your code should
219  * compile independent of new callbacks being added in future SCIP versions
220  */
222  eventExecGlobalbnd, eventhdlrdata) );
223  assert(eventhdlr != NULL);
224 
225  /* set non fundamental callbacks via setter functions */
226  SCIP_CALL( SCIPsetEventhdlrFree(scip, eventhdlr, eventFreeGlobalbnd) );
227  SCIP_CALL( SCIPsetEventhdlrInit(scip, eventhdlr, eventInitGlobalbnd) );
228  SCIP_CALL( SCIPsetEventhdlrExit(scip, eventhdlr, eventExitGlobalbnd) );
229 
230  return SCIP_OKAY;
231 }
232 
233 
234 /** gets the global bound changes stored in the eventhandler */
236  SCIP_EVENTHDLR* eventhdlr /**< the globalbound eventhandler */
237  )
238 {
239  SCIP_EVENTHDLRDATA* eventhdlrdata;
240  assert(eventhdlr != NULL);
241  assert(strcmp(EVENTHDLR_NAME, SCIPeventhdlrGetName(eventhdlr)) == 0);
242 
243  eventhdlrdata = SCIPeventhdlrGetData(eventhdlr);
244  assert(eventhdlrdata != NULL);
245 
246  return eventhdlrdata->boundstore;
247 }
248 
249 /** enables storing of bound changes */
251  SCIP_EVENTHDLR* eventhdlr /**< the globalbound eventhandler */
252  )
253 {
254  SCIP_EVENTHDLRDATA* eventhdlrdata;
255 
256  assert(eventhdlr != NULL);
257  assert(strcmp(EVENTHDLR_NAME, SCIPeventhdlrGetName(eventhdlr)) == 0);
258 
259  eventhdlrdata = SCIPeventhdlrGetData(eventhdlr);
260  assert(eventhdlrdata != NULL);
261 
262  eventhdlrdata->storebounds = TRUE;
263 }
264 
265 /** disables storing of bound changes */
267  SCIP_EVENTHDLR* eventhdlr /**< the globalbound eventhandler */
268  )
269 {
270  SCIP_EVENTHDLRDATA* eventhdlrdata;
271 
272  assert(eventhdlr != NULL);
273  assert(strcmp(EVENTHDLR_NAME, SCIPeventhdlrGetName(eventhdlr)) == 0);
274 
275  eventhdlrdata = SCIPeventhdlrGetData(eventhdlr);
276  assert(eventhdlrdata != NULL);
277 
278  eventhdlrdata->storebounds = FALSE;
279 }
280 
281 /** clears all bound changes stored in the eventhandler */
283  SCIP_EVENTHDLR* eventhdlr /**< the globalbound eventhandler */
284  )
285 {
286  SCIP_EVENTHDLRDATA* eventhdlrdata;
287 
288  assert(eventhdlr != NULL);
289  assert(strcmp(EVENTHDLR_NAME, SCIPeventhdlrGetName(eventhdlr)) == 0);
290 
291  eventhdlrdata = SCIPeventhdlrGetData(eventhdlr);
292  assert(eventhdlrdata != NULL);
293 
294  SCIPboundstoreClear(eventhdlrdata->boundstore);
295 }
void SCIPeventhdlrSetData(SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTHDLRDATA *eventhdlrdata)
Definition: event.c:334
enum SCIP_BoundType SCIP_BOUNDTYPE
Definition: type_lp.h:50
#define NULL
Definition: def.h:253
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:138
const char * SCIPeventhdlrGetName(SCIP_EVENTHDLR *eventhdlr)
Definition: event.c:314
int SCIPgetNVars(SCIP *scip)
Definition: scip_prob.c:1987
#define FALSE
Definition: def.h:73
#define EVENTHDLR_DESC
#define TRUE
Definition: def.h:72
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:53
#define SCIP_EVENTTYPE_GLBCHANGED
Definition: type_event.h:61
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:324
SCIP_BOUNDTYPE SCIPboundtypeOpposite(SCIP_BOUNDTYPE boundtype)
Definition: lp.c:16877
SCIP_RETCODE SCIPsetEventhdlrFree(SCIP *scip, SCIP_EVENTHDLR *eventhdlr, SCIP_DECL_EVENTFREE((*eventfree)))
Definition: scip_event.c:140
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:276
SCIP_VAR ** SCIPgetVars(SCIP *scip)
Definition: scip_prob.c:1942
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)
the interface of the boundstore structure
void SCIPeventGlobalbndEnableBoundStorage(SCIP_EVENTHDLR *eventhdlr)
public methods for problem copies
#define SCIP_CALL(x)
Definition: def.h:365
SCIP_EVENTTYPE SCIPeventGetType(SCIP_EVENT *event)
Definition: event.c:995
SCIP_Real SCIPeventGetNewbound(SCIP_EVENT *event)
Definition: event.c:1198
int SCIPgetNOrigVars(SCIP *scip)
Definition: scip_prob.c:2427
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:103
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:94
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:154
SCIP_RETCODE SCIPdropEvent(SCIP *scip, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int filterpos)
Definition: scip_event.c:310
SCIP_SYNCSTORE * SCIPgetSyncstore(SCIP *scip)
public methods for message output
#define SCIP_Real
Definition: def.h:164
public methods for message handling
SCIP_EXPORT SCIP_RETCODE SCIPvarGetOrigvarSum(SCIP_VAR **var, SCIP_Real *scalar, SCIP_Real *constant)
Definition: var.c:12268
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:344
#define SCIPallocMemory(scip, ptr)
Definition: scip_mem.h:51
SCIP_VAR * SCIPeventGetVar(SCIP_EVENT *event)
Definition: event.c:1018
#define SCIP_EVENTTYPE_GUBCHANGED
Definition: type_event.h:62
static SCIP_DECL_EVENTINIT(eventInitGlobalbnd)
#define SCIPABORT()
Definition: def.h:337
public methods for global and local (sub)problems
#define SCIP_EVENTTYPE_VARADDED
Definition: type_event.h:56
int SCIPgetSubscipDepth(SCIP *scip)
Definition: scip_copy.c:2289
SCIP_RETCODE SCIPsetEventhdlrExit(SCIP *scip, SCIP_EVENTHDLR *eventhdlr, SCIP_DECL_EVENTEXIT((*eventexit)))
Definition: scip_event.c:168
void SCIPboundstoreClear(SCIP_BOUNDSTORE *boundstore)
Definition: boundstore.c:137
memory allocation routines