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 
36 #include "blockmemshell/memory.h"
37 #include "scip/boundstore.h"
38 #include "scip/concurrent.h"
39 #include "scip/event_globalbnd.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"
44 #include "scip/scip_concurrent.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 */
62 struct 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) */
78 static
79 SCIP_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) */
97 static
98 SCIP_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) */
132 static
133 SCIP_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 */
156 static
157 SCIP_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 }
enum SCIP_BoundType SCIP_BOUNDTYPE
Definition: type_lp.h:59
#define NULL
Definition: def.h:267
public methods for memory management
SCIP_RETCODE SCIPcatchVarEvent(SCIP *scip, SCIP_VAR *var, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int *filterpos)
Definition: scip_event.c:354
static SCIP_DECL_EVENTEXEC(eventExecGlobalbnd)
SCIP_RETCODE SCIPsetEventhdlrExit(SCIP *scip, SCIP_EVENTHDLR *eventhdlr, SCIP_DECL_EVENTEXIT((*eventexit)))
Definition: scip_event.c:178
eventhdlr for storing all global bound changes
int SCIPgetNOrigVars(SCIP *scip)
Definition: scip_prob.c:2432
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_event.c:104
struct SCIP_EventhdlrData SCIP_EVENTHDLRDATA
Definition: type_event.h:155
#define FALSE
Definition: def.h:94
const char * SCIPeventhdlrGetName(SCIP_EVENTHDLR *eventhdlr)
Definition: event.c:324
int SCIPgetSubscipDepth(SCIP *scip)
Definition: scip_copy.c:2605
#define EVENTHDLR_DESC
#define TRUE
Definition: def.h:93
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:63
#define SCIP_EVENTTYPE_GLBCHANGED
Definition: type_event.h:75
public methods for problem variables
static SCIP_DECL_EVENTEXIT(eventExitGlobalbnd)
#define SCIPdebugMsg
Definition: scip_message.h:78
void SCIPeventhdlrSetData(SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTHDLRDATA *eventhdlrdata)
Definition: event.c:344
SCIP_Real SCIPeventGetNewbound(SCIP_EVENT *event)
Definition: event.c:1242
SCIP_BOUNDTYPE SCIPboundtypeOpposite(SCIP_BOUNDTYPE boundtype)
Definition: lp.c:17203
SCIP_Bool SCIPsyncstoreIsInitialized(SCIP_SYNCSTORE *syncstore)
Definition: syncstore.c:791
SCIP_RETCODE SCIPsetEventhdlrFree(SCIP *scip, SCIP_EVENTHDLR *eventhdlr, SCIP_DECL_EVENTFREE((*eventfree)))
Definition: scip_event.c:150
void SCIPboundstoreFree(SCIP *scip, SCIP_BOUNDSTORE **boundstore)
Definition: boundstore.c:60
public methods for event handler plugins and event handlers
SCIP_RETCODE SCIPincludeEventHdlrGlobalbnd(SCIP *scip)
SCIP_RETCODE SCIPboundstoreAdd(SCIP *scip, SCIP_BOUNDSTORE *boundstore, int varidx, SCIP_Real newbound, SCIP_BOUNDTYPE boundtype)
Definition: boundstore.c:75
SCIP_RETCODE SCIPsetEventhdlrInit(SCIP *scip, SCIP_EVENTHDLR *eventhdlr, SCIP_DECL_EVENTINIT((*eventinit)))
Definition: scip_event.c:164
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:380
the function declarations for the synchronization store
SCIP_VAR * SCIPeventGetVar(SCIP_EVENT *event)
Definition: event.c:1053
#define SCIP_Bool
Definition: def.h:91
SCIP_RETCODE SCIPcatchEvent(SCIP *scip, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int *filterpos)
Definition: scip_event.c:286
SCIP_BOUNDSTORE * SCIPeventGlobalbndGetBoundChanges(SCIP_EVENTHDLR *eventhdlr)
SCIP_EVENTTYPE SCIPeventGetType(SCIP_EVENT *event)
Definition: event.c:1030
SCIP_SYNCSTORE * SCIPgetSyncstore(SCIP *scip)
int SCIPgetConcurrentVaridx(SCIP *scip, SCIP_VAR *var)
Definition: concurrent.c:423
public methods for concurrent solving mode
public methods for LP management
SCIP_RETCODE SCIPdropEvent(SCIP *scip, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int filterpos)
Definition: scip_event.c:320
#define EVENTHDLR_NAME
static SCIP_DECL_EVENTFREE(eventFreeGlobalbnd)
#define SCIP_EVENTTYPE_GBDCHANGED
Definition: type_event.h:120
SCIP_RETCODE SCIPvarGetOrigvarSum(SCIP_VAR **var, SCIP_Real *scalar, SCIP_Real *constant)
Definition: var.c:12775
helper functions for concurrent scip solvers
int SCIPgetNVars(SCIP *scip)
Definition: scip_prob.c:1992
#define SCIPfreeMemory(scip, ptr)
Definition: scip_mem.h:78
public methods for managing events
public methods for message output
SCIP_VAR ** SCIPgetVars(SCIP *scip)
Definition: scip_prob.c:1947
#define SCIP_Real
Definition: def.h:173
public methods for message handling
SCIP_RETCODE SCIPboundstoreCreate(SCIP *scip, SCIP_BOUNDSTORE **boundstore, int nvars)
Definition: boundstore.c:39
#define SCIPallocMemory(scip, ptr)
Definition: scip_mem.h:60
#define SCIP_EVENTTYPE_GUBCHANGED
Definition: type_event.h:76
static SCIP_DECL_EVENTINIT(eventInitGlobalbnd)
SCIP_EVENTHDLRDATA * SCIPeventhdlrGetData(SCIP_EVENTHDLR *eventhdlr)
Definition: event.c:334
#define SCIPABORT()
Definition: def.h:352
public methods for global and local (sub)problems
#define SCIP_EVENTTYPE_VARADDED
Definition: type_event.h:70
void SCIPboundstoreClear(SCIP_BOUNDSTORE *boundstore)
Definition: boundstore.c:146
memory allocation routines