Scippy

SCIP

Solving Constraint Integer Programs

event.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-2016 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.c
17  * @brief methods and datastructures for managing events
18  * @author Tobias Achterberg
19  */
20 
21 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
22 
23 #include <assert.h>
24 #include <string.h>
25 
26 #include "scip/def.h"
27 #include "scip/set.h"
28 #include "scip/clock.h"
29 #include "scip/event.h"
30 #include "scip/lp.h"
31 #include "scip/var.h"
32 #include "scip/primal.h"
33 #include "scip/branch.h"
34 #include "scip/pub_message.h"
35 
36 /* timing the execution methods for event handling takes a lot of time, so it is disabled */
37 /* #define TIMEEVENTEXEC */
38 
39 
40 /*
41  * Event handler methods
42  */
43 
44 /** copies the given event handler to a new scip */
46  SCIP_EVENTHDLR* eventhdlr, /**< event handler */
47  SCIP_SET* set /**< SCIP_SET of SCIP to copy to */
48  )
49 {
50  assert(eventhdlr != NULL);
51  assert(set != NULL);
52  assert(set->scip != NULL);
53 
54  if( eventhdlr->eventcopy != NULL )
55  {
56  SCIPdebugMessage("including event handler %s in subscip %p\n", SCIPeventhdlrGetName(eventhdlr), (void*)set->scip);
57  SCIP_CALL( eventhdlr->eventcopy(set->scip, eventhdlr) );
58  }
59 
60  return SCIP_OKAY;
61 }
62 
63 /** creates an event handler */
65  SCIP_EVENTHDLR** eventhdlr, /**< pointer to event handler data structure */
66  const char* name, /**< name of event handler */
67  const char* desc, /**< description of event handler */
68  SCIP_DECL_EVENTCOPY ((*eventcopy)), /**< copy method of event handler or NULL if you don't want to copy your plugin into sub-SCIPs */
69  SCIP_DECL_EVENTFREE ((*eventfree)), /**< destructor of event handler */
70  SCIP_DECL_EVENTINIT ((*eventinit)), /**< initialize event handler */
71  SCIP_DECL_EVENTEXIT ((*eventexit)), /**< deinitialize event handler */
72  SCIP_DECL_EVENTINITSOL((*eventinitsol)), /**< solving process initialization method of event handler */
73  SCIP_DECL_EVENTEXITSOL((*eventexitsol)), /**< solving process deinitialization method of event handler */
74  SCIP_DECL_EVENTDELETE ((*eventdelete)), /**< free specific event data */
75  SCIP_DECL_EVENTEXEC ((*eventexec)), /**< execute event handler */
76  SCIP_EVENTHDLRDATA* eventhdlrdata /**< event handler data */
77  )
78 {
79  assert(eventhdlr != NULL);
80  assert(name != NULL);
81  assert(desc != NULL);
82  assert(eventexec != NULL);
83 
84  SCIP_ALLOC( BMSallocMemory(eventhdlr) );
85  SCIP_ALLOC( BMSduplicateMemoryArray(&(*eventhdlr)->name, name, strlen(name)+1) );
86  SCIP_ALLOC( BMSduplicateMemoryArray(&(*eventhdlr)->desc, desc, strlen(desc)+1) );
87  (*eventhdlr)->eventcopy = eventcopy;
88  (*eventhdlr)->eventfree = eventfree;
89  (*eventhdlr)->eventinit = eventinit;
90  (*eventhdlr)->eventexit = eventexit;
91  (*eventhdlr)->eventinitsol = eventinitsol;
92  (*eventhdlr)->eventexitsol = eventexitsol;
93  (*eventhdlr)->eventdelete = eventdelete;
94  (*eventhdlr)->eventexec = eventexec;
95  (*eventhdlr)->eventhdlrdata = eventhdlrdata;
96  (*eventhdlr)->initialized = FALSE;
97 
98  /* create clocks */
99  SCIP_CALL( SCIPclockCreate(&(*eventhdlr)->setuptime, SCIP_CLOCKTYPE_DEFAULT) );
100  SCIP_CALL( SCIPclockCreate(&(*eventhdlr)->eventtime, SCIP_CLOCKTYPE_DEFAULT) );
101 
102  return SCIP_OKAY;
103 }
104 
105 /** calls destructor and frees memory of event handler */
107  SCIP_EVENTHDLR** eventhdlr, /**< pointer to event handler data structure */
108  SCIP_SET* set /**< global SCIP settings */
109  )
110 {
111  assert(eventhdlr != NULL);
112  assert(*eventhdlr != NULL);
113  assert(!(*eventhdlr)->initialized);
114  assert(set != NULL);
115 
116  /* call destructor of event handler */
117  if( (*eventhdlr)->eventfree != NULL )
118  {
119  SCIP_CALL( (*eventhdlr)->eventfree(set->scip, *eventhdlr) );
120  }
121 
122  /* free clocks */
123  SCIPclockFree(&(*eventhdlr)->eventtime);
124  SCIPclockFree(&(*eventhdlr)->setuptime);
125 
126  BMSfreeMemoryArray(&(*eventhdlr)->name);
127  BMSfreeMemoryArray(&(*eventhdlr)->desc);
128  BMSfreeMemory(eventhdlr);
129 
130  return SCIP_OKAY;
131 }
132 
133 /** initializes event handler */
135  SCIP_EVENTHDLR* eventhdlr, /**< event handler for this event */
136  SCIP_SET* set /**< global SCIP settings */
137  )
138 {
139  assert(eventhdlr != NULL);
140  assert(set != NULL);
141 
142  if( eventhdlr->initialized )
143  {
144  SCIPerrorMessage("event handler <%s> already initialized\n", eventhdlr->name);
145  return SCIP_INVALIDCALL;
146  }
147 
148  if( set->misc_resetstat )
149  {
150  SCIPclockReset(eventhdlr->setuptime);
151  SCIPclockReset(eventhdlr->eventtime);
152  }
153 
154  if( eventhdlr->eventinit != NULL )
155  {
156  /* start timing */
157  SCIPclockStart(eventhdlr->setuptime, set);
158 
159  SCIP_CALL( eventhdlr->eventinit(set->scip, eventhdlr) );
160 
161  /* stop timing */
162  SCIPclockStop(eventhdlr->setuptime, set);
163  }
164  eventhdlr->initialized = TRUE;
165 
166  return SCIP_OKAY;
167 }
168 
169 /** calls exit method of event handler */
171  SCIP_EVENTHDLR* eventhdlr, /**< event handler for this event */
172  SCIP_SET* set /**< global SCIP settings */
173  )
174 {
175  assert(eventhdlr != NULL);
176  assert(set != NULL);
177 
178  if( !eventhdlr->initialized )
179  {
180  SCIPerrorMessage("event handler <%s> not initialized\n", eventhdlr->name);
181  return SCIP_INVALIDCALL;
182  }
183 
184  if( eventhdlr->eventexit != NULL )
185  {
186  /* start timing */
187  SCIPclockStart(eventhdlr->setuptime, set);
188 
189  SCIP_CALL( eventhdlr->eventexit(set->scip, eventhdlr) );
190 
191  /* stop timing */
192  SCIPclockStop(eventhdlr->setuptime, set);
193  }
194  eventhdlr->initialized = FALSE;
195 
196  return SCIP_OKAY;
197 }
198 
199 /** informs event handler that the branch and bound process is being started */
201  SCIP_EVENTHDLR* eventhdlr, /**< event handler */
202  SCIP_SET* set /**< global SCIP settings */
203  )
204 {
205  assert(eventhdlr != NULL);
206  assert(set != NULL);
207 
208  /* call solving process initialization method of event handler */
209  if( eventhdlr->eventinitsol != NULL )
210  {
211  /* start timing */
212  SCIPclockStart(eventhdlr->setuptime, set);
213 
214  SCIP_CALL( eventhdlr->eventinitsol(set->scip, eventhdlr) );
215 
216  /* stop timing */
217  SCIPclockStop(eventhdlr->setuptime, set);
218  }
219 
220  return SCIP_OKAY;
221 }
222 
223 /** informs event handler that the branch and bound process data is being freed */
225  SCIP_EVENTHDLR* eventhdlr, /**< event handler */
226  SCIP_SET* set /**< global SCIP settings */
227  )
228 {
229  assert(eventhdlr != NULL);
230  assert(set != NULL);
231 
232  /* call solving process deinitialization method of event handler */
233  if( eventhdlr->eventexitsol != NULL )
234  {
235  /* start timing */
236  SCIPclockStart(eventhdlr->setuptime, set);
237 
238  SCIP_CALL( eventhdlr->eventexitsol(set->scip, eventhdlr) );
239 
240  /* stop timing */
241  SCIPclockStop(eventhdlr->setuptime, set);
242  }
243 
244  return SCIP_OKAY;
245 }
246 
247 /** calls execution method of event handler */
249  SCIP_EVENTHDLR* eventhdlr, /**< event handler */
250  SCIP_SET* set, /**< global SCIP settings */
251  SCIP_EVENT* event, /**< event to call event handler with */
252  SCIP_EVENTDATA* eventdata /**< user data for the issued event */
253  )
254 {
255  assert(eventhdlr != NULL);
256  assert(eventhdlr->eventexec != NULL);
257  assert(set != NULL);
258  assert(event != NULL);
259 
260  SCIPdebugMessage("execute event of handler <%s> with event %p of type 0x%x\n", eventhdlr->name, (void*)event, event->eventtype);
261 
262 #ifdef TIMEEVENTEXEC
263  /* start timing */
264  SCIPclockStart(eventhdlr->eventtime, set);
265 #endif
266 
267  SCIP_CALL( eventhdlr->eventexec(set->scip, eventhdlr, event, eventdata) );
268 
269 #ifdef TIMEEVENTEXEC
270  /* stop timing */
271  SCIPclockStop(eventhdlr->eventtime, set);
272 #endif
273 
274  return SCIP_OKAY;
275 }
276 
277 /** gets name of event handler */
279  SCIP_EVENTHDLR* eventhdlr /**< event handler */
280  )
281 {
282  assert(eventhdlr != NULL);
283 
284  return eventhdlr->name;
285 }
286 
287 /** gets user data of event handler */
289  SCIP_EVENTHDLR* eventhdlr /**< event handler */
290  )
291 {
292  assert(eventhdlr != NULL);
293 
294  return eventhdlr->eventhdlrdata;
295 }
296 
297 /** sets user data of event handler; user has to free old data in advance! */
299  SCIP_EVENTHDLR* eventhdlr, /**< event handler */
300  SCIP_EVENTHDLRDATA* eventhdlrdata /**< new event handler user data */
301  )
302 {
303  assert(eventhdlr != NULL);
304 
305  eventhdlr->eventhdlrdata = eventhdlrdata;
306 }
307 
308 /** sets copy callback for all events of this event handler */
310  SCIP_EVENTHDLR* eventhdlr, /**< event handler */
311  SCIP_DECL_EVENTCOPY ((*eventcopy)) /**< copy callback for events */
312  )
313 {
314  assert(eventhdlr != NULL);
315 
316  eventhdlr->eventcopy = eventcopy;
317 }
318 
319 /** sets destructor callback of this event handler */
321  SCIP_EVENTHDLR* eventhdlr, /**< event handler */
322  SCIP_DECL_EVENTFREE ((*eventfree)) /**< destructor callback of event handler */
323  )
324 {
325  assert(eventhdlr != NULL);
326 
327  eventhdlr->eventfree = eventfree;
328 }
329 
330 /** sets initialization callback of this event handler */
332  SCIP_EVENTHDLR* eventhdlr, /**< event handler */
333  SCIP_DECL_EVENTINIT ((*eventinit)) /**< initialization callback of event handler */
334  )
335 {
336  assert(eventhdlr != NULL);
337 
338  eventhdlr->eventinit = eventinit;
339 }
340 
341 /** sets deinitialization callback of this event handler */
343  SCIP_EVENTHDLR* eventhdlr, /**< event handler */
344  SCIP_DECL_EVENTEXIT ((*eventexit)) /**< deinitialization callback of event handler */
345  )
346 {
347  assert(eventhdlr != NULL);
348 
349  eventhdlr->eventexit = eventexit;
350 }
351 
352 /** sets solving process initialization callback of this event handler */
354  SCIP_EVENTHDLR* eventhdlr, /**< event handler */
355  SCIP_DECL_EVENTINITSOL((*eventinitsol)) /**< solving process initialization callback of event handler */
356  )
357 {
358  assert(eventhdlr != NULL);
359 
360  eventhdlr->eventinitsol = eventinitsol;
361 }
362 
363 /** sets solving process deinitialization callback of this event handler */
365  SCIP_EVENTHDLR* eventhdlr, /**< event handler */
366  SCIP_DECL_EVENTEXITSOL((*eventexitsol)) /**< solving process deinitialization callback of event handler */
367  )
368 {
369  assert(eventhdlr != NULL);
370 
371  eventhdlr->eventexitsol = eventexitsol;
372 }
373 
374 /** sets callback to free specific event data */
376  SCIP_EVENTHDLR* eventhdlr, /**< event handler */
377  SCIP_DECL_EVENTDELETE ((*eventdelete)) /**< callback to free specific event data */
378  )
379 {
380  assert(eventhdlr != NULL);
381 
382  eventhdlr->eventdelete = eventdelete;
383 }
384 
385 /** is event handler initialized? */
387  SCIP_EVENTHDLR* eventhdlr /**< event handler */
388  )
389 {
390  assert(eventhdlr != NULL);
391 
392  return eventhdlr->initialized;
393 }
394 
395 /** enables or disables all clocks of \p eventhdlr, depending on the value of the flag */
397  SCIP_EVENTHDLR* eventhdlr, /**< the event handler for which all clocks should be enabled or disabled */
398  SCIP_Bool enable /**< should the clocks of the event handler be enabled? */
399  )
400 {
401  assert(eventhdlr != NULL);
402 
403  SCIPclockEnableOrDisable(eventhdlr->setuptime, enable);
404  SCIPclockEnableOrDisable(eventhdlr->eventtime, enable);
405 }
406 
407 /** gets time in seconds used in this event handler for setting up for next stages */
409  SCIP_EVENTHDLR* eventhdlr /**< event handler */
410  )
411 {
412  assert(eventhdlr != NULL);
413 
414  return SCIPclockGetTime(eventhdlr->setuptime);
415 }
416 
417 /** gets time in seconds used in this event handler, this measurement is currently disabled so this method will return
418  * 0, define TIMEEVENTEXEC in the beginning of this file to enable
419  */
421  SCIP_EVENTHDLR* eventhdlr /**< event handler */
422  )
423 {
424  assert(eventhdlr != NULL);
425 
426  return SCIPclockGetTime(eventhdlr->eventtime);
427 }
428 
429 
430 
431 /*
432  * Event methods
433  */
434 
435 /** creates an event for an addition of a variable to the problem */
437  SCIP_EVENT** event, /**< pointer to store the event */
438  BMS_BLKMEM* blkmem, /**< block memory */
439  SCIP_VAR* var /**< variable that was added to the problem */
440  )
441 {
442  assert(event != NULL);
443  assert(blkmem != NULL);
444 
445  /* create event data */
446  SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
447  (*event)->eventtype = SCIP_EVENTTYPE_VARADDED;
448  (*event)->data.eventvaradded.var = var;
449 
450  return SCIP_OKAY;
451 }
452 
453 /** creates an event for a deletion of a variable from the problem */
455  SCIP_EVENT** event, /**< pointer to store the event */
456  BMS_BLKMEM* blkmem, /**< block memory */
457  SCIP_VAR* var /**< variable that is to be deleted from the problem */
458  )
459 {
460  assert(event != NULL);
461  assert(blkmem != NULL);
462 
463  /* create event data */
464  SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
465  (*event)->eventtype = SCIP_EVENTTYPE_VARDELETED;
466  (*event)->data.eventvardeleted.var = var;
467 
468  return SCIP_OKAY;
469 }
470 
471 /** creates an event for a fixing of a variable */
473  SCIP_EVENT** event, /**< pointer to store the event */
474  BMS_BLKMEM* blkmem, /**< block memory */
475  SCIP_VAR* var /**< variable that was fixed */
476  )
477 {
478  assert(event != NULL);
479  assert(blkmem != NULL);
484 
485  /* create event data */
486  SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
487  (*event)->eventtype = SCIP_EVENTTYPE_VARFIXED;
488  (*event)->data.eventvarfixed.var = var;
489 
490  return SCIP_OKAY;
491 }
492 
493 /** creates an event for a change in the number of locks of a variable down to zero or one */
495  SCIP_EVENT** event, /**< pointer to store the event */
496  BMS_BLKMEM* blkmem, /**< block memory */
497  SCIP_VAR* var /**< variable that changed the number of locks */
498  )
499 {
500  assert(event != NULL);
501  assert(blkmem != NULL);
505 
506  /* create event data */
507  SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
508  (*event)->eventtype = SCIP_EVENTTYPE_VARUNLOCKED;
509  (*event)->data.eventvarunlocked.var = var;
510 
511  return SCIP_OKAY;
512 }
513 
514 /** creates an event for a change in the objective value of a variable */
516  SCIP_EVENT** event, /**< pointer to store the event */
517  BMS_BLKMEM* blkmem, /**< block memory */
518  SCIP_VAR* var, /**< variable whose objective value changed */
519  SCIP_Real oldobj, /**< old objective value before value changed */
520  SCIP_Real newobj /**< new objective value after value changed */
521  )
522 {
523  assert(event != NULL);
524  assert(blkmem != NULL);
525  assert(oldobj != newobj); /*lint !e777*/
526 
527  /* create event data */
528  SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
529  (*event)->eventtype = SCIP_EVENTTYPE_OBJCHANGED;
530  (*event)->data.eventobjchg.var = var;
531  (*event)->data.eventobjchg.oldobj = oldobj;
532  (*event)->data.eventobjchg.newobj = newobj;
533 
534  return SCIP_OKAY;
535 }
536 
537 /** creates an event for a change in the global lower bound of a variable */
539  SCIP_EVENT** event, /**< pointer to store the event */
540  BMS_BLKMEM* blkmem, /**< block memory */
541  SCIP_VAR* var, /**< variable whose bound changed */
542  SCIP_Real oldbound, /**< old bound before bound changed */
543  SCIP_Real newbound /**< new bound after bound changed */
544  )
545 {
546  assert(event != NULL);
547  assert(blkmem != NULL);
548  assert(oldbound != newbound); /*lint !e777*/
549 
550  /* create event data */
551  SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
552  (*event)->eventtype = SCIP_EVENTTYPE_GLBCHANGED;
553  (*event)->data.eventbdchg.var = var;
554  (*event)->data.eventbdchg.oldbound = oldbound;
555  (*event)->data.eventbdchg.newbound = newbound;
556 
557  return SCIP_OKAY;
558 }
559 
560 /** creates an event for a change in the global upper bound of a variable */
562  SCIP_EVENT** event, /**< pointer to store the event */
563  BMS_BLKMEM* blkmem, /**< block memory */
564  SCIP_VAR* var, /**< variable whose bound changed */
565  SCIP_Real oldbound, /**< old bound before bound changed */
566  SCIP_Real newbound /**< new bound after bound changed */
567  )
568 {
569  assert(event != NULL);
570  assert(blkmem != NULL);
571  assert(oldbound != newbound); /*lint !e777*/
572 
573  /* create event data */
574  SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
575  (*event)->eventtype = SCIP_EVENTTYPE_GUBCHANGED;
576  (*event)->data.eventbdchg.var = var;
577  (*event)->data.eventbdchg.oldbound = oldbound;
578  (*event)->data.eventbdchg.newbound = newbound;
579 
580  return SCIP_OKAY;
581 }
582 
583 /** creates an event for a change in the lower bound of a variable */
585  SCIP_EVENT** event, /**< pointer to store the event */
586  BMS_BLKMEM* blkmem, /**< block memory */
587  SCIP_VAR* var, /**< variable whose bound changed */
588  SCIP_Real oldbound, /**< old bound before bound changed */
589  SCIP_Real newbound /**< new bound after bound changed */
590  )
591 {
592  assert(event != NULL);
593  assert(blkmem != NULL);
594  assert(oldbound != newbound); /*lint !e777*/
595 
596  /* create event data */
597  SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
598  if( newbound > oldbound )
599  (*event)->eventtype = SCIP_EVENTTYPE_LBTIGHTENED;
600  else
601  (*event)->eventtype = SCIP_EVENTTYPE_LBRELAXED;
602  (*event)->data.eventbdchg.var = var;
603  (*event)->data.eventbdchg.oldbound = oldbound;
604  (*event)->data.eventbdchg.newbound = newbound;
605 
606  return SCIP_OKAY;
607 }
608 
609 /** creates an event for a change in the upper bound of a variable */
611  SCIP_EVENT** event, /**< pointer to store the event */
612  BMS_BLKMEM* blkmem, /**< block memory */
613  SCIP_VAR* var, /**< variable whose bound changed */
614  SCIP_Real oldbound, /**< old bound before bound changed */
615  SCIP_Real newbound /**< new bound after bound changed */
616  )
617 {
618  assert(event != NULL);
619  assert(blkmem != NULL);
620  assert(oldbound != newbound); /*lint !e777*/
621 
622  /* create event data */
623  SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
624  if( newbound < oldbound )
625  (*event)->eventtype = SCIP_EVENTTYPE_UBTIGHTENED;
626  else
627  (*event)->eventtype = SCIP_EVENTTYPE_UBRELAXED;
628  (*event)->data.eventbdchg.var = var;
629  (*event)->data.eventbdchg.oldbound = oldbound;
630  (*event)->data.eventbdchg.newbound = newbound;
631 
632  return SCIP_OKAY;
633 }
634 
635 /** creates an event for an addition of a domain hole to a variable */
637  SCIP_EVENT** event, /**< pointer to store the event */
638  BMS_BLKMEM* blkmem, /**< block memory */
639  SCIP_VAR* var, /**< variable whose bound changed */
640  SCIP_Real left, /**< left bound of open interval in new hole */
641  SCIP_Real right /**< right bound of open interval in new hole */
642  )
643 {
644  assert(event != NULL);
645  assert(blkmem != NULL);
646 
647  /* create event data */
648  SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
649  (*event)->eventtype = SCIP_EVENTTYPE_GHOLEADDED;
650  (*event)->data.eventhole.var = var;
651  (*event)->data.eventhole.left = left;
652  (*event)->data.eventhole.right = right;
653 
654  return SCIP_OKAY;
655 }
656 
657 /** creates an event for removing a domain hole of a variable */
659  SCIP_EVENT** event, /**< pointer to store the event */
660  BMS_BLKMEM* blkmem, /**< block memory */
661  SCIP_VAR* var, /**< variable whose bound changed */
662  SCIP_Real left, /**< left bound of open interval in hole */
663  SCIP_Real right /**< right bound of open interval in hole */
664  )
665 {
666  assert(event != NULL);
667  assert(blkmem != NULL);
668 
669  /* create event data */
670  SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
671  (*event)->eventtype = SCIP_EVENTTYPE_GHOLEREMOVED;
672  (*event)->data.eventhole.var = var;
673  (*event)->data.eventhole.left = left;
674  (*event)->data.eventhole.right = right;
675 
676  return SCIP_OKAY;
677 }
678 
679 /** creates an event for an addition of a domain hole to a variable */
681  SCIP_EVENT** event, /**< pointer to store the event */
682  BMS_BLKMEM* blkmem, /**< block memory */
683  SCIP_VAR* var, /**< variable whose bound changed */
684  SCIP_Real left, /**< left bound of open interval in new hole */
685  SCIP_Real right /**< right bound of open interval in new hole */
686  )
687 {
688  assert(event != NULL);
689  assert(blkmem != NULL);
690 
691  /* create event data */
692  SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
693  (*event)->eventtype = SCIP_EVENTTYPE_LHOLEADDED;
694  (*event)->data.eventhole.var = var;
695  (*event)->data.eventhole.left = left;
696  (*event)->data.eventhole.right = right;
697 
698  return SCIP_OKAY;
699 }
700 
701 /** creates an event for removing a domain hole of a variable */
703  SCIP_EVENT** event, /**< pointer to store the event */
704  BMS_BLKMEM* blkmem, /**< block memory */
705  SCIP_VAR* var, /**< variable whose bound changed */
706  SCIP_Real left, /**< left bound of open interval in hole */
707  SCIP_Real right /**< right bound of open interval in hole */
708  )
709 {
710  assert(event != NULL);
711  assert(blkmem != NULL);
712 
713  /* create event data */
714  SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
715  (*event)->eventtype = SCIP_EVENTTYPE_LHOLEREMOVED;
716  (*event)->data.eventhole.var = var;
717  (*event)->data.eventhole.left = left;
718  (*event)->data.eventhole.right = right;
719 
720  return SCIP_OKAY;
721 }
722 
723 /** creates an event for an addition to the variable's implications list, clique or variable bounds information */
725  SCIP_EVENT** event, /**< pointer to store the event */
726  BMS_BLKMEM* blkmem, /**< block memory */
727  SCIP_VAR* var /**< variable that was fixed */
728  )
729 {
730  assert(event != NULL);
731  assert(blkmem != NULL);
733 
734  /* create event data */
735  SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
736  (*event)->eventtype = SCIP_EVENTTYPE_IMPLADDED;
737  (*event)->data.eventimpladd.var = var;
738 
739  return SCIP_OKAY;
740 }
741 
742 /** creates an event for the addition of a linear row to the separation storage */
744  SCIP_EVENT** event, /**< pointer to store the event */
745  BMS_BLKMEM* blkmem, /**< block memory */
746  SCIP_ROW* row /**< row that was added to the separation storage*/
747  )
748 {
749  assert(event != NULL);
750  assert(blkmem != NULL);
751  assert(row != NULL);
752 
753  /* create event data */
754  SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
755  (*event)->eventtype = SCIP_EVENTTYPE_ROWADDEDSEPA;
756  (*event)->data.eventrowaddedsepa.row = row;
757 
758  return SCIP_OKAY;
759 }
760 
761 /** creates an event for the deletion of a linear row from the separation storage */
763  SCIP_EVENT** event, /**< pointer to store the event */
764  BMS_BLKMEM* blkmem, /**< block memory */
765  SCIP_ROW* row /**< row that was deleted from the separation storage */
766  )
767 {
768  assert(event != NULL);
769  assert(blkmem != NULL);
770  assert(row != NULL);
771 
772  /* create event data */
773  SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
774  (*event)->eventtype = SCIP_EVENTTYPE_ROWDELETEDSEPA;
775  (*event)->data.eventrowdeletedsepa.row = row;
776 
777  return SCIP_OKAY;
778 }
779 
780 /** creates an event for the addition of a linear row to the LP */
782  SCIP_EVENT** event, /**< pointer to store the event */
783  BMS_BLKMEM* blkmem, /**< block memory */
784  SCIP_ROW* row /**< row that was added to the LP */
785  )
786 {
787  assert(event != NULL);
788  assert(blkmem != NULL);
789  assert(row != NULL);
790 
791  /* create event data */
792  SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
793  (*event)->eventtype = SCIP_EVENTTYPE_ROWADDEDLP;
794  (*event)->data.eventrowaddedlp.row = row;
795 
796  return SCIP_OKAY;
797 }
798 
799 /** creates an event for the deletion of a linear row from the LP */
801  SCIP_EVENT** event, /**< pointer to store the event */
802  BMS_BLKMEM* blkmem, /**< block memory */
803  SCIP_ROW* row /**< row that was deleted from the LP */
804  )
805 {
806  assert(event != NULL);
807  assert(blkmem != NULL);
808  assert(row != NULL);
809 
810  /* create event data */
811  SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
812  (*event)->eventtype = SCIP_EVENTTYPE_ROWDELETEDLP;
813  (*event)->data.eventrowdeletedlp.row = row;
814 
815  return SCIP_OKAY;
816 }
817 
818 /** creates an event for the change of a coefficient in a linear row */
820  SCIP_EVENT** event, /**< pointer to store the event */
821  BMS_BLKMEM* blkmem, /**< block memory */
822  SCIP_ROW* row, /**< row in which a coefficient changed */
823  SCIP_COL* col, /**< column which coefficient changed */
824  SCIP_Real oldval, /**< old value of coefficient */
825  SCIP_Real newval /**< new value of coefficient */
826  )
827 {
828  assert(event != NULL);
829  assert(blkmem != NULL);
830  assert(row != NULL);
831 
832  /* create event data */
833  SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
834  (*event)->eventtype = SCIP_EVENTTYPE_ROWCOEFCHANGED;
835  (*event)->data.eventrowcoefchanged.row = row;
836  (*event)->data.eventrowcoefchanged.col = col;
837  (*event)->data.eventrowcoefchanged.oldval = oldval;
838  (*event)->data.eventrowcoefchanged.newval = newval;
839 
840  return SCIP_OKAY;
841 }
842 
843 /** creates an event for the change of a constant in a linear row */
845  SCIP_EVENT** event, /**< pointer to store the event */
846  BMS_BLKMEM* blkmem, /**< block memory */
847  SCIP_ROW* row, /**< row in which the constant changed */
848  SCIP_Real oldval, /**< old value of constant */
849  SCIP_Real newval /**< new value of constant */
850  )
851 {
852  assert(event != NULL);
853  assert(blkmem != NULL);
854  assert(row != NULL);
855 
856  /* create event data */
857  SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
858  (*event)->eventtype = SCIP_EVENTTYPE_ROWCONSTCHANGED;
859  (*event)->data.eventrowconstchanged.row = row;
860  (*event)->data.eventrowconstchanged.oldval = oldval;
861  (*event)->data.eventrowconstchanged.newval = newval;
862 
863  return SCIP_OKAY;
864 }
865 
866 /** creates an event for the change of a side of a linear row */
868  SCIP_EVENT** event, /**< pointer to store the event */
869  BMS_BLKMEM* blkmem, /**< block memory */
870  SCIP_ROW* row, /**< row which side has changed */
871  SCIP_SIDETYPE side, /**< which side has changed */
872  SCIP_Real oldval, /**< old value of side */
873  SCIP_Real newval /**< new value of side */
874  )
875 {
876  assert(event != NULL);
877  assert(blkmem != NULL);
878  assert(row != NULL);
879 
880  /* create event data */
881  SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
882  (*event)->eventtype = SCIP_EVENTTYPE_ROWSIDECHANGED;
883  (*event)->data.eventrowsidechanged.row = row;
884  (*event)->data.eventrowsidechanged.side = side;
885  (*event)->data.eventrowsidechanged.oldval = oldval;
886  (*event)->data.eventrowsidechanged.newval = newval;
887 
888  return SCIP_OKAY;
889 }
890 
891 /** frees an event */
893  SCIP_EVENT** event, /**< event to free */
894  BMS_BLKMEM* blkmem /**< block memory buffer */
895  )
896 {
897  assert(event != NULL);
898  assert(blkmem != NULL);
899 
900  BMSfreeBlockMemory(blkmem, event);
901 
902  return SCIP_OKAY;
903 }
904 
905 /** disables an event */
906 static
908  SCIP_EVENT* event /**< event to disable */
909  )
910 {
911  assert(event != NULL);
912 
913  event->eventtype = SCIP_EVENTTYPE_DISABLED;
914 }
915 
916 /** gets type of event */
918  SCIP_EVENT* event /**< event */
919  )
920 {
921  assert(event != NULL);
922 
923  return event->eventtype;
924 }
925 
926 /** sets type of event */
928  SCIP_EVENT* event, /**< event */
929  SCIP_EVENTTYPE eventtype /**< new event type */
930  )
931 {
932  assert(event != NULL);
933 
934  event->eventtype = eventtype;
935 
936  return SCIP_OKAY;
937 }
938 
939 /** gets variable for a variable event (var added, var deleted, var fixed, objective value or domain change) */
941  SCIP_EVENT* event /**< event */
942  )
943 {
944  assert(event != NULL);
945 
946  switch( event->eventtype )
947  {
949  assert(event->data.eventvaradded.var != NULL);
950  return event->data.eventvaradded.var;
951 
953  assert(event->data.eventvardeleted.var != NULL);
954  return event->data.eventvardeleted.var;
955 
957  assert(event->data.eventvarfixed.var != NULL);
958  return event->data.eventvarfixed.var;
959 
961  assert(event->data.eventvarunlocked.var != NULL);
962  return event->data.eventvarunlocked.var;
963 
965  assert(event->data.eventobjchg.var != NULL);
966  return event->data.eventobjchg.var;
967 
974  assert(event->data.eventbdchg.var != NULL);
975  return event->data.eventbdchg.var;
976 
981  assert(event->data.eventhole.var != NULL);
982  return event->data.eventhole.var;
983 
985  assert(event->data.eventimpladd.var != NULL);
986  return event->data.eventimpladd.var;
987 
988  default:
989  SCIPerrorMessage("event does not belong to a variable\n");
990  SCIPABORT();
991  return NULL; /*lint !e527*/
992  } /*lint !e788*/
993 }
994 
995 /** sets variable for a variable event */
997  SCIP_EVENT* event, /**< event */
998  SCIP_VAR* var /**< new variable */
999  )
1000 {
1001  assert(event != NULL);
1002 
1003  switch( event->eventtype )
1004  {
1006  assert(event->data.eventvaradded.var != NULL);
1007  event->data.eventvaradded.var = var;
1008  break;
1009 
1011  assert(event->data.eventvardeleted.var != NULL);
1012  event->data.eventvardeleted.var = var;
1013  break;
1014 
1016  assert(event->data.eventvarfixed.var != NULL);
1017  event->data.eventvarfixed.var = var;
1018  break;
1019 
1021  assert(event->data.eventvarunlocked.var != NULL);
1022  event->data.eventvarunlocked.var = var;
1023  break;
1024 
1026  assert(event->data.eventobjchg.var != NULL);
1027  event->data.eventobjchg.var = var;
1028  break;
1029 
1036  assert(event->data.eventbdchg.var != NULL);
1037  event->data.eventbdchg.var = var;
1038  break;
1039 
1044  assert(event->data.eventhole.var != NULL);
1045  event->data.eventhole.var = var;
1046  break;
1047 
1049  assert(event->data.eventimpladd.var != NULL);
1050  event->data.eventimpladd.var = var;
1051  break;
1052 
1053  default:
1054  SCIPerrorMessage("event does not belong to a variable\n");
1055  return SCIP_INVALIDDATA;
1056  } /*lint !e788*/
1057 
1058  return SCIP_OKAY;
1059 }
1060 
1061 /** gets old objective value for an objective value change event */
1063  SCIP_EVENT* event /**< event */
1064  )
1065 {
1066  assert(event != NULL);
1067 
1068  if( event->eventtype != SCIP_EVENTTYPE_OBJCHANGED )
1069  {
1070  SCIPerrorMessage("event is not an objective value change event\n");
1071  SCIPABORT();
1072  return SCIP_INVALID; /*lint !e527*/
1073  }
1074 
1075  return event->data.eventobjchg.oldobj;
1076 }
1077 
1078 /** gets new objective value for an objective value change event */
1080  SCIP_EVENT* event /**< event */
1081  )
1082 {
1083  assert(event != NULL);
1084 
1085  if( event->eventtype != SCIP_EVENTTYPE_OBJCHANGED )
1086  {
1087  SCIPerrorMessage("event is not an objective value change event\n");
1088  SCIPABORT();
1089  return SCIP_INVALID; /*lint !e527*/
1090  }
1091 
1092  return event->data.eventobjchg.newobj;
1093 }
1094 
1095 /** gets old bound for a bound change event */
1097  SCIP_EVENT* event /**< event */
1098  )
1099 {
1100  assert(event != NULL);
1101 
1102  switch( event->eventtype )
1103  {
1110  return event->data.eventbdchg.oldbound;
1111 
1112  default:
1113  SCIPerrorMessage("event is not a bound change event\n");
1114  SCIPABORT();
1115  return 0.0; /*lint !e527*/
1116  } /*lint !e788*/
1117 }
1118 
1119 /** gets new bound for a bound change event */
1121  SCIP_EVENT* event /**< event */
1122  )
1123 {
1124  assert(event != NULL);
1125 
1126  switch( event->eventtype )
1127  {
1134  return event->data.eventbdchg.newbound;
1135 
1136  default:
1137  SCIPerrorMessage("event is not a bound change event\n");
1138  SCIPABORT();
1139  return 0.0; /*lint !e527*/
1140  } /*lint !e788*/
1141 }
1142 
1143 /** gets node for a node or LP event */
1145  SCIP_EVENT* event /**< event */
1146  )
1147 {
1148  assert(event != NULL);
1149 
1151  {
1152  SCIPerrorMessage("event is neither node nor LP event\n");
1153  SCIPABORT();
1154  return NULL; /*lint !e527*/
1155  }
1156 
1157  return event->data.node;
1158 }
1159 
1160 /** sets node for a node or LP event */
1162  SCIP_EVENT* event, /**< event */
1163  SCIP_NODE* node /**< new node */
1164  )
1165 {
1166  assert(event != NULL);
1167 
1169  {
1170  SCIPerrorMessage("event is neither node nor LP event\n");
1171  SCIPABORT();
1172  return SCIP_INVALIDDATA; /*lint !e527*/
1173  }
1174 
1175  event->data.node = node;
1176 
1177  return SCIP_OKAY;
1178 }
1179 
1180 /** gets solution for a primal solution event */
1182  SCIP_EVENT* event /**< event */
1183  )
1184 {
1185  assert(event != NULL);
1186 
1187  if( (event->eventtype & SCIP_EVENTTYPE_SOLEVENT) == 0 )
1188  {
1189  SCIPerrorMessage("event is not a primal solution event\n");
1190  SCIPABORT();
1191  return NULL; /*lint !e527*/
1192  }
1193 
1194  return event->data.sol;
1195 }
1196 
1197 /** sets solution for a primal solution event */
1199  SCIP_EVENT* event, /**< event */
1200  SCIP_SOL* sol /**< new primal solution */
1201  )
1202 {
1203  assert(event != NULL);
1204 
1205  if( (event->eventtype & SCIP_EVENTTYPE_SOLEVENT) == 0 )
1206  {
1207  SCIPerrorMessage("event is not a primal solution event\n");
1208  SCIPABORT();
1209  return SCIP_INVALIDDATA; /*lint !e527*/
1210  }
1211 
1212  event->data.sol = sol;
1213 
1214  return SCIP_OKAY;
1215 }
1216 
1217 /** gets the left bound of open interval in the hole */
1219  SCIP_EVENT* event /**< event */
1220  )
1221 {
1222  assert(event != NULL);
1223 
1224  if( (event->eventtype & SCIP_EVENTTYPE_HOLECHANGED) == 0 )
1225  {
1226  SCIPerrorMessage("event is not a hole added or removed event\n");
1227  SCIPABORT();
1228  return SCIP_INVALID; /*lint !e527*/
1229  }
1230 
1231  return event->data.eventhole.left;
1232 }
1233 
1234 /** gets the right bound of open interval in the hole */
1236  SCIP_EVENT* event /**< event */
1237  )
1238 {
1239  assert(event != NULL);
1240 
1241  if( (event->eventtype & SCIP_EVENTTYPE_HOLECHANGED) == 0 )
1242  {
1243  SCIPerrorMessage("event is not a hole added or removed event\n");
1244  SCIPABORT();
1245  return SCIP_INVALID; /*lint !e527*/
1246  }
1247 
1248  return event->data.eventhole.right;
1249 }
1250 
1251 /** gets row for a row event */
1253  SCIP_EVENT* event /**< event */
1254  )
1255 {
1256  assert(event != NULL);
1257 
1258  switch( event->eventtype )
1259  {
1261  return event->data.eventrowaddedsepa.row;
1263  return event->data.eventrowdeletedsepa.row;
1265  return event->data.eventrowaddedlp.row;
1267  return event->data.eventrowdeletedlp.row;
1269  return event->data.eventrowcoefchanged.row;
1271  return event->data.eventrowconstchanged.row;
1273  return event->data.eventrowsidechanged.row;
1274  default:
1275  SCIPerrorMessage("event does not belong to a row\n");
1276  SCIPABORT();
1277  return NULL; /*lint !e527*/
1278  }
1279 }
1280 
1281 /** gets column for a row change coefficient event */
1283  SCIP_EVENT* event /**< event */
1284  )
1285 {
1286  assert(event != NULL);
1287 
1288  if( (event->eventtype & SCIP_EVENTTYPE_ROWCOEFCHANGED) == 0 )
1289  {
1290  SCIPerrorMessage("event is not a row coefficient changed event\n");
1291  SCIPABORT();
1292  return NULL; /*lint !e527*/
1293  }
1294 
1295  return event->data.eventrowcoefchanged.col;
1296 }
1297 
1298 /** gets old coefficient value for a row change coefficient event */
1300  SCIP_EVENT* event /**< event */
1301  )
1302 {
1303  assert(event != NULL);
1304 
1305  if( (event->eventtype & SCIP_EVENTTYPE_ROWCOEFCHANGED) == 0 )
1306  {
1307  SCIPerrorMessage("event is not a row coefficient changed event\n");
1308  SCIPABORT();
1309  return SCIP_INVALID; /*lint !e527*/
1310  }
1311 
1312  return event->data.eventrowcoefchanged.oldval;
1313 }
1314 
1315 /** gets new coefficient value for a row change coefficient event */
1317  SCIP_EVENT* event /**< event */
1318  )
1319 {
1320  assert(event != NULL);
1321 
1322  if( (event->eventtype & SCIP_EVENTTYPE_ROWCOEFCHANGED) == 0 )
1323  {
1324  SCIPerrorMessage("event is not a row coefficient changed event\n");
1325  SCIPABORT();
1326  return SCIP_INVALID; /*lint !e527*/
1327  }
1328 
1329  return event->data.eventrowcoefchanged.newval;
1330 }
1331 
1332 /** gets old constant value for a row change constant event */
1334  SCIP_EVENT* event /**< event */
1335  )
1336 {
1337  assert(event != NULL);
1338 
1339  if( (event->eventtype & SCIP_EVENTTYPE_ROWCONSTCHANGED) == 0 )
1340  {
1341  SCIPerrorMessage("event is not a row coefficient changed event\n");
1342  SCIPABORT();
1343  return SCIP_INVALID; /*lint !e527*/
1344  }
1345 
1346  return event->data.eventrowconstchanged.oldval;
1347 }
1348 
1349 /** gets new constant value for a row change constant event */
1351  SCIP_EVENT* event /**< event */
1352  )
1353 {
1354  assert(event != NULL);
1355 
1356  if( (event->eventtype & SCIP_EVENTTYPE_ROWCONSTCHANGED) == 0 )
1357  {
1358  SCIPerrorMessage("event is not a row coefficient changed event\n");
1359  SCIPABORT();
1360  return SCIP_INVALID; /*lint !e527*/
1361  }
1362 
1363  return event->data.eventrowconstchanged.newval;
1364 }
1365 
1366 /** gets side for a row change side event */
1368  SCIP_EVENT* event /**< event */
1369  )
1370 {
1371  assert(event != NULL);
1372 
1373  if( (event->eventtype & SCIP_EVENTTYPE_ROWSIDECHANGED) == 0 )
1374  {
1375  SCIPerrorMessage("event is not a row side changed event\n");
1376  SCIPABORT();
1377  return SCIP_SIDETYPE_LEFT; /*lint !e527*/
1378  }
1379 
1380  return event->data.eventrowsidechanged.side;
1381 }
1382 
1383 /** gets old side value for a row change side event */
1385  SCIP_EVENT* event /**< event */
1386  )
1387 {
1388  assert(event != NULL);
1389 
1390  if( (event->eventtype & SCIP_EVENTTYPE_ROWSIDECHANGED) == 0 )
1391  {
1392  SCIPerrorMessage("event is not a row side changed event\n");
1393  SCIPABORT();
1394  return SCIP_INVALID; /*lint !e527*/
1395  }
1396 
1397  return event->data.eventrowsidechanged.oldval;
1398 }
1399 
1400 /** gets new side value for a row change side event */
1402  SCIP_EVENT* event /**< event */
1403  )
1404 {
1405  assert(event != NULL);
1406 
1407  if( (event->eventtype & SCIP_EVENTTYPE_ROWSIDECHANGED) == 0 )
1408  {
1409  SCIPerrorMessage("event is not a row side changed event\n");
1410  SCIPABORT();
1411  return SCIP_INVALID; /*lint !e527*/
1412  }
1413 
1414  return event->data.eventrowsidechanged.newval;
1415 }
1416 
1417 /** processes event by calling the appropriate event handlers */
1419  SCIP_EVENT* event, /**< event */
1420  SCIP_SET* set, /**< global SCIP settings */
1421  SCIP_PRIMAL* primal, /**< primal data; only needed for objchanged events, or NULL */
1422  SCIP_LP* lp, /**< current LP data; only needed for obj/boundchanged events, or NULL */
1423  SCIP_BRANCHCAND* branchcand, /**< branching candidate storage; only needed for bound change events, or NULL */
1424  SCIP_EVENTFILTER* eventfilter /**< event filter for global events; not needed for variable specific events */
1425  )
1426 {
1427  SCIP_VAR* var;
1428 
1429  assert(event != NULL);
1430  assert((event->eventtype & SCIP_EVENTTYPE_OBJCHANGED) == 0 || primal != NULL);
1431  assert((event->eventtype & (SCIP_EVENTTYPE_BOUNDCHANGED | SCIP_EVENTTYPE_OBJCHANGED)) == 0 || lp != NULL);
1432  assert((event->eventtype & SCIP_EVENTTYPE_BOUNDCHANGED) == 0 || branchcand != NULL);
1433 
1434  SCIPdebugMessage("processing event of type 0x%x\n", event->eventtype);
1435 
1436  switch( event->eventtype )
1437  {
1439  break;
1440 
1458  SCIP_CALL( SCIPeventfilterProcess(eventfilter, set, event) );
1459  break;
1460 
1462  var = event->data.eventvardeleted.var;
1463  assert(var != NULL);
1464 
1465  /* process variable's event filter */
1466  SCIP_CALL( SCIPeventfilterProcess(var->eventfilter, set, event) );
1467  break;
1468 
1470  var = event->data.eventvarfixed.var;
1471  assert(var != NULL);
1472 
1473  /* process variable's event filter */
1474  SCIP_CALL( SCIPeventfilterProcess(var->eventfilter, set, event) );
1475  break;
1476 
1478  var = event->data.eventvarunlocked.var;
1479  assert(var != NULL);
1480 
1481  /* process variable's event filter */
1482  SCIP_CALL( SCIPeventfilterProcess(var->eventfilter, set, event) );
1483  break;
1484 
1486  var = event->data.eventobjchg.var;
1487  assert(var != NULL);
1488  assert(var->eventqueueindexobj == -1);
1490 
1491  /* inform LP about the objective change */
1492  if( SCIPvarGetProbindex(var) >= 0 )
1493  {
1495  {
1496  SCIP_CALL( SCIPcolChgObj(SCIPvarGetCol(var), set, lp, event->data.eventobjchg.newobj) );
1497  }
1498  SCIP_CALL( SCIPlpUpdateVarObj(lp, set, var, event->data.eventobjchg.oldobj, event->data.eventobjchg.newobj) );
1499  }
1500 
1501  /* inform all existing primal solutions about the objective change */
1502  SCIPprimalUpdateVarObj(primal, var, event->data.eventobjchg.oldobj, event->data.eventobjchg.newobj);
1503 
1504  /* process variable's event filter */
1505  SCIP_CALL( SCIPeventfilterProcess(var->eventfilter, set, event) );
1506  break;
1507 
1509  var = event->data.eventbdchg.var;
1510  assert(var != NULL);
1511 
1512  /* inform LP about global bound change */
1514  {
1515  assert(SCIPvarGetProbindex(var) >= 0);
1517  event->data.eventbdchg.newbound) );
1518  }
1519 
1520  /* process variable's event filter */
1521  SCIP_CALL( SCIPeventfilterProcess(var->eventfilter, set, event) );
1522  break;
1523 
1525  var = event->data.eventbdchg.var;
1526  assert(var != NULL);
1527 
1528  /* inform LP about global bound change */
1530  {
1531  assert(SCIPvarGetProbindex(var) >= 0);
1533  event->data.eventbdchg.newbound) );
1534  }
1535 
1536  /* process variable's event filter */
1537  SCIP_CALL( SCIPeventfilterProcess(var->eventfilter, set, event) );
1538  break;
1539 
1542  var = event->data.eventbdchg.var;
1543  assert(var != NULL);
1544  assert(var->eventqueueindexlb == -1);
1545 
1546  /* inform LP about bound change and update branching candidates */
1548  {
1549  assert(SCIPvarGetProbindex(var) >= 0);
1551  {
1552  SCIP_CALL( SCIPcolChgLb(SCIPvarGetCol(var), set, lp, event->data.eventbdchg.newbound) );
1553  }
1554  SCIP_CALL( SCIPlpUpdateVarLb(lp, set, var, event->data.eventbdchg.oldbound,
1555  event->data.eventbdchg.newbound) );
1556  SCIP_CALL( SCIPbranchcandUpdateVar(branchcand, set, var) );
1557  }
1558 
1559  /* process variable's event filter */
1560  SCIP_CALL( SCIPeventfilterProcess(var->eventfilter, set, event) );
1561  break;
1562 
1565  var = event->data.eventbdchg.var;
1566  assert(var != NULL);
1567  assert(var->eventqueueindexub == -1);
1568 
1569  /* inform LP about bound change and update branching candidates */
1571  {
1572  assert(SCIPvarGetProbindex(var) >= 0);
1574  {
1575  SCIP_CALL( SCIPcolChgUb(SCIPvarGetCol(var), set, lp, event->data.eventbdchg.newbound) );
1576  }
1577  SCIP_CALL( SCIPlpUpdateVarUb(lp, set, var, event->data.eventbdchg.oldbound,
1578  event->data.eventbdchg.newbound) );
1579  SCIP_CALL( SCIPbranchcandUpdateVar(branchcand, set, var) );
1580  }
1581 
1582  /* process variable's event filter */
1583  SCIP_CALL( SCIPeventfilterProcess(var->eventfilter, set, event) );
1584  break;
1585 
1590  var = event->data.eventhole.var;
1591  assert(var != NULL);
1592 
1593  /* process variable's event filter */
1594  SCIP_CALL( SCIPeventfilterProcess(var->eventfilter, set, event) );
1595  break;
1596 
1598  var = event->data.eventimpladd.var;
1599  assert(var != NULL);
1600  assert(!var->eventqueueimpl);
1601 
1602  /* process variable's event filter */
1603  SCIP_CALL( SCIPeventfilterProcess(var->eventfilter, set, event) );
1604  break;
1605 
1606  default:
1607  SCIPerrorMessage("unknown event type <%d>\n", event->eventtype);
1608  return SCIP_INVALIDDATA;
1609  }
1610 
1611  return SCIP_OKAY;
1612 }
1613 
1614 
1615 
1616 /*
1617  * Event filter methods
1618  */
1619 
1620 /** resizes eventfilter arrays to be able to store at least num entries */
1621 static
1623  SCIP_EVENTFILTER* eventfilter, /**< event filter */
1624  BMS_BLKMEM* blkmem, /**< block memory buffer */
1625  SCIP_SET* set, /**< global SCIP settings */
1626  int num /**< minimal number of node slots in array */
1627  )
1628 {
1629  assert(eventfilter != NULL);
1630  assert(blkmem != NULL);
1631  assert(set != NULL);
1632 
1633  if( num > eventfilter->size )
1634  {
1635  int newsize;
1636 
1637  newsize = SCIPsetCalcMemGrowSize(set, num);
1638  SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &eventfilter->eventtypes, eventfilter->size, newsize) );
1639  SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &eventfilter->eventhdlrs, eventfilter->size, newsize) );
1640  SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &eventfilter->eventdata, eventfilter->size, newsize) );
1641  SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &eventfilter->nextpos, eventfilter->size, newsize) );
1642  eventfilter->size = newsize;
1643  }
1644  assert(num <= eventfilter->size);
1645 
1646  return SCIP_OKAY;
1647 }
1648 
1649 /** creates an event filter */
1651  SCIP_EVENTFILTER** eventfilter, /**< pointer to store the event filter */
1652  BMS_BLKMEM* blkmem /**< block memory buffer */
1653  )
1654 {
1655  assert(eventfilter != NULL);
1656  assert(blkmem != NULL);
1657 
1658  SCIP_ALLOC( BMSallocBlockMemory(blkmem, eventfilter) );
1659  (*eventfilter)->eventtypes = NULL;
1660  (*eventfilter)->eventhdlrs = NULL;
1661  (*eventfilter)->eventdata = NULL;
1662  (*eventfilter)->nextpos = NULL;
1663  (*eventfilter)->size = 0;
1664  (*eventfilter)->len = 0;
1665  (*eventfilter)->firstfreepos = -1;
1666  (*eventfilter)->firstdeletedpos = -1;
1667  (*eventfilter)->eventmask = SCIP_EVENTTYPE_DISABLED;
1668  (*eventfilter)->delayedeventmask = SCIP_EVENTTYPE_DISABLED;
1669  (*eventfilter)->delayupdates = FALSE;
1670 
1671  return SCIP_OKAY;
1672 }
1673 
1674 /** frees an event filter and the associated event data entries */
1676  SCIP_EVENTFILTER** eventfilter, /**< pointer to store the event filter */
1677  BMS_BLKMEM* blkmem, /**< block memory buffer */
1678  SCIP_SET* set /**< global SCIP settings */
1679  )
1680 {
1681  int i;
1682 
1683  assert(eventfilter != NULL);
1684  assert(*eventfilter != NULL);
1685  assert(!(*eventfilter)->delayupdates);
1686  assert(blkmem != NULL);
1687  assert(set != NULL);
1688  assert(set->scip != NULL);
1689 
1690  /* free event data */
1691  for( i = 0; i < (*eventfilter)->len; ++i )
1692  {
1693  if( (*eventfilter)->eventtypes[i] != SCIP_EVENTTYPE_DISABLED )
1694  {
1695  assert((*eventfilter)->eventhdlrs[i] != NULL);
1696  if( (*eventfilter)->eventhdlrs[i]->eventdelete != NULL )
1697  {
1698  SCIP_CALL( (*eventfilter)->eventhdlrs[i]->eventdelete(set->scip, (*eventfilter)->eventhdlrs[i],
1699  &(*eventfilter)->eventdata[i]) );
1700  }
1701  }
1702  }
1703 
1704  /* free event filter data */
1705  BMSfreeBlockMemoryArrayNull(blkmem, &(*eventfilter)->eventtypes, (*eventfilter)->size);
1706  BMSfreeBlockMemoryArrayNull(blkmem, &(*eventfilter)->eventhdlrs, (*eventfilter)->size);
1707  BMSfreeBlockMemoryArrayNull(blkmem, &(*eventfilter)->eventdata, (*eventfilter)->size);
1708  BMSfreeBlockMemoryArrayNull(blkmem, &(*eventfilter)->nextpos, (*eventfilter)->size);
1709  BMSfreeBlockMemory(blkmem, eventfilter);
1710 
1711  return SCIP_OKAY;
1712 }
1713 
1714 /** adds element to event filter */
1716  SCIP_EVENTFILTER* eventfilter, /**< event filter */
1717  BMS_BLKMEM* blkmem, /**< block memory buffer */
1718  SCIP_SET* set, /**< global SCIP settings */
1719  SCIP_EVENTTYPE eventtype, /**< event type to catch */
1720  SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
1721  SCIP_EVENTDATA* eventdata, /**< event data to pass to the event handler for the event processing */
1722  int* filterpos /**< pointer to store position of event filter entry, or NULL */
1723  )
1724 {
1725  int pos;
1726 
1727  assert(eventfilter != NULL);
1728  assert(blkmem != NULL);
1729  assert(set != NULL);
1730  assert(eventhdlr != NULL);
1731 
1732  if( eventfilter->delayupdates )
1733  {
1734  /* insert addition to the end of the arrays;
1735  * in delayed addition we have to add to the end of the arrays, in order to not destroy the validity of the
1736  * arrays we are currently iterating over
1737  */
1738  SCIP_CALL( eventfilterEnsureMem(eventfilter, blkmem, set, eventfilter->len + 1) );
1739  pos = eventfilter->len;
1740  eventfilter->len++;
1741 
1742  /* update delayed event filter mask */
1743  eventfilter->delayedeventmask |= eventtype;
1744  }
1745  else
1746  {
1747  if( eventfilter->firstfreepos == -1 )
1748  {
1749  /* insert addition to the end of the arrays */
1750  SCIP_CALL( eventfilterEnsureMem(eventfilter, blkmem, set, eventfilter->len + 1) );
1751  pos = eventfilter->len;
1752  eventfilter->len++;
1753  }
1754  else
1755  {
1756  /* use the first free slot to store the added event filter entry */
1757  pos = eventfilter->firstfreepos;
1758  assert(0 <= pos && pos < eventfilter->len);
1759  assert(eventfilter->eventtypes[pos] == SCIP_EVENTTYPE_DISABLED);
1760  eventfilter->firstfreepos = eventfilter->nextpos[pos];
1761  assert(-1 <= eventfilter->firstfreepos && eventfilter->firstfreepos < eventfilter->len);
1762  }
1763 
1764  /* update event filter mask */
1765  eventfilter->eventmask |= eventtype;
1766  }
1767  assert(0 <= pos && pos < eventfilter->len);
1768 
1769  eventfilter->eventtypes[pos] = eventtype;
1770  eventfilter->eventhdlrs[pos] = eventhdlr;
1771  eventfilter->eventdata[pos] = eventdata;
1772  eventfilter->nextpos[pos] = -2;
1773 
1774  if( filterpos != NULL )
1775  *filterpos = pos;
1776 
1777  return SCIP_OKAY;
1778 }
1779 
1780 /** linear search for the given entry in event filter */
1781 static
1783  SCIP_EVENTFILTER*const eventfilter, /**< event filter */
1784  SCIP_EVENTTYPE const eventtype, /**< event type */
1785  SCIP_EVENTHDLR*const eventhdlr, /**< event handler to call for the event processing */
1786  SCIP_EVENTDATA*const eventdata /**< event data to pass to the event handler for the event processing */
1787  )
1788 {
1789  int i;
1790 
1791  assert(eventfilter != NULL);
1792  assert(eventtype != SCIP_EVENTTYPE_DISABLED);
1793  assert(eventhdlr != NULL);
1794 
1795  for( i = eventfilter->len - 1; i >= 0; --i )
1796  {
1797  if( eventdata == eventfilter->eventdata[i]
1798  && eventhdlr == eventfilter->eventhdlrs[i]
1799  && eventtype == eventfilter->eventtypes[i]
1800  && eventfilter->nextpos[i] == -2 )
1801  return i;
1802  }
1803 
1804  return -1;
1805 }
1806 
1807 /** deletes element from event filter */
1809  SCIP_EVENTFILTER* eventfilter, /**< event filter */
1810  BMS_BLKMEM* blkmem, /**< block memory buffer */
1811  SCIP_SET* set, /**< global SCIP settings */
1812  SCIP_EVENTTYPE eventtype, /**< event type */
1813  SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
1814  SCIP_EVENTDATA* eventdata, /**< event data to pass to the event handler for the event processing */
1815  int filterpos /**< position of event filter entry, or -1 if unknown */
1816  )
1817 {
1818  assert(eventfilter != NULL);
1819  assert(blkmem != NULL);
1820  assert(set != NULL);
1821  assert(eventtype != SCIP_EVENTTYPE_DISABLED);
1822  assert(eventhdlr != NULL);
1823  assert(-1 <= filterpos && filterpos < eventfilter->len);
1824 
1825  /* search position of event filter entry, if not given by the user */
1826  if( filterpos == -1 )
1827  filterpos = eventfilterSearch(eventfilter, eventtype, eventhdlr, eventdata);
1828  if( filterpos == -1 )
1829  {
1830  SCIPerrorMessage("no event for event handler %p with data %p and event mask 0x%x found in event filter %p\n",
1831  eventhdlr, eventdata, eventtype, eventfilter);
1832  return SCIP_INVALIDDATA;
1833  }
1834  assert(0 <= filterpos && filterpos < eventfilter->len);
1835  assert(eventfilter->eventtypes[filterpos] == eventtype);
1836  assert(eventfilter->eventhdlrs[filterpos] == eventhdlr);
1837  assert(eventfilter->eventdata[filterpos] == eventdata);
1838  assert(eventfilter->nextpos[filterpos] == -2);
1839 
1840  /* if updates are delayed, insert entry into the list of delayed deletions;
1841  * otherwise, delete the entry from the filter directly and add the slot to the free list
1842  */
1843  if( eventfilter->delayupdates )
1844  {
1845  /* append filterpos to the list of deleted entries */
1846  eventfilter->nextpos[filterpos] = eventfilter->firstdeletedpos;
1847  eventfilter->firstdeletedpos = filterpos;
1848  }
1849  else
1850  {
1851  /* disable the entry in the filter and add the slot to the free list */
1852  assert(eventfilter->nextpos[filterpos] == -2);
1853  eventfilter->eventtypes[filterpos] = SCIP_EVENTTYPE_DISABLED;
1854  eventfilter->nextpos[filterpos] = eventfilter->firstfreepos;
1855  eventfilter->firstfreepos = filterpos;
1856  }
1857 
1858  return SCIP_OKAY;
1859 }
1860 
1861 /** makes the event filter to delay and buffer all updates until eventfilterProcessUpdates() is called */
1862 static
1864  SCIP_EVENTFILTER* eventfilter /**< event filter */
1865  )
1866 {
1867  assert(eventfilter != NULL);
1868  assert(!eventfilter->delayupdates);
1869  assert(eventfilter->delayedeventmask == SCIP_EVENTTYPE_DISABLED);
1870 
1871  eventfilter->delayupdates = TRUE;
1872 }
1873 
1874 /** processes all delayed additions and deletions */
1875 static
1877  SCIP_EVENTFILTER* eventfilter /**< event filter */
1878  )
1879 {
1880  int pos;
1881  int nextpos;
1882 
1883  assert(eventfilter != NULL);
1884  assert(eventfilter->delayupdates);
1885 
1886  /* move deleted entries into the free list and disable them */
1887  pos = eventfilter->firstdeletedpos;
1888  while( pos != -1 )
1889  {
1890  assert(0 <= pos && pos < eventfilter->len);
1891  assert(eventfilter->eventtypes[pos] != SCIP_EVENTTYPE_DISABLED);
1892  assert(eventfilter->nextpos[pos] >= -1);
1893 
1894  nextpos = eventfilter->nextpos[pos];
1895  eventfilter->nextpos[pos] = eventfilter->firstfreepos;
1896  eventfilter->firstfreepos = pos;
1897  eventfilter->eventtypes[pos] = SCIP_EVENTTYPE_DISABLED;
1898  pos = nextpos;
1899  }
1900  eventfilter->firstdeletedpos = -1;
1901 
1902  /* update event mask */
1903  eventfilter->eventmask |= eventfilter->delayedeventmask;
1905 
1906  /* mark the event filter updates to be no longer delayed */
1907  eventfilter->delayupdates = FALSE;
1908 }
1909 
1910 /** processes the event with all event handlers with matching filter setting */
1912  SCIP_EVENTFILTER* eventfilter, /**< event filter */
1913  SCIP_SET* set, /**< global SCIP settings */
1914  SCIP_EVENT* event /**< event to process */
1915  )
1916 {
1917  SCIP_EVENTTYPE eventtype;
1918  SCIP_EVENTTYPE* eventtypes;
1919  SCIP_Bool processed;
1920  int len;
1921  int i;
1922 
1923  assert(eventfilter != NULL);
1924  assert(set != NULL);
1925  assert(event != NULL);
1926 
1927  SCIPdebugMessage("processing event filter %p (len %d, mask 0x%x) with event type 0x%x\n",
1928  (void*)eventfilter, eventfilter->len, eventfilter->eventmask, event->eventtype);
1929 
1930  eventtype = event->eventtype;
1931 
1932  /* check, if there may be any event handler for specific event */
1933  if( (eventtype & eventfilter->eventmask) == 0 )
1934  return SCIP_OKAY;
1935 
1936  /* delay the updates on this eventfilter, such that changes during event processing to the event filter
1937  * don't destroy necessary information of the arrays we are currently using
1938  */
1939  eventfilterDelayUpdates(eventfilter);
1940 
1941  /* process the event by calling the event handlers */
1942  processed = FALSE;
1943  len = eventfilter->len;
1944  eventtypes = eventfilter->eventtypes;
1945  for( i = 0; i < len; ++i )
1946  {
1947  /* check, if event is applicable for the filter element */
1948  if( (eventtype & eventtypes[i]) != 0 )
1949  {
1950  /* call event handler */
1951  SCIP_CALL( SCIPeventhdlrExec(eventfilter->eventhdlrs[i], set, event, eventfilter->eventdata[i]) );
1952  processed = TRUE;
1953  }
1954  }
1955 
1956  /* update eventfilter mask, if event was not processed by any event handler */
1957  if( !processed )
1958  {
1959  eventfilter->eventmask &= ~event->eventtype;
1960  SCIPdebugMessage(" -> event type 0x%x not processed. new mask of event filter %p: 0x%x\n",
1961  event->eventtype, (void*)eventfilter, eventfilter->eventmask);
1962  }
1963 
1964  /* process delayed events on this eventfilter */
1965  eventfilterProcessUpdates(eventfilter);
1966 
1967  return SCIP_OKAY;
1968 }
1969 
1970 
1971 
1972 /*
1973  * Event queue methods
1974  */
1975 
1976 /** resizes events array to be able to store at least num entries */
1977 static
1979  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
1980  SCIP_SET* set, /**< global SCIP settings */
1981  int num /**< minimal number of node slots in array */
1982  )
1983 {
1984  assert(eventqueue != NULL);
1985  assert(set != NULL);
1986 
1987  if( num > eventqueue->eventssize )
1988  {
1989  int newsize;
1990 
1991  newsize = SCIPsetCalcMemGrowSize(set, num);
1992  SCIP_ALLOC( BMSreallocMemoryArray(&eventqueue->events, newsize) );
1993  eventqueue->eventssize = newsize;
1994  }
1995  assert(num <= eventqueue->eventssize);
1996 
1997  return SCIP_OKAY;
1998 }
1999 
2000 /** creates an event queue */
2002  SCIP_EVENTQUEUE** eventqueue /**< pointer to store the event queue */
2003  )
2004 {
2005  assert(eventqueue != NULL);
2006 
2007  SCIP_ALLOC( BMSallocMemory(eventqueue) );
2008  (*eventqueue)->events = NULL;
2009  (*eventqueue)->eventssize = 0;
2010  (*eventqueue)->nevents = 0;
2011  (*eventqueue)->delayevents = FALSE;
2012 
2013  return SCIP_OKAY;
2014 }
2015 
2016 /** frees event queue; there must not be any unprocessed events in the queue! */
2018  SCIP_EVENTQUEUE** eventqueue /**< pointer to the event queue */
2019  )
2020 {
2021  assert(eventqueue != NULL);
2022  assert(*eventqueue != NULL);
2023  assert((*eventqueue)->nevents == 0);
2024 
2025  BMSfreeMemoryArrayNull(&(*eventqueue)->events);
2026  BMSfreeMemory(eventqueue);
2027 
2028  return SCIP_OKAY;
2029 }
2030 
2031 /** appends event to the event queue; sets event to NULL afterwards */
2032 static
2034  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
2035  SCIP_SET* set, /**< global SCIP settings */
2036  SCIP_EVENT** event /**< pointer to event to append to the queue */
2037  )
2038 {
2039  assert(eventqueue != NULL);
2040  assert(eventqueue->delayevents);
2041  assert(event != NULL);
2042  assert(*event != NULL);
2043 
2044  SCIPdebugMessage("appending event %p of type 0x%x to event queue %p at position %d\n",
2045  (void*)*event, (*event)->eventtype, (void*)eventqueue, eventqueue->nevents);
2046 
2047  SCIP_CALL( eventqueueEnsureEventsMem(eventqueue, set, eventqueue->nevents+1) );
2048  eventqueue->events[eventqueue->nevents] = *event;
2049  eventqueue->nevents++;
2050 
2051  *event = NULL;
2052 
2053  return SCIP_OKAY;
2054 }
2055 
2056 /** processes event or adds event to the event queue */
2058  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
2059  BMS_BLKMEM* blkmem, /**< block memory buffer */
2060  SCIP_SET* set, /**< global SCIP settings */
2061  SCIP_PRIMAL* primal, /**< primal data; only needed for objchanged events, or NULL */
2062  SCIP_LP* lp, /**< current LP data; only needed for obj/boundchanged events, or NULL */
2063  SCIP_BRANCHCAND* branchcand, /**< branching candidate storage; only needed for bound change events, or NULL */
2064  SCIP_EVENTFILTER* eventfilter, /**< event filter for global events; not needed for variable specific events */
2065  SCIP_EVENT** event /**< pointer to event to add to the queue; will be NULL after queue addition */
2066  )
2067 {
2068  SCIP_VAR* var;
2069  SCIP_EVENT* qevent;
2070  int pos;
2071 
2072  assert(eventqueue != NULL);
2073  assert(event != NULL);
2074  assert(*event != NULL);
2075  assert(((*event)->eventtype & SCIP_EVENTTYPE_OBJCHANGED) == 0 || primal != NULL);
2076  assert(((*event)->eventtype & (SCIP_EVENTTYPE_BOUNDCHANGED | SCIP_EVENTTYPE_OBJCHANGED)) == 0 || lp != NULL);
2077  assert(((*event)->eventtype & SCIP_EVENTTYPE_BOUNDCHANGED) == 0 || branchcand != NULL);
2078 
2079  if( !eventqueue->delayevents )
2080  {
2081  /* immediately process event */
2082  SCIP_CALL( SCIPeventProcess(*event, set, primal, lp, branchcand, eventfilter) );
2083  SCIP_CALL( SCIPeventFree(event, blkmem) );
2084  }
2085  else
2086  {
2087  /* delay processing of event by appending it to the event queue */
2088  SCIPdebugMessage("adding event %p of type 0x%x to event queue %p\n", (void*)*event, (*event)->eventtype, (void*)eventqueue);
2089 
2090  switch( (*event)->eventtype )
2091  {
2093  SCIPerrorMessage("cannot add a disabled event to the event queue\n");
2094  return SCIP_INVALIDDATA;
2095 
2115  case SCIP_EVENTTYPE_ROWADDEDSEPA: /* @todo remove previous DELETEDSEPA event */
2116  case SCIP_EVENTTYPE_ROWDELETEDSEPA: /* @todo remove previous ADDEDSEPA event */
2117  case SCIP_EVENTTYPE_ROWADDEDLP: /* @todo remove previous DELETEDLP event */
2118  case SCIP_EVENTTYPE_ROWDELETEDLP: /* @todo remove previous ADDEDLP event */
2119  case SCIP_EVENTTYPE_ROWCOEFCHANGED: /* @todo merge? */
2120  case SCIP_EVENTTYPE_ROWCONSTCHANGED: /* @todo merge with previous constchanged event */
2121  case SCIP_EVENTTYPE_ROWSIDECHANGED: /* @todo merge with previous sidechanged event */
2122  /* these events cannot (or need not) be merged; just add them to the queue */
2123  SCIP_CALL( eventqueueAppend(eventqueue, set, event) );
2124  break;
2125 
2127  /* changes in objective value may be merged with older changes in objective value */
2128  var = (*event)->data.eventobjchg.var;
2129  assert(var != NULL);
2130  pos = var->eventqueueindexobj;
2131  if( pos >= 0 )
2132  {
2133  /* the objective value change event already exists -> modify it accordingly */
2134  assert(pos < eventqueue->nevents);
2135  qevent = eventqueue->events[pos];
2136  assert(qevent != NULL);
2137  assert(qevent->eventtype == SCIP_EVENTTYPE_OBJCHANGED);
2138  assert(qevent->data.eventobjchg.var == var);
2139  assert(SCIPsetIsEQ(set, (*event)->data.eventobjchg.oldobj, qevent->data.eventobjchg.newobj));
2140 
2141  SCIPdebugMessage(" -> merging OBJ event (<%s>,%g -> %g) with event at position %d (<%s>,%g -> %g)\n",
2142  SCIPvarGetName((*event)->data.eventobjchg.var), (*event)->data.eventobjchg.oldobj,
2143  (*event)->data.eventobjchg.newobj,
2144  pos, SCIPvarGetName(qevent->data.eventobjchg.var), qevent->data.eventobjchg.oldobj,
2145  qevent->data.eventobjchg.newobj);
2146 
2147  qevent->data.eventobjchg.newobj = (*event)->data.eventobjchg.newobj;
2148  if( qevent->data.eventobjchg.newobj == qevent->data.eventobjchg.oldobj ) /*lint !e777*/
2149  {
2150  /* the queued objective value change was reversed -> disable the event in the queue */
2151  eventDisable(qevent);
2152  var->eventqueueindexobj = -1;
2153  SCIPdebugMessage(" -> event disabled\n");
2154  }
2155 
2156  /* free the event that is of no use any longer */
2157  SCIP_CALL( SCIPeventFree(event, blkmem) );
2158  }
2159  else
2160  {
2161  /* the objective value change event doesn't exist -> add it to the queue, and remember the array index */
2162  var->eventqueueindexobj = eventqueue->nevents;
2163  SCIP_CALL( eventqueueAppend(eventqueue, set, event) );
2164  }
2165  break;
2166 
2169  /* changes in lower bound may be merged with older changes in lower bound */
2170  var = (*event)->data.eventbdchg.var;
2171  assert(var != NULL);
2172  pos = var->eventqueueindexlb;
2173  if( pos >= 0 )
2174  {
2175  /* the lower bound change event already exists -> modify it accordingly */
2176  assert(pos < eventqueue->nevents);
2177  qevent = eventqueue->events[pos];
2178  assert(qevent != NULL);
2180  assert(qevent->data.eventbdchg.var == var);
2181  assert(SCIPsetIsEQ(set, (*event)->data.eventbdchg.oldbound, qevent->data.eventbdchg.newbound));
2182 
2183  SCIPdebugMessage(" -> merging LB event (<%s>,%g -> %g) with event at position %d (<%s>,%g -> %g)\n",
2184  SCIPvarGetName((*event)->data.eventbdchg.var), (*event)->data.eventbdchg.oldbound,
2185  (*event)->data.eventbdchg.newbound,
2186  pos, SCIPvarGetName(qevent->data.eventbdchg.var), qevent->data.eventbdchg.oldbound,
2187  qevent->data.eventbdchg.newbound);
2188 
2189  qevent->data.eventbdchg.newbound = (*event)->data.eventbdchg.newbound;
2190  /*if( SCIPsetIsLT(set, qevent->data.eventbdchg.newbound, qevent->data.eventbdchg.oldbound) )*/
2191  if( qevent->data.eventbdchg.newbound < qevent->data.eventbdchg.oldbound )
2193  /*else if( SCIPsetIsGT(set, qevent->data.eventbdchg.newbound, qevent->data.eventbdchg.oldbound) )*/
2194  else if( qevent->data.eventbdchg.newbound > qevent->data.eventbdchg.oldbound )
2196  else
2197  {
2198  /* the queued bound change was reversed -> disable the event in the queue */
2199  assert(qevent->data.eventbdchg.newbound == qevent->data.eventbdchg.oldbound); /*lint !e777*/
2200  eventDisable(qevent);
2201  var->eventqueueindexlb = -1;
2202  SCIPdebugMessage(" -> event disabled\n");
2203  }
2204 
2205  /* free the event that is of no use any longer */
2206  SCIP_CALL( SCIPeventFree(event, blkmem) );
2207  }
2208  else
2209  {
2210  /* the lower bound change event doesn't exist -> add it to the queue, and remember the array index */
2211  var->eventqueueindexlb = eventqueue->nevents;
2212  SCIP_CALL( eventqueueAppend(eventqueue, set, event) );
2213  }
2214  break;
2215 
2218  /* changes in upper bound may be merged with older changes in upper bound */
2219  var = (*event)->data.eventbdchg.var;
2220  assert(var != NULL);
2221  pos = var->eventqueueindexub;
2222  if( pos >= 0 )
2223  {
2224  /* the upper bound change event already exists -> modify it accordingly */
2225  assert(pos < eventqueue->nevents);
2226  qevent = eventqueue->events[pos];
2227  assert(qevent != NULL);
2229  assert(qevent->data.eventbdchg.var == var);
2230  assert(SCIPsetIsEQ(set, (*event)->data.eventbdchg.oldbound, qevent->data.eventbdchg.newbound));
2231 
2232  SCIPdebugMessage(" -> merging UB event (<%s>,%g -> %g) with event at position %d (<%s>,%g -> %g)\n",
2233  SCIPvarGetName((*event)->data.eventbdchg.var), (*event)->data.eventbdchg.oldbound,
2234  (*event)->data.eventbdchg.newbound,
2235  pos, SCIPvarGetName(qevent->data.eventbdchg.var), qevent->data.eventbdchg.oldbound,
2236  qevent->data.eventbdchg.newbound);
2237 
2238  qevent->data.eventbdchg.newbound = (*event)->data.eventbdchg.newbound;
2239  /*if( SCIPsetIsLT(set, qevent->data.eventbdchg.newbound, qevent->data.eventbdchg.oldbound) )*/
2240  if( qevent->data.eventbdchg.newbound < qevent->data.eventbdchg.oldbound )
2242  /*else if( SCIPsetIsGT(set, qevent->data.eventbdchg.newbound, qevent->data.eventbdchg.oldbound) )*/
2243  else if( qevent->data.eventbdchg.newbound > qevent->data.eventbdchg.oldbound )
2245  else
2246  {
2247  /* the queued bound change was reversed -> disable the event in the queue */
2248  assert(qevent->data.eventbdchg.newbound == qevent->data.eventbdchg.oldbound); /*lint !e777*/
2249  eventDisable(qevent);
2250  var->eventqueueindexub = -1;
2251  SCIPdebugMessage(" -> event disabled\n");
2252  }
2253 
2254  /* free the event that is of no use any longer */
2255  SCIP_CALL( SCIPeventFree(event, blkmem) );
2256  }
2257  else
2258  {
2259  /* the upper bound change event doesn't exist -> add it to the queue, and remember the array index */
2260  var->eventqueueindexub = eventqueue->nevents;
2261  SCIP_CALL( eventqueueAppend(eventqueue, set, event) );
2262  }
2263  break;
2264 
2266  var = (*event)->data.eventimpladd.var;
2267  assert(var != NULL);
2268  if( var->eventqueueimpl )
2269  {
2270  /* free the event that is of no use any longer */
2271  SCIP_CALL( SCIPeventFree(event, blkmem) );
2272  }
2273  else
2274  {
2275  var->eventqueueimpl = TRUE;
2276  SCIP_CALL( eventqueueAppend(eventqueue, set, event) );
2277  }
2278  break;
2279 
2280  default:
2281  SCIPerrorMessage("unknown event type <%d>\n", (*event)->eventtype);
2282  return SCIP_INVALIDDATA;
2283  }
2284  }
2285 
2286  assert(*event == NULL);
2287 
2288  return SCIP_OKAY;
2289 }
2290 
2291 /** marks queue to delay incoming events until a call to SCIPeventqueueProcess() */
2293  SCIP_EVENTQUEUE* eventqueue /**< event queue */
2294  )
2295 {
2296  assert(eventqueue != NULL);
2297  assert(!eventqueue->delayevents);
2298 
2299  SCIPdebugMessage("event processing is delayed\n");
2300 
2301  eventqueue->delayevents = TRUE;
2302 
2303  return SCIP_OKAY;
2304 }
2305 
2306 /** processes all delayed events, marks queue to process events immediately */
2308  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
2309  BMS_BLKMEM* blkmem, /**< block memory buffer */
2310  SCIP_SET* set, /**< global SCIP settings */
2311  SCIP_PRIMAL* primal, /**< primal data */
2312  SCIP_LP* lp, /**< current LP data */
2313  SCIP_BRANCHCAND* branchcand, /**< branching candidate storage */
2314  SCIP_EVENTFILTER* eventfilter /**< event filter for global (not variable dependent) events */
2315  )
2316 {
2317  SCIP_EVENT* event;
2318  int i;
2319 
2320  assert(eventqueue != NULL);
2321  assert(eventqueue->delayevents);
2322 
2323  SCIPdebugMessage("processing %d queued events\n", eventqueue->nevents);
2324 
2325  /* pass events to the responsible event filters
2326  * During event processing, new events may be raised. We have to loop to the mutable eventqueue->nevents.
2327  * A loop to something like "nevents = eventqueue->nevents; for(...; i < nevents; ...)" would miss the
2328  * newly created events. The same holds for eventqueue->events, which can be moved in memory due to
2329  * memory reallocation in eventqueueAppend().
2330  */
2331  for( i = 0; i < eventqueue->nevents; ++i )
2332  {
2333  event = eventqueue->events[i];
2334  assert(event != NULL);
2335 
2336  SCIPdebugMessage("processing event %d of %d events in queue: eventtype=0x%x\n", i, eventqueue->nevents, event->eventtype);
2337 
2338  /* unmark the event queue index of a variable with changed objective value or bounds, and unmark the event queue
2339  * member flag of a variable with added implication
2340  */
2341  if( (event->eventtype & SCIP_EVENTTYPE_OBJCHANGED) != 0 )
2342  {
2343  assert(event->data.eventobjchg.var->eventqueueindexobj == i);
2344  event->data.eventobjchg.var->eventqueueindexobj = -1;
2345  }
2346  else if( (event->eventtype & SCIP_EVENTTYPE_LBCHANGED) != 0 )
2347  {
2348  assert(event->data.eventbdchg.var->eventqueueindexlb == i);
2349  event->data.eventbdchg.var->eventqueueindexlb = -1;
2350  }
2351  else if( (event->eventtype & SCIP_EVENTTYPE_UBCHANGED) != 0 )
2352  {
2353  assert(event->data.eventbdchg.var->eventqueueindexub == i);
2354  event->data.eventbdchg.var->eventqueueindexub = -1;
2355  }
2356  else if( (event->eventtype & SCIP_EVENTTYPE_IMPLADDED) != 0 )
2357  {
2358  assert(event->data.eventimpladd.var->eventqueueimpl);
2359  event->data.eventimpladd.var->eventqueueimpl = FALSE;
2360  }
2361 
2362  /* process event */
2363  SCIP_CALL( SCIPeventProcess(event, set, primal, lp, branchcand, eventfilter) );
2364 
2365  /* free the event immediately, because additionally raised events during event processing
2366  * can lead to a large event queue
2367  */
2368  SCIP_CALL( SCIPeventFree(&eventqueue->events[i], blkmem) );
2369  }
2370 
2371  assert(i == eventqueue->nevents);
2372  eventqueue->nevents = 0;
2373  eventqueue->delayevents = FALSE;
2374 
2375  return SCIP_OKAY;
2376 }
2377 
2378 /** returns TRUE iff events of the queue are delayed until the next SCIPeventqueueProcess() call */
2380  SCIP_EVENTQUEUE* eventqueue /**< event queue */
2381  )
2382 {
2383  assert(eventqueue != NULL);
2384 
2385  return eventqueue->delayevents;
2386 }
#define BMSfreeMemoryArray(ptr)
Definition: memory.h:102
SCIP_RETCODE SCIPeventfilterCreate(SCIP_EVENTFILTER **eventfilter, BMS_BLKMEM *blkmem)
Definition: event.c:1650
SCIP_Real SCIPeventGetRowOldCoefVal(SCIP_EVENT *event)
Definition: event.c:1299
void SCIPeventhdlrSetInit(SCIP_EVENTHDLR *eventhdlr, SCIP_DECL_EVENTINIT((*eventinit)))
Definition: event.c:331
void SCIPeventhdlrSetCopy(SCIP_EVENTHDLR *eventhdlr, SCIP_DECL_EVENTCOPY((*eventcopy)))
Definition: event.c:309
#define SCIP_EVENTTYPE_LPSOLVED
Definition: type_event.h:78
#define BMSallocBlockMemory(mem, ptr)
Definition: memory.h:406
#define BMSfreeBlockMemoryArrayNull(mem, ptr, num)
Definition: memory.h:422
SCIP_RETCODE SCIPeventCreateRowAddedLP(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_ROW *row)
Definition: event.c:781
internal methods for managing events
#define SCIP_DECL_EVENTDELETE(x)
Definition: type_event.h:211
unsigned int delayedeventmask
Definition: struct_event.h:180
#define SCIP_DECL_EVENTEXIT(x)
Definition: type_event.h:180
const char * SCIPvarGetName(SCIP_VAR *var)
Definition: var.c:16443
#define SCIP_EVENTTYPE_OBJCHANGED
Definition: type_event.h:52
#define SCIP_EVENTTYPE_LPEVENT
Definition: type_event.h:115
static int eventfilterSearch(SCIP_EVENTFILTER *const eventfilter, SCIP_EVENTTYPE const eventtype, SCIP_EVENTHDLR *const eventhdlr, SCIP_EVENTDATA *const eventdata)
Definition: event.c:1782
SCIP_RETCODE SCIPeventhdlrCreate(SCIP_EVENTHDLR **eventhdlr, const char *name, const char *desc, SCIP_DECL_EVENTCOPY((*eventcopy)), SCIP_DECL_EVENTFREE((*eventfree)), SCIP_DECL_EVENTINIT((*eventinit)), SCIP_DECL_EVENTEXIT((*eventexit)), SCIP_DECL_EVENTINITSOL((*eventinitsol)), SCIP_DECL_EVENTEXITSOL((*eventexitsol)), SCIP_DECL_EVENTDELETE((*eventdelete)), SCIP_DECL_EVENTEXEC((*eventexec)), SCIP_EVENTHDLRDATA *eventhdlrdata)
Definition: event.c:64
#define SCIP_EVENTTYPE_VARFIXED
Definition: type_event.h:48
static SCIP_RETCODE eventqueueEnsureEventsMem(SCIP_EVENTQUEUE *eventqueue, SCIP_SET *set, int num)
Definition: event.c:1978
void SCIPeventhdlrSetExitsol(SCIP_EVENTHDLR *eventhdlr, SCIP_DECL_EVENTEXITSOL((*eventexitsol)))
Definition: event.c:364
SCIP_EVENTVARUNLOCKED eventvarunlocked
Definition: struct_event.h:150
#define SCIP_EVENTTYPE_ROWADDEDLP
Definition: type_event.h:87
SCIP_RETCODE SCIPeventqueueProcess(SCIP_EVENTQUEUE *eventqueue, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_PRIMAL *primal, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTFILTER *eventfilter)
Definition: event.c:2307
SCIP_RETCODE SCIPeventCreateRowDeletedLP(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_ROW *row)
Definition: event.c:800
int eventqueueindexub
Definition: struct_var.h:251
SCIP_RETCODE SCIPeventqueueAdd(SCIP_EVENTQUEUE *eventqueue, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_PRIMAL *primal, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTFILTER *eventfilter, SCIP_EVENT **event)
Definition: event.c:2057
static void eventDisable(SCIP_EVENT *event)
Definition: event.c:907
SCIP_RETCODE SCIPeventChgType(SCIP_EVENT *event, SCIP_EVENTTYPE eventtype)
Definition: event.c:927
SCIP_RETCODE SCIPeventhdlrExit(SCIP_EVENTHDLR *eventhdlr, SCIP_SET *set)
Definition: event.c:170
internal methods for clocks and timing issues
SCIP_RETCODE SCIPeventCreateImplAdded(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_VAR *var)
Definition: event.c:724
SCIP_EVENTHDLR ** eventhdlrs
Definition: struct_event.h:172
#define NULL
Definition: lpi_spx.cpp:130
SCIP_RETCODE SCIPeventfilterDel(SCIP_EVENTFILTER *eventfilter, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int filterpos)
Definition: event.c:1808
SCIP_VAR * SCIPeventGetVar(SCIP_EVENT *event)
Definition: event.c:940
SCIP_EVENTOBJCHG eventobjchg
Definition: struct_event.h:151
SCIP_RETCODE SCIPeventhdlrCopyInclude(SCIP_EVENTHDLR *eventhdlr, SCIP_SET *set)
Definition: event.c:45
struct SCIP_EventhdlrData SCIP_EVENTHDLRDATA
Definition: type_event.h:129
SCIP_RETCODE SCIPcolChgObj(SCIP_COL *col, SCIP_SET *set, SCIP_LP *lp, SCIP_Real newobj)
Definition: lp.c:3504
SCIP_RETCODE SCIPlpUpdateVarLb(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldlb, SCIP_Real newlb)
Definition: lp.c:15872
#define SCIP_EVENTTYPE_ROWSIDECHANGED
Definition: type_event.h:91
void SCIPclockStop(SCIP_CLOCK *clck, SCIP_SET *set)
Definition: clock.c:350
SCIP_RETCODE SCIPlpUpdateVarLbGlobal(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldlb, SCIP_Real newlb)
Definition: lp.c:15844
#define FALSE
Definition: def.h:56
SCIP_RETCODE SCIPeventProcess(SCIP_EVENT *event, SCIP_SET *set, SCIP_PRIMAL *primal, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTFILTER *eventfilter)
Definition: event.c:1418
SCIP_RETCODE SCIPlpUpdateVarUbGlobal(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldub, SCIP_Real newub)
Definition: lp.c:15913
static void eventfilterDelayUpdates(SCIP_EVENTFILTER *eventfilter)
Definition: event.c:1863
void SCIPclockStart(SCIP_CLOCK *clck, SCIP_SET *set)
Definition: clock.c:280
SCIP_RETCODE SCIPeventqueueDelay(SCIP_EVENTQUEUE *eventqueue)
Definition: event.c:2292
#define TRUE
Definition: def.h:55
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:53
SCIP_VAR * var
Definition: struct_event.h:89
#define SCIP_EVENTTYPE_NODEFOCUSED
Definition: type_event.h:71
SCIP_RETCODE SCIPeventCreateUbChanged(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_VAR *var, SCIP_Real oldbound, SCIP_Real newbound)
Definition: event.c:610
#define SCIP_CALL(x)
Definition: def.h:266
SCIP_Real SCIPeventGetRowNewCoefVal(SCIP_EVENT *event)
Definition: event.c:1316
internal methods for branching rules and branching candidate storage
int SCIPsetCalcMemGrowSize(SCIP_SET *set, int num)
Definition: set.c:4766
#define SCIP_EVENTTYPE_GLBCHANGED
Definition: type_event.h:53
SCIP_RETCODE SCIPeventqueueFree(SCIP_EVENTQUEUE **eventqueue)
Definition: event.c:2017
SCIP_RETCODE SCIPeventChgNode(SCIP_EVENT *event, SCIP_NODE *node)
Definition: event.c:1161
SCIP_Real SCIPeventGetRowOldSideVal(SCIP_EVENT *event)
Definition: event.c:1384
#define SCIPdebugMessage
Definition: pub_message.h:77
SCIP_RETCODE SCIPeventChgVar(SCIP_EVENT *event, SCIP_VAR *var)
Definition: event.c:996
#define SCIP_EVENTTYPE_ROWDELETEDLP
Definition: type_event.h:88
void SCIPclockEnableOrDisable(SCIP_CLOCK *clck, SCIP_Bool enable)
Definition: clock.c:250
SCIP_RETCODE SCIPeventCreateLholeAdded(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_VAR *var, SCIP_Real left, SCIP_Real right)
Definition: event.c:680
#define SCIP_EVENTTYPE_BOUNDCHANGED
Definition: type_event.h:99
#define SCIP_DECL_EVENTEXEC(x)
Definition: type_event.h:226
internal methods for LP management
#define SCIP_DECL_EVENTFREE(x)
Definition: type_event.h:164
SCIP_Bool delayupdates
Definition: struct_event.h:181
SCIP_Real SCIPeventGetOldobj(SCIP_EVENT *event)
Definition: event.c:1062
SCIP_RETCODE SCIPeventCreateObjChanged(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_VAR *var, SCIP_Real oldobj, SCIP_Real newobj)
Definition: event.c:515
internal methods for collecting primal CIP solutions and primal informations
void SCIPeventhdlrSetData(SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTHDLRDATA *eventhdlrdata)
Definition: event.c:298
#define SCIP_EVENTTYPE_LBCHANGED
Definition: type_event.h:95
#define SCIP_EVENTTYPE_NODEFEASIBLE
Definition: type_event.h:72
SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
Definition: var.c:16562
#define SCIP_EVENTTYPE_LBRELAXED
Definition: type_event.h:56
#define SCIP_EVENTTYPE_NODEBRANCHED
Definition: type_event.h:74
SCIP_Real newobj
Definition: struct_event.h:66
static SCIP_RETCODE eventfilterEnsureMem(SCIP_EVENTFILTER *eventfilter, BMS_BLKMEM *blkmem, SCIP_SET *set, int num)
Definition: event.c:1622
SCIP_RETCODE SCIPeventCreateVarFixed(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_VAR *var)
Definition: event.c:472
SCIP_RETCODE SCIPeventhdlrFree(SCIP_EVENTHDLR **eventhdlr, SCIP_SET *set)
Definition: event.c:106
SCIP_RETCODE SCIPeventCreateRowDeletedSepa(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_ROW *row)
Definition: event.c:762
union SCIP_Var::@12 data
SCIP_Real SCIPeventGetOldbound(SCIP_EVENT *event)
Definition: event.c:1096
SCIP_RETCODE SCIPeventChgSol(SCIP_EVENT *event, SCIP_SOL *sol)
Definition: event.c:1198
void SCIPeventhdlrSetInitsol(SCIP_EVENTHDLR *eventhdlr, SCIP_DECL_EVENTINITSOL((*eventinitsol)))
Definition: event.c:353
#define SCIP_EVENTTYPE_ROWADDEDSEPA
Definition: type_event.h:85
SCIP_RETCODE SCIPlpUpdateVarUb(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldub, SCIP_Real newub)
Definition: lp.c:15940
#define SCIP_EVENTTYPE_SOLEVENT
Definition: type_event.h:119
SCIP_RETCODE SCIPeventfilterAdd(SCIP_EVENTFILTER *eventfilter, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int *filterpos)
Definition: event.c:1715
#define SCIPerrorMessage
Definition: pub_message.h:45
SCIP_Real SCIPeventGetRowNewSideVal(SCIP_EVENT *event)
Definition: event.c:1401
#define SCIP_EVENTTYPE_LHOLEREMOVED
Definition: type_event.h:62
void SCIPclockReset(SCIP_CLOCK *clck)
Definition: clock.c:199
SCIP_Real SCIPeventGetRowNewConstVal(SCIP_EVENT *event)
Definition: event.c:1350
SCIP_RETCODE SCIPeventqueueCreate(SCIP_EVENTQUEUE **eventqueue)
Definition: event.c:2001
SCIP_RETCODE SCIPeventCreateVarAdded(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_VAR *var)
Definition: event.c:436
#define SCIP_EVENTTYPE_GHOLEREMOVED
Definition: type_event.h:60
#define SCIP_DECL_EVENTINIT(x)
Definition: type_event.h:172
void SCIPeventhdlrEnableOrDisableClocks(SCIP_EVENTHDLR *eventhdlr, SCIP_Bool enable)
Definition: event.c:396
#define BMSallocMemory(ptr)
Definition: memory.h:74
#define SCIP_EVENTTYPE_IMPLADDED
Definition: type_event.h:63
#define SCIP_EVENTTYPE_ROWCONSTCHANGED
Definition: type_event.h:90
SCIP_Bool initialized
Definition: struct_event.h:200
struct SCIP_EventData SCIP_EVENTDATA
Definition: type_event.h:146
void SCIPeventhdlrSetExit(SCIP_EVENTHDLR *eventhdlr, SCIP_DECL_EVENTEXIT((*eventexit)))
Definition: event.c:342
SCIP_EVENTVARADDED eventvaradded
Definition: struct_event.h:147
SCIP_Real SCIPclockGetTime(SCIP_CLOCK *clck)
Definition: clock.c:428
SCIP_RETCODE SCIPeventCreateLbChanged(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_VAR *var, SCIP_Real oldbound, SCIP_Real newbound)
Definition: event.c:584
SCIP_COL * SCIPvarGetCol(SCIP_VAR *var)
Definition: var.c:16771
#define SCIP_EVENTTYPE_UBRELAXED
Definition: type_event.h:58
SCIP_EVENTTYPE eventtype
Definition: struct_event.h:165
SCIP_Real SCIPeventhdlrGetSetupTime(SCIP_EVENTHDLR *eventhdlr)
Definition: event.c:408
SCIP_RETCODE SCIPeventCreateLholeRemoved(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_VAR *var, SCIP_Real left, SCIP_Real right)
Definition: event.c:702
internal methods for global SCIP settings
#define SCIP_EVENTTYPE_LBTIGHTENED
Definition: type_event.h:55
SCIP_EVENTHDLRDATA * SCIPeventhdlrGetData(SCIP_EVENTHDLR *eventhdlr)
Definition: event.c:288
#define SCIP_DECL_EVENTEXITSOL(x)
Definition: type_event.h:202
#define BMSreallocMemoryArray(ptr, num)
Definition: memory.h:82
#define BMSfreeMemory(ptr)
Definition: memory.h:100
SCIP_RETCODE SCIPeventhdlrInitsol(SCIP_EVENTHDLR *eventhdlr, SCIP_SET *set)
Definition: event.c:200
int eventqueueindexlb
Definition: struct_var.h:250
#define SCIP_EVENTTYPE_LHOLEADDED
Definition: type_event.h:61
SCIP_Bool SCIPsetIsEQ(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:5202
SCIP_EVENTIMPLADD eventimpladd
Definition: struct_event.h:154
unsigned int eventmask
Definition: struct_event.h:179
#define BMSduplicateMemoryArray(ptr, source, num)
Definition: memory.h:98
SCIP_Real newbound
Definition: struct_event.h:74
#define SCIP_EVENTTYPE_UBCHANGED
Definition: type_event.h:96
SCIP_RETCODE SCIPclockCreate(SCIP_CLOCK **clck, SCIP_CLOCKTYPE clocktype)
Definition: clock.c:160
SCIP_VAR * var
Definition: struct_event.h:75
#define BMSfreeMemoryArrayNull(ptr)
Definition: memory.h:103
internal methods for problem variables
SCIP_SOL * SCIPeventGetSol(SCIP_EVENT *event)
Definition: event.c:1181
unsigned int SCIP_EVENTTYPE
Definition: type_event.h:125
#define SCIP_Bool
Definition: def.h:53
#define SCIP_EVENTTYPE_NODEEVENT
Definition: type_event.h:112
void SCIPeventhdlrSetFree(SCIP_EVENTHDLR *eventhdlr, SCIP_DECL_EVENTFREE((*eventfree)))
Definition: event.c:320
void SCIPprimalUpdateVarObj(SCIP_PRIMAL *primal, SCIP_VAR *var, SCIP_Real oldobj, SCIP_Real newobj)
Definition: primal.c:1480
SCIP_NODE * SCIPeventGetNode(SCIP_EVENT *event)
Definition: event.c:1144
SCIP_EVENTHDLRDATA * eventhdlrdata
Definition: struct_event.h:197
SCIP_Real oldobj
Definition: struct_event.h:65
#define SCIP_EVENTTYPE_ROWCOEFCHANGED
Definition: type_event.h:89
SCIP_RETCODE SCIPeventCreateRowSideChanged(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_ROW *row, SCIP_SIDETYPE side, SCIP_Real oldval, SCIP_Real newval)
Definition: event.c:867
SCIP_RETCODE SCIPeventCreateGholeRemoved(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_VAR *var, SCIP_Real left, SCIP_Real right)
Definition: event.c:658
void SCIPclockFree(SCIP_CLOCK **clck)
Definition: clock.c:175
SCIP_RETCODE SCIPeventCreateGlbChanged(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_VAR *var, SCIP_Real oldbound, SCIP_Real newbound)
Definition: event.c:538
SCIP_RETCODE SCIPcolChgLb(SCIP_COL *col, SCIP_SET *set, SCIP_LP *lp, SCIP_Real newlb)
Definition: lp.c:3563
static void eventfilterProcessUpdates(SCIP_EVENTFILTER *eventfilter)
Definition: event.c:1876
SCIP_COL * SCIPeventGetRowCol(SCIP_EVENT *event)
Definition: event.c:1282
SCIP_RETCODE SCIPeventCreateVarDeleted(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_VAR *var)
Definition: event.c:454
#define SCIP_EVENTTYPE_NODEINFEASIBLE
Definition: type_event.h:73
#define SCIP_EVENTTYPE_ROWDELETEDSEPA
Definition: type_event.h:86
SCIP_EVENT ** events
Definition: struct_event.h:206
#define BMSfreeBlockMemory(mem, ptr)
Definition: memory.h:419
#define SCIP_EVENTTYPE_HOLECHANGED
Definition: type_event.h:102
SCIP_Bool SCIPeventhdlrIsInitialized(SCIP_EVENTHDLR *eventhdlr)
Definition: event.c:386
#define SCIP_EVENTTYPE_GHOLEADDED
Definition: type_event.h:59
SCIP_Bool delayevents
Definition: struct_event.h:209
SCIP_RETCODE SCIPbranchcandUpdateVar(SCIP_BRANCHCAND *branchcand, SCIP_SET *set, SCIP_VAR *var)
Definition: branch.c:1080
#define SCIP_EVENTTYPE_UBTIGHTENED
Definition: type_event.h:57
SCIP_RETCODE SCIPeventhdlrExec(SCIP_EVENTHDLR *eventhdlr, SCIP_SET *set, SCIP_EVENT *event, SCIP_EVENTDATA *eventdata)
Definition: event.c:248
#define SCIP_EVENTTYPE_FIRSTLPSOLVED
Definition: type_event.h:77
SCIP_RETCODE SCIPeventFree(SCIP_EVENT **event, BMS_BLKMEM *blkmem)
Definition: event.c:892
SCIP_ROW * SCIPeventGetRow(SCIP_EVENT *event)
Definition: event.c:1252
static SCIP_RETCODE eventqueueAppend(SCIP_EVENTQUEUE *eventqueue, SCIP_SET *set, SCIP_EVENT **event)
Definition: event.c:2033
SCIP_Real SCIPeventGetHoleLeft(SCIP_EVENT *event)
Definition: event.c:1218
SCIP_RETCODE SCIPcolChgUb(SCIP_COL *col, SCIP_SET *set, SCIP_LP *lp, SCIP_Real newub)
Definition: lp.c:3608
SCIP_EVENTFILTER * eventfilter
Definition: struct_var.h:239
SCIP_RETCODE SCIPeventCreateRowCoefChanged(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_ROW *row, SCIP_COL *col, SCIP_Real oldval, SCIP_Real newval)
Definition: event.c:819
SCIP_EVENTDATA ** eventdata
Definition: struct_event.h:173
#define SCIP_EVENTTYPE_DISABLED
Definition: type_event.h:43
SCIP_SIDETYPE SCIPeventGetRowSide(SCIP_EVENT *event)
Definition: event.c:1367
SCIP_EVENTBDCHG eventbdchg
Definition: struct_event.h:152
SCIP_VAR * var
Definition: struct_event.h:67
SCIP_Real SCIPeventhdlrGetTime(SCIP_EVENTHDLR *eventhdlr)
Definition: event.c:420
#define SCIP_EVENTTYPE_BESTSOLFOUND
Definition: type_event.h:82
SCIP_EVENTHOLE eventhole
Definition: struct_event.h:153
#define SCIP_EVENTTYPE_POORSOLFOUND
Definition: type_event.h:81
#define SCIP_DECL_EVENTINITSOL(x)
Definition: type_event.h:191
SCIP_RETCODE SCIPeventfilterFree(SCIP_EVENTFILTER **eventfilter, BMS_BLKMEM *blkmem, SCIP_SET *set)
Definition: event.c:1675
SCIP_RETCODE SCIPlpUpdateVarObj(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldobj, SCIP_Real newobj)
Definition: lp.c:15790
SCIP_VAR * var
Definition: struct_event.h:83
SCIP_RETCODE SCIPeventfilterProcess(SCIP_EVENTFILTER *eventfilter, SCIP_SET *set, SCIP_EVENT *event)
Definition: event.c:1911
int eventqueueindexobj
Definition: struct_var.h:249
const char * SCIPeventhdlrGetName(SCIP_EVENTHDLR *eventhdlr)
Definition: event.c:278
SCIP_Real oldbound
Definition: struct_event.h:73
public methods for message output
int SCIPvarGetProbindex(SCIP_VAR *var)
Definition: var.c:16750
SCIP_RETCODE SCIPeventhdlrExitsol(SCIP_EVENTHDLR *eventhdlr, SCIP_SET *set)
Definition: event.c:224
#define SCIP_Real
Definition: def.h:127
#define SCIP_EVENTTYPE_VARUNLOCKED
Definition: type_event.h:49
unsigned int eventqueueimpl
Definition: struct_var.h:275
SCIP_Real SCIPeventGetRowOldConstVal(SCIP_EVENT *event)
Definition: event.c:1333
#define SCIP_DECL_EVENTCOPY(x)
Definition: type_event.h:156
SCIP_CLOCK * eventtime
Definition: struct_event.h:199
#define SCIP_INVALID
Definition: def.h:147
SCIP_RETCODE SCIPeventCreateGholeAdded(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_VAR *var, SCIP_Real left, SCIP_Real right)
Definition: event.c:636
SCIP_RETCODE SCIPeventCreateVarUnlocked(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_VAR *var)
Definition: event.c:494
union SCIP_Event::@7 data
SCIP_CLOCK * setuptime
Definition: struct_event.h:198
SCIP_EVENTTYPE SCIPeventGetType(SCIP_EVENT *event)
Definition: event.c:917
SCIP_EVENTTYPE * eventtypes
Definition: struct_event.h:171
SCIP_EVENTVARDELETED eventvardeleted
Definition: struct_event.h:148
SCIP_EVENTVARFIXED eventvarfixed
Definition: struct_event.h:149
void SCIPeventhdlrSetDelete(SCIP_EVENTHDLR *eventhdlr, SCIP_DECL_EVENTDELETE((*eventdelete)))
Definition: event.c:375
SCIP_Bool SCIPeventqueueIsDelayed(SCIP_EVENTQUEUE *eventqueue)
Definition: event.c:2379
common defines and data types used in all packages of SCIP
struct BMS_BlkMem BMS_BLKMEM
Definition: memory.h:392
#define SCIP_EVENTTYPE_GUBCHANGED
Definition: type_event.h:54
SCIP_Real SCIPeventGetNewbound(SCIP_EVENT *event)
Definition: event.c:1120
#define SCIP_ALLOC(x)
Definition: def.h:277
#define SCIPABORT()
Definition: def.h:238
#define SCIP_EVENTTYPE_PRESOLVEROUND
Definition: type_event.h:68
SCIP_RETCODE SCIPeventCreateGubChanged(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_VAR *var, SCIP_Real oldbound, SCIP_Real newbound)
Definition: event.c:561
#define SCIP_EVENTTYPE_VARADDED
Definition: type_event.h:46
#define BMSreallocBlockMemoryArray(mem, ptr, oldnum, newnum)
Definition: memory.h:412
SCIP_Real SCIPeventGetHoleRight(SCIP_EVENT *event)
Definition: event.c:1235
#define SCIP_EVENTTYPE_VARDELETED
Definition: type_event.h:47
SCIP_RETCODE SCIPeventhdlrInit(SCIP_EVENTHDLR *eventhdlr, SCIP_SET *set)
Definition: event.c:134
SCIP_RETCODE SCIPeventCreateRowAddedSepa(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_ROW *row)
Definition: event.c:743
SCIP_RETCODE SCIPeventCreateRowConstChanged(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_ROW *row, SCIP_Real oldval, SCIP_Real newval)
Definition: event.c:844
SCIP_Real SCIPeventGetNewobj(SCIP_EVENT *event)
Definition: event.c:1079
enum SCIP_SideType SCIP_SIDETYPE
Definition: type_lp.h:58