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 */
79static
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 */
1019static
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
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
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
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
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
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
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
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 */
1625 break;
1626
1628 var = event->data.eventvarfixed.var;
1629 assert(var != NULL);
1630
1631 /* process variable's event filter */
1633 break;
1634
1636 var = event->data.eventvarunlocked.var;
1637 assert(var != NULL);
1638
1639 /* process variable's event filter */
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 {
1655 }
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 {
1665 }
1666
1667 /* process variable's event filter */
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 */
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 */
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 {
1716 }
1718 event->data.eventbdchg.newbound) );
1719 SCIP_CALL( SCIPbranchcandUpdateVar(branchcand, set, var) );
1720 }
1721
1722 /* process variable's event filter */
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 {
1739 }
1741 event->data.eventbdchg.newbound) );
1742 SCIP_CALL( SCIPbranchcandUpdateVar(branchcand, set, var) );
1743 }
1744
1745 /* process variable's event filter */
1747 break;
1748
1753 var = event->data.eventhole.var;
1754 assert(var != NULL);
1755
1756 /* process variable's event filter */
1758 break;
1759
1761 var = event->data.eventimpladd.var;
1762 assert(var != NULL);
1763 assert(!var->eventqueueimpl);
1764
1765 /* process variable's event filter */
1767 break;
1768
1770 var = event->data.eventtypechg.var;
1771 assert(var != NULL);
1772
1773 /* process variable's event filter */
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 */
1792static
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 */
1952static
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 */
2033static
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 */
2046static
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 */
2160static
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 */
2215static
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_DECL_EVENTDELETE(EventhdlrNewSol::scip_delete)
SCIP_DECL_EVENTEXEC(EventhdlrNewSol::scip_exec)
SCIP_DECL_EVENTINIT(EventhdlrNewSol::scip_init)
SCIP_DECL_EVENTINITSOL(EventhdlrNewSol::scip_initsol)
SCIP_DECL_EVENTEXIT(EventhdlrNewSol::scip_exit)
SCIP_DECL_EVENTEXITSOL(EventhdlrNewSol::scip_exitsol)
SCIP_DECL_EVENTFREE(EventhdlrNewSol::scip_free)
SCIP_RETCODE SCIPbranchcandUpdateVar(SCIP_BRANCHCAND *branchcand, SCIP_SET *set, SCIP_VAR *var)
Definition: branch.c:1136
internal methods for branching rules and branching candidate storage
void SCIPclockStop(SCIP_CLOCK *clck, SCIP_SET *set)
Definition: clock.c:360
void SCIPclockEnableOrDisable(SCIP_CLOCK *clck, SCIP_Bool enable)
Definition: clock.c:260
void SCIPclockStart(SCIP_CLOCK *clck, SCIP_SET *set)
Definition: clock.c:290
SCIP_Real SCIPclockGetTime(SCIP_CLOCK *clck)
Definition: clock.c:438
void SCIPclockReset(SCIP_CLOCK *clck)
Definition: clock.c:209
void SCIPclockFree(SCIP_CLOCK **clck)
Definition: clock.c:185
SCIP_RETCODE SCIPclockCreate(SCIP_CLOCK **clck, SCIP_CLOCKTYPE clocktype)
Definition: clock.c:170
internal methods for clocks and timing issues
#define NULL
Definition: def.h:267
#define SCIP_INVALID
Definition: def.h:193
#define SCIP_Bool
Definition: def.h:91
#define SCIP_ALLOC(x)
Definition: def.h:385
#define SCIP_Real
Definition: def.h:173
#define TRUE
Definition: def.h:93
#define FALSE
Definition: def.h:94
#define SCIPABORT()
Definition: def.h:346
#define SCIP_CALL(x)
Definition: def.h:374
#define SCIP_CALL_FINALLY(x, y)
Definition: def.h:416
SCIP_RETCODE SCIPeventhdlrCopyInclude(SCIP_EVENTHDLR *eventhdlr, SCIP_SET *set)
Definition: event.c:60
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 SCIPeventCreateLbChanged(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_VAR *var, SCIP_Real oldbound, SCIP_Real newbound)
Definition: event.c:674
static void eventfilterProcessUpdates(SCIP_EVENTFILTER *eventfilter)
Definition: event.c:2047
SCIP_RETCODE SCIPeventCreateVarFixed(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_VAR *var)
Definition: event.c:562
SCIP_RETCODE SCIPeventhdlrInitsol(SCIP_EVENTHDLR *eventhdlr, SCIP_SET *set)
Definition: event.c:246
SCIP_RETCODE SCIPeventCreateVarAdded(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_VAR *var)
Definition: event.c:526
SCIP_RETCODE SCIPeventCreateRowDeletedLP(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_ROW *row)
Definition: event.c:913
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
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 SCIPeventqueueFree(SCIP_EVENTQUEUE **eventqueue)
Definition: event.c:2200
void SCIPeventhdlrSetFree(SCIP_EVENTHDLR *eventhdlr, SCIP_DECL_EVENTFREE((*eventfree)))
Definition: event.c:366
SCIP_RETCODE SCIPeventCreateGholeRemoved(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_VAR *var, SCIP_Real left, SCIP_Real right)
Definition: event.c:748
SCIP_RETCODE SCIPeventhdlrExitsol(SCIP_EVENTHDLR *eventhdlr, SCIP_SET *set)
Definition: event.c:270
SCIP_RETCODE SCIPeventCreateUbChanged(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_VAR *var, SCIP_Real oldbound, SCIP_Real newbound)
Definition: event.c:700
void SCIPeventhdlrEnableOrDisableClocks(SCIP_EVENTHDLR *eventhdlr, SCIP_Bool enable)
Definition: event.c:442
void SCIPeventhdlrSetExitsol(SCIP_EVENTHDLR *eventhdlr, SCIP_DECL_EVENTEXITSOL((*eventexitsol)))
Definition: event.c:410
SCIP_RETCODE SCIPeventCreateVarUnlocked(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_VAR *var)
Definition: event.c:584
SCIP_RETCODE SCIPeventhdlrExit(SCIP_EVENTHDLR *eventhdlr, SCIP_SET *set)
Definition: event.c:216
SCIP_RETCODE SCIPeventChgSol(SCIP_EVENT *event, SCIP_SOL *sol)
Definition: event.c:1354
static SCIP_RETCODE eventqueueEnsureEventsMem(SCIP_EVENTQUEUE *eventqueue, SCIP_SET *set, int num)
Definition: event.c:2161
void SCIPeventhdlrSetInitsol(SCIP_EVENTHDLR *eventhdlr, SCIP_DECL_EVENTINITSOL((*eventinitsol)))
Definition: event.c:399
SCIP_RETCODE SCIPeventCreateObjChanged(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_VAR *var, SCIP_Real oldobj, SCIP_Real newobj)
Definition: event.c:605
SCIP_RETCODE SCIPeventChgNode(SCIP_EVENT *event, SCIP_NODE *node)
Definition: event.c:1317
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
SCIP_RETCODE SCIPeventhdlrFree(SCIP_EVENTHDLR **eventhdlr, SCIP_SET *set)
Definition: event.c:149
SCIP_RETCODE SCIPeventfilterFree(SCIP_EVENTFILTER **eventfilter, BMS_BLKMEM *blkmem, SCIP_SET *set)
Definition: event.c:1846
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 SCIPeventCreateRowAddedSepa(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_ROW *row)
Definition: event.c:856
SCIP_Bool SCIPeventqueueIsDelayed(SCIP_EVENTQUEUE *eventqueue)
Definition: event.c:2568
SCIP_RETCODE SCIPeventCreateGholeAdded(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_VAR *var, SCIP_Real left, SCIP_Real right)
Definition: event.c:726
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 SCIPeventCreateRowDeletedSepa(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_ROW *row)
Definition: event.c:875
void SCIPeventhdlrSetCopy(SCIP_EVENTHDLR *eventhdlr, SCIP_DECL_EVENTCOPY((*eventcopy)))
Definition: event.c:355
SCIP_RETCODE SCIPeventCreateLholeAdded(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_VAR *var, SCIP_Real left, SCIP_Real right)
Definition: event.c:770
void SCIPeventhdlrSetInit(SCIP_EVENTHDLR *eventhdlr, SCIP_DECL_EVENTINIT((*eventinit)))
Definition: event.c:377
SCIP_RETCODE SCIPeventhdlrInit(SCIP_EVENTHDLR *eventhdlr, SCIP_SET *set)
Definition: event.c:180
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
SCIP_RETCODE SCIPeventfilterCreate(SCIP_EVENTFILTER **eventfilter, BMS_BLKMEM *blkmem)
Definition: event.c:1821
void SCIPeventhdlrSetDelete(SCIP_EVENTHDLR *eventhdlr, SCIP_DECL_EVENTDELETE((*eventdelete)))
Definition: event.c:421
void SCIPeventhdlrSetExit(SCIP_EVENTHDLR *eventhdlr, SCIP_DECL_EVENTEXIT((*eventexit)))
Definition: event.c:388
SCIP_RETCODE SCIPeventhdlrExec(SCIP_EVENTHDLR *eventhdlr, SCIP_SET *set, SCIP_EVENT *event, SCIP_EVENTDATA *eventdata)
Definition: event.c:294
SCIP_RETCODE SCIPeventChgVar(SCIP_EVENT *event, SCIP_VAR *var)
Definition: event.c:1113
SCIP_RETCODE SCIPeventCreateRowConstChanged(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_ROW *row, SCIP_Real oldval, SCIP_Real newval)
Definition: event.c:957
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 SCIPeventCreateSync(SCIP_EVENT **event, BMS_BLKMEM *blkmem)
Definition: event.c:483
static SCIP_RETCODE eventfilterEnsureMem(SCIP_EVENTFILTER *eventfilter, BMS_BLKMEM *blkmem, SCIP_SET *set, int num)
Definition: event.c:1793
SCIP_RETCODE SCIPeventCreateImplAdded(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_VAR *var)
Definition: event.c:814
SCIP_RETCODE SCIPeventChgType(SCIP_EVENT *event, SCIP_EVENTTYPE eventtype)
Definition: event.c:1040
SCIP_RETCODE SCIPeventqueueCreate(SCIP_EVENTQUEUE **eventqueue)
Definition: event.c:2184
SCIP_RETCODE SCIPeventfilterProcess(SCIP_EVENTFILTER *eventfilter, SCIP_SET *set, SCIP_EVENT *event)
Definition: event.c:2082
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_RETCODE SCIPeventCreateVarDeleted(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_VAR *var)
Definition: event.c:544
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_RETCODE SCIPeventCreateGubChanged(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_VAR *var, SCIP_Real oldbound, SCIP_Real newbound)
Definition: event.c:651
SCIP_RETCODE SCIPeventCreateGlbChanged(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_VAR *var, SCIP_Real oldbound, SCIP_Real newbound)
Definition: event.c:628
SCIP_RETCODE SCIPeventqueueDelay(SCIP_EVENTQUEUE *eventqueue)
Definition: event.c:2481
SCIP_RETCODE SCIPeventCreateLholeRemoved(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_VAR *var, SCIP_Real left, SCIP_Real right)
Definition: event.c:792
SCIP_RETCODE SCIPeventCreateTypeChanged(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_VAR *var, SCIP_VARTYPE oldtype, SCIP_VARTYPE newtype)
Definition: event.c:833
static int eventfilterSearch(SCIP_EVENTFILTER *const eventfilter, SCIP_EVENTTYPE const eventtype, SCIP_EVENTHDLR *const eventhdlr, SCIP_EVENTDATA *const eventdata)
Definition: event.c:1953
static void eventfilterDelayUpdates(SCIP_EVENTFILTER *eventfilter)
Definition: event.c:2034
SCIP_RETCODE SCIPeventCreateRowAddedLP(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_ROW *row)
Definition: event.c:894
static void eventDisable(SCIP_EVENT *event)
Definition: event.c:1020
internal methods for managing events
SCIP_Real SCIPeventhdlrGetSetupTime(SCIP_EVENTHDLR *eventhdlr)
Definition: event.c:454
SCIP_Bool SCIPeventhdlrIsInitialized(SCIP_EVENTHDLR *eventhdlr)
Definition: event.c:432
SCIP_Real SCIPeventhdlrGetTime(SCIP_EVENTHDLR *eventhdlr)
Definition: event.c:466
const char * SCIPeventhdlrGetName(SCIP_EVENTHDLR *eventhdlr)
Definition: event.c:324
SCIP_EVENTHDLRDATA * SCIPeventhdlrGetData(SCIP_EVENTHDLR *eventhdlr)
Definition: event.c:334
void SCIPeventhdlrSetData(SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTHDLRDATA *eventhdlrdata)
Definition: event.c:344
SCIP_Real SCIPeventGetRowOldCoefVal(SCIP_EVENT *event)
Definition: event.c:1455
SCIP_EVENTTYPE SCIPeventGetType(SCIP_EVENT *event)
Definition: event.c:1030
SCIP_SOL * SCIPeventGetSol(SCIP_EVENT *event)
Definition: event.c:1337
SCIP_VARTYPE SCIPeventGetNewtype(SCIP_EVENT *event)
Definition: event.c:1283
SCIP_Real SCIPeventGetHoleRight(SCIP_EVENT *event)
Definition: event.c:1391
SCIP_Real SCIPeventGetHoleLeft(SCIP_EVENT *event)
Definition: event.c:1374
SCIP_Real SCIPeventGetOldobj(SCIP_EVENT *event)
Definition: event.c:1184
SCIP_Real SCIPeventGetOldbound(SCIP_EVENT *event)
Definition: event.c:1218
SCIP_VAR * SCIPeventGetVar(SCIP_EVENT *event)
Definition: event.c:1053
SCIP_Real SCIPeventGetRowNewConstVal(SCIP_EVENT *event)
Definition: event.c:1506
SCIP_COL * SCIPeventGetRowCol(SCIP_EVENT *event)
Definition: event.c:1438
SCIP_Real SCIPeventGetNewobj(SCIP_EVENT *event)
Definition: event.c:1201
SCIP_SIDETYPE SCIPeventGetRowSide(SCIP_EVENT *event)
Definition: event.c:1523
SCIP_Real SCIPeventGetRowOldSideVal(SCIP_EVENT *event)
Definition: event.c:1540
SCIP_Real SCIPeventGetNewbound(SCIP_EVENT *event)
Definition: event.c:1242
SCIP_NODE * SCIPeventGetNode(SCIP_EVENT *event)
Definition: event.c:1300
SCIP_Real SCIPeventGetRowNewCoefVal(SCIP_EVENT *event)
Definition: event.c:1472
SCIP_Real SCIPeventGetRowNewSideVal(SCIP_EVENT *event)
Definition: event.c:1557
SCIP_Real SCIPeventGetRowOldConstVal(SCIP_EVENT *event)
Definition: event.c:1489
SCIP_ROW * SCIPeventGetRow(SCIP_EVENT *event)
Definition: event.c:1408
SCIP_VARTYPE SCIPeventGetOldtype(SCIP_EVENT *event)
Definition: event.c:1266
SCIP_COL * SCIPvarGetCol(SCIP_VAR *var)
Definition: var.c:17789
SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
Definition: var.c:17538
int SCIPvarGetProbindex(SCIP_VAR *var)
Definition: var.c:17768
const char * SCIPvarGetName(SCIP_VAR *var)
Definition: var.c:17419
SCIP_RETCODE SCIPcolChgUb(SCIP_COL *col, SCIP_SET *set, SCIP_LP *lp, SCIP_Real newub)
Definition: lp.c:3802
SCIP_RETCODE SCIPcolChgLb(SCIP_COL *col, SCIP_SET *set, SCIP_LP *lp, SCIP_Real newlb)
Definition: lp.c:3757
SCIP_RETCODE SCIPlpUpdateVarLb(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldlb, SCIP_Real newlb)
Definition: lp.c:13919
SCIP_RETCODE SCIPlpUpdateVarLbGlobal(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldlb, SCIP_Real newlb)
Definition: lp.c:13892
SCIP_RETCODE SCIPcolChgObj(SCIP_COL *col, SCIP_SET *set, SCIP_LP *lp, SCIP_Real newobj)
Definition: lp.c:3698
SCIP_RETCODE SCIPlpUpdateVarUbGlobal(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldub, SCIP_Real newub)
Definition: lp.c:13960
SCIP_RETCODE SCIPlpUpdateVarUb(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldub, SCIP_Real newub)
Definition: lp.c:13987
SCIP_RETCODE SCIPlpUpdateVarObj(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldobj, SCIP_Real newobj)
Definition: lp.c:13838
internal methods for LP management
#define BMSfreeMemory(ptr)
Definition: memory.h:145
#define BMSfreeBlockMemory(mem, ptr)
Definition: memory.h:465
#define BMSallocBlockMemory(mem, ptr)
Definition: memory.h:451
#define BMSreallocMemoryArray(ptr, num)
Definition: memory.h:127
#define BMSfreeBlockMemoryArrayNull(mem, ptr, num)
Definition: memory.h:468
#define BMSduplicateMemoryArray(ptr, source, num)
Definition: memory.h:143
#define BMSclearMemory(ptr)
Definition: memory.h:129
#define BMSreallocBlockMemoryArray(mem, ptr, oldnum, newnum)
Definition: memory.h:458
struct BMS_BlkMem BMS_BLKMEM
Definition: memory.h:437
#define BMSfreeMemoryArrayNull(ptr)
Definition: memory.h:148
#define BMSallocMemory(ptr)
Definition: memory.h:118
void SCIPprimalUpdateVarObj(SCIP_PRIMAL *primal, SCIP_VAR *var, SCIP_Real oldobj, SCIP_Real newobj)
Definition: primal.c:1731
internal methods for collecting primal CIP solutions and primal informations
public methods for managing events
public methods for message output
#define SCIPerrorMessage
Definition: pub_message.h:64
#define SCIPdebugMessage
Definition: pub_message.h:96
public methods for problem variables
SCIP_Bool SCIPsetIsEQ(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6221
int SCIPsetCalcMemGrowSize(SCIP_SET *set, int num)
Definition: set.c:5764
internal methods for global SCIP settings
#define SCIPsetDebugMsg
Definition: set.h:1784
SCIP_Real oldbound
Definition: struct_event.h:83
SCIP_Real newbound
Definition: struct_event.h:84
SCIP_VAR * var
Definition: struct_event.h:85
SCIP_EVENTTYPE delayedeventmask
Definition: struct_event.h:199
SCIP_EVENTHDLR ** eventhdlrs
Definition: struct_event.h:191
SCIP_Bool delayupdates
Definition: struct_event.h:200
SCIP_EVENTTYPE eventmask
Definition: struct_event.h:198
SCIP_EVENTTYPE * eventtypes
Definition: struct_event.h:190
SCIP_EVENTDATA ** eventdata
Definition: struct_event.h:192
SCIP_VAR * var
Definition: struct_event.h:93
SCIP_VAR * var
Definition: struct_event.h:99
SCIP_Real newobj
Definition: struct_event.h:76
SCIP_Real oldobj
Definition: struct_event.h:75
SCIP_VAR * var
Definition: struct_event.h:77
SCIP_EVENT ** events
Definition: struct_event.h:225
SCIP_Bool delayevents
Definition: struct_event.h:228
SCIP_EVENTVARFIXED eventvarfixed
Definition: struct_event.h:167
SCIP_EVENTTYPECHG eventtypechg
Definition: struct_event.h:173
SCIP_EVENTTYPE eventtype
Definition: struct_event.h:184
union SCIP_Event::@16 data
SCIP_EVENTVARUNLOCKED eventvarunlocked
Definition: struct_event.h:168
SCIP_EVENTBDCHG eventbdchg
Definition: struct_event.h:170
SCIP_EVENTHOLE eventhole
Definition: struct_event.h:171
SCIP_EVENTIMPLADD eventimpladd
Definition: struct_event.h:172
SCIP_EVENTOBJCHG eventobjchg
Definition: struct_event.h:169
SCIP_EVENTVARADDED eventvaradded
Definition: struct_event.h:165
SCIP_EVENTVARDELETED eventvardeleted
Definition: struct_event.h:166
SCIP_Bool initialized
Definition: struct_event.h:219
SCIP_CLOCK * setuptime
Definition: struct_event.h:217
SCIP_CLOCK * eventtime
Definition: struct_event.h:218
SCIP_EVENTHDLRDATA * eventhdlrdata
Definition: struct_event.h:216
SCIP_Bool divingobjchg
Definition: struct_lp.h:381
SCIP_EVENTFILTER * eventfilter
Definition: struct_var.h:247
int eventqueueindexobj
Definition: struct_var.h:257
union SCIP_Var::@22 data
unsigned int eventqueueimpl
Definition: struct_var.h:284
int eventqueueindexlb
Definition: struct_var.h:258
int eventqueueindexub
Definition: struct_var.h:259
datastructures for managing events
data structures for LP management
datastructures for global SCIP settings
datastructures for problem variables
Definition: heur_padm.c:135
@ SCIP_CLOCKTYPE_DEFAULT
Definition: type_clock.h:43
#define SCIP_EVENTTYPE_GHOLEADDED
Definition: type_event.h:81
#define SCIP_EVENTTYPE_FIRSTLPSOLVED
Definition: type_event.h:100
#define SCIP_EVENTTYPE_NODEFEASIBLE
Definition: type_event.h:93
#define SCIP_EVENTTYPE_BOUNDCHANGED
Definition: type_event.h:125
#define SCIP_EVENTTYPE_VARUNLOCKED
Definition: type_event.h:73
#define SCIP_EVENTTYPE_ROWSIDECHANGED
Definition: type_event.h:114
#define SCIP_EVENTTYPE_SYNC
Definition: type_event.h:117
#define SCIP_EVENTTYPE_ROWADDEDLP
Definition: type_event.h:110
#define SCIP_EVENTTYPE_POORSOLFOUND
Definition: type_event.h:104
#define SCIP_EVENTTYPE_TYPECHANGED
Definition: type_event.h:86
#define SCIP_EVENTTYPE_PRESOLVEROUND
Definition: type_event.h:89
#define SCIP_EVENTTYPE_GUBCHANGED
Definition: type_event.h:76
#define SCIP_EVENTTYPE_GHOLEREMOVED
Definition: type_event.h:82
struct SCIP_EventData SCIP_EVENTDATA
Definition: type_event.h:173
#define SCIP_EVENTTYPE_UBTIGHTENED
Definition: type_event.h:79
#define SCIP_EVENTTYPE_NODEFOCUSED
Definition: type_event.h:92
#define SCIP_EVENTTYPE_NODEINFEASIBLE
Definition: type_event.h:94
#define SCIP_EVENTTYPE_OBJCHANGED
Definition: type_event.h:74
#define SCIP_EVENTTYPE_VARFIXED
Definition: type_event.h:72
#define SCIP_EVENTTYPE_VARDELETED
Definition: type_event.h:71
struct SCIP_EventhdlrData SCIP_EVENTHDLRDATA
Definition: type_event.h:155
#define SCIP_EVENTTYPE_NODEEVENT
Definition: type_event.h:138
#define SCIP_EVENTTYPE_LHOLEREMOVED
Definition: type_event.h:84
#define SCIP_EVENTTYPE_NODEBRANCHED
Definition: type_event.h:95
#define SCIP_DECL_EVENTCOPY(x)
Definition: type_event.h:183
#define SCIP_EVENTTYPE_LBRELAXED
Definition: type_event.h:78
#define SCIP_EVENTTYPE_BESTSOLFOUND
Definition: type_event.h:105
#define SCIP_EVENTTYPE_FORMAT
Definition: type_event.h:152
#define SCIP_EVENTTYPE_GLBCHANGED
Definition: type_event.h:75
#define SCIP_EVENTTYPE_HOLECHANGED
Definition: type_event.h:128
#define SCIP_EVENTTYPE_ROWDELETEDSEPA
Definition: type_event.h:109
#define SCIP_EVENTTYPE_VARADDED
Definition: type_event.h:70
#define SCIP_EVENTTYPE_LBCHANGED
Definition: type_event.h:121
#define SCIP_EVENTTYPE_ROWDELETEDLP
Definition: type_event.h:111
#define SCIP_EVENTTYPE_UBCHANGED
Definition: type_event.h:122
#define SCIP_EVENTTYPE_LHOLEADDED
Definition: type_event.h:83
uint64_t SCIP_EVENTTYPE
Definition: type_event.h:151
#define SCIP_EVENTTYPE_LPSOLVED
Definition: type_event.h:101
#define SCIP_EVENTTYPE_IMPLADDED
Definition: type_event.h:85
#define SCIP_EVENTTYPE_ROWCOEFCHANGED
Definition: type_event.h:112
#define SCIP_EVENTTYPE_ROWADDEDSEPA
Definition: type_event.h:108
#define SCIP_EVENTTYPE_LPEVENT
Definition: type_event.h:141
#define SCIP_EVENTTYPE_NODEDELETE
Definition: type_event.h:96
#define SCIP_EVENTTYPE_DISABLED
Definition: type_event.h:67
#define SCIP_EVENTTYPE_SOLEVENT
Definition: type_event.h:145
#define SCIP_EVENTTYPE_ROWCONSTCHANGED
Definition: type_event.h:113
#define SCIP_EVENTTYPE_LBTIGHTENED
Definition: type_event.h:77
#define SCIP_EVENTTYPE_UBRELAXED
Definition: type_event.h:80
@ SCIP_SIDETYPE_LEFT
Definition: type_lp.h:64
enum SCIP_SideType SCIP_SIDETYPE
Definition: type_lp.h:67
@ SCIP_INVALIDDATA
Definition: type_retcode.h:52
@ SCIP_OKAY
Definition: type_retcode.h:42
@ SCIP_INVALIDCALL
Definition: type_retcode.h:51
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:63
@ SCIP_VARTYPE_CONTINUOUS
Definition: type_var.h:71
@ SCIP_VARSTATUS_FIXED
Definition: type_var.h:52
@ SCIP_VARSTATUS_COLUMN
Definition: type_var.h:51
@ SCIP_VARSTATUS_MULTAGGR
Definition: type_var.h:54
@ SCIP_VARSTATUS_NEGATED
Definition: type_var.h:55
@ SCIP_VARSTATUS_AGGREGATED
Definition: type_var.h:53
@ SCIP_VARSTATUS_LOOSE
Definition: type_var.h:50
enum SCIP_Vartype SCIP_VARTYPE
Definition: type_var.h:73
internal methods for problem variables