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