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-2017 Konrad-Zuse-Zentrum */
7 /* fuer Informationstechnik Berlin */
8 /* */
9 /* SCIP is distributed under the terms of the ZIB Academic License. */
10 /* */
11 /* You should have received a copy of the ZIB Academic License */
12 /* along with SCIP; see the file COPYING. If not email to scip@zib.de. */
13 /* */
14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15 
16 /**@file event.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 */
1545  SCIPprimalUpdateVarObj(primal, var, event->data.eventobjchg.oldobj, event->data.eventobjchg.newobj);
1546 
1547  /* process variable's event filter */
1548  SCIP_CALL( SCIPeventfilterProcess(var->eventfilter, set, event) );
1549  break;
1550 
1552  var = event->data.eventbdchg.var;
1553  assert(var != NULL);
1554 
1555  /* inform LP about global bound change */
1557  {
1558  assert(SCIPvarGetProbindex(var) >= 0);
1560  event->data.eventbdchg.newbound) );
1561  }
1562 
1563  /* process variable's event filter */
1564  SCIP_CALL( SCIPeventfilterProcess(var->eventfilter, set, event) );
1565  break;
1566 
1568  var = event->data.eventbdchg.var;
1569  assert(var != NULL);
1570 
1571  /* inform LP about global bound change */
1573  {
1574  assert(SCIPvarGetProbindex(var) >= 0);
1576  event->data.eventbdchg.newbound) );
1577  }
1578 
1579  /* process variable's event filter */
1580  SCIP_CALL( SCIPeventfilterProcess(var->eventfilter, set, event) );
1581  break;
1582 
1585  var = event->data.eventbdchg.var;
1586  assert(var != NULL);
1587  assert(var->eventqueueindexlb == -1);
1588 
1589  /* inform LP about bound change and update branching candidates */
1591  {
1592  assert(SCIPvarGetProbindex(var) >= 0);
1594  {
1595  SCIP_CALL( SCIPcolChgLb(SCIPvarGetCol(var), set, lp, event->data.eventbdchg.newbound) );
1596  }
1597  SCIP_CALL( SCIPlpUpdateVarLb(lp, set, var, event->data.eventbdchg.oldbound,
1598  event->data.eventbdchg.newbound) );
1599  SCIP_CALL( SCIPbranchcandUpdateVar(branchcand, set, var) );
1600  }
1601 
1602  /* process variable's event filter */
1603  SCIP_CALL( SCIPeventfilterProcess(var->eventfilter, set, event) );
1604  break;
1605 
1608  var = event->data.eventbdchg.var;
1609  assert(var != NULL);
1610  assert(var->eventqueueindexub == -1);
1611 
1612  /* inform LP about bound change and update branching candidates */
1614  {
1615  assert(SCIPvarGetProbindex(var) >= 0);
1617  {
1618  SCIP_CALL( SCIPcolChgUb(SCIPvarGetCol(var), set, lp, event->data.eventbdchg.newbound) );
1619  }
1620  SCIP_CALL( SCIPlpUpdateVarUb(lp, set, var, event->data.eventbdchg.oldbound,
1621  event->data.eventbdchg.newbound) );
1622  SCIP_CALL( SCIPbranchcandUpdateVar(branchcand, set, var) );
1623  }
1624 
1625  /* process variable's event filter */
1626  SCIP_CALL( SCIPeventfilterProcess(var->eventfilter, set, event) );
1627  break;
1628 
1633  var = event->data.eventhole.var;
1634  assert(var != NULL);
1635 
1636  /* process variable's event filter */
1637  SCIP_CALL( SCIPeventfilterProcess(var->eventfilter, set, event) );
1638  break;
1639 
1641  var = event->data.eventimpladd.var;
1642  assert(var != NULL);
1643  assert(!var->eventqueueimpl);
1644 
1645  /* process variable's event filter */
1646  SCIP_CALL( SCIPeventfilterProcess(var->eventfilter, set, event) );
1647  break;
1648 
1649  default:
1650  SCIPerrorMessage("unknown event type <%d>\n", event->eventtype);
1651  return SCIP_INVALIDDATA;
1652  }
1653 
1654  return SCIP_OKAY;
1655 }
1656 
1657 
1658 
1659 /*
1660  * Event filter methods
1661  */
1662 
1663 /** resizes eventfilter arrays to be able to store at least num entries */
1664 static
1666  SCIP_EVENTFILTER* eventfilter, /**< event filter */
1667  BMS_BLKMEM* blkmem, /**< block memory buffer */
1668  SCIP_SET* set, /**< global SCIP settings */
1669  int num /**< minimal number of node slots in array */
1670  )
1671 {
1672  assert(eventfilter != NULL);
1673  assert(blkmem != NULL);
1674  assert(set != NULL);
1675 
1676  if( num > eventfilter->size )
1677  {
1678  int newsize;
1679 
1680  newsize = SCIPsetCalcMemGrowSize(set, num);
1681  SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &eventfilter->eventtypes, eventfilter->size, newsize) );
1682  SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &eventfilter->eventhdlrs, eventfilter->size, newsize) );
1683  SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &eventfilter->eventdata, eventfilter->size, newsize) );
1684  SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &eventfilter->nextpos, eventfilter->size, newsize) );
1685  eventfilter->size = newsize;
1686  }
1687  assert(num <= eventfilter->size);
1688 
1689  return SCIP_OKAY;
1690 }
1691 
1692 /** creates an event filter */
1694  SCIP_EVENTFILTER** eventfilter, /**< pointer to store the event filter */
1695  BMS_BLKMEM* blkmem /**< block memory buffer */
1696  )
1697 {
1698  assert(eventfilter != NULL);
1699  assert(blkmem != NULL);
1700 
1701  SCIP_ALLOC( BMSallocBlockMemory(blkmem, eventfilter) );
1702  (*eventfilter)->eventtypes = NULL;
1703  (*eventfilter)->eventhdlrs = NULL;
1704  (*eventfilter)->eventdata = NULL;
1705  (*eventfilter)->nextpos = NULL;
1706  (*eventfilter)->size = 0;
1707  (*eventfilter)->len = 0;
1708  (*eventfilter)->firstfreepos = -1;
1709  (*eventfilter)->firstdeletedpos = -1;
1710  (*eventfilter)->eventmask = SCIP_EVENTTYPE_DISABLED;
1711  (*eventfilter)->delayedeventmask = SCIP_EVENTTYPE_DISABLED;
1712  (*eventfilter)->delayupdates = FALSE;
1713 
1714  return SCIP_OKAY;
1715 }
1716 
1717 /** frees an event filter and the associated event data entries */
1719  SCIP_EVENTFILTER** eventfilter, /**< pointer to store the event filter */
1720  BMS_BLKMEM* blkmem, /**< block memory buffer */
1721  SCIP_SET* set /**< global SCIP settings */
1722  )
1723 {
1724  int i;
1725 
1726  assert(eventfilter != NULL);
1727  assert(*eventfilter != NULL);
1728  assert(!(*eventfilter)->delayupdates);
1729  assert(blkmem != NULL);
1730  assert(set != NULL);
1731  assert(set->scip != NULL);
1732 
1733  /* free event data */
1734  for( i = 0; i < (*eventfilter)->len; ++i )
1735  {
1736  if( (*eventfilter)->eventtypes[i] != SCIP_EVENTTYPE_DISABLED )
1737  {
1738  assert((*eventfilter)->eventhdlrs[i] != NULL);
1739  if( (*eventfilter)->eventhdlrs[i]->eventdelete != NULL )
1740  {
1741  SCIP_CALL( (*eventfilter)->eventhdlrs[i]->eventdelete(set->scip, (*eventfilter)->eventhdlrs[i],
1742  &(*eventfilter)->eventdata[i]) );
1743  }
1744  }
1745  }
1746 
1747  /* free event filter data */
1748  BMSfreeBlockMemoryArrayNull(blkmem, &(*eventfilter)->eventtypes, (*eventfilter)->size);
1749  BMSfreeBlockMemoryArrayNull(blkmem, &(*eventfilter)->eventhdlrs, (*eventfilter)->size);
1750  BMSfreeBlockMemoryArrayNull(blkmem, &(*eventfilter)->eventdata, (*eventfilter)->size);
1751  BMSfreeBlockMemoryArrayNull(blkmem, &(*eventfilter)->nextpos, (*eventfilter)->size);
1752  BMSfreeBlockMemory(blkmem, eventfilter);
1753 
1754  return SCIP_OKAY;
1755 }
1756 
1757 /** adds element to event filter */
1759  SCIP_EVENTFILTER* eventfilter, /**< event filter */
1760  BMS_BLKMEM* blkmem, /**< block memory buffer */
1761  SCIP_SET* set, /**< global SCIP settings */
1762  SCIP_EVENTTYPE eventtype, /**< event type to catch */
1763  SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
1764  SCIP_EVENTDATA* eventdata, /**< event data to pass to the event handler for the event processing */
1765  int* filterpos /**< pointer to store position of event filter entry, or NULL */
1766  )
1767 {
1768  int pos;
1769 
1770  assert(eventfilter != NULL);
1771  assert(blkmem != NULL);
1772  assert(set != NULL);
1773  assert(eventhdlr != NULL);
1774 
1775  if( eventfilter->delayupdates )
1776  {
1777  /* insert addition to the end of the arrays;
1778  * in delayed addition we have to add to the end of the arrays, in order to not destroy the validity of the
1779  * arrays we are currently iterating over
1780  */
1781  SCIP_CALL( eventfilterEnsureMem(eventfilter, blkmem, set, eventfilter->len + 1) );
1782  pos = eventfilter->len;
1783  eventfilter->len++;
1784 
1785  /* update delayed event filter mask */
1786  eventfilter->delayedeventmask |= eventtype;
1787  }
1788  else
1789  {
1790  if( eventfilter->firstfreepos == -1 )
1791  {
1792  /* insert addition to the end of the arrays */
1793  SCIP_CALL( eventfilterEnsureMem(eventfilter, blkmem, set, eventfilter->len + 1) );
1794  pos = eventfilter->len;
1795  eventfilter->len++;
1796  }
1797  else
1798  {
1799  /* use the first free slot to store the added event filter entry */
1800  pos = eventfilter->firstfreepos;
1801  assert(0 <= pos && pos < eventfilter->len);
1802  assert(eventfilter->eventtypes[pos] == SCIP_EVENTTYPE_DISABLED);
1803  eventfilter->firstfreepos = eventfilter->nextpos[pos];
1804  assert(-1 <= eventfilter->firstfreepos && eventfilter->firstfreepos < eventfilter->len);
1805  }
1806 
1807  /* update event filter mask */
1808  eventfilter->eventmask |= eventtype;
1809  }
1810  assert(0 <= pos && pos < eventfilter->len);
1811 
1812  eventfilter->eventtypes[pos] = eventtype;
1813  eventfilter->eventhdlrs[pos] = eventhdlr;
1814  eventfilter->eventdata[pos] = eventdata;
1815  eventfilter->nextpos[pos] = -2;
1816 
1817  if( filterpos != NULL )
1818  *filterpos = pos;
1819 
1820  return SCIP_OKAY;
1821 }
1822 
1823 /** linear search for the given entry in event filter */
1824 static
1826  SCIP_EVENTFILTER*const eventfilter, /**< event filter */
1827  SCIP_EVENTTYPE const eventtype, /**< event type */
1828  SCIP_EVENTHDLR*const eventhdlr, /**< event handler to call for the event processing */
1829  SCIP_EVENTDATA*const eventdata /**< event data to pass to the event handler for the event processing */
1830  )
1831 {
1832  int i;
1833 
1834  assert(eventfilter != NULL);
1835  assert(eventtype != SCIP_EVENTTYPE_DISABLED);
1836  assert(eventhdlr != NULL);
1837 
1838  for( i = eventfilter->len - 1; i >= 0; --i )
1839  {
1840  if( eventdata == eventfilter->eventdata[i]
1841  && eventhdlr == eventfilter->eventhdlrs[i]
1842  && eventtype == eventfilter->eventtypes[i]
1843  && eventfilter->nextpos[i] == -2 )
1844  return i;
1845  }
1846 
1847  return -1;
1848 }
1849 
1850 /** deletes element from event filter */
1852  SCIP_EVENTFILTER* eventfilter, /**< event filter */
1853  BMS_BLKMEM* blkmem, /**< block memory buffer */
1854  SCIP_SET* set, /**< global SCIP settings */
1855  SCIP_EVENTTYPE eventtype, /**< event type */
1856  SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
1857  SCIP_EVENTDATA* eventdata, /**< event data to pass to the event handler for the event processing */
1858  int filterpos /**< position of event filter entry, or -1 if unknown */
1859  )
1860 {
1861  assert(eventfilter != NULL);
1862  assert(blkmem != NULL);
1863  assert(set != NULL);
1864  assert(eventtype != SCIP_EVENTTYPE_DISABLED);
1865  assert(eventhdlr != NULL);
1866  assert(-1 <= filterpos && filterpos < eventfilter->len);
1867 
1868  /* search position of event filter entry, if not given by the user */
1869  if( filterpos == -1 )
1870  filterpos = eventfilterSearch(eventfilter, eventtype, eventhdlr, eventdata);
1871  if( filterpos == -1 )
1872  {
1873  SCIPerrorMessage("no event for event handler %p with data %p and event mask 0x%x found in event filter %p\n",
1874  eventhdlr, eventdata, eventtype, eventfilter);
1875  return SCIP_INVALIDDATA;
1876  }
1877  assert(0 <= filterpos && filterpos < eventfilter->len);
1878  assert(eventfilter->eventtypes[filterpos] == eventtype);
1879  assert(eventfilter->eventhdlrs[filterpos] == eventhdlr);
1880  assert(eventfilter->eventdata[filterpos] == eventdata);
1881  assert(eventfilter->nextpos[filterpos] == -2);
1882 
1883  /* if updates are delayed, insert entry into the list of delayed deletions;
1884  * otherwise, delete the entry from the filter directly and add the slot to the free list
1885  */
1886  if( eventfilter->delayupdates )
1887  {
1888  /* append filterpos to the list of deleted entries */
1889  eventfilter->nextpos[filterpos] = eventfilter->firstdeletedpos;
1890  eventfilter->firstdeletedpos = filterpos;
1891  }
1892  else
1893  {
1894  /* disable the entry in the filter and add the slot to the free list */
1895  assert(eventfilter->nextpos[filterpos] == -2);
1896  eventfilter->eventtypes[filterpos] = SCIP_EVENTTYPE_DISABLED;
1897  eventfilter->nextpos[filterpos] = eventfilter->firstfreepos;
1898  eventfilter->firstfreepos = filterpos;
1899  }
1900 
1901  return SCIP_OKAY;
1902 }
1903 
1904 /** makes the event filter to delay and buffer all updates until eventfilterProcessUpdates() is called */
1905 static
1907  SCIP_EVENTFILTER* eventfilter /**< event filter */
1908  )
1909 {
1910  assert(eventfilter != NULL);
1911  assert(!eventfilter->delayupdates);
1912  assert(eventfilter->delayedeventmask == SCIP_EVENTTYPE_DISABLED);
1913 
1914  eventfilter->delayupdates = TRUE;
1915 }
1916 
1917 /** processes all delayed additions and deletions */
1918 static
1920  SCIP_EVENTFILTER* eventfilter /**< event filter */
1921  )
1922 {
1923  int pos;
1924  int nextpos;
1925 
1926  assert(eventfilter != NULL);
1927  assert(eventfilter->delayupdates);
1928 
1929  /* move deleted entries into the free list and disable them */
1930  pos = eventfilter->firstdeletedpos;
1931  while( pos != -1 )
1932  {
1933  assert(0 <= pos && pos < eventfilter->len);
1934  assert(eventfilter->eventtypes[pos] != SCIP_EVENTTYPE_DISABLED);
1935  assert(eventfilter->nextpos[pos] >= -1);
1936 
1937  nextpos = eventfilter->nextpos[pos];
1938  eventfilter->nextpos[pos] = eventfilter->firstfreepos;
1939  eventfilter->firstfreepos = pos;
1940  eventfilter->eventtypes[pos] = SCIP_EVENTTYPE_DISABLED;
1941  pos = nextpos;
1942  }
1943  eventfilter->firstdeletedpos = -1;
1944 
1945  /* update event mask */
1946  eventfilter->eventmask |= eventfilter->delayedeventmask;
1948 
1949  /* mark the event filter updates to be no longer delayed */
1950  eventfilter->delayupdates = FALSE;
1951 }
1952 
1953 /** processes the event with all event handlers with matching filter setting */
1955  SCIP_EVENTFILTER* eventfilter, /**< event filter */
1956  SCIP_SET* set, /**< global SCIP settings */
1957  SCIP_EVENT* event /**< event to process */
1958  )
1959 {
1960  SCIP_EVENTTYPE eventtype;
1961  SCIP_EVENTTYPE* eventtypes;
1962  SCIP_Bool processed;
1963  int len;
1964  int i;
1965 
1966  assert(eventfilter != NULL);
1967  assert(set != NULL);
1968  assert(event != NULL);
1969 
1970  SCIPsetDebugMsg(set, "processing event filter %p (len %d, mask 0x%" SCIP_EVENTTYPE_FORMAT ") with event type 0x%" SCIP_EVENTTYPE_FORMAT "\n",
1971  (void*)eventfilter, eventfilter->len, eventfilter->eventmask, event->eventtype);
1972 
1973  eventtype = event->eventtype;
1974 
1975  /* check, if there may be any event handler for specific event */
1976  if( (eventtype & eventfilter->eventmask) == 0 )
1977  return SCIP_OKAY;
1978 
1979  /* delay the updates on this eventfilter, such that changes during event processing to the event filter
1980  * don't destroy necessary information of the arrays we are currently using
1981  */
1982  eventfilterDelayUpdates(eventfilter);
1983 
1984  /* process the event by calling the event handlers */
1985  processed = FALSE;
1986  len = eventfilter->len;
1987  eventtypes = eventfilter->eventtypes;
1988  for( i = 0; i < len; ++i )
1989  {
1990  /* check, if event is applicable for the filter element */
1991  if( (eventtype & eventtypes[i]) != 0 )
1992  {
1993  /* call event handler */
1994  SCIP_CALL( SCIPeventhdlrExec(eventfilter->eventhdlrs[i], set, event, eventfilter->eventdata[i]) );
1995  processed = TRUE;
1996  }
1997  }
1998 
1999  /* update eventfilter mask, if event was not processed by any event handler */
2000  if( !processed )
2001  {
2002  eventfilter->eventmask &= ~event->eventtype;
2003  SCIPsetDebugMsg(set, " -> event type 0x%" SCIP_EVENTTYPE_FORMAT " not processed. new mask of event filter %p: 0x%" SCIP_EVENTTYPE_FORMAT "\n",
2004  event->eventtype, (void*)eventfilter, eventfilter->eventmask);
2005  }
2006 
2007  /* process delayed events on this eventfilter */
2008  eventfilterProcessUpdates(eventfilter);
2009 
2010  return SCIP_OKAY;
2011 }
2012 
2013 
2014 
2015 /*
2016  * Event queue methods
2017  */
2018 
2019 /*
2020  * simple functions implemented as defines
2021  */
2022 
2023 /* In debug mode, the following methods are implemented as function calls to ensure
2024  * type validity.
2025  * In optimized mode, the methods are implemented as defines to improve performance.
2026  * However, we want to have them in the library anyways, so we have to undef the defines.
2027  */
2028 
2029 #undef SCIPeventqueueIsDelayed
2030 
2031 /** resizes events array to be able to store at least num entries */
2032 static
2034  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
2035  SCIP_SET* set, /**< global SCIP settings */
2036  int num /**< minimal number of node slots in array */
2037  )
2038 {
2039  assert(eventqueue != NULL);
2040  assert(set != NULL);
2041 
2042  if( num > eventqueue->eventssize )
2043  {
2044  int newsize;
2045 
2046  newsize = SCIPsetCalcMemGrowSize(set, num);
2047  SCIP_ALLOC( BMSreallocMemoryArray(&eventqueue->events, newsize) );
2048  eventqueue->eventssize = newsize;
2049  }
2050  assert(num <= eventqueue->eventssize);
2051 
2052  return SCIP_OKAY;
2053 }
2054 
2055 /** creates an event queue */
2057  SCIP_EVENTQUEUE** eventqueue /**< pointer to store the event queue */
2058  )
2059 {
2060  assert(eventqueue != NULL);
2061 
2062  SCIP_ALLOC( BMSallocMemory(eventqueue) );
2063  (*eventqueue)->events = NULL;
2064  (*eventqueue)->eventssize = 0;
2065  (*eventqueue)->nevents = 0;
2066  (*eventqueue)->delayevents = FALSE;
2067 
2068  return SCIP_OKAY;
2069 }
2070 
2071 /** frees event queue; there must not be any unprocessed events in the queue! */
2073  SCIP_EVENTQUEUE** eventqueue /**< pointer to the event queue */
2074  )
2075 {
2076  assert(eventqueue != NULL);
2077  assert(*eventqueue != NULL);
2078  assert((*eventqueue)->nevents == 0);
2079 
2080  BMSfreeMemoryArrayNull(&(*eventqueue)->events);
2081  BMSfreeMemory(eventqueue);
2082 
2083  return SCIP_OKAY;
2084 }
2085 
2086 /** appends event to the event queue; sets event to NULL afterwards */
2087 static
2089  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
2090  SCIP_SET* set, /**< global SCIP settings */
2091  SCIP_EVENT** event /**< pointer to event to append to the queue */
2092  )
2093 {
2094  assert(eventqueue != NULL);
2095  assert(eventqueue->delayevents);
2096  assert(event != NULL);
2097  assert(*event != NULL);
2098 
2099  SCIPsetDebugMsg(set, "appending event %p of type 0x%" SCIP_EVENTTYPE_FORMAT " to event queue %p at position %d\n",
2100  (void*)*event, (*event)->eventtype, (void*)eventqueue, eventqueue->nevents);
2101 
2102  SCIP_CALL( eventqueueEnsureEventsMem(eventqueue, set, eventqueue->nevents+1) );
2103  eventqueue->events[eventqueue->nevents] = *event;
2104  eventqueue->nevents++;
2105 
2106  *event = NULL;
2107 
2108  return SCIP_OKAY;
2109 }
2110 
2111 /** processes event or adds event to the event queue */
2113  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
2114  BMS_BLKMEM* blkmem, /**< block memory buffer */
2115  SCIP_SET* set, /**< global SCIP settings */
2116  SCIP_PRIMAL* primal, /**< primal data; only needed for objchanged events, or NULL */
2117  SCIP_LP* lp, /**< current LP data; only needed for obj/boundchanged events, or NULL */
2118  SCIP_BRANCHCAND* branchcand, /**< branching candidate storage; only needed for bound change events, or NULL */
2119  SCIP_EVENTFILTER* eventfilter, /**< event filter for global events; not needed for variable specific events */
2120  SCIP_EVENT** event /**< pointer to event to add to the queue; will be NULL after queue addition */
2121  )
2122 {
2123  SCIP_VAR* var;
2124  SCIP_EVENT* qevent;
2125  int pos;
2126 
2127  assert(eventqueue != NULL);
2128  assert(event != NULL);
2129  assert(*event != NULL);
2130  assert(((*event)->eventtype & SCIP_EVENTTYPE_OBJCHANGED) == 0 || primal != NULL);
2131  assert(((*event)->eventtype & (SCIP_EVENTTYPE_BOUNDCHANGED | SCIP_EVENTTYPE_OBJCHANGED)) == 0 || lp != NULL);
2132  assert(((*event)->eventtype & SCIP_EVENTTYPE_BOUNDCHANGED) == 0 || branchcand != NULL);
2133 
2134  if( !eventqueue->delayevents )
2135  {
2136  /* immediately process event */
2137  SCIP_CALL( SCIPeventProcess(*event, set, primal, lp, branchcand, eventfilter) );
2138  SCIP_CALL( SCIPeventFree(event, blkmem) );
2139  }
2140  else
2141  {
2142  /* delay processing of event by appending it to the event queue */
2143  SCIPsetDebugMsg(set, "adding event %p of type 0x%" SCIP_EVENTTYPE_FORMAT " to event queue %p\n", (void*)*event, (*event)->eventtype, (void*)eventqueue);
2144 
2145  switch( (*event)->eventtype )
2146  {
2148  SCIPerrorMessage("cannot add a disabled event to the event queue\n");
2149  return SCIP_INVALIDDATA;
2150 
2151  case SCIP_EVENTTYPE_SYNC: /*lint !e30 !e142*/
2171  case SCIP_EVENTTYPE_ROWADDEDSEPA: /* @todo remove previous DELETEDSEPA event */
2172  case SCIP_EVENTTYPE_ROWDELETEDSEPA: /* @todo remove previous ADDEDSEPA event */
2173  case SCIP_EVENTTYPE_ROWADDEDLP: /* @todo remove previous DELETEDLP event */
2174  case SCIP_EVENTTYPE_ROWDELETEDLP: /* @todo remove previous ADDEDLP event */
2175  case SCIP_EVENTTYPE_ROWCOEFCHANGED: /* @todo merge? */
2176  case SCIP_EVENTTYPE_ROWCONSTCHANGED: /* @todo merge with previous constchanged event */
2177  case SCIP_EVENTTYPE_ROWSIDECHANGED: /* @todo merge with previous sidechanged event */
2178  /* these events cannot (or need not) be merged; just add them to the queue */
2179  SCIP_CALL( eventqueueAppend(eventqueue, set, event) );
2180  break;
2181 
2183  /* changes in objective value may be merged with older changes in objective value */
2184  var = (*event)->data.eventobjchg.var;
2185  assert(var != NULL);
2186  pos = var->eventqueueindexobj;
2187  if( pos >= 0 )
2188  {
2189  /* the objective value change event already exists -> modify it accordingly */
2190  assert(pos < eventqueue->nevents);
2191  qevent = eventqueue->events[pos];
2192  assert(qevent != NULL);
2193  assert(qevent->eventtype == SCIP_EVENTTYPE_OBJCHANGED);
2194  assert(qevent->data.eventobjchg.var == var);
2195  assert(SCIPsetIsEQ(set, (*event)->data.eventobjchg.oldobj, qevent->data.eventobjchg.newobj));
2196 
2197  SCIPsetDebugMsg(set, " -> merging OBJ event (<%s>,%g -> %g) with event at position %d (<%s>,%g -> %g)\n",
2198  SCIPvarGetName((*event)->data.eventobjchg.var), (*event)->data.eventobjchg.oldobj,
2199  (*event)->data.eventobjchg.newobj,
2200  pos, SCIPvarGetName(qevent->data.eventobjchg.var), qevent->data.eventobjchg.oldobj,
2201  qevent->data.eventobjchg.newobj);
2202 
2203  qevent->data.eventobjchg.newobj = (*event)->data.eventobjchg.newobj;
2204  if( qevent->data.eventobjchg.newobj == qevent->data.eventobjchg.oldobj ) /*lint !e777*/
2205  {
2206  /* the queued objective value change was reversed -> disable the event in the queue */
2207  eventDisable(qevent);
2208  var->eventqueueindexobj = -1;
2209  SCIPsetDebugMsg(set, " -> event disabled\n");
2210  }
2211 
2212  /* free the event that is of no use any longer */
2213  SCIP_CALL( SCIPeventFree(event, blkmem) );
2214  }
2215  else
2216  {
2217  /* the objective value change event doesn't exist -> add it to the queue, and remember the array index */
2218  var->eventqueueindexobj = eventqueue->nevents;
2219  SCIP_CALL( eventqueueAppend(eventqueue, set, event) );
2220  }
2221  break;
2222 
2225  /* changes in lower bound may be merged with older changes in lower bound */
2226  var = (*event)->data.eventbdchg.var;
2227  assert(var != NULL);
2228  pos = var->eventqueueindexlb;
2229  if( pos >= 0 )
2230  {
2231  /* the lower bound change event already exists -> modify it accordingly */
2232  assert(pos < eventqueue->nevents);
2233  qevent = eventqueue->events[pos];
2234  assert(qevent != NULL);
2236  assert(qevent->data.eventbdchg.var == var);
2237  assert(SCIPsetIsEQ(set, (*event)->data.eventbdchg.oldbound, qevent->data.eventbdchg.newbound));
2238 
2239  SCIPsetDebugMsg(set, " -> merging LB event (<%s>,%g -> %g) with event at position %d (<%s>,%g -> %g)\n",
2240  SCIPvarGetName((*event)->data.eventbdchg.var), (*event)->data.eventbdchg.oldbound,
2241  (*event)->data.eventbdchg.newbound,
2242  pos, SCIPvarGetName(qevent->data.eventbdchg.var), qevent->data.eventbdchg.oldbound,
2243  qevent->data.eventbdchg.newbound);
2244 
2245  qevent->data.eventbdchg.newbound = (*event)->data.eventbdchg.newbound;
2246  /*if( SCIPsetIsLT(set, qevent->data.eventbdchg.newbound, qevent->data.eventbdchg.oldbound) )*/
2247  if( qevent->data.eventbdchg.newbound < qevent->data.eventbdchg.oldbound )
2249  /*else if( SCIPsetIsGT(set, qevent->data.eventbdchg.newbound, qevent->data.eventbdchg.oldbound) )*/
2250  else if( qevent->data.eventbdchg.newbound > qevent->data.eventbdchg.oldbound )
2252  else
2253  {
2254  /* the queued bound change was reversed -> disable the event in the queue */
2255  assert(qevent->data.eventbdchg.newbound == qevent->data.eventbdchg.oldbound); /*lint !e777*/
2256  eventDisable(qevent);
2257  var->eventqueueindexlb = -1;
2258  SCIPsetDebugMsg(set, " -> event disabled\n");
2259  }
2260 
2261  /* free the event that is of no use any longer */
2262  SCIP_CALL( SCIPeventFree(event, blkmem) );
2263  }
2264  else
2265  {
2266  /* the lower bound change event doesn't exist -> add it to the queue, and remember the array index */
2267  var->eventqueueindexlb = eventqueue->nevents;
2268  SCIP_CALL( eventqueueAppend(eventqueue, set, event) );
2269  }
2270  break;
2271 
2274  /* changes in upper bound may be merged with older changes in upper bound */
2275  var = (*event)->data.eventbdchg.var;
2276  assert(var != NULL);
2277  pos = var->eventqueueindexub;
2278  if( pos >= 0 )
2279  {
2280  /* the upper bound change event already exists -> modify it accordingly */
2281  assert(pos < eventqueue->nevents);
2282  qevent = eventqueue->events[pos];
2283  assert(qevent != NULL);
2285  assert(qevent->data.eventbdchg.var == var);
2286  assert(SCIPsetIsEQ(set, (*event)->data.eventbdchg.oldbound, qevent->data.eventbdchg.newbound));
2287 
2288  SCIPsetDebugMsg(set, " -> merging UB event (<%s>,%g -> %g) with event at position %d (<%s>,%g -> %g)\n",
2289  SCIPvarGetName((*event)->data.eventbdchg.var), (*event)->data.eventbdchg.oldbound,
2290  (*event)->data.eventbdchg.newbound,
2291  pos, SCIPvarGetName(qevent->data.eventbdchg.var), qevent->data.eventbdchg.oldbound,
2292  qevent->data.eventbdchg.newbound);
2293 
2294  qevent->data.eventbdchg.newbound = (*event)->data.eventbdchg.newbound;
2295  /*if( SCIPsetIsLT(set, qevent->data.eventbdchg.newbound, qevent->data.eventbdchg.oldbound) )*/
2296  if( qevent->data.eventbdchg.newbound < qevent->data.eventbdchg.oldbound )
2298  /*else if( SCIPsetIsGT(set, qevent->data.eventbdchg.newbound, qevent->data.eventbdchg.oldbound) )*/
2299  else if( qevent->data.eventbdchg.newbound > qevent->data.eventbdchg.oldbound )
2301  else
2302  {
2303  /* the queued bound change was reversed -> disable the event in the queue */
2304  assert(qevent->data.eventbdchg.newbound == qevent->data.eventbdchg.oldbound); /*lint !e777*/
2305  eventDisable(qevent);
2306  var->eventqueueindexub = -1;
2307  SCIPsetDebugMsg(set, " -> event disabled\n");
2308  }
2309 
2310  /* free the event that is of no use any longer */
2311  SCIP_CALL( SCIPeventFree(event, blkmem) );
2312  }
2313  else
2314  {
2315  /* the upper bound change event doesn't exist -> add it to the queue, and remember the array index */
2316  var->eventqueueindexub = eventqueue->nevents;
2317  SCIP_CALL( eventqueueAppend(eventqueue, set, event) );
2318  }
2319  break;
2320 
2322  var = (*event)->data.eventimpladd.var;
2323  assert(var != NULL);
2324  if( var->eventqueueimpl )
2325  {
2326  /* free the event that is of no use any longer */
2327  SCIP_CALL( SCIPeventFree(event, blkmem) );
2328  }
2329  else
2330  {
2331  var->eventqueueimpl = TRUE;
2332  SCIP_CALL( eventqueueAppend(eventqueue, set, event) );
2333  }
2334  break;
2335 
2336  default:
2337  SCIPerrorMessage("unknown event type <%d>\n", (*event)->eventtype);
2338  return SCIP_INVALIDDATA;
2339  }
2340  }
2341 
2342  assert(*event == NULL);
2343 
2344  return SCIP_OKAY;
2345 }
2346 
2347 /** marks queue to delay incoming events until a call to SCIPeventqueueProcess() */
2349  SCIP_EVENTQUEUE* eventqueue /**< event queue */
2350  )
2351 {
2352  assert(eventqueue != NULL);
2353  assert(!eventqueue->delayevents);
2354 
2355  SCIPdebugMessage("event processing is delayed\n");
2356 
2357  eventqueue->delayevents = TRUE;
2358 
2359  return SCIP_OKAY;
2360 }
2361 
2362 /** processes all delayed events, marks queue to process events immediately */
2364  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
2365  BMS_BLKMEM* blkmem, /**< block memory buffer */
2366  SCIP_SET* set, /**< global SCIP settings */
2367  SCIP_PRIMAL* primal, /**< primal data */
2368  SCIP_LP* lp, /**< current LP data */
2369  SCIP_BRANCHCAND* branchcand, /**< branching candidate storage */
2370  SCIP_EVENTFILTER* eventfilter /**< event filter for global (not variable dependent) events */
2371  )
2372 {
2373  SCIP_EVENT* event;
2374  int i;
2375 
2376  assert(eventqueue != NULL);
2377  assert(eventqueue->delayevents);
2378 
2379  SCIPsetDebugMsg(set, "processing %d queued events\n", eventqueue->nevents);
2380 
2381  /* pass events to the responsible event filters
2382  * During event processing, new events may be raised. We have to loop to the mutable eventqueue->nevents.
2383  * A loop to something like "nevents = eventqueue->nevents; for(...; i < nevents; ...)" would miss the
2384  * newly created events. The same holds for eventqueue->events, which can be moved in memory due to
2385  * memory reallocation in eventqueueAppend().
2386  */
2387  for( i = 0; i < eventqueue->nevents; ++i )
2388  {
2389  event = eventqueue->events[i];
2390  assert(event != NULL);
2391 
2392  SCIPsetDebugMsg(set, "processing event %d of %d events in queue: eventtype=0x%" SCIP_EVENTTYPE_FORMAT "\n", i, eventqueue->nevents, event->eventtype);
2393 
2394  /* unmark the event queue index of a variable with changed objective value or bounds, and unmark the event queue
2395  * member flag of a variable with added implication
2396  */
2397  if( (event->eventtype & SCIP_EVENTTYPE_OBJCHANGED) != 0 )
2398  {
2399  assert(event->data.eventobjchg.var->eventqueueindexobj == i);
2400  event->data.eventobjchg.var->eventqueueindexobj = -1;
2401  }
2402  else if( (event->eventtype & SCIP_EVENTTYPE_LBCHANGED) != 0 )
2403  {
2404  assert(event->data.eventbdchg.var->eventqueueindexlb == i);
2405  event->data.eventbdchg.var->eventqueueindexlb = -1;
2406  }
2407  else if( (event->eventtype & SCIP_EVENTTYPE_UBCHANGED) != 0 )
2408  {
2409  assert(event->data.eventbdchg.var->eventqueueindexub == i);
2410  event->data.eventbdchg.var->eventqueueindexub = -1;
2411  }
2412  else if( (event->eventtype & SCIP_EVENTTYPE_IMPLADDED) != 0 )
2413  {
2414  assert(event->data.eventimpladd.var->eventqueueimpl);
2415  event->data.eventimpladd.var->eventqueueimpl = FALSE;
2416  }
2417 
2418  /* process event */
2419  SCIP_CALL( SCIPeventProcess(event, set, primal, lp, branchcand, eventfilter) );
2420 
2421  /* free the event immediately, because additionally raised events during event processing
2422  * can lead to a large event queue
2423  */
2424  SCIP_CALL( SCIPeventFree(&eventqueue->events[i], blkmem) );
2425  }
2426 
2427  assert(i == eventqueue->nevents);
2428  eventqueue->nevents = 0;
2429  eventqueue->delayevents = FALSE;
2430 
2431  return SCIP_OKAY;
2432 }
2433 
2434 /** returns TRUE iff events of the queue are delayed until the next SCIPeventqueueProcess() call */
2436  SCIP_EVENTQUEUE* eventqueue /**< event queue */
2437  )
2438 {
2439  assert(eventqueue != NULL);
2440 
2441  return eventqueue->delayevents;
2442 }
SCIP_Real SCIPeventGetRowNewSideVal(SCIP_EVENT *event)
Definition: event.c:1443
SCIP_RETCODE SCIPeventfilterCreate(SCIP_EVENTFILTER **eventfilter, BMS_BLKMEM *blkmem)
Definition: event.c:1693
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:426
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:1825
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:107
#define SCIP_EVENTTYPE_VARFIXED
Definition: type_event.h:58
static SCIP_RETCODE eventqueueEnsureEventsMem(SCIP_EVENTQUEUE *eventqueue, SCIP_SET *set, int num)
Definition: event.c:2033
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:2363
SCIP_RETCODE SCIPeventCreateRowDeletedLP(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_ROW *row)
Definition: event.c:842
int eventqueueindexub
Definition: struct_var.h:254
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:2112
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:1851
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:3567
SCIP_RETCODE SCIPlpUpdateVarLb(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldlb, SCIP_Real newlb)
Definition: lp.c:13339
#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:13311
#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:13380
const char * SCIPeventhdlrGetName(SCIP_EVENTHDLR *eventhdlr)
Definition: event.c:278
static void eventfilterDelayUpdates(SCIP_EVENTFILTER *eventfilter)
Definition: event.c:1906
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:2348
#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:16862
internal methods for branching rules and branching candidate storage
int SCIPsetCalcMemGrowSize(SCIP_SET *set, int num)
Definition: set.c:5091
#define SCIP_EVENTTYPE_GLBCHANGED
Definition: type_event.h:61
SCIP_RETCODE SCIPeventqueueFree(SCIP_EVENTQUEUE **eventqueue)
Definition: event.c:2072
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:104
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:1665
SCIP_RETCODE SCIPeventCreateVarFixed(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_VAR *var)
Definition: event.c:514
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
union SCIP_Var::@12 data
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:13407
#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:1758
SCIP_Real SCIPeventGetOldobj(SCIP_EVENT *event)
Definition: event.c:1104
#define BMSfreeMemoryArray(ptr)
Definition: memory.h:106
#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:2056
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:16555
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 NULL
Definition: lpi_spx1.cpp:137
#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:316
#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:253
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:5539
SCIP_EVENTIMPLADD eventimpladd
Definition: struct_event.h:155
#define BMSduplicateMemoryArray(ptr, source, num)
Definition: memory.h:102
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:423
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:1666
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
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:3626
static void eventfilterProcessUpdates(SCIP_EVENTFILTER *eventfilter)
Definition: event.c:1919
#define SCIPsetDebugMsg
Definition: set.h:1870
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:16883
SCIP_RETCODE SCIPbranchcandUpdateVar(SCIP_BRANCHCAND *branchcand, SCIP_SET *set, SCIP_VAR *var)
Definition: branch.c:1107
#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:2088
SCIP_RETCODE SCIPcolChgUb(SCIP_COL *col, SCIP_SET *set, SCIP_LP *lp, SCIP_Real newub)
Definition: lp.c:3671
SCIP_EVENTFILTER * eventfilter
Definition: struct_var.h:240
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
SCIP_RETCODE SCIPeventfilterFree(SCIP_EVENTFILTER **eventfilter, BMS_BLKMEM *blkmem, SCIP_SET *set)
Definition: event.c:1718
#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:13257
SCIP_VAR * var
Definition: struct_event.h:84
SCIP_RETCODE SCIPeventfilterProcess(SCIP_EVENTFILTER *eventfilter, SCIP_SET *set, SCIP_EVENT *event)
Definition: event.c:1954
int eventqueueindexobj
Definition: struct_var.h:252
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:16674
SCIP_Real SCIPeventGetHoleRight(SCIP_EVENT *event)
Definition: event.c:1277
#define SCIP_Real
Definition: def.h:145
#define SCIP_EVENTTYPE_VARUNLOCKED
Definition: type_event.h:59
SCIP_DECL_EVENTEXITSOL(EventhdlrNewSol::scip_exitsol)
unsigned int eventqueueimpl
Definition: struct_var.h:278
#define SCIP_DECL_EVENTCOPY(x)
Definition: type_event.h:165
SCIP_CLOCK * eventtime
Definition: struct_event.h:200
#define BMSallocMemory(ptr)
Definition: memory.h:78
#define SCIP_INVALID
Definition: def.h:165
#define BMSreallocMemoryArray(ptr, num)
Definition: memory.h:86
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
union SCIP_Event::@7 data
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:410
void SCIPeventhdlrSetDelete(SCIP_EVENTHDLR *eventhdlr, SCIP_DECL_EVENTDELETE((*eventdelete)))
Definition: event.c:375
SCIP_Bool SCIPeventqueueIsDelayed(SCIP_EVENTQUEUE *eventqueue)
Definition: event.c:2435
common defines and data types used in all packages of SCIP
struct BMS_BlkMem BMS_BLKMEM
Definition: memory.h:396
#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:327
#define SCIPABORT()
Definition: def.h:288
#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:416
#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