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