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