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-2018 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  SCIPsetDebugMsg(set, "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  SCIPsetDebugMsg(set, "execute event of handler <%s> with event %p of type 0x%" SCIP_EVENTTYPE_FORMAT "\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 
436 /** creates a synchronization event */
438  SCIP_EVENT** event, /**< pointer to store the event */
439  BMS_BLKMEM* blkmem /**< block memory */
440  )
441 {
442  assert(event != NULL);
443 
444  /* create event data */
445  SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
446  (*event)->eventtype = SCIP_EVENTTYPE_SYNC;
447 
448  return SCIP_OKAY;
449 }
450 
451 /*
452  * simple functions implemented as defines
453  */
454 
455 /* In debug mode, the following methods are implemented as function calls to ensure
456  * type validity.
457  * In optimized mode, the methods are implemented as defines to improve performance.
458  * However, we want to have them in the library anyways, so we have to undef the defines.
459  */
460 
461 #undef SCIPeventGetType
462 #undef SCIPeventGetOldobj
463 #undef SCIPeventGetNewobj
464 #undef SCIPeventGetOldbound
465 #undef SCIPeventGetNewbound
466 #undef SCIPeventGetNode
467 #undef SCIPeventGetSol
468 #undef SCIPeventGetRowCol
469 #undef SCIPeventGetRowOldCoefVal
470 #undef SCIPeventGetRowNewCoefVal
471 #undef SCIPeventGetRowOldConstVal
472 #undef SCIPeventGetRowNewConstVal
473 #undef SCIPeventGetRowSide
474 #undef SCIPeventGetRowOldSideVal
475 #undef SCIPeventGetRowNewSideVal
476 
477 /** creates an event for an addition of a variable to the problem */
479  SCIP_EVENT** event, /**< pointer to store the event */
480  BMS_BLKMEM* blkmem, /**< block memory */
481  SCIP_VAR* var /**< variable that was added to the problem */
482  )
483 {
484  assert(event != NULL);
485  assert(blkmem != NULL);
486 
487  /* create event data */
488  SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
489  (*event)->eventtype = SCIP_EVENTTYPE_VARADDED;
490  (*event)->data.eventvaradded.var = var;
491 
492  return SCIP_OKAY;
493 }
494 
495 /** creates an event for a deletion of a variable from the problem */
497  SCIP_EVENT** event, /**< pointer to store the event */
498  BMS_BLKMEM* blkmem, /**< block memory */
499  SCIP_VAR* var /**< variable that is to be deleted from the problem */
500  )
501 {
502  assert(event != NULL);
503  assert(blkmem != NULL);
504 
505  /* create event data */
506  SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
507  (*event)->eventtype = SCIP_EVENTTYPE_VARDELETED;
508  (*event)->data.eventvardeleted.var = var;
509 
510  return SCIP_OKAY;
511 }
512 
513 /** creates an event for a fixing of a variable */
515  SCIP_EVENT** event, /**< pointer to store the event */
516  BMS_BLKMEM* blkmem, /**< block memory */
517  SCIP_VAR* var /**< variable that was fixed */
518  )
519 {
520  assert(event != NULL);
521  assert(blkmem != NULL);
526 
527  /* create event data */
528  SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
529  (*event)->eventtype = SCIP_EVENTTYPE_VARFIXED;
530  (*event)->data.eventvarfixed.var = var;
531 
532  return SCIP_OKAY;
533 }
534 
535 /** creates an event for a change in the number of locks of a variable down to zero or one */
537  SCIP_EVENT** event, /**< pointer to store the event */
538  BMS_BLKMEM* blkmem, /**< block memory */
539  SCIP_VAR* var /**< variable that changed the number of locks */
540  )
541 {
542  assert(event != NULL);
543  assert(blkmem != NULL);
547 
548  /* create event data */
549  SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
550  (*event)->eventtype = SCIP_EVENTTYPE_VARUNLOCKED;
551  (*event)->data.eventvarunlocked.var = var;
552 
553  return SCIP_OKAY;
554 }
555 
556 /** creates an event for a change in the objective value of a variable */
558  SCIP_EVENT** event, /**< pointer to store the event */
559  BMS_BLKMEM* blkmem, /**< block memory */
560  SCIP_VAR* var, /**< variable whose objective value changed */
561  SCIP_Real oldobj, /**< old objective value before value changed */
562  SCIP_Real newobj /**< new objective value after value changed */
563  )
564 {
565  assert(event != NULL);
566  assert(blkmem != NULL);
567  assert(oldobj != newobj); /*lint !e777*/
568 
569  /* create event data */
570  SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
571  (*event)->eventtype = SCIP_EVENTTYPE_OBJCHANGED;
572  (*event)->data.eventobjchg.var = var;
573  (*event)->data.eventobjchg.oldobj = oldobj;
574  (*event)->data.eventobjchg.newobj = newobj;
575 
576  return SCIP_OKAY;
577 }
578 
579 /** creates an event for a change in the global lower bound of a variable */
581  SCIP_EVENT** event, /**< pointer to store the event */
582  BMS_BLKMEM* blkmem, /**< block memory */
583  SCIP_VAR* var, /**< variable whose bound changed */
584  SCIP_Real oldbound, /**< old bound before bound changed */
585  SCIP_Real newbound /**< new bound after bound changed */
586  )
587 {
588  assert(event != NULL);
589  assert(blkmem != NULL);
590  assert(oldbound != newbound); /*lint !e777*/
591 
592  /* create event data */
593  SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
594  (*event)->eventtype = SCIP_EVENTTYPE_GLBCHANGED;
595  (*event)->data.eventbdchg.var = var;
596  (*event)->data.eventbdchg.oldbound = oldbound;
597  (*event)->data.eventbdchg.newbound = newbound;
598 
599  return SCIP_OKAY;
600 }
601 
602 /** creates an event for a change in the global upper bound of a variable */
604  SCIP_EVENT** event, /**< pointer to store the event */
605  BMS_BLKMEM* blkmem, /**< block memory */
606  SCIP_VAR* var, /**< variable whose bound changed */
607  SCIP_Real oldbound, /**< old bound before bound changed */
608  SCIP_Real newbound /**< new bound after bound changed */
609  )
610 {
611  assert(event != NULL);
612  assert(blkmem != NULL);
613  assert(oldbound != newbound); /*lint !e777*/
614 
615  /* create event data */
616  SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
617  (*event)->eventtype = SCIP_EVENTTYPE_GUBCHANGED;
618  (*event)->data.eventbdchg.var = var;
619  (*event)->data.eventbdchg.oldbound = oldbound;
620  (*event)->data.eventbdchg.newbound = newbound;
621 
622  return SCIP_OKAY;
623 }
624 
625 /** creates an event for a change in the lower bound of a variable */
627  SCIP_EVENT** event, /**< pointer to store the event */
628  BMS_BLKMEM* blkmem, /**< block memory */
629  SCIP_VAR* var, /**< variable whose bound changed */
630  SCIP_Real oldbound, /**< old bound before bound changed */
631  SCIP_Real newbound /**< new bound after bound changed */
632  )
633 {
634  assert(event != NULL);
635  assert(blkmem != NULL);
636  assert(oldbound != newbound); /*lint !e777*/
637 
638  /* create event data */
639  SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
640  if( newbound > oldbound )
641  (*event)->eventtype = SCIP_EVENTTYPE_LBTIGHTENED;
642  else
643  (*event)->eventtype = SCIP_EVENTTYPE_LBRELAXED;
644  (*event)->data.eventbdchg.var = var;
645  (*event)->data.eventbdchg.oldbound = oldbound;
646  (*event)->data.eventbdchg.newbound = newbound;
647 
648  return SCIP_OKAY;
649 }
650 
651 /** creates an event for a change in the upper bound of a variable */
653  SCIP_EVENT** event, /**< pointer to store the event */
654  BMS_BLKMEM* blkmem, /**< block memory */
655  SCIP_VAR* var, /**< variable whose bound changed */
656  SCIP_Real oldbound, /**< old bound before bound changed */
657  SCIP_Real newbound /**< new bound after bound changed */
658  )
659 {
660  assert(event != NULL);
661  assert(blkmem != NULL);
662  assert(oldbound != newbound); /*lint !e777*/
663 
664  /* create event data */
665  SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
666  if( newbound < oldbound )
667  (*event)->eventtype = SCIP_EVENTTYPE_UBTIGHTENED;
668  else
669  (*event)->eventtype = SCIP_EVENTTYPE_UBRELAXED;
670  (*event)->data.eventbdchg.var = var;
671  (*event)->data.eventbdchg.oldbound = oldbound;
672  (*event)->data.eventbdchg.newbound = newbound;
673 
674  return SCIP_OKAY;
675 }
676 
677 /** creates an event for an addition of a domain hole to a variable */
679  SCIP_EVENT** event, /**< pointer to store the event */
680  BMS_BLKMEM* blkmem, /**< block memory */
681  SCIP_VAR* var, /**< variable whose bound changed */
682  SCIP_Real left, /**< left bound of open interval in new hole */
683  SCIP_Real right /**< right bound of open interval in new hole */
684  )
685 {
686  assert(event != NULL);
687  assert(blkmem != NULL);
688 
689  /* create event data */
690  SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
691  (*event)->eventtype = SCIP_EVENTTYPE_GHOLEADDED;
692  (*event)->data.eventhole.var = var;
693  (*event)->data.eventhole.left = left;
694  (*event)->data.eventhole.right = right;
695 
696  return SCIP_OKAY;
697 }
698 
699 /** creates an event for removing a domain hole of a variable */
701  SCIP_EVENT** event, /**< pointer to store the event */
702  BMS_BLKMEM* blkmem, /**< block memory */
703  SCIP_VAR* var, /**< variable whose bound changed */
704  SCIP_Real left, /**< left bound of open interval in hole */
705  SCIP_Real right /**< right bound of open interval in hole */
706  )
707 {
708  assert(event != NULL);
709  assert(blkmem != NULL);
710 
711  /* create event data */
712  SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
713  (*event)->eventtype = SCIP_EVENTTYPE_GHOLEREMOVED;
714  (*event)->data.eventhole.var = var;
715  (*event)->data.eventhole.left = left;
716  (*event)->data.eventhole.right = right;
717 
718  return SCIP_OKAY;
719 }
720 
721 /** creates an event for an addition of a domain hole to a variable */
723  SCIP_EVENT** event, /**< pointer to store the event */
724  BMS_BLKMEM* blkmem, /**< block memory */
725  SCIP_VAR* var, /**< variable whose bound changed */
726  SCIP_Real left, /**< left bound of open interval in new hole */
727  SCIP_Real right /**< right bound of open interval in new hole */
728  )
729 {
730  assert(event != NULL);
731  assert(blkmem != NULL);
732 
733  /* create event data */
734  SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
735  (*event)->eventtype = SCIP_EVENTTYPE_LHOLEADDED;
736  (*event)->data.eventhole.var = var;
737  (*event)->data.eventhole.left = left;
738  (*event)->data.eventhole.right = right;
739 
740  return SCIP_OKAY;
741 }
742 
743 /** creates an event for removing a domain hole of a variable */
745  SCIP_EVENT** event, /**< pointer to store the event */
746  BMS_BLKMEM* blkmem, /**< block memory */
747  SCIP_VAR* var, /**< variable whose bound changed */
748  SCIP_Real left, /**< left bound of open interval in hole */
749  SCIP_Real right /**< right bound of open interval in hole */
750  )
751 {
752  assert(event != NULL);
753  assert(blkmem != NULL);
754 
755  /* create event data */
756  SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
757  (*event)->eventtype = SCIP_EVENTTYPE_LHOLEREMOVED;
758  (*event)->data.eventhole.var = var;
759  (*event)->data.eventhole.left = left;
760  (*event)->data.eventhole.right = right;
761 
762  return SCIP_OKAY;
763 }
764 
765 /** creates an event for an addition to the variable's implications list, clique or variable bounds information */
767  SCIP_EVENT** event, /**< pointer to store the event */
768  BMS_BLKMEM* blkmem, /**< block memory */
769  SCIP_VAR* var /**< variable that was fixed */
770  )
771 {
772  assert(event != NULL);
773  assert(blkmem != NULL);
775 
776  /* create event data */
777  SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
778  (*event)->eventtype = SCIP_EVENTTYPE_IMPLADDED;
779  (*event)->data.eventimpladd.var = var;
780 
781  return SCIP_OKAY;
782 }
783 
784 /** creates an event for the addition of a linear row to the separation storage */
786  SCIP_EVENT** event, /**< pointer to store the event */
787  BMS_BLKMEM* blkmem, /**< block memory */
788  SCIP_ROW* row /**< row that was added to the separation storage*/
789  )
790 {
791  assert(event != NULL);
792  assert(blkmem != NULL);
793  assert(row != NULL);
794 
795  /* create event data */
796  SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
797  (*event)->eventtype = SCIP_EVENTTYPE_ROWADDEDSEPA;
798  (*event)->data.eventrowaddedsepa.row = row;
799 
800  return SCIP_OKAY;
801 }
802 
803 /** creates an event for the deletion of a linear row from the separation storage */
805  SCIP_EVENT** event, /**< pointer to store the event */
806  BMS_BLKMEM* blkmem, /**< block memory */
807  SCIP_ROW* row /**< row that was deleted from the separation storage */
808  )
809 {
810  assert(event != NULL);
811  assert(blkmem != NULL);
812  assert(row != NULL);
813 
814  /* create event data */
815  SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
816  (*event)->eventtype = SCIP_EVENTTYPE_ROWDELETEDSEPA;
817  (*event)->data.eventrowdeletedsepa.row = row;
818 
819  return SCIP_OKAY;
820 }
821 
822 /** creates an event for the addition of a linear row to the LP */
824  SCIP_EVENT** event, /**< pointer to store the event */
825  BMS_BLKMEM* blkmem, /**< block memory */
826  SCIP_ROW* row /**< row that was added to the LP */
827  )
828 {
829  assert(event != NULL);
830  assert(blkmem != NULL);
831  assert(row != NULL);
832 
833  /* create event data */
834  SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
835  (*event)->eventtype = SCIP_EVENTTYPE_ROWADDEDLP;
836  (*event)->data.eventrowaddedlp.row = row;
837 
838  return SCIP_OKAY;
839 }
840 
841 /** creates an event for the deletion of a linear row from the LP */
843  SCIP_EVENT** event, /**< pointer to store the event */
844  BMS_BLKMEM* blkmem, /**< block memory */
845  SCIP_ROW* row /**< row that was deleted from the LP */
846  )
847 {
848  assert(event != NULL);
849  assert(blkmem != NULL);
850  assert(row != NULL);
851 
852  /* create event data */
853  SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
854  (*event)->eventtype = SCIP_EVENTTYPE_ROWDELETEDLP;
855  (*event)->data.eventrowdeletedlp.row = row;
856 
857  return SCIP_OKAY;
858 }
859 
860 /** creates an event for the change of a coefficient in a linear row */
862  SCIP_EVENT** event, /**< pointer to store the event */
863  BMS_BLKMEM* blkmem, /**< block memory */
864  SCIP_ROW* row, /**< row in which a coefficient changed */
865  SCIP_COL* col, /**< column which coefficient changed */
866  SCIP_Real oldval, /**< old value of coefficient */
867  SCIP_Real newval /**< new value of coefficient */
868  )
869 {
870  assert(event != NULL);
871  assert(blkmem != NULL);
872  assert(row != NULL);
873 
874  /* create event data */
875  SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
876  (*event)->eventtype = SCIP_EVENTTYPE_ROWCOEFCHANGED;
877  (*event)->data.eventrowcoefchanged.row = row;
878  (*event)->data.eventrowcoefchanged.col = col;
879  (*event)->data.eventrowcoefchanged.oldval = oldval;
880  (*event)->data.eventrowcoefchanged.newval = newval;
881 
882  return SCIP_OKAY;
883 }
884 
885 /** creates an event for the change of a constant in a linear row */
887  SCIP_EVENT** event, /**< pointer to store the event */
888  BMS_BLKMEM* blkmem, /**< block memory */
889  SCIP_ROW* row, /**< row in which the constant changed */
890  SCIP_Real oldval, /**< old value of constant */
891  SCIP_Real newval /**< new value of constant */
892  )
893 {
894  assert(event != NULL);
895  assert(blkmem != NULL);
896  assert(row != NULL);
897 
898  /* create event data */
899  SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
900  (*event)->eventtype = SCIP_EVENTTYPE_ROWCONSTCHANGED;
901  (*event)->data.eventrowconstchanged.row = row;
902  (*event)->data.eventrowconstchanged.oldval = oldval;
903  (*event)->data.eventrowconstchanged.newval = newval;
904 
905  return SCIP_OKAY;
906 }
907 
908 /** creates an event for the change of a side of a linear row */
910  SCIP_EVENT** event, /**< pointer to store the event */
911  BMS_BLKMEM* blkmem, /**< block memory */
912  SCIP_ROW* row, /**< row which side has changed */
913  SCIP_SIDETYPE side, /**< which side has changed */
914  SCIP_Real oldval, /**< old value of side */
915  SCIP_Real newval /**< new value of side */
916  )
917 {
918  assert(event != NULL);
919  assert(blkmem != NULL);
920  assert(row != NULL);
921 
922  /* create event data */
923  SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
924  (*event)->eventtype = SCIP_EVENTTYPE_ROWSIDECHANGED;
925  (*event)->data.eventrowsidechanged.row = row;
926  (*event)->data.eventrowsidechanged.side = side;
927  (*event)->data.eventrowsidechanged.oldval = oldval;
928  (*event)->data.eventrowsidechanged.newval = newval;
929 
930  return SCIP_OKAY;
931 }
932 
933 /** frees an event */
935  SCIP_EVENT** event, /**< event to free */
936  BMS_BLKMEM* blkmem /**< block memory buffer */
937  )
938 {
939  assert(event != NULL);
940  assert(blkmem != NULL);
941 
942  BMSfreeBlockMemory(blkmem, event);
943 
944  return SCIP_OKAY;
945 }
946 
947 /** disables an event */
948 static
950  SCIP_EVENT* event /**< event to disable */
951  )
952 {
953  assert(event != NULL);
954 
955  event->eventtype = SCIP_EVENTTYPE_DISABLED;
956 }
957 
958 /** gets type of event */
960  SCIP_EVENT* event /**< event */
961  )
962 {
963  assert(event != NULL);
964 
965  return event->eventtype;
966 }
967 
968 /** sets type of event */
970  SCIP_EVENT* event, /**< event */
971  SCIP_EVENTTYPE eventtype /**< new event type */
972  )
973 {
974  assert(event != NULL);
975 
976  event->eventtype = eventtype;
977 
978  return SCIP_OKAY;
979 }
980 
981 /** gets variable for a variable event (var added, var deleted, var fixed, objective value or domain change) */
983  SCIP_EVENT* event /**< event */
984  )
985 {
986  assert(event != NULL);
987 
988  switch( event->eventtype )
989  {
991  assert(event->data.eventvaradded.var != NULL);
992  return event->data.eventvaradded.var;
993 
995  assert(event->data.eventvardeleted.var != NULL);
996  return event->data.eventvardeleted.var;
997 
999  assert(event->data.eventvarfixed.var != NULL);
1000  return event->data.eventvarfixed.var;
1001 
1003  assert(event->data.eventvarunlocked.var != NULL);
1004  return event->data.eventvarunlocked.var;
1005 
1007  assert(event->data.eventobjchg.var != NULL);
1008  return event->data.eventobjchg.var;
1009 
1016  assert(event->data.eventbdchg.var != NULL);
1017  return event->data.eventbdchg.var;
1018 
1023  assert(event->data.eventhole.var != NULL);
1024  return event->data.eventhole.var;
1025 
1027  assert(event->data.eventimpladd.var != NULL);
1028  return event->data.eventimpladd.var;
1029 
1030  default:
1031  SCIPerrorMessage("event does not belong to a variable\n");
1032  SCIPABORT();
1033  return NULL; /*lint !e527*/
1034  } /*lint !e788*/
1035 }
1036 
1037 /** sets variable for a variable event */
1039  SCIP_EVENT* event, /**< event */
1040  SCIP_VAR* var /**< new variable */
1041  )
1042 {
1043  assert(event != NULL);
1044 
1045  switch( event->eventtype )
1046  {
1048  assert(event->data.eventvaradded.var != NULL);
1049  event->data.eventvaradded.var = var;
1050  break;
1051 
1053  assert(event->data.eventvardeleted.var != NULL);
1054  event->data.eventvardeleted.var = var;
1055  break;
1056 
1058  assert(event->data.eventvarfixed.var != NULL);
1059  event->data.eventvarfixed.var = var;
1060  break;
1061 
1063  assert(event->data.eventvarunlocked.var != NULL);
1064  event->data.eventvarunlocked.var = var;
1065  break;
1066 
1068  assert(event->data.eventobjchg.var != NULL);
1069  event->data.eventobjchg.var = var;
1070  break;
1071 
1078  assert(event->data.eventbdchg.var != NULL);
1079  event->data.eventbdchg.var = var;
1080  break;
1081 
1086  assert(event->data.eventhole.var != NULL);
1087  event->data.eventhole.var = var;
1088  break;
1089 
1091  assert(event->data.eventimpladd.var != NULL);
1092  event->data.eventimpladd.var = var;
1093  break;
1094 
1095  default:
1096  SCIPerrorMessage("event does not belong to a variable\n");
1097  return SCIP_INVALIDDATA;
1098  } /*lint !e788*/
1099 
1100  return SCIP_OKAY;
1101 }
1102 
1103 /** gets old objective value for an objective value change event */
1105  SCIP_EVENT* event /**< event */
1106  )
1107 {
1108  assert(event != NULL);
1109 
1110  if( event->eventtype != SCIP_EVENTTYPE_OBJCHANGED )
1111  {
1112  SCIPerrorMessage("event is not an objective value change event\n");
1113  SCIPABORT();
1114  return SCIP_INVALID; /*lint !e527*/
1115  }
1116 
1117  return event->data.eventobjchg.oldobj;
1118 }
1119 
1120 /** gets new objective value for an objective value change event */
1122  SCIP_EVENT* event /**< event */
1123  )
1124 {
1125  assert(event != NULL);
1126 
1127  if( event->eventtype != SCIP_EVENTTYPE_OBJCHANGED )
1128  {
1129  SCIPerrorMessage("event is not an objective value change event\n");
1130  SCIPABORT();
1131  return SCIP_INVALID; /*lint !e527*/
1132  }
1133 
1134  return event->data.eventobjchg.newobj;
1135 }
1136 
1137 /** gets old bound for a bound change event */
1139  SCIP_EVENT* event /**< event */
1140  )
1141 {
1142  assert(event != NULL);
1143 
1144  switch( event->eventtype )
1145  {
1152  return event->data.eventbdchg.oldbound;
1153 
1154  default:
1155  SCIPerrorMessage("event is not a bound change event\n");
1156  SCIPABORT();
1157  return 0.0; /*lint !e527*/
1158  } /*lint !e788*/
1159 }
1160 
1161 /** gets new bound for a bound change event */
1163  SCIP_EVENT* event /**< event */
1164  )
1165 {
1166  assert(event != NULL);
1167 
1168  switch( event->eventtype )
1169  {
1176  return event->data.eventbdchg.newbound;
1177 
1178  default:
1179  SCIPerrorMessage("event is not a bound change event\n");
1180  SCIPABORT();
1181  return 0.0; /*lint !e527*/
1182  } /*lint !e788*/
1183 }
1184 
1185 /** gets node for a node or LP event */
1187  SCIP_EVENT* event /**< event */
1188  )
1189 {
1190  assert(event != NULL);
1191 
1193  {
1194  SCIPerrorMessage("event is neither node nor LP event\n");
1195  SCIPABORT();
1196  return NULL; /*lint !e527*/
1197  }
1198 
1199  return event->data.node;
1200 }
1201 
1202 /** sets node for a node or LP event */
1204  SCIP_EVENT* event, /**< event */
1205  SCIP_NODE* node /**< new node */
1206  )
1207 {
1208  assert(event != NULL);
1209 
1211  {
1212  SCIPerrorMessage("event is neither node nor LP event\n");
1213  SCIPABORT();
1214  return SCIP_INVALIDDATA; /*lint !e527*/
1215  }
1216 
1217  event->data.node = node;
1218 
1219  return SCIP_OKAY;
1220 }
1221 
1222 /** gets solution for a primal solution event */
1224  SCIP_EVENT* event /**< event */
1225  )
1226 {
1227  assert(event != NULL);
1228 
1229  if( (event->eventtype & SCIP_EVENTTYPE_SOLEVENT) == 0 )
1230  {
1231  SCIPerrorMessage("event is not a primal solution event\n");
1232  SCIPABORT();
1233  return NULL; /*lint !e527*/
1234  }
1235 
1236  return event->data.sol;
1237 }
1238 
1239 /** sets solution for a primal solution event */
1241  SCIP_EVENT* event, /**< event */
1242  SCIP_SOL* sol /**< new primal solution */
1243  )
1244 {
1245  assert(event != NULL);
1246 
1247  if( (event->eventtype & SCIP_EVENTTYPE_SOLEVENT) == 0 )
1248  {
1249  SCIPerrorMessage("event is not a primal solution event\n");
1250  SCIPABORT();
1251  return SCIP_INVALIDDATA; /*lint !e527*/
1252  }
1253 
1254  event->data.sol = sol;
1255 
1256  return SCIP_OKAY;
1257 }
1258 
1259 /** gets the left bound of open interval in the hole */
1261  SCIP_EVENT* event /**< event */
1262  )
1263 {
1264  assert(event != NULL);
1265 
1266  if( (event->eventtype & SCIP_EVENTTYPE_HOLECHANGED) == 0 )
1267  {
1268  SCIPerrorMessage("event is not a hole added or removed event\n");
1269  SCIPABORT();
1270  return SCIP_INVALID; /*lint !e527*/
1271  }
1272 
1273  return event->data.eventhole.left;
1274 }
1275 
1276 /** gets the right bound of open interval in the hole */
1278  SCIP_EVENT* event /**< event */
1279  )
1280 {
1281  assert(event != NULL);
1282 
1283  if( (event->eventtype & SCIP_EVENTTYPE_HOLECHANGED) == 0 )
1284  {
1285  SCIPerrorMessage("event is not a hole added or removed event\n");
1286  SCIPABORT();
1287  return SCIP_INVALID; /*lint !e527*/
1288  }
1289 
1290  return event->data.eventhole.right;
1291 }
1292 
1293 /** gets row for a row event */
1295  SCIP_EVENT* event /**< event */
1296  )
1297 {
1298  assert(event != NULL);
1299 
1300  switch( event->eventtype )
1301  {
1303  return event->data.eventrowaddedsepa.row;
1305  return event->data.eventrowdeletedsepa.row;
1307  return event->data.eventrowaddedlp.row;
1309  return event->data.eventrowdeletedlp.row;
1311  return event->data.eventrowcoefchanged.row;
1313  return event->data.eventrowconstchanged.row;
1315  return event->data.eventrowsidechanged.row;
1316  default:
1317  SCIPerrorMessage("event does not belong to a row\n");
1318  SCIPABORT();
1319  return NULL; /*lint !e527*/
1320  }
1321 }
1322 
1323 /** gets column for a row change coefficient event */
1325  SCIP_EVENT* event /**< event */
1326  )
1327 {
1328  assert(event != NULL);
1329 
1330  if( (event->eventtype & SCIP_EVENTTYPE_ROWCOEFCHANGED) == 0 )
1331  {
1332  SCIPerrorMessage("event is not a row coefficient changed event\n");
1333  SCIPABORT();
1334  return NULL; /*lint !e527*/
1335  }
1336 
1337  return event->data.eventrowcoefchanged.col;
1338 }
1339 
1340 /** gets old coefficient value for a row change coefficient event */
1342  SCIP_EVENT* event /**< event */
1343  )
1344 {
1345  assert(event != NULL);
1346 
1347  if( (event->eventtype & SCIP_EVENTTYPE_ROWCOEFCHANGED) == 0 )
1348  {
1349  SCIPerrorMessage("event is not a row coefficient changed event\n");
1350  SCIPABORT();
1351  return SCIP_INVALID; /*lint !e527*/
1352  }
1353 
1354  return event->data.eventrowcoefchanged.oldval;
1355 }
1356 
1357 /** gets new coefficient value for a row change coefficient event */
1359  SCIP_EVENT* event /**< event */
1360  )
1361 {
1362  assert(event != NULL);
1363 
1364  if( (event->eventtype & SCIP_EVENTTYPE_ROWCOEFCHANGED) == 0 )
1365  {
1366  SCIPerrorMessage("event is not a row coefficient changed event\n");
1367  SCIPABORT();
1368  return SCIP_INVALID; /*lint !e527*/
1369  }
1370 
1371  return event->data.eventrowcoefchanged.newval;
1372 }
1373 
1374 /** gets old constant value for a row change constant event */
1376  SCIP_EVENT* event /**< event */
1377  )
1378 {
1379  assert(event != NULL);
1380 
1381  if( (event->eventtype & SCIP_EVENTTYPE_ROWCONSTCHANGED) == 0 )
1382  {
1383  SCIPerrorMessage("event is not a row coefficient changed event\n");
1384  SCIPABORT();
1385  return SCIP_INVALID; /*lint !e527*/
1386  }
1387 
1388  return event->data.eventrowconstchanged.oldval;
1389 }
1390 
1391 /** gets new constant value for a row change constant event */
1393  SCIP_EVENT* event /**< event */
1394  )
1395 {
1396  assert(event != NULL);
1397 
1398  if( (event->eventtype & SCIP_EVENTTYPE_ROWCONSTCHANGED) == 0 )
1399  {
1400  SCIPerrorMessage("event is not a row coefficient changed event\n");
1401  SCIPABORT();
1402  return SCIP_INVALID; /*lint !e527*/
1403  }
1404 
1405  return event->data.eventrowconstchanged.newval;
1406 }
1407 
1408 /** gets side for a row change side event */
1410  SCIP_EVENT* event /**< event */
1411  )
1412 {
1413  assert(event != NULL);
1414 
1415  if( (event->eventtype & SCIP_EVENTTYPE_ROWSIDECHANGED) == 0 )
1416  {
1417  SCIPerrorMessage("event is not a row side changed event\n");
1418  SCIPABORT();
1419  return SCIP_SIDETYPE_LEFT; /*lint !e527*/
1420  }
1421 
1422  return event->data.eventrowsidechanged.side;
1423 }
1424 
1425 /** gets old side value for a row change side event */
1427  SCIP_EVENT* event /**< event */
1428  )
1429 {
1430  assert(event != NULL);
1431 
1432  if( (event->eventtype & SCIP_EVENTTYPE_ROWSIDECHANGED) == 0 )
1433  {
1434  SCIPerrorMessage("event is not a row side changed event\n");
1435  SCIPABORT();
1436  return SCIP_INVALID; /*lint !e527*/
1437  }
1438 
1439  return event->data.eventrowsidechanged.oldval;
1440 }
1441 
1442 /** gets new side value for a row change side event */
1444  SCIP_EVENT* event /**< event */
1445  )
1446 {
1447  assert(event != NULL);
1448 
1449  if( (event->eventtype & SCIP_EVENTTYPE_ROWSIDECHANGED) == 0 )
1450  {
1451  SCIPerrorMessage("event is not a row side changed event\n");
1452  SCIPABORT();
1453  return SCIP_INVALID; /*lint !e527*/
1454  }
1455 
1456  return event->data.eventrowsidechanged.newval;
1457 }
1458 
1459 /** processes event by calling the appropriate event handlers */
1461  SCIP_EVENT* event, /**< event */
1462  SCIP_SET* set, /**< global SCIP settings */
1463  SCIP_PRIMAL* primal, /**< primal data; only needed for objchanged events, or NULL */
1464  SCIP_LP* lp, /**< current LP data; only needed for obj/boundchanged events, or NULL */
1465  SCIP_BRANCHCAND* branchcand, /**< branching candidate storage; only needed for bound change events, or NULL */
1466  SCIP_EVENTFILTER* eventfilter /**< event filter for global events; not needed for variable specific events */
1467  )
1468 {
1469  SCIP_VAR* var;
1470 
1471  assert(event != NULL);
1472  assert((event->eventtype & SCIP_EVENTTYPE_OBJCHANGED) == 0 || primal != NULL);
1473  assert((event->eventtype & (SCIP_EVENTTYPE_BOUNDCHANGED | SCIP_EVENTTYPE_OBJCHANGED)) == 0 || lp != NULL);
1474  assert((event->eventtype & SCIP_EVENTTYPE_BOUNDCHANGED) == 0 || branchcand != NULL);
1475 
1476  SCIPsetDebugMsg(set, "processing event of type 0x%" SCIP_EVENTTYPE_FORMAT "\n", event->eventtype);
1477 
1478  switch( event->eventtype )
1479  {
1481  break;
1482 
1483  case SCIP_EVENTTYPE_SYNC: /*lint !e30 !e142*/
1501  SCIP_CALL( SCIPeventfilterProcess(eventfilter, set, event) );
1502  break;
1503 
1505  var = event->data.eventvardeleted.var;
1506  assert(var != NULL);
1507 
1508  /* process variable's event filter */
1509  SCIP_CALL( SCIPeventfilterProcess(var->eventfilter, set, event) );
1510  break;
1511 
1513  var = event->data.eventvarfixed.var;
1514  assert(var != NULL);
1515 
1516  /* process variable's event filter */
1517  SCIP_CALL( SCIPeventfilterProcess(var->eventfilter, set, event) );
1518  break;
1519 
1521  var = event->data.eventvarunlocked.var;
1522  assert(var != NULL);
1523 
1524  /* process variable's event filter */
1525  SCIP_CALL( SCIPeventfilterProcess(var->eventfilter, set, event) );
1526  break;
1527 
1529  var = event->data.eventobjchg.var;
1530  assert(var != NULL);
1531  assert(var->eventqueueindexobj == -1);
1533 
1534  /* inform LP about the objective change */
1535  if( SCIPvarGetProbindex(var) >= 0 )
1536  {
1538  {
1539  SCIP_CALL( SCIPcolChgObj(SCIPvarGetCol(var), set, lp, event->data.eventobjchg.newobj) );
1540  }
1541  SCIP_CALL( SCIPlpUpdateVarObj(lp, set, var, event->data.eventobjchg.oldobj, event->data.eventobjchg.newobj) );
1542  }
1543 
1544  /* inform all existing primal solutions about the objective change (only if this is not a temporary change in
1545  * probing mode)
1546  */
1547  if( ! lp->divingobjchg )
1548  {
1549  SCIPprimalUpdateVarObj(primal, var, event->data.eventobjchg.oldobj, event->data.eventobjchg.newobj);
1550  }
1551 
1552  /* process variable's event filter */
1553  SCIP_CALL( SCIPeventfilterProcess(var->eventfilter, set, event) );
1554  break;
1555 
1557  var = event->data.eventbdchg.var;
1558  assert(var != NULL);
1559 
1560  /* inform LP about global bound change */
1562  {
1563  assert(SCIPvarGetProbindex(var) >= 0);
1565  event->data.eventbdchg.newbound) );
1566  }
1567 
1568  /* process variable's event filter */
1569  SCIP_CALL( SCIPeventfilterProcess(var->eventfilter, set, event) );
1570  break;
1571 
1573  var = event->data.eventbdchg.var;
1574  assert(var != NULL);
1575 
1576  /* inform LP about global bound change */
1578  {
1579  assert(SCIPvarGetProbindex(var) >= 0);
1581  event->data.eventbdchg.newbound) );
1582  }
1583 
1584  /* process variable's event filter */
1585  SCIP_CALL( SCIPeventfilterProcess(var->eventfilter, set, event) );
1586  break;
1587 
1590  var = event->data.eventbdchg.var;
1591  assert(var != NULL);
1592  assert(var->eventqueueindexlb == -1);
1593 
1594  /* inform LP about bound change and update branching candidates */
1596  {
1597  assert(SCIPvarGetProbindex(var) >= 0);
1599  {
1600  SCIP_CALL( SCIPcolChgLb(SCIPvarGetCol(var), set, lp, event->data.eventbdchg.newbound) );
1601  }
1602  SCIP_CALL( SCIPlpUpdateVarLb(lp, set, var, event->data.eventbdchg.oldbound,
1603  event->data.eventbdchg.newbound) );
1604  SCIP_CALL( SCIPbranchcandUpdateVar(branchcand, set, var) );
1605  }
1606 
1607  /* process variable's event filter */
1608  SCIP_CALL( SCIPeventfilterProcess(var->eventfilter, set, event) );
1609  break;
1610 
1613  var = event->data.eventbdchg.var;
1614  assert(var != NULL);
1615  assert(var->eventqueueindexub == -1);
1616 
1617  /* inform LP about bound change and update branching candidates */
1619  {
1620  assert(SCIPvarGetProbindex(var) >= 0);
1622  {
1623  SCIP_CALL( SCIPcolChgUb(SCIPvarGetCol(var), set, lp, event->data.eventbdchg.newbound) );
1624  }
1625  SCIP_CALL( SCIPlpUpdateVarUb(lp, set, var, event->data.eventbdchg.oldbound,
1626  event->data.eventbdchg.newbound) );
1627  SCIP_CALL( SCIPbranchcandUpdateVar(branchcand, set, var) );
1628  }
1629 
1630  /* process variable's event filter */
1631  SCIP_CALL( SCIPeventfilterProcess(var->eventfilter, set, event) );
1632  break;
1633 
1638  var = event->data.eventhole.var;
1639  assert(var != NULL);
1640 
1641  /* process variable's event filter */
1642  SCIP_CALL( SCIPeventfilterProcess(var->eventfilter, set, event) );
1643  break;
1644 
1646  var = event->data.eventimpladd.var;
1647  assert(var != NULL);
1648  assert(!var->eventqueueimpl);
1649 
1650  /* process variable's event filter */
1651  SCIP_CALL( SCIPeventfilterProcess(var->eventfilter, set, event) );
1652  break;
1653 
1654  default:
1655  SCIPerrorMessage("unknown event type <%d>\n", event->eventtype);
1656  return SCIP_INVALIDDATA;
1657  }
1658 
1659  return SCIP_OKAY;
1660 }
1661 
1662 
1663 
1664 /*
1665  * Event filter methods
1666  */
1667 
1668 /** resizes eventfilter arrays to be able to store at least num entries */
1669 static
1671  SCIP_EVENTFILTER* eventfilter, /**< event filter */
1672  BMS_BLKMEM* blkmem, /**< block memory buffer */
1673  SCIP_SET* set, /**< global SCIP settings */
1674  int num /**< minimal number of node slots in array */
1675  )
1676 {
1677  assert(eventfilter != NULL);
1678  assert(blkmem != NULL);
1679  assert(set != NULL);
1680 
1681  if( num > eventfilter->size )
1682  {
1683  int newsize;
1684 
1685  newsize = SCIPsetCalcMemGrowSize(set, num);
1686  SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &eventfilter->eventtypes, eventfilter->size, newsize) );
1687  SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &eventfilter->eventhdlrs, eventfilter->size, newsize) );
1688  SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &eventfilter->eventdata, eventfilter->size, newsize) );
1689  SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &eventfilter->nextpos, eventfilter->size, newsize) );
1690  eventfilter->size = newsize;
1691  }
1692  assert(num <= eventfilter->size);
1693 
1694  return SCIP_OKAY;
1695 }
1696 
1697 /** creates an event filter */
1699  SCIP_EVENTFILTER** eventfilter, /**< pointer to store the event filter */
1700  BMS_BLKMEM* blkmem /**< block memory buffer */
1701  )
1702 {
1703  assert(eventfilter != NULL);
1704  assert(blkmem != NULL);
1705 
1706  SCIP_ALLOC( BMSallocBlockMemory(blkmem, eventfilter) );
1707  (*eventfilter)->eventtypes = NULL;
1708  (*eventfilter)->eventhdlrs = NULL;
1709  (*eventfilter)->eventdata = NULL;
1710  (*eventfilter)->nextpos = NULL;
1711  (*eventfilter)->size = 0;
1712  (*eventfilter)->len = 0;
1713  (*eventfilter)->firstfreepos = -1;
1714  (*eventfilter)->firstdeletedpos = -1;
1715  (*eventfilter)->eventmask = SCIP_EVENTTYPE_DISABLED;
1716  (*eventfilter)->delayedeventmask = SCIP_EVENTTYPE_DISABLED;
1717  (*eventfilter)->delayupdates = FALSE;
1718 
1719  return SCIP_OKAY;
1720 }
1721 
1722 /** frees an event filter and the associated event data entries */
1724  SCIP_EVENTFILTER** eventfilter, /**< pointer to store the event filter */
1725  BMS_BLKMEM* blkmem, /**< block memory buffer */
1726  SCIP_SET* set /**< global SCIP settings */
1727  )
1728 {
1729  int i;
1730 
1731  assert(eventfilter != NULL);
1732  assert(*eventfilter != NULL);
1733  assert(!(*eventfilter)->delayupdates);
1734  assert(blkmem != NULL);
1735  assert(set != NULL);
1736  assert(set->scip != NULL);
1737 
1738  /* free event data */
1739  for( i = 0; i < (*eventfilter)->len; ++i )
1740  {
1741  if( (*eventfilter)->eventtypes[i] != SCIP_EVENTTYPE_DISABLED )
1742  {
1743  assert((*eventfilter)->eventhdlrs[i] != NULL);
1744  if( (*eventfilter)->eventhdlrs[i]->eventdelete != NULL )
1745  {
1746  SCIP_CALL( (*eventfilter)->eventhdlrs[i]->eventdelete(set->scip, (*eventfilter)->eventhdlrs[i],
1747  &(*eventfilter)->eventdata[i]) );
1748  }
1749  }
1750  }
1751 
1752  /* free event filter data */
1753  BMSfreeBlockMemoryArrayNull(blkmem, &(*eventfilter)->eventtypes, (*eventfilter)->size);
1754  BMSfreeBlockMemoryArrayNull(blkmem, &(*eventfilter)->eventhdlrs, (*eventfilter)->size);
1755  BMSfreeBlockMemoryArrayNull(blkmem, &(*eventfilter)->eventdata, (*eventfilter)->size);
1756  BMSfreeBlockMemoryArrayNull(blkmem, &(*eventfilter)->nextpos, (*eventfilter)->size);
1757  BMSfreeBlockMemory(blkmem, eventfilter);
1758 
1759  return SCIP_OKAY;
1760 }
1761 
1762 /** adds element to event filter */
1764  SCIP_EVENTFILTER* eventfilter, /**< event filter */
1765  BMS_BLKMEM* blkmem, /**< block memory buffer */
1766  SCIP_SET* set, /**< global SCIP settings */
1767  SCIP_EVENTTYPE eventtype, /**< event type to catch */
1768  SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
1769  SCIP_EVENTDATA* eventdata, /**< event data to pass to the event handler for the event processing */
1770  int* filterpos /**< pointer to store position of event filter entry, or NULL */
1771  )
1772 {
1773  int pos;
1774 
1775  assert(eventfilter != NULL);
1776  assert(blkmem != NULL);
1777  assert(set != NULL);
1778  assert(eventhdlr != NULL);
1779 
1780  if( eventfilter->delayupdates )
1781  {
1782  /* insert addition to the end of the arrays;
1783  * in delayed addition we have to add to the end of the arrays, in order to not destroy the validity of the
1784  * arrays we are currently iterating over
1785  */
1786  SCIP_CALL( eventfilterEnsureMem(eventfilter, blkmem, set, eventfilter->len + 1) );
1787  pos = eventfilter->len;
1788  eventfilter->len++;
1789 
1790  /* update delayed event filter mask */
1791  eventfilter->delayedeventmask |= eventtype;
1792  }
1793  else
1794  {
1795  if( eventfilter->firstfreepos == -1 )
1796  {
1797  /* insert addition to the end of the arrays */
1798  SCIP_CALL( eventfilterEnsureMem(eventfilter, blkmem, set, eventfilter->len + 1) );
1799  pos = eventfilter->len;
1800  eventfilter->len++;
1801  }
1802  else
1803  {
1804  /* use the first free slot to store the added event filter entry */
1805  pos = eventfilter->firstfreepos;
1806  assert(0 <= pos && pos < eventfilter->len);
1807  assert(eventfilter->eventtypes[pos] == SCIP_EVENTTYPE_DISABLED);
1808  eventfilter->firstfreepos = eventfilter->nextpos[pos];
1809  assert(-1 <= eventfilter->firstfreepos && eventfilter->firstfreepos < eventfilter->len);
1810  }
1811 
1812  /* update event filter mask */
1813  eventfilter->eventmask |= eventtype;
1814  }
1815  assert(0 <= pos && pos < eventfilter->len);
1816 
1817  eventfilter->eventtypes[pos] = eventtype;
1818  eventfilter->eventhdlrs[pos] = eventhdlr;
1819  eventfilter->eventdata[pos] = eventdata;
1820  eventfilter->nextpos[pos] = -2;
1821 
1822  if( filterpos != NULL )
1823  *filterpos = pos;
1824 
1825  return SCIP_OKAY;
1826 }
1827 
1828 /** linear search for the given entry in event filter */
1829 static
1831  SCIP_EVENTFILTER*const eventfilter, /**< event filter */
1832  SCIP_EVENTTYPE const eventtype, /**< event type */
1833  SCIP_EVENTHDLR*const eventhdlr, /**< event handler to call for the event processing */
1834  SCIP_EVENTDATA*const eventdata /**< event data to pass to the event handler for the event processing */
1835  )
1836 {
1837  int i;
1838 
1839  assert(eventfilter != NULL);
1840  assert(eventtype != SCIP_EVENTTYPE_DISABLED);
1841  assert(eventhdlr != NULL);
1842 
1843  for( i = eventfilter->len - 1; i >= 0; --i )
1844  {
1845  if( eventdata == eventfilter->eventdata[i]
1846  && eventhdlr == eventfilter->eventhdlrs[i]
1847  && eventtype == eventfilter->eventtypes[i]
1848  && eventfilter->nextpos[i] == -2 )
1849  return i;
1850  }
1851 
1852  return -1;
1853 }
1854 
1855 /** deletes element from event filter */
1857  SCIP_EVENTFILTER* eventfilter, /**< event filter */
1858  BMS_BLKMEM* blkmem, /**< block memory buffer */
1859  SCIP_SET* set, /**< global SCIP settings */
1860  SCIP_EVENTTYPE eventtype, /**< event type */
1861  SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
1862  SCIP_EVENTDATA* eventdata, /**< event data to pass to the event handler for the event processing */
1863  int filterpos /**< position of event filter entry, or -1 if unknown */
1864  )
1865 {
1866  assert(eventfilter != NULL);
1867  assert(blkmem != NULL);
1868  assert(set != NULL);
1869  assert(eventtype != SCIP_EVENTTYPE_DISABLED);
1870  assert(eventhdlr != NULL);
1871  assert(-1 <= filterpos && filterpos < eventfilter->len);
1872 
1873  /* search position of event filter entry, if not given by the user */
1874  if( filterpos == -1 )
1875  filterpos = eventfilterSearch(eventfilter, eventtype, eventhdlr, eventdata);
1876  if( filterpos == -1 )
1877  {
1878  SCIPerrorMessage("no event for event handler %p with data %p and event mask 0x%x found in event filter %p\n",
1879  eventhdlr, eventdata, eventtype, eventfilter);
1880  return SCIP_INVALIDDATA;
1881  }
1882  assert(0 <= filterpos && filterpos < eventfilter->len);
1883  assert(eventfilter->eventtypes[filterpos] == eventtype);
1884  assert(eventfilter->eventhdlrs[filterpos] == eventhdlr);
1885  assert(eventfilter->eventdata[filterpos] == eventdata);
1886  assert(eventfilter->nextpos[filterpos] == -2);
1887 
1888  /* if updates are delayed, insert entry into the list of delayed deletions;
1889  * otherwise, delete the entry from the filter directly and add the slot to the free list
1890  */
1891  if( eventfilter->delayupdates )
1892  {
1893  /* append filterpos to the list of deleted entries */
1894  eventfilter->nextpos[filterpos] = eventfilter->firstdeletedpos;
1895  eventfilter->firstdeletedpos = filterpos;
1896  }
1897  else
1898  {
1899  /* disable the entry in the filter and add the slot to the free list */
1900  assert(eventfilter->nextpos[filterpos] == -2);
1901  eventfilter->eventtypes[filterpos] = SCIP_EVENTTYPE_DISABLED;
1902  eventfilter->nextpos[filterpos] = eventfilter->firstfreepos;
1903  eventfilter->firstfreepos = filterpos;
1904  }
1905 
1906  return SCIP_OKAY;
1907 }
1908 
1909 /** makes the event filter to delay and buffer all updates until eventfilterProcessUpdates() is called */
1910 static
1912  SCIP_EVENTFILTER* eventfilter /**< event filter */
1913  )
1914 {
1915  assert(eventfilter != NULL);
1916  assert(!eventfilter->delayupdates);
1917  assert(eventfilter->delayedeventmask == SCIP_EVENTTYPE_DISABLED);
1918 
1919  eventfilter->delayupdates = TRUE;
1920 }
1921 
1922 /** processes all delayed additions and deletions */
1923 static
1925  SCIP_EVENTFILTER* eventfilter /**< event filter */
1926  )
1927 {
1928  int pos;
1929  int nextpos;
1930 
1931  assert(eventfilter != NULL);
1932  assert(eventfilter->delayupdates);
1933 
1934  /* move deleted entries into the free list and disable them */
1935  pos = eventfilter->firstdeletedpos;
1936  while( pos != -1 )
1937  {
1938  assert(0 <= pos && pos < eventfilter->len);
1939  assert(eventfilter->eventtypes[pos] != SCIP_EVENTTYPE_DISABLED);
1940  assert(eventfilter->nextpos[pos] >= -1);
1941 
1942  nextpos = eventfilter->nextpos[pos];
1943  eventfilter->nextpos[pos] = eventfilter->firstfreepos;
1944  eventfilter->firstfreepos = pos;
1945  eventfilter->eventtypes[pos] = SCIP_EVENTTYPE_DISABLED;
1946  pos = nextpos;
1947  }
1948  eventfilter->firstdeletedpos = -1;
1949 
1950  /* update event mask */
1951  eventfilter->eventmask |= eventfilter->delayedeventmask;
1953 
1954  /* mark the event filter updates to be no longer delayed */
1955  eventfilter->delayupdates = FALSE;
1956 }
1957 
1958 /** processes the event with all event handlers with matching filter setting */
1960  SCIP_EVENTFILTER* eventfilter, /**< event filter */
1961  SCIP_SET* set, /**< global SCIP settings */
1962  SCIP_EVENT* event /**< event to process */
1963  )
1964 {
1965  SCIP_EVENTTYPE eventtype;
1966  SCIP_EVENTTYPE* eventtypes;
1967  SCIP_Bool processed;
1968  int len;
1969  int i;
1970 
1971  assert(eventfilter != NULL);
1972  assert(set != NULL);
1973  assert(event != NULL);
1974 
1975  SCIPsetDebugMsg(set, "processing event filter %p (len %d, mask 0x%" SCIP_EVENTTYPE_FORMAT ") with event type 0x%" SCIP_EVENTTYPE_FORMAT "\n",
1976  (void*)eventfilter, eventfilter->len, eventfilter->eventmask, event->eventtype);
1977 
1978  eventtype = event->eventtype;
1979 
1980  /* check, if there may be any event handler for specific event */
1981  if( (eventtype & eventfilter->eventmask) == 0 )
1982  return SCIP_OKAY;
1983 
1984  /* delay the updates on this eventfilter, such that changes during event processing to the event filter
1985  * don't destroy necessary information of the arrays we are currently using
1986  */
1987  eventfilterDelayUpdates(eventfilter);
1988 
1989  /* process the event by calling the event handlers */
1990  processed = FALSE;
1991  len = eventfilter->len;
1992  eventtypes = eventfilter->eventtypes;
1993  for( i = 0; i < len; ++i )
1994  {
1995  /* check, if event is applicable for the filter element */
1996  if( (eventtype & eventtypes[i]) != 0 )
1997  {
1998  /* call event handler */
1999  SCIP_CALL( SCIPeventhdlrExec(eventfilter->eventhdlrs[i], set, event, eventfilter->eventdata[i]) );
2000  processed = TRUE;
2001  }
2002  }
2003 
2004  /* update eventfilter mask, if event was not processed by any event handler */
2005  if( !processed )
2006  {
2007  eventfilter->eventmask &= ~event->eventtype;
2008  SCIPsetDebugMsg(set, " -> event type 0x%" SCIP_EVENTTYPE_FORMAT " not processed. new mask of event filter %p: 0x%" SCIP_EVENTTYPE_FORMAT "\n",
2009  event->eventtype, (void*)eventfilter, eventfilter->eventmask);
2010  }
2011 
2012  /* process delayed events on this eventfilter */
2013  eventfilterProcessUpdates(eventfilter);
2014 
2015  return SCIP_OKAY;
2016 }
2017 
2018 
2019 
2020 /*
2021  * Event queue methods
2022  */
2023 
2024 /*
2025  * simple functions implemented as defines
2026  */
2027 
2028 /* In debug mode, the following methods are implemented as function calls to ensure
2029  * type validity.
2030  * In optimized mode, the methods are implemented as defines to improve performance.
2031  * However, we want to have them in the library anyways, so we have to undef the defines.
2032  */
2033 
2034 #undef SCIPeventqueueIsDelayed
2035 
2036 /** resizes events array to be able to store at least num entries */
2037 static
2039  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
2040  SCIP_SET* set, /**< global SCIP settings */
2041  int num /**< minimal number of node slots in array */
2042  )
2043 {
2044  assert(eventqueue != NULL);
2045  assert(set != NULL);
2046 
2047  if( num > eventqueue->eventssize )
2048  {
2049  int newsize;
2050 
2051  newsize = SCIPsetCalcMemGrowSize(set, num);
2052  SCIP_ALLOC( BMSreallocMemoryArray(&eventqueue->events, newsize) );
2053  eventqueue->eventssize = newsize;
2054  }
2055  assert(num <= eventqueue->eventssize);
2056 
2057  return SCIP_OKAY;
2058 }
2059 
2060 /** creates an event queue */
2062  SCIP_EVENTQUEUE** eventqueue /**< pointer to store the event queue */
2063  )
2064 {
2065  assert(eventqueue != NULL);
2066 
2067  SCIP_ALLOC( BMSallocMemory(eventqueue) );
2068  (*eventqueue)->events = NULL;
2069  (*eventqueue)->eventssize = 0;
2070  (*eventqueue)->nevents = 0;
2071  (*eventqueue)->delayevents = FALSE;
2072 
2073  return SCIP_OKAY;
2074 }
2075 
2076 /** frees event queue; there must not be any unprocessed events in the queue! */
2078  SCIP_EVENTQUEUE** eventqueue /**< pointer to the event queue */
2079  )
2080 {
2081  assert(eventqueue != NULL);
2082  assert(*eventqueue != NULL);
2083  assert((*eventqueue)->nevents == 0);
2084 
2085  BMSfreeMemoryArrayNull(&(*eventqueue)->events);
2086  BMSfreeMemory(eventqueue);
2087 
2088  return SCIP_OKAY;
2089 }
2090 
2091 /** appends event to the event queue; sets event to NULL afterwards */
2092 static
2094  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
2095  SCIP_SET* set, /**< global SCIP settings */
2096  SCIP_EVENT** event /**< pointer to event to append to the queue */
2097  )
2098 {
2099  assert(eventqueue != NULL);
2100  assert(eventqueue->delayevents);
2101  assert(event != NULL);
2102  assert(*event != NULL);
2103 
2104  SCIPsetDebugMsg(set, "appending event %p of type 0x%" SCIP_EVENTTYPE_FORMAT " to event queue %p at position %d\n",
2105  (void*)*event, (*event)->eventtype, (void*)eventqueue, eventqueue->nevents);
2106 
2107  SCIP_CALL( eventqueueEnsureEventsMem(eventqueue, set, eventqueue->nevents+1) );
2108  eventqueue->events[eventqueue->nevents] = *event;
2109  eventqueue->nevents++;
2110 
2111  *event = NULL;
2112 
2113  return SCIP_OKAY;
2114 }
2115 
2116 /** processes event or adds event to the event queue */
2118  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
2119  BMS_BLKMEM* blkmem, /**< block memory buffer */
2120  SCIP_SET* set, /**< global SCIP settings */
2121  SCIP_PRIMAL* primal, /**< primal data; only needed for objchanged events, or NULL */
2122  SCIP_LP* lp, /**< current LP data; only needed for obj/boundchanged events, or NULL */
2123  SCIP_BRANCHCAND* branchcand, /**< branching candidate storage; only needed for bound change events, or NULL */
2124  SCIP_EVENTFILTER* eventfilter, /**< event filter for global events; not needed for variable specific events */
2125  SCIP_EVENT** event /**< pointer to event to add to the queue; will be NULL after queue addition */
2126  )
2127 {
2128  SCIP_VAR* var;
2129  SCIP_EVENT* qevent;
2130  int pos;
2131 
2132  assert(eventqueue != NULL);
2133  assert(event != NULL);
2134  assert(*event != NULL);
2135  assert(((*event)->eventtype & SCIP_EVENTTYPE_OBJCHANGED) == 0 || primal != NULL);
2136  assert(((*event)->eventtype & (SCIP_EVENTTYPE_BOUNDCHANGED | SCIP_EVENTTYPE_OBJCHANGED)) == 0 || lp != NULL);
2137  assert(((*event)->eventtype & SCIP_EVENTTYPE_BOUNDCHANGED) == 0 || branchcand != NULL);
2138 
2139  if( !eventqueue->delayevents )
2140  {
2141  /* immediately process event */
2142  SCIP_CALL( SCIPeventProcess(*event, set, primal, lp, branchcand, eventfilter) );
2143  SCIP_CALL( SCIPeventFree(event, blkmem) );
2144  }
2145  else
2146  {
2147  /* delay processing of event by appending it to the event queue */
2148  SCIPsetDebugMsg(set, "adding event %p of type 0x%" SCIP_EVENTTYPE_FORMAT " to event queue %p\n", (void*)*event, (*event)->eventtype, (void*)eventqueue);
2149 
2150  switch( (*event)->eventtype )
2151  {
2153  SCIPerrorMessage("cannot add a disabled event to the event queue\n");
2154  return SCIP_INVALIDDATA;
2155 
2156  case SCIP_EVENTTYPE_SYNC: /*lint !e30 !e142*/
2176  case SCIP_EVENTTYPE_ROWADDEDSEPA: /* @todo remove previous DELETEDSEPA event */
2177  case SCIP_EVENTTYPE_ROWDELETEDSEPA: /* @todo remove previous ADDEDSEPA event */
2178  case SCIP_EVENTTYPE_ROWADDEDLP: /* @todo remove previous DELETEDLP event */
2179  case SCIP_EVENTTYPE_ROWDELETEDLP: /* @todo remove previous ADDEDLP event */
2180  case SCIP_EVENTTYPE_ROWCOEFCHANGED: /* @todo merge? */
2181  case SCIP_EVENTTYPE_ROWCONSTCHANGED: /* @todo merge with previous constchanged event */
2182  case SCIP_EVENTTYPE_ROWSIDECHANGED: /* @todo merge with previous sidechanged event */
2183  /* these events cannot (or need not) be merged; just add them to the queue */
2184  SCIP_CALL( eventqueueAppend(eventqueue, set, event) );
2185  break;
2186 
2188  /* changes in objective value may be merged with older changes in objective value */
2189  var = (*event)->data.eventobjchg.var;
2190  assert(var != NULL);
2191  pos = var->eventqueueindexobj;
2192  if( pos >= 0 )
2193  {
2194  /* the objective value change event already exists -> modify it accordingly */
2195  assert(pos < eventqueue->nevents);
2196  qevent = eventqueue->events[pos];
2197  assert(qevent != NULL);
2198  assert(qevent->eventtype == SCIP_EVENTTYPE_OBJCHANGED);
2199  assert(qevent->data.eventobjchg.var == var);
2200  assert(SCIPsetIsEQ(set, (*event)->data.eventobjchg.oldobj, qevent->data.eventobjchg.newobj));
2201 
2202  SCIPsetDebugMsg(set, " -> merging OBJ event (<%s>,%g -> %g) with event at position %d (<%s>,%g -> %g)\n",
2203  SCIPvarGetName((*event)->data.eventobjchg.var), (*event)->data.eventobjchg.oldobj,
2204  (*event)->data.eventobjchg.newobj,
2205  pos, SCIPvarGetName(qevent->data.eventobjchg.var), qevent->data.eventobjchg.oldobj,
2206  qevent->data.eventobjchg.newobj);
2207 
2208  qevent->data.eventobjchg.newobj = (*event)->data.eventobjchg.newobj;
2209  if( qevent->data.eventobjchg.newobj == qevent->data.eventobjchg.oldobj ) /*lint !e777*/
2210  {
2211  /* the queued objective value change was reversed -> disable the event in the queue */
2212  eventDisable(qevent);
2213  var->eventqueueindexobj = -1;
2214  SCIPsetDebugMsg(set, " -> event disabled\n");
2215  }
2216 
2217  /* free the event that is of no use any longer */
2218  SCIP_CALL( SCIPeventFree(event, blkmem) );
2219  }
2220  else
2221  {
2222  /* the objective value change event doesn't exist -> add it to the queue, and remember the array index */
2223  var->eventqueueindexobj = eventqueue->nevents;
2224  SCIP_CALL( eventqueueAppend(eventqueue, set, event) );
2225  }
2226  break;
2227 
2230  /* changes in lower bound may be merged with older changes in lower bound */
2231  var = (*event)->data.eventbdchg.var;
2232  assert(var != NULL);
2233  pos = var->eventqueueindexlb;
2234  if( pos >= 0 )
2235  {
2236  /* the lower bound change event already exists -> modify it accordingly */
2237  assert(pos < eventqueue->nevents);
2238  qevent = eventqueue->events[pos];
2239  assert(qevent != NULL);
2241  assert(qevent->data.eventbdchg.var == var);
2242  assert(SCIPsetIsEQ(set, (*event)->data.eventbdchg.oldbound, qevent->data.eventbdchg.newbound));
2243 
2244  SCIPsetDebugMsg(set, " -> merging LB event (<%s>,%g -> %g) with event at position %d (<%s>,%g -> %g)\n",
2245  SCIPvarGetName((*event)->data.eventbdchg.var), (*event)->data.eventbdchg.oldbound,
2246  (*event)->data.eventbdchg.newbound,
2247  pos, SCIPvarGetName(qevent->data.eventbdchg.var), qevent->data.eventbdchg.oldbound,
2248  qevent->data.eventbdchg.newbound);
2249 
2250  qevent->data.eventbdchg.newbound = (*event)->data.eventbdchg.newbound;
2251  /*if( SCIPsetIsLT(set, qevent->data.eventbdchg.newbound, qevent->data.eventbdchg.oldbound) )*/
2252  if( qevent->data.eventbdchg.newbound < qevent->data.eventbdchg.oldbound )
2254  /*else if( SCIPsetIsGT(set, qevent->data.eventbdchg.newbound, qevent->data.eventbdchg.oldbound) )*/
2255  else if( qevent->data.eventbdchg.newbound > qevent->data.eventbdchg.oldbound )
2257  else
2258  {
2259  /* the queued bound change was reversed -> disable the event in the queue */
2260  assert(qevent->data.eventbdchg.newbound == qevent->data.eventbdchg.oldbound); /*lint !e777*/
2261  eventDisable(qevent);
2262  var->eventqueueindexlb = -1;
2263  SCIPsetDebugMsg(set, " -> event disabled\n");
2264  }
2265 
2266  /* free the event that is of no use any longer */
2267  SCIP_CALL( SCIPeventFree(event, blkmem) );
2268  }
2269  else
2270  {
2271  /* the lower bound change event doesn't exist -> add it to the queue, and remember the array index */
2272  var->eventqueueindexlb = eventqueue->nevents;
2273  SCIP_CALL( eventqueueAppend(eventqueue, set, event) );
2274  }
2275  break;
2276 
2279  /* changes in upper bound may be merged with older changes in upper bound */
2280  var = (*event)->data.eventbdchg.var;
2281  assert(var != NULL);
2282  pos = var->eventqueueindexub;
2283  if( pos >= 0 )
2284  {
2285  /* the upper bound change event already exists -> modify it accordingly */
2286  assert(pos < eventqueue->nevents);
2287  qevent = eventqueue->events[pos];
2288  assert(qevent != NULL);
2290  assert(qevent->data.eventbdchg.var == var);
2291  assert(SCIPsetIsEQ(set, (*event)->data.eventbdchg.oldbound, qevent->data.eventbdchg.newbound));
2292 
2293  SCIPsetDebugMsg(set, " -> merging UB event (<%s>,%g -> %g) with event at position %d (<%s>,%g -> %g)\n",
2294  SCIPvarGetName((*event)->data.eventbdchg.var), (*event)->data.eventbdchg.oldbound,
2295  (*event)->data.eventbdchg.newbound,
2296  pos, SCIPvarGetName(qevent->data.eventbdchg.var), qevent->data.eventbdchg.oldbound,
2297  qevent->data.eventbdchg.newbound);
2298 
2299  qevent->data.eventbdchg.newbound = (*event)->data.eventbdchg.newbound;
2300  /*if( SCIPsetIsLT(set, qevent->data.eventbdchg.newbound, qevent->data.eventbdchg.oldbound) )*/
2301  if( qevent->data.eventbdchg.newbound < qevent->data.eventbdchg.oldbound )
2303  /*else if( SCIPsetIsGT(set, qevent->data.eventbdchg.newbound, qevent->data.eventbdchg.oldbound) )*/
2304  else if( qevent->data.eventbdchg.newbound > qevent->data.eventbdchg.oldbound )
2306  else
2307  {
2308  /* the queued bound change was reversed -> disable the event in the queue */
2309  assert(qevent->data.eventbdchg.newbound == qevent->data.eventbdchg.oldbound); /*lint !e777*/
2310  eventDisable(qevent);
2311  var->eventqueueindexub = -1;
2312  SCIPsetDebugMsg(set, " -> event disabled\n");
2313  }
2314 
2315  /* free the event that is of no use any longer */
2316  SCIP_CALL( SCIPeventFree(event, blkmem) );
2317  }
2318  else
2319  {
2320  /* the upper bound change event doesn't exist -> add it to the queue, and remember the array index */
2321  var->eventqueueindexub = eventqueue->nevents;
2322  SCIP_CALL( eventqueueAppend(eventqueue, set, event) );
2323  }
2324  break;
2325 
2327  var = (*event)->data.eventimpladd.var;
2328  assert(var != NULL);
2329  if( var->eventqueueimpl )
2330  {
2331  /* free the event that is of no use any longer */
2332  SCIP_CALL( SCIPeventFree(event, blkmem) );
2333  }
2334  else
2335  {
2336  var->eventqueueimpl = TRUE;
2337  SCIP_CALL( eventqueueAppend(eventqueue, set, event) );
2338  }
2339  break;
2340 
2341  default:
2342  SCIPerrorMessage("unknown event type <%d>\n", (*event)->eventtype);
2343  return SCIP_INVALIDDATA;
2344  }
2345  }
2346 
2347  assert(*event == NULL);
2348 
2349  return SCIP_OKAY;
2350 }
2351 
2352 /** marks queue to delay incoming events until a call to SCIPeventqueueProcess() */
2354  SCIP_EVENTQUEUE* eventqueue /**< event queue */
2355  )
2356 {
2357  assert(eventqueue != NULL);
2358  assert(!eventqueue->delayevents);
2359 
2360  SCIPdebugMessage("event processing is delayed\n");
2361 
2362  eventqueue->delayevents = TRUE;
2363 
2364  return SCIP_OKAY;
2365 }
2366 
2367 /** processes all delayed events, marks queue to process events immediately */
2369  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
2370  BMS_BLKMEM* blkmem, /**< block memory buffer */
2371  SCIP_SET* set, /**< global SCIP settings */
2372  SCIP_PRIMAL* primal, /**< primal data */
2373  SCIP_LP* lp, /**< current LP data */
2374  SCIP_BRANCHCAND* branchcand, /**< branching candidate storage */
2375  SCIP_EVENTFILTER* eventfilter /**< event filter for global (not variable dependent) events */
2376  )
2377 {
2378  SCIP_EVENT* event;
2379  int i;
2380 
2381  assert(eventqueue != NULL);
2382  assert(eventqueue->delayevents);
2383 
2384  SCIPsetDebugMsg(set, "processing %d queued events\n", eventqueue->nevents);
2385 
2386  /* pass events to the responsible event filters
2387  * During event processing, new events may be raised. We have to loop to the mutable eventqueue->nevents.
2388  * A loop to something like "nevents = eventqueue->nevents; for(...; i < nevents; ...)" would miss the
2389  * newly created events. The same holds for eventqueue->events, which can be moved in memory due to
2390  * memory reallocation in eventqueueAppend().
2391  */
2392  for( i = 0; i < eventqueue->nevents; ++i )
2393  {
2394  event = eventqueue->events[i];
2395  assert(event != NULL);
2396 
2397  SCIPsetDebugMsg(set, "processing event %d of %d events in queue: eventtype=0x%" SCIP_EVENTTYPE_FORMAT "\n", i, eventqueue->nevents, event->eventtype);
2398 
2399  /* unmark the event queue index of a variable with changed objective value or bounds, and unmark the event queue
2400  * member flag of a variable with added implication
2401  */
2402  if( (event->eventtype & SCIP_EVENTTYPE_OBJCHANGED) != 0 )
2403  {
2404  assert(event->data.eventobjchg.var->eventqueueindexobj == i);
2405  event->data.eventobjchg.var->eventqueueindexobj = -1;
2406  }
2407  else if( (event->eventtype & SCIP_EVENTTYPE_LBCHANGED) != 0 )
2408  {
2409  assert(event->data.eventbdchg.var->eventqueueindexlb == i);
2410  event->data.eventbdchg.var->eventqueueindexlb = -1;
2411  }
2412  else if( (event->eventtype & SCIP_EVENTTYPE_UBCHANGED) != 0 )
2413  {
2414  assert(event->data.eventbdchg.var->eventqueueindexub == i);
2415  event->data.eventbdchg.var->eventqueueindexub = -1;
2416  }
2417  else if( (event->eventtype & SCIP_EVENTTYPE_IMPLADDED) != 0 )
2418  {
2419  assert(event->data.eventimpladd.var->eventqueueimpl);
2420  event->data.eventimpladd.var->eventqueueimpl = FALSE;
2421  }
2422 
2423  /* process event */
2424  SCIP_CALL( SCIPeventProcess(event, set, primal, lp, branchcand, eventfilter) );
2425 
2426  /* free the event immediately, because additionally raised events during event processing
2427  * can lead to a large event queue
2428  */
2429  SCIP_CALL( SCIPeventFree(&eventqueue->events[i], blkmem) );
2430  }
2431 
2432  assert(i == eventqueue->nevents);
2433  eventqueue->nevents = 0;
2434  eventqueue->delayevents = FALSE;
2435 
2436  return SCIP_OKAY;
2437 }
2438 
2439 /** returns TRUE iff events of the queue are delayed until the next SCIPeventqueueProcess() call */
2441  SCIP_EVENTQUEUE* eventqueue /**< event queue */
2442  )
2443 {
2444  assert(eventqueue != NULL);
2445 
2446  return eventqueue->delayevents;
2447 }
SCIP_Real SCIPeventGetRowNewSideVal(SCIP_EVENT *event)
Definition: event.c:1443
SCIP_RETCODE SCIPeventfilterCreate(SCIP_EVENTFILTER **eventfilter, BMS_BLKMEM *blkmem)
Definition: event.c:1698
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:84
#define BMSfreeBlockMemoryArrayNull(mem, ptr, num)
Definition: memory.h:449
SCIP_RETCODE SCIPeventCreateRowAddedLP(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_ROW *row)
Definition: event.c:823
internal methods for managing events
#define SCIP_EVENTTYPE_OBJCHANGED
Definition: type_event.h:60
#define SCIP_EVENTTYPE_LPEVENT
Definition: type_event.h:124
static int eventfilterSearch(SCIP_EVENTFILTER *const eventfilter, SCIP_EVENTTYPE const eventtype, SCIP_EVENTHDLR *const eventhdlr, SCIP_EVENTDATA *const eventdata)
Definition: event.c:1830
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 BMSfreeMemoryArrayNull(ptr)
Definition: memory.h:130
#define SCIP_EVENTTYPE_VARFIXED
Definition: type_event.h:58
static SCIP_RETCODE eventqueueEnsureEventsMem(SCIP_EVENTQUEUE *eventqueue, SCIP_SET *set, int num)
Definition: event.c:2038
void SCIPeventhdlrSetExitsol(SCIP_EVENTHDLR *eventhdlr, SCIP_DECL_EVENTEXITSOL((*eventexitsol)))
Definition: event.c:364
SCIP_EVENTVARUNLOCKED eventvarunlocked
Definition: struct_event.h:151
#define SCIP_EVENTTYPE_ROWADDEDLP
Definition: type_event.h:93
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:2368
SCIP_RETCODE SCIPeventCreateRowDeletedLP(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_ROW *row)
Definition: event.c:842
int eventqueueindexub
Definition: struct_var.h:253
SCIP_SIDETYPE SCIPeventGetRowSide(SCIP_EVENT *event)
Definition: event.c:1409
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:2117
static void eventDisable(SCIP_EVENT *event)
Definition: event.c:949
SCIP_RETCODE SCIPeventChgType(SCIP_EVENT *event, SCIP_EVENTTYPE eventtype)
Definition: event.c:969
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:766
SCIP_EVENTHDLR ** eventhdlrs
Definition: struct_event.h:173
SCIP_Real SCIPeventGetRowNewConstVal(SCIP_EVENT *event)
Definition: event.c:1392
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:1856
SCIP_RETCODE SCIPeventCreateSync(SCIP_EVENT **event, BMS_BLKMEM *blkmem)
Definition: event.c:437
SCIP_EVENTOBJCHG eventobjchg
Definition: struct_event.h:152
SCIP_RETCODE SCIPeventhdlrCopyInclude(SCIP_EVENTHDLR *eventhdlr, SCIP_SET *set)
Definition: event.c:45
SCIP_DECL_EVENTEXIT(EventhdlrNewSol::scip_exit)
struct SCIP_EventhdlrData SCIP_EVENTHDLRDATA
Definition: type_event.h:138
SCIP_RETCODE SCIPcolChgObj(SCIP_COL *col, SCIP_SET *set, SCIP_LP *lp, SCIP_Real newobj)
Definition: lp.c:3601
SCIP_RETCODE SCIPlpUpdateVarLb(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldlb, SCIP_Real newlb)
Definition: lp.c:13433
#define SCIP_EVENTTYPE_ROWSIDECHANGED
Definition: type_event.h:97
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:13405
#define FALSE
Definition: def.h:64
SCIP_RETCODE SCIPeventProcess(SCIP_EVENT *event, SCIP_SET *set, SCIP_PRIMAL *primal, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTFILTER *eventfilter)
Definition: event.c:1460
SCIP_RETCODE SCIPlpUpdateVarUbGlobal(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldub, SCIP_Real newub)
Definition: lp.c:13474
const char * SCIPeventhdlrGetName(SCIP_EVENTHDLR *eventhdlr)
Definition: event.c:278
static void eventfilterDelayUpdates(SCIP_EVENTFILTER *eventfilter)
Definition: event.c:1911
void SCIPclockStart(SCIP_CLOCK *clck, SCIP_SET *set)
Definition: clock.c:280
SCIP_ROW * SCIPeventGetRow(SCIP_EVENT *event)
Definition: event.c:1294
SCIP_RETCODE SCIPeventqueueDelay(SCIP_EVENTQUEUE *eventqueue)
Definition: event.c:2353
#define TRUE
Definition: def.h:63
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:53
SCIP_VAR * var
Definition: struct_event.h:90
#define SCIP_EVENTTYPE_NODEFOCUSED
Definition: type_event.h:77
SCIP_RETCODE SCIPeventCreateUbChanged(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_VAR *var, SCIP_Real oldbound, SCIP_Real newbound)
Definition: event.c:652
int SCIPvarGetProbindex(SCIP_VAR *var)
Definition: var.c:16969
internal methods for branching rules and branching candidate storage
int SCIPsetCalcMemGrowSize(SCIP_SET *set, int num)
Definition: set.c:5326
#define SCIP_EVENTTYPE_GLBCHANGED
Definition: type_event.h:61
SCIP_RETCODE SCIPeventqueueFree(SCIP_EVENTQUEUE **eventqueue)
Definition: event.c:2077
SCIP_RETCODE SCIPeventChgNode(SCIP_EVENT *event, SCIP_NODE *node)
Definition: event.c:1203
#define SCIPdebugMessage
Definition: pub_message.h:77
SCIP_RETCODE SCIPeventChgVar(SCIP_EVENT *event, SCIP_VAR *var)
Definition: event.c:1038
#define SCIP_EVENTTYPE_ROWDELETEDLP
Definition: type_event.h:94
void SCIPclockEnableOrDisable(SCIP_CLOCK *clck, SCIP_Bool enable)
Definition: clock.c:250
#define BMSfreeMemory(ptr)
Definition: memory.h:127
SCIP_Real SCIPeventGetRowOldSideVal(SCIP_EVENT *event)
Definition: event.c:1426
SCIP_RETCODE SCIPeventCreateLholeAdded(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_VAR *var, SCIP_Real left, SCIP_Real right)
Definition: event.c:722
#define SCIP_EVENTTYPE_BOUNDCHANGED
Definition: type_event.h:108
internal methods for LP management
SCIP_Bool delayupdates
Definition: struct_event.h:182
SCIP_DECL_EVENTINITSOL(EventhdlrNewSol::scip_initsol)
SCIP_RETCODE SCIPeventCreateObjChanged(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_VAR *var, SCIP_Real oldobj, SCIP_Real newobj)
Definition: event.c:557
internal methods for collecting primal CIP solutions and primal informations
#define SCIP_EVENTTYPE_LBCHANGED
Definition: type_event.h:104
#define SCIP_EVENTTYPE_NODEFEASIBLE
Definition: type_event.h:78
void SCIPeventhdlrSetData(SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTHDLRDATA *eventhdlrdata)
Definition: event.c:298
#define SCIP_EVENTTYPE_LBRELAXED
Definition: type_event.h:64
#define SCIP_EVENTTYPE_NODEBRANCHED
Definition: type_event.h:80
SCIP_Real newobj
Definition: struct_event.h:67
SCIP_DECL_EVENTINIT(EventhdlrNewSol::scip_init)
static SCIP_RETCODE eventfilterEnsureMem(SCIP_EVENTFILTER *eventfilter, BMS_BLKMEM *blkmem, SCIP_SET *set, int num)
Definition: event.c:1670
SCIP_RETCODE SCIPeventCreateVarFixed(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_VAR *var)
Definition: event.c:514
union SCIP_Var::@13 data
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:804
SCIP_DECL_EVENTFREE(EventhdlrNewSol::scip_free)
SCIP_Real SCIPeventGetHoleLeft(SCIP_EVENT *event)
Definition: event.c:1260
SCIP_RETCODE SCIPeventChgSol(SCIP_EVENT *event, SCIP_SOL *sol)
Definition: event.c:1240
SCIP_Real SCIPeventGetRowOldConstVal(SCIP_EVENT *event)
Definition: event.c:1375
SCIP_Real SCIPeventhdlrGetTime(SCIP_EVENTHDLR *eventhdlr)
Definition: event.c:420
SCIP_Real SCIPeventGetNewbound(SCIP_EVENT *event)
Definition: event.c:1162
void SCIPeventhdlrSetInitsol(SCIP_EVENTHDLR *eventhdlr, SCIP_DECL_EVENTINITSOL((*eventinitsol)))
Definition: event.c:353
#define SCIP_EVENTTYPE_ROWADDEDSEPA
Definition: type_event.h:91
SCIP_RETCODE SCIPlpUpdateVarUb(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldub, SCIP_Real newub)
Definition: lp.c:13501
#define SCIP_EVENTTYPE_SOLEVENT
Definition: type_event.h:128
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:1763
SCIP_Real SCIPeventGetOldobj(SCIP_EVENT *event)
Definition: event.c:1104
#define BMSfreeMemoryArray(ptr)
Definition: memory.h:129
#define SCIPerrorMessage
Definition: pub_message.h:45
#define SCIP_EVENTTYPE_LHOLEREMOVED
Definition: type_event.h:70
void SCIPclockReset(SCIP_CLOCK *clck)
Definition: clock.c:199
SCIP_Bool SCIPeventhdlrIsInitialized(SCIP_EVENTHDLR *eventhdlr)
Definition: event.c:386
SCIP_RETCODE SCIPeventqueueCreate(SCIP_EVENTQUEUE **eventqueue)
Definition: event.c:2061
SCIP_NODE * SCIPeventGetNode(SCIP_EVENT *event)
Definition: event.c:1186
SCIP_RETCODE SCIPeventCreateVarAdded(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_VAR *var)
Definition: event.c:478
SCIP_EVENTTYPE eventmask
Definition: struct_event.h:180
#define SCIP_EVENTTYPE_GHOLEREMOVED
Definition: type_event.h:68
void SCIPeventhdlrEnableOrDisableClocks(SCIP_EVENTHDLR *eventhdlr, SCIP_Bool enable)
Definition: event.c:396
#define SCIP_EVENTTYPE_IMPLADDED
Definition: type_event.h:71
#define SCIP_EVENTTYPE_ROWCONSTCHANGED
Definition: type_event.h:96
SCIP_Bool initialized
Definition: struct_event.h:201
struct SCIP_EventData SCIP_EVENTDATA
Definition: type_event.h:155
void SCIPeventhdlrSetExit(SCIP_EVENTHDLR *eventhdlr, SCIP_DECL_EVENTEXIT((*eventexit)))
Definition: event.c:342
SCIP_Real SCIPeventhdlrGetSetupTime(SCIP_EVENTHDLR *eventhdlr)
Definition: event.c:408
const char * SCIPvarGetName(SCIP_VAR *var)
Definition: var.c:16662
SCIP_EVENTVARADDED eventvaradded
Definition: struct_event.h:148
SCIP_Real SCIPclockGetTime(SCIP_CLOCK *clck)
Definition: clock.c:428
SCIP_Real SCIPeventGetNewobj(SCIP_EVENT *event)
Definition: event.c:1121
SCIP_RETCODE SCIPeventCreateLbChanged(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_VAR *var, SCIP_Real oldbound, SCIP_Real newbound)
Definition: event.c:626
#define SCIP_EVENTTYPE_UBRELAXED
Definition: type_event.h:66
SCIP_EVENTTYPE eventtype
Definition: struct_event.h:166
SCIP_RETCODE SCIPeventCreateLholeRemoved(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_VAR *var, SCIP_Real left, SCIP_Real right)
Definition: event.c:744
internal methods for global SCIP settings
#define SCIP_CALL(x)
Definition: def.h:350
#define SCIP_EVENTTYPE_LBTIGHTENED
Definition: type_event.h:63
SCIP_RETCODE SCIPeventhdlrInitsol(SCIP_EVENTHDLR *eventhdlr, SCIP_SET *set)
Definition: event.c:200
int eventqueueindexlb
Definition: struct_var.h:252
SCIP_COL * SCIPeventGetRowCol(SCIP_EVENT *event)
Definition: event.c:1324
#define SCIP_EVENTTYPE_LHOLEADDED
Definition: type_event.h:69
SCIP_Bool SCIPsetIsEQ(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:5798
SCIP_EVENTIMPLADD eventimpladd
Definition: struct_event.h:155
#define BMSduplicateMemoryArray(ptr, source, num)
Definition: memory.h:125
SCIP_Real newbound
Definition: struct_event.h:75
#define SCIP_EVENTTYPE_UBCHANGED
Definition: type_event.h:105
SCIP_RETCODE SCIPclockCreate(SCIP_CLOCK **clck, SCIP_CLOCKTYPE clocktype)
Definition: clock.c:160
SCIP_VAR * var
Definition: struct_event.h:76
#define BMSfreeBlockMemory(mem, ptr)
Definition: memory.h:446
internal methods for problem variables
SCIP_VAR * SCIPeventGetVar(SCIP_EVENT *event)
Definition: event.c:982
SCIP_Real SCIPeventGetRowNewCoefVal(SCIP_EVENT *event)
Definition: event.c:1358
#define SCIP_Bool
Definition: def.h:61
#define SCIP_EVENTTYPE_NODEEVENT
Definition: type_event.h:121
SCIP_EVENTTYPE SCIPeventGetType(SCIP_EVENT *event)
Definition: event.c:959
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:1668
SCIP_EVENTHDLRDATA * eventhdlrdata
Definition: struct_event.h:198
SCIP_Real oldobj
Definition: struct_event.h:66
#define SCIP_EVENTTYPE_ROWCOEFCHANGED
Definition: type_event.h:95
SCIP_RETCODE SCIPeventCreateRowSideChanged(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_ROW *row, SCIP_SIDETYPE side, SCIP_Real oldval, SCIP_Real newval)
Definition: event.c:909
SCIP_RETCODE SCIPeventCreateGholeRemoved(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_VAR *var, SCIP_Real left, SCIP_Real right)
Definition: event.c:700
SCIP_Bool divingobjchg
Definition: struct_lp.h:362
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:580
SCIP_RETCODE SCIPcolChgLb(SCIP_COL *col, SCIP_SET *set, SCIP_LP *lp, SCIP_Real newlb)
Definition: lp.c:3660
static void eventfilterProcessUpdates(SCIP_EVENTFILTER *eventfilter)
Definition: event.c:1924
#define SCIPsetDebugMsg
Definition: set.h:1913
SCIP_RETCODE SCIPeventCreateVarDeleted(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_VAR *var)
Definition: event.c:496
#define SCIP_EVENTTYPE_NODEINFEASIBLE
Definition: type_event.h:79
#define SCIP_EVENTTYPE_ROWDELETEDSEPA
Definition: type_event.h:92
SCIP_EVENT ** events
Definition: struct_event.h:207
#define SCIP_EVENTTYPE_HOLECHANGED
Definition: type_event.h:111
#define SCIP_EVENTTYPE_GHOLEADDED
Definition: type_event.h:67
SCIP_Bool delayevents
Definition: struct_event.h:210
SCIP_COL * SCIPvarGetCol(SCIP_VAR *var)
Definition: var.c:16990
SCIP_RETCODE SCIPbranchcandUpdateVar(SCIP_BRANCHCAND *branchcand, SCIP_SET *set, SCIP_VAR *var)
Definition: branch.c:1137
#define SCIP_EVENTTYPE_UBTIGHTENED
Definition: type_event.h:65
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:83
SCIP_RETCODE SCIPeventFree(SCIP_EVENT **event, BMS_BLKMEM *blkmem)
Definition: event.c:934
static SCIP_RETCODE eventqueueAppend(SCIP_EVENTQUEUE *eventqueue, SCIP_SET *set, SCIP_EVENT **event)
Definition: event.c:2093
SCIP_RETCODE SCIPcolChgUb(SCIP_COL *col, SCIP_SET *set, SCIP_LP *lp, SCIP_Real newub)
Definition: lp.c:3705
SCIP_EVENTFILTER * eventfilter
Definition: struct_var.h:241
SCIP_Real SCIPeventGetRowOldCoefVal(SCIP_EVENT *event)
Definition: event.c:1341
SCIP_RETCODE SCIPeventCreateRowCoefChanged(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_ROW *row, SCIP_COL *col, SCIP_Real oldval, SCIP_Real newval)
Definition: event.c:861
SCIP_EVENTDATA ** eventdata
Definition: struct_event.h:174
#define SCIP_EVENTTYPE_DISABLED
Definition: type_event.h:53
SCIP_EVENTBDCHG eventbdchg
Definition: struct_event.h:153
SCIP_VAR * var
Definition: struct_event.h:68
#define SCIP_EVENTTYPE_BESTSOLFOUND
Definition: type_event.h:88
SCIP_EVENTHOLE eventhole
Definition: struct_event.h:154
#define SCIP_EVENTTYPE_POORSOLFOUND
Definition: type_event.h:87
union SCIP_Event::@8 data
SCIP_RETCODE SCIPeventfilterFree(SCIP_EVENTFILTER **eventfilter, BMS_BLKMEM *blkmem, SCIP_SET *set)
Definition: event.c:1723
#define SCIP_EVENTTYPE_FORMAT
Definition: type_event.h:135
SCIP_RETCODE SCIPlpUpdateVarObj(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldobj, SCIP_Real newobj)
Definition: lp.c:13351
SCIP_VAR * var
Definition: struct_event.h:84
SCIP_RETCODE SCIPeventfilterProcess(SCIP_EVENTFILTER *eventfilter, SCIP_SET *set, SCIP_EVENT *event)
Definition: event.c:1959
int eventqueueindexobj
Definition: struct_var.h:251
SCIP_Real oldbound
Definition: struct_event.h:74
public methods for message output
SCIP_RETCODE SCIPeventhdlrExitsol(SCIP_EVENTHDLR *eventhdlr, SCIP_SET *set)
Definition: event.c:224
SCIP_Real SCIPeventGetOldbound(SCIP_EVENT *event)
Definition: event.c:1138
SCIP_DECL_EVENTEXEC(EventhdlrNewSol::scip_exec)
SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
Definition: var.c:16781
SCIP_Real SCIPeventGetHoleRight(SCIP_EVENT *event)
Definition: event.c:1277
#define SCIP_Real
Definition: def.h:149
#define SCIP_EVENTTYPE_VARUNLOCKED
Definition: type_event.h:59
SCIP_DECL_EVENTEXITSOL(EventhdlrNewSol::scip_exitsol)
unsigned int eventqueueimpl
Definition: struct_var.h:277
#define SCIP_DECL_EVENTCOPY(x)
Definition: type_event.h:165
SCIP_CLOCK * eventtime
Definition: struct_event.h:200
#define BMSallocMemory(ptr)
Definition: memory.h:101
#define SCIP_INVALID
Definition: def.h:169
#define BMSreallocMemoryArray(ptr, num)
Definition: memory.h:109
SCIP_RETCODE SCIPeventCreateGholeAdded(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_VAR *var, SCIP_Real left, SCIP_Real right)
Definition: event.c:678
SCIP_RETCODE SCIPeventCreateVarUnlocked(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_VAR *var)
Definition: event.c:536
SCIP_CLOCK * setuptime
Definition: struct_event.h:199
SCIP_EVENTTYPE delayedeventmask
Definition: struct_event.h:181
SCIP_EVENTTYPE * eventtypes
Definition: struct_event.h:172
SCIP_EVENTVARDELETED eventvardeleted
Definition: struct_event.h:149
SCIP_EVENTVARFIXED eventvarfixed
Definition: struct_event.h:150
SCIP_DECL_EVENTDELETE(EventhdlrNewSol::scip_delete)
#define BMSallocBlockMemory(mem, ptr)
Definition: memory.h:433
void SCIPeventhdlrSetDelete(SCIP_EVENTHDLR *eventhdlr, SCIP_DECL_EVENTDELETE((*eventdelete)))
Definition: event.c:375
SCIP_Bool SCIPeventqueueIsDelayed(SCIP_EVENTQUEUE *eventqueue)
Definition: event.c:2440
common defines and data types used in all packages of SCIP
struct BMS_BlkMem BMS_BLKMEM
Definition: memory.h:419
#define SCIP_EVENTTYPE_GUBCHANGED
Definition: type_event.h:62
SCIP_EVENTHDLRDATA * SCIPeventhdlrGetData(SCIP_EVENTHDLR *eventhdlr)
Definition: event.c:288
#define SCIP_EVENTTYPE_SYNC
Definition: type_event.h:100
#define SCIP_ALLOC(x)
Definition: def.h:361
#define SCIPABORT()
Definition: def.h:322
#define SCIP_EVENTTYPE_PRESOLVEROUND
Definition: type_event.h:74
SCIP_RETCODE SCIPeventCreateGubChanged(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_VAR *var, SCIP_Real oldbound, SCIP_Real newbound)
Definition: event.c:603
#define SCIP_EVENTTYPE_VARADDED
Definition: type_event.h:56
SCIP_SOL * SCIPeventGetSol(SCIP_EVENT *event)
Definition: event.c:1223
#define BMSreallocBlockMemoryArray(mem, ptr, oldnum, newnum)
Definition: memory.h:439
#define SCIP_EVENTTYPE_VARDELETED
Definition: type_event.h:57
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:785
SCIP_RETCODE SCIPeventCreateRowConstChanged(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_ROW *row, SCIP_Real oldval, SCIP_Real newval)
Definition: event.c:886
uint64_t SCIP_EVENTTYPE
Definition: type_event.h:134
enum SCIP_SideType SCIP_SIDETYPE
Definition: type_lp.h:58