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-2025 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/lpexact.h"
41#include "scip/primal.h"
42#include "scip/pub_event.h"
43#include "scip/pub_message.h"
44#include "scip/pub_var.h"
45#include "scip/rational.h"
46#include "scip/set.h"
47#include "scip/struct_event.h"
48#include "scip/struct_lp.h"
49#include "scip/struct_set.h"
50#include "scip/struct_var.h"
51#include "scip/var.h"
52
53/* timing the execution methods for event handling takes a lot of time, so it is disabled */
54/* #define TIMEEVENTEXEC */
55
56
57/*
58 * Event handler methods
59 */
60
61/** copies the given event handler to a new scip */
63 SCIP_EVENTHDLR* eventhdlr, /**< event handler */
64 SCIP_SET* set /**< SCIP_SET of SCIP to copy to */
65 )
66{
67 assert(eventhdlr != NULL);
68 assert(set != NULL);
69 assert(set->scip != NULL);
70
71 if( eventhdlr->eventcopy != NULL )
72 {
73 SCIPsetDebugMsg(set, "including event handler %s in subscip %p\n", SCIPeventhdlrGetName(eventhdlr), (void*)set->scip);
74 SCIP_CALL( eventhdlr->eventcopy(set->scip, eventhdlr) );
75 }
76
77 return SCIP_OKAY;
78}
79
80/** wrapper method to update the exact data of a variable if a bound gets changed */
81static
83 SCIP_VAR* var, /**< variable that gets changed */
84 SCIP_LPEXACT* lp, /**< current LP data */
85 SCIP_SET* set, /**< global SCIP settings */
86 SCIP_EVENT* event, /**< event */
87 SCIP_Bool isUb, /**< is it an upper bound */
88 SCIP_Bool isGlb /**< is it a global or local bound */
89 )
90{
91 /* do nothing if not in exact solving mode */
92 if( !set->exact_enable )
93 return SCIP_OKAY;
94
95 assert(var != NULL);
96 assert(lp != NULL);
97
100 {
101 SCIP_RATIONAL* newbound;
102 SCIP_RATIONAL* oldbound;
103
104 SCIP_CALL( SCIPrationalCreateBuffer(set->buffer, &newbound) );
105 SCIP_CALL( SCIPrationalCreateBuffer(set->buffer, &oldbound) );
108
110 {
111 if( isUb )
112 {
113 SCIP_CALL( SCIPcolExactChgUb(SCIPvarGetColExact(var), set, lp, newbound) );
114 }
115 else
116 {
117 SCIP_CALL( SCIPcolExactChgLb(SCIPvarGetColExact(var), set, lp, newbound) );
118 }
119 }
120 if( isUb )
121 {
122 if( isGlb )
123 {
124 SCIP_CALL( SCIPlpExactUpdateVarUbGlobal(lp, set, var, oldbound, newbound) );
125 }
126 else
127 {
128 SCIP_CALL( SCIPlpExactUpdateVarUb(lp, set, var, oldbound, newbound) );
129 }
130 }
131 else
132 {
133 if( isGlb )
134 {
135 SCIP_CALL( SCIPlpExactUpdateVarLbGlobal(lp, set, var, oldbound, newbound) );
136 }
137 else
138 {
139 SCIP_CALL( SCIPlpExactUpdateVarLb(lp, set, var, oldbound, newbound) );
140 }
141 }
142
143 SCIPrationalFreeBuffer(set->buffer, &oldbound);
144 SCIPrationalFreeBuffer(set->buffer, &newbound);
145 }
146
147 return SCIP_OKAY;
148}
149
150/** internal method for creating an event handler */
151static
153 SCIP_EVENTHDLR** eventhdlr, /**< pointer to event handler data structure */
154 const char* name, /**< name of event handler */
155 const char* desc, /**< description of event handler */
156 SCIP_DECL_EVENTCOPY ((*eventcopy)), /**< copy method of event handler or NULL if you don't want to copy your plugin into sub-SCIPs */
157 SCIP_DECL_EVENTFREE ((*eventfree)), /**< destructor of event handler */
158 SCIP_DECL_EVENTINIT ((*eventinit)), /**< initialize event handler */
159 SCIP_DECL_EVENTEXIT ((*eventexit)), /**< deinitialize event handler */
160 SCIP_DECL_EVENTINITSOL((*eventinitsol)), /**< solving process initialization method of event handler */
161 SCIP_DECL_EVENTEXITSOL((*eventexitsol)), /**< solving process deinitialization method of event handler */
162 SCIP_DECL_EVENTDELETE ((*eventdelete)), /**< free specific event data */
163 SCIP_DECL_EVENTEXEC ((*eventexec)), /**< execute event handler */
164 SCIP_EVENTHDLRDATA* eventhdlrdata /**< event handler data */
165 )
166{
167 assert(eventhdlr != NULL);
168 assert(name != NULL);
169 assert(desc != NULL);
170 assert(eventexec != NULL);
171
172 SCIP_ALLOC( BMSallocMemory(eventhdlr) );
173 BMSclearMemory(*eventhdlr);
174 SCIP_ALLOC( BMSduplicateMemoryArray(&(*eventhdlr)->name, name, strlen(name)+1) );
175 SCIP_ALLOC( BMSduplicateMemoryArray(&(*eventhdlr)->desc, desc, strlen(desc)+1) );
176 (*eventhdlr)->eventcopy = eventcopy;
177 (*eventhdlr)->eventfree = eventfree;
178 (*eventhdlr)->eventinit = eventinit;
179 (*eventhdlr)->eventexit = eventexit;
180 (*eventhdlr)->eventinitsol = eventinitsol;
181 (*eventhdlr)->eventexitsol = eventexitsol;
182 (*eventhdlr)->eventdelete = eventdelete;
183 (*eventhdlr)->eventexec = eventexec;
184 (*eventhdlr)->eventhdlrdata = eventhdlrdata;
185 (*eventhdlr)->initialized = FALSE;
186
187 /* create clocks */
188 SCIP_CALL( SCIPclockCreate(&(*eventhdlr)->setuptime, SCIP_CLOCKTYPE_DEFAULT) );
189 SCIP_CALL( SCIPclockCreate(&(*eventhdlr)->eventtime, SCIP_CLOCKTYPE_DEFAULT) );
190
191 return SCIP_OKAY;
192}
193
194/** creates an event handler */
196 SCIP_EVENTHDLR** eventhdlr, /**< pointer to event handler data structure */
197 SCIP_SET* set, /**< global SCIP settings */
198 const char* name, /**< name of event handler */
199 const char* desc, /**< description of event handler */
200 SCIP_DECL_EVENTCOPY ((*eventcopy)), /**< copy method of event handler or NULL if you don't want to copy your plugin into sub-SCIPs */
201 SCIP_DECL_EVENTFREE ((*eventfree)), /**< destructor of event handler */
202 SCIP_DECL_EVENTINIT ((*eventinit)), /**< initialize event handler */
203 SCIP_DECL_EVENTEXIT ((*eventexit)), /**< deinitialize event handler */
204 SCIP_DECL_EVENTINITSOL((*eventinitsol)), /**< solving process initialization method of event handler */
205 SCIP_DECL_EVENTEXITSOL((*eventexitsol)), /**< solving process deinitialization method of event handler */
206 SCIP_DECL_EVENTDELETE ((*eventdelete)), /**< free specific event data */
207 SCIP_DECL_EVENTEXEC ((*eventexec)), /**< execute event handler */
208 SCIP_EVENTHDLRDATA* eventhdlrdata /**< event handler data */
209 )
210{
211 assert(eventhdlr != NULL);
212 assert(set != NULL);
213
214 SCIP_CALL_FINALLY( doEventhdlrCreate(eventhdlr, name, desc, eventcopy, eventfree, eventinit, eventexit,
215 eventinitsol, eventexitsol, eventdelete, eventexec, eventhdlrdata), (void) SCIPeventhdlrFree(eventhdlr, set) );
216
217 return SCIP_OKAY;
218}
219
220/** calls destructor and frees memory of event handler */
222 SCIP_EVENTHDLR** eventhdlr, /**< pointer to event handler data structure */
223 SCIP_SET* set /**< global SCIP settings */
224 )
225{
226 assert(eventhdlr != NULL);
227 assert(set != NULL);
228
229 if( *eventhdlr == NULL )
230 return SCIP_OKAY;
231
232 assert(!(*eventhdlr)->initialized);
233
234 /* call destructor of event handler */
235 if( (*eventhdlr)->eventfree != NULL )
236 {
237 SCIP_CALL( (*eventhdlr)->eventfree(set->scip, *eventhdlr) );
238 }
239
240 /* free clocks */
241 SCIPclockFree(&(*eventhdlr)->eventtime);
242 SCIPclockFree(&(*eventhdlr)->setuptime);
243
244 BMSfreeMemoryArrayNull(&(*eventhdlr)->name);
245 BMSfreeMemoryArrayNull(&(*eventhdlr)->desc);
246 BMSfreeMemory(eventhdlr);
247
248 return SCIP_OKAY;
249}
250
251/** initializes event handler */
253 SCIP_EVENTHDLR* eventhdlr, /**< event handler for this event */
254 SCIP_SET* set /**< global SCIP settings */
255 )
256{
257 assert(eventhdlr != NULL);
258 assert(set != NULL);
259
260 if( eventhdlr->initialized )
261 {
262 SCIPerrorMessage("event handler <%s> already initialized\n", eventhdlr->name);
263 return SCIP_INVALIDCALL;
264 }
265
266 if( set->misc_resetstat )
267 {
268 SCIPclockReset(eventhdlr->setuptime);
269 SCIPclockReset(eventhdlr->eventtime);
270 }
271
272 if( eventhdlr->eventinit != NULL )
273 {
274 /* start timing */
275 SCIPclockStart(eventhdlr->setuptime, set);
276
277 SCIP_CALL( eventhdlr->eventinit(set->scip, eventhdlr) );
278
279 /* stop timing */
280 SCIPclockStop(eventhdlr->setuptime, set);
281 }
282 eventhdlr->initialized = TRUE;
283
284 return SCIP_OKAY;
285}
286
287/** calls exit method of event handler */
289 SCIP_EVENTHDLR* eventhdlr, /**< event handler for this event */
290 SCIP_SET* set /**< global SCIP settings */
291 )
292{
293 assert(eventhdlr != NULL);
294 assert(set != NULL);
295
296 if( !eventhdlr->initialized )
297 {
298 SCIPerrorMessage("event handler <%s> not initialized\n", eventhdlr->name);
299 return SCIP_INVALIDCALL;
300 }
301
302 if( eventhdlr->eventexit != NULL )
303 {
304 /* start timing */
305 SCIPclockStart(eventhdlr->setuptime, set);
306
307 SCIP_CALL( eventhdlr->eventexit(set->scip, eventhdlr) );
308
309 /* stop timing */
310 SCIPclockStop(eventhdlr->setuptime, set);
311 }
312 eventhdlr->initialized = FALSE;
313
314 return SCIP_OKAY;
315}
316
317/** informs event handler that the branch and bound process is being started */
319 SCIP_EVENTHDLR* eventhdlr, /**< event handler */
320 SCIP_SET* set /**< global SCIP settings */
321 )
322{
323 assert(eventhdlr != NULL);
324 assert(set != NULL);
325
326 /* call solving process initialization method of event handler */
327 if( eventhdlr->eventinitsol != NULL )
328 {
329 /* start timing */
330 SCIPclockStart(eventhdlr->setuptime, set);
331
332 SCIP_CALL( eventhdlr->eventinitsol(set->scip, eventhdlr) );
333
334 /* stop timing */
335 SCIPclockStop(eventhdlr->setuptime, set);
336 }
337
338 return SCIP_OKAY;
339}
340
341/** informs event handler that the branch and bound process data is being freed */
343 SCIP_EVENTHDLR* eventhdlr, /**< event handler */
344 SCIP_SET* set /**< global SCIP settings */
345 )
346{
347 assert(eventhdlr != NULL);
348 assert(set != NULL);
349
350 /* call solving process deinitialization method of event handler */
351 if( eventhdlr->eventexitsol != NULL )
352 {
353 /* start timing */
354 SCIPclockStart(eventhdlr->setuptime, set);
355
356 SCIP_CALL( eventhdlr->eventexitsol(set->scip, eventhdlr) );
357
358 /* stop timing */
359 SCIPclockStop(eventhdlr->setuptime, set);
360 }
361
362 return SCIP_OKAY;
363}
364
365/** calls execution method of event handler */
367 SCIP_EVENTHDLR* eventhdlr, /**< event handler */
368 SCIP_SET* set, /**< global SCIP settings */
369 SCIP_EVENT* event, /**< event to call event handler with */
370 SCIP_EVENTDATA* eventdata /**< user data for the issued event */
371 )
372{
373 assert(eventhdlr != NULL);
374 assert(eventhdlr->eventexec != NULL);
375 assert(set != NULL);
376 assert(event != NULL);
377
378 SCIPsetDebugMsg(set, "execute event of handler <%s> with event %p of type 0x%" SCIP_EVENTTYPE_FORMAT "\n", eventhdlr->name, (void*)event, event->eventtype);
379
380#ifdef TIMEEVENTEXEC
381 /* start timing */
382 SCIPclockStart(eventhdlr->eventtime, set);
383#endif
384
385 SCIP_CALL( eventhdlr->eventexec(set->scip, eventhdlr, event, eventdata) );
386
387#ifdef TIMEEVENTEXEC
388 /* stop timing */
389 SCIPclockStop(eventhdlr->eventtime, set);
390#endif
391
392 return SCIP_OKAY;
393}
394
395/** gets name of event handler */
397 SCIP_EVENTHDLR* eventhdlr /**< event handler */
398 )
399{
400 assert(eventhdlr != NULL);
401
402 return eventhdlr->name;
403}
404
405/** gets user data of event handler */
407 SCIP_EVENTHDLR* eventhdlr /**< event handler */
408 )
409{
410 assert(eventhdlr != NULL);
411
412 return eventhdlr->eventhdlrdata;
413}
414
415/** sets user data of event handler; user has to free old data in advance! */
417 SCIP_EVENTHDLR* eventhdlr, /**< event handler */
418 SCIP_EVENTHDLRDATA* eventhdlrdata /**< new event handler user data */
419 )
420{
421 assert(eventhdlr != NULL);
422
423 eventhdlr->eventhdlrdata = eventhdlrdata;
424}
425
426/** sets copy callback for all events of this event handler */
428 SCIP_EVENTHDLR* eventhdlr, /**< event handler */
429 SCIP_DECL_EVENTCOPY ((*eventcopy)) /**< copy callback for events */
430 )
431{
432 assert(eventhdlr != NULL);
433
434 eventhdlr->eventcopy = eventcopy;
435}
436
437/** sets destructor callback of this event handler */
439 SCIP_EVENTHDLR* eventhdlr, /**< event handler */
440 SCIP_DECL_EVENTFREE ((*eventfree)) /**< destructor callback of event handler */
441 )
442{
443 assert(eventhdlr != NULL);
444
445 eventhdlr->eventfree = eventfree;
446}
447
448/** sets initialization callback of this event handler */
450 SCIP_EVENTHDLR* eventhdlr, /**< event handler */
451 SCIP_DECL_EVENTINIT ((*eventinit)) /**< initialization callback of event handler */
452 )
453{
454 assert(eventhdlr != NULL);
455
456 eventhdlr->eventinit = eventinit;
457}
458
459/** sets deinitialization callback of this event handler */
461 SCIP_EVENTHDLR* eventhdlr, /**< event handler */
462 SCIP_DECL_EVENTEXIT ((*eventexit)) /**< deinitialization callback of event handler */
463 )
464{
465 assert(eventhdlr != NULL);
466
467 eventhdlr->eventexit = eventexit;
468}
469
470/** sets solving process initialization callback of this event handler */
472 SCIP_EVENTHDLR* eventhdlr, /**< event handler */
473 SCIP_DECL_EVENTINITSOL((*eventinitsol)) /**< solving process initialization callback of event handler */
474 )
475{
476 assert(eventhdlr != NULL);
477
478 eventhdlr->eventinitsol = eventinitsol;
479}
480
481/** sets solving process deinitialization callback of this event handler */
483 SCIP_EVENTHDLR* eventhdlr, /**< event handler */
484 SCIP_DECL_EVENTEXITSOL((*eventexitsol)) /**< solving process deinitialization callback of event handler */
485 )
486{
487 assert(eventhdlr != NULL);
488
489 eventhdlr->eventexitsol = eventexitsol;
490}
491
492/** sets callback to free specific event data */
494 SCIP_EVENTHDLR* eventhdlr, /**< event handler */
495 SCIP_DECL_EVENTDELETE ((*eventdelete)) /**< callback to free specific event data */
496 )
497{
498 assert(eventhdlr != NULL);
499
500 eventhdlr->eventdelete = eventdelete;
501}
502
503/** is event handler initialized? */
505 SCIP_EVENTHDLR* eventhdlr /**< event handler */
506 )
507{
508 assert(eventhdlr != NULL);
509
510 return eventhdlr->initialized;
511}
512
513/** enables or disables all clocks of \p eventhdlr, depending on the value of the flag */
515 SCIP_EVENTHDLR* eventhdlr, /**< the event handler for which all clocks should be enabled or disabled */
516 SCIP_Bool enable /**< should the clocks of the event handler be enabled? */
517 )
518{
519 assert(eventhdlr != NULL);
520
521 SCIPclockEnableOrDisable(eventhdlr->setuptime, enable);
522 SCIPclockEnableOrDisable(eventhdlr->eventtime, enable);
523}
524
525/** gets time in seconds used in this event handler for setting up for next stages */
527 SCIP_EVENTHDLR* eventhdlr /**< event handler */
528 )
529{
530 assert(eventhdlr != NULL);
531
532 return SCIPclockGetTime(eventhdlr->setuptime);
533}
534
535/** gets time in seconds used in this event handler, this measurement is currently disabled so this method will return
536 * 0, define TIMEEVENTEXEC in the beginning of this file to enable
537 */
539 SCIP_EVENTHDLR* eventhdlr /**< event handler */
540 )
541{
542 assert(eventhdlr != NULL);
543
544 return SCIPclockGetTime(eventhdlr->eventtime);
545}
546
547
548
549/*
550 * Event methods
551 */
552
553
554/** creates a synchronization event */
556 SCIP_EVENT** event, /**< pointer to store the event */
557 BMS_BLKMEM* blkmem /**< block memory */
558 )
559{
560 assert(event != NULL);
561
562 /* create event data */
563 SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
564 (*event)->eventtype = SCIP_EVENTTYPE_SYNC;
565
566 return SCIP_OKAY;
567}
568
569/*
570 * simple functions implemented as defines
571 */
572
573/* In debug mode, the following methods are implemented as function calls to ensure
574 * type validity.
575 * In optimized mode, the methods are implemented as defines to improve performance.
576 * However, we want to have them in the library anyways, so we have to undef the defines.
577 */
578
579#undef SCIPeventGetType
580#undef SCIPeventGetOldobj
581#undef SCIPeventGetNewobj
582#undef SCIPeventGetOldtype
583#undef SCIPeventGetNewtype
584#undef SCIPeventGetOldbound
585#undef SCIPeventGetNewbound
586#undef SCIPeventGetNode
587#undef SCIPeventGetSol
588#undef SCIPeventGetRowCol
589#undef SCIPeventGetRowOldCoefVal
590#undef SCIPeventGetRowNewCoefVal
591#undef SCIPeventGetRowOldConstVal
592#undef SCIPeventGetRowNewConstVal
593#undef SCIPeventGetRowSide
594#undef SCIPeventGetRowOldSideVal
595#undef SCIPeventGetRowNewSideVal
596
597/** creates an event for an addition of a variable to the problem */
599 SCIP_EVENT** event, /**< pointer to store the event */
600 BMS_BLKMEM* blkmem, /**< block memory */
601 SCIP_VAR* var /**< variable that was added to the problem */
602 )
603{
604 assert(event != NULL);
605 assert(blkmem != NULL);
606
607 /* create event data */
608 SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
609 (*event)->eventtype = SCIP_EVENTTYPE_VARADDED;
610 (*event)->data.eventvaradded.var = var;
611
612 return SCIP_OKAY;
613}
614
615/** creates an event for a deletion of a variable from the problem */
617 SCIP_EVENT** event, /**< pointer to store the event */
618 BMS_BLKMEM* blkmem, /**< block memory */
619 SCIP_VAR* var /**< variable that is to be deleted from the problem */
620 )
621{
622 assert(event != NULL);
623 assert(blkmem != NULL);
624
625 /* create event data */
626 SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
627 (*event)->eventtype = SCIP_EVENTTYPE_VARDELETED;
628 (*event)->data.eventvardeleted.var = var;
629
630 return SCIP_OKAY;
631}
632
633/** creates an event for a fixing of a variable */
635 SCIP_EVENT** event, /**< pointer to store the event */
636 BMS_BLKMEM* blkmem, /**< block memory */
637 SCIP_VAR* var /**< variable that was fixed */
638 )
639{
640 assert(event != NULL);
641 assert(blkmem != NULL);
646
647 /* create event data */
648 SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
649 (*event)->eventtype = SCIP_EVENTTYPE_VARFIXED;
650 (*event)->data.eventvarfixed.var = var;
651
652 return SCIP_OKAY;
653}
654
655/** creates an event for a change in the number of locks of a variable down to zero or one */
657 SCIP_EVENT** event, /**< pointer to store the event */
658 BMS_BLKMEM* blkmem, /**< block memory */
659 SCIP_VAR* var /**< variable that changed the number of locks */
660 )
661{
662 assert(event != NULL);
663 assert(blkmem != NULL);
667
668 /* create event data */
669 SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
670 (*event)->eventtype = SCIP_EVENTTYPE_VARUNLOCKED;
671 (*event)->data.eventvarunlocked.var = var;
672
673 return SCIP_OKAY;
674}
675
676/** creates an event for a change in the objective value of a variable */
678 SCIP_EVENT** event, /**< pointer to store the event */
679 BMS_BLKMEM* blkmem, /**< block memory */
680 SCIP_VAR* var, /**< variable whose objective value changed */
681 SCIP_Real oldobj, /**< old objective value before value changed */
682 SCIP_Real newobj /**< new objective value after value changed */
683 )
684{
685 assert(event != NULL);
686 assert(blkmem != NULL);
687 assert(oldobj != newobj || (var->exactdata != NULL)); /*lint !e777*/
688
689 /* create event data */
690 SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
691 (*event)->eventtype = SCIP_EVENTTYPE_OBJCHANGED;
692 (*event)->data.eventobjchg.var = var;
693 (*event)->data.eventobjchg.oldobj = oldobj;
694 (*event)->data.eventobjchg.newobj = newobj;
695 (*event)->data.eventobjchg.oldobjexact = NULL;
696 (*event)->data.eventobjchg.newobjexact = NULL;
697
698 return SCIP_OKAY;
699}
700
701/** creates an event for a change in the global lower bound of a variable */
703 SCIP_EVENT** event, /**< pointer to store the event */
704 BMS_BLKMEM* blkmem, /**< block memory */
705 SCIP_VAR* var, /**< variable whose bound changed */
706 SCIP_Real oldbound, /**< old bound before bound changed */
707 SCIP_Real newbound /**< new bound after bound changed */
708 )
709{
710 assert(event != NULL);
711 assert(blkmem != NULL);
712 assert(oldbound != newbound || (var->exactdata != NULL)); /*lint !e777*/
713
714 /* create event data */
715 SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
716 (*event)->eventtype = SCIP_EVENTTYPE_GLBCHANGED;
717 (*event)->data.eventbdchg.var = var;
718 (*event)->data.eventbdchg.oldbound = oldbound;
719 (*event)->data.eventbdchg.newbound = newbound;
720 (*event)->data.eventbdchg.oldboundexact = NULL;
721 (*event)->data.eventbdchg.newboundexact = NULL;
722
723 return SCIP_OKAY;
724}
725
726/** creates an event for a change in the global upper bound of a variable */
728 SCIP_EVENT** event, /**< pointer to store the event */
729 BMS_BLKMEM* blkmem, /**< block memory */
730 SCIP_VAR* var, /**< variable whose bound changed */
731 SCIP_Real oldbound, /**< old bound before bound changed */
732 SCIP_Real newbound /**< new bound after bound changed */
733 )
734{
735 assert(event != NULL);
736 assert(blkmem != NULL);
737 assert(oldbound != newbound || (var->exactdata != NULL)); /*lint !e777*/
738
739 /* create event data */
740 SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
741 (*event)->eventtype = SCIP_EVENTTYPE_GUBCHANGED;
742 (*event)->data.eventbdchg.var = var;
743 (*event)->data.eventbdchg.oldbound = oldbound;
744 (*event)->data.eventbdchg.newbound = newbound;
745 (*event)->data.eventbdchg.oldboundexact = NULL;
746 (*event)->data.eventbdchg.newboundexact = NULL;
747
748 return SCIP_OKAY;
749}
750
751/** creates an event for a change in the lower bound of a variable */
753 SCIP_EVENT** event, /**< pointer to store the event */
754 BMS_BLKMEM* blkmem, /**< block memory */
755 SCIP_VAR* var, /**< variable whose bound changed */
756 SCIP_Real oldbound, /**< old bound before bound changed */
757 SCIP_Real newbound /**< new bound after bound changed */
758 )
759{
760 assert(event != NULL);
761 assert(blkmem != NULL);
762 assert(oldbound != newbound || (var->exactdata != NULL)); /*lint !e777*/
763
764 /* create event data */
765 SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
766 if( newbound > oldbound )
767 (*event)->eventtype = SCIP_EVENTTYPE_LBTIGHTENED;
768 else
769 (*event)->eventtype = SCIP_EVENTTYPE_LBRELAXED;
770 (*event)->data.eventbdchg.var = var;
771 (*event)->data.eventbdchg.oldbound = oldbound;
772 (*event)->data.eventbdchg.newbound = newbound;
773 (*event)->data.eventbdchg.oldboundexact = NULL;
774 (*event)->data.eventbdchg.newboundexact = NULL;
775
776 return SCIP_OKAY;
777}
778
779/** creates an event for a change in the upper bound of a variable */
781 SCIP_EVENT** event, /**< pointer to store the event */
782 BMS_BLKMEM* blkmem, /**< block memory */
783 SCIP_VAR* var, /**< variable whose bound changed */
784 SCIP_Real oldbound, /**< old bound before bound changed */
785 SCIP_Real newbound /**< new bound after bound changed */
786 )
787{
788 assert(event != NULL);
789 assert(blkmem != NULL);
790 assert(oldbound != newbound || (var->exactdata != NULL)); /*lint !e777*/
791
792 /* create event data */
793 SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
794 if( newbound < oldbound )
795 (*event)->eventtype = SCIP_EVENTTYPE_UBTIGHTENED;
796 else
797 (*event)->eventtype = SCIP_EVENTTYPE_UBRELAXED;
798 (*event)->data.eventbdchg.var = var;
799 (*event)->data.eventbdchg.oldbound = oldbound;
800 (*event)->data.eventbdchg.newbound = newbound;
801 (*event)->data.eventbdchg.oldboundexact = NULL;
802 (*event)->data.eventbdchg.newboundexact = NULL;
803
804 return SCIP_OKAY;
805}
806
807/** adds the data for the exact changes to existing bound event */
809 SCIP_EVENT* event, /**< the event */
810 BMS_BLKMEM* blkmem, /**< block memory */
811 SCIP_RATIONAL* oldbound, /**< old bound before bound changed */
812 SCIP_RATIONAL* newbound /**< new bound after bound changed */
813 )
814{
815 assert(event != NULL);
816 assert(blkmem != NULL);
817 assert(!SCIPrationalIsEQ(oldbound, newbound));
818 assert((event)->eventtype & (SCIP_EVENTTYPE_BOUNDCHANGED | SCIP_EVENTTYPE_GBDCHANGED));
819
820 SCIP_CALL( SCIPrationalCopyBlock(blkmem, &(event->data.eventbdchg.oldboundexact), oldbound) );
821 SCIP_CALL( SCIPrationalCopyBlock(blkmem, &(event->data.eventbdchg.newboundexact), newbound) );
822
823 return SCIP_OKAY;
824}
825
826/** adds the data for the exact changes to existing obj event */
828 SCIP_EVENT* event, /**< the event */
829 BMS_BLKMEM* blkmem, /**< block memory */
830 SCIP_RATIONAL* oldobj, /**< old obj before change */
831 SCIP_RATIONAL* newobj /**< new obj after change */
832 )
833{
834 assert(event != NULL);
835 assert(blkmem != NULL);
836 assert(!SCIPrationalIsEQ(oldobj, newobj));
837
838 SCIP_CALL( SCIPrationalCopyBlock(blkmem, &(event->data.eventobjchg.oldobjexact), oldobj) );
839 SCIP_CALL( SCIPrationalCopyBlock(blkmem, &(event->data.eventobjchg.newobjexact), newobj) );
840
841 return SCIP_OKAY;
842}
843
844/** creates an event for an addition of a domain hole to a variable */
846 SCIP_EVENT** event, /**< pointer to store the event */
847 BMS_BLKMEM* blkmem, /**< block memory */
848 SCIP_VAR* var, /**< variable whose bound changed */
849 SCIP_Real left, /**< left bound of open interval in new hole */
850 SCIP_Real right /**< right bound of open interval in new hole */
851 )
852{
853 assert(event != NULL);
854 assert(blkmem != NULL);
855
856 /* create event data */
857 SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
858 (*event)->eventtype = SCIP_EVENTTYPE_GHOLEADDED;
859 (*event)->data.eventhole.var = var;
860 (*event)->data.eventhole.left = left;
861 (*event)->data.eventhole.right = right;
862
863 return SCIP_OKAY;
864}
865
866/** creates an event for removing a domain hole of a variable */
868 SCIP_EVENT** event, /**< pointer to store the event */
869 BMS_BLKMEM* blkmem, /**< block memory */
870 SCIP_VAR* var, /**< variable whose bound changed */
871 SCIP_Real left, /**< left bound of open interval in hole */
872 SCIP_Real right /**< right bound of open interval in hole */
873 )
874{
875 assert(event != NULL);
876 assert(blkmem != NULL);
877
878 /* create event data */
879 SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
880 (*event)->eventtype = SCIP_EVENTTYPE_GHOLEREMOVED;
881 (*event)->data.eventhole.var = var;
882 (*event)->data.eventhole.left = left;
883 (*event)->data.eventhole.right = right;
884
885 return SCIP_OKAY;
886}
887
888/** creates an event for an addition of a domain hole to a variable */
890 SCIP_EVENT** event, /**< pointer to store the event */
891 BMS_BLKMEM* blkmem, /**< block memory */
892 SCIP_VAR* var, /**< variable whose bound changed */
893 SCIP_Real left, /**< left bound of open interval in new hole */
894 SCIP_Real right /**< right bound of open interval in new hole */
895 )
896{
897 assert(event != NULL);
898 assert(blkmem != NULL);
899
900 /* create event data */
901 SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
902 (*event)->eventtype = SCIP_EVENTTYPE_LHOLEADDED;
903 (*event)->data.eventhole.var = var;
904 (*event)->data.eventhole.left = left;
905 (*event)->data.eventhole.right = right;
906
907 return SCIP_OKAY;
908}
909
910/** creates an event for removing a domain hole of a variable */
912 SCIP_EVENT** event, /**< pointer to store the event */
913 BMS_BLKMEM* blkmem, /**< block memory */
914 SCIP_VAR* var, /**< variable whose bound changed */
915 SCIP_Real left, /**< left bound of open interval in hole */
916 SCIP_Real right /**< right bound of open interval in hole */
917 )
918{
919 assert(event != NULL);
920 assert(blkmem != NULL);
921
922 /* create event data */
923 SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
924 (*event)->eventtype = SCIP_EVENTTYPE_LHOLEREMOVED;
925 (*event)->data.eventhole.var = var;
926 (*event)->data.eventhole.left = left;
927 (*event)->data.eventhole.right = right;
928
929 return SCIP_OKAY;
930}
931
932/** creates an event for an addition to the variable's implications list, clique or variable bounds information */
934 SCIP_EVENT** event, /**< pointer to store the event */
935 BMS_BLKMEM* blkmem, /**< block memory */
936 SCIP_VAR* var /**< variable that was fixed */
937 )
938{
939 assert(event != NULL);
940 assert(blkmem != NULL);
942
943 /* create event data */
944 SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
945 (*event)->eventtype = SCIP_EVENTTYPE_IMPLADDED;
946 (*event)->data.eventimpladd.var = var;
947
948 return SCIP_OKAY;
949}
950
951/** creates an event for changing the type of a variable */
953 SCIP_EVENT** event, /**< pointer to store the event */
954 BMS_BLKMEM* blkmem, /**< block memory */
955 SCIP_VAR* var, /**< variable whose type changed */
956 SCIP_VARTYPE oldtype, /**< old variable type */
957 SCIP_VARTYPE newtype /**< new variable type */
958 )
959{
960 assert(event != NULL);
961 assert(blkmem != NULL);
962 assert(oldtype != newtype);
963
964 /* create event data */
965 SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
966 (*event)->eventtype = SCIP_EVENTTYPE_TYPECHANGED;
967 (*event)->data.eventtypechg.var = var;
968 (*event)->data.eventtypechg.oldtype = oldtype;
969 (*event)->data.eventtypechg.newtype = newtype;
970
971 return SCIP_OKAY;
972}
973
974/** creates an event for changing the implied integral type of a variable */
976 SCIP_EVENT** event, /**< pointer to store the event */
977 BMS_BLKMEM* blkmem, /**< block memory */
978 SCIP_VAR* var, /**< variable whose implied type changed */
979 SCIP_IMPLINTTYPE oldtype, /**< old variable implied type */
980 SCIP_IMPLINTTYPE newtype /**< new variable implied type */
981 )
982{
983 assert(event != NULL);
984 assert(blkmem != NULL);
985 assert(oldtype != newtype);
986
987 /* create event data */
988 SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
989 (*event)->eventtype = SCIP_EVENTTYPE_IMPLTYPECHANGED;
990 (*event)->data.eventimpltypechg.var = var;
991 (*event)->data.eventimpltypechg.oldtype = oldtype;
992 (*event)->data.eventimpltypechg.newtype = newtype;
993
994 return SCIP_OKAY;
995}
996
997/** creates an event for the addition of a linear row to the separation storage */
999 SCIP_EVENT** event, /**< pointer to store the event */
1000 BMS_BLKMEM* blkmem, /**< block memory */
1001 SCIP_ROW* row /**< row that was added to the separation storage*/
1002 )
1003{
1004 assert(event != NULL);
1005 assert(blkmem != NULL);
1006 assert(row != NULL);
1007
1008 /* create event data */
1009 SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
1010 (*event)->eventtype = SCIP_EVENTTYPE_ROWADDEDSEPA;
1011 (*event)->data.eventrowaddedsepa.row = row;
1012
1013 return SCIP_OKAY;
1014}
1015
1016/** creates an event for the deletion of a linear row from the separation storage */
1018 SCIP_EVENT** event, /**< pointer to store the event */
1019 BMS_BLKMEM* blkmem, /**< block memory */
1020 SCIP_ROW* row /**< row that was deleted from the separation storage */
1021 )
1022{
1023 assert(event != NULL);
1024 assert(blkmem != NULL);
1025 assert(row != NULL);
1026
1027 /* create event data */
1028 SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
1029 (*event)->eventtype = SCIP_EVENTTYPE_ROWDELETEDSEPA;
1030 (*event)->data.eventrowdeletedsepa.row = row;
1031
1032 return SCIP_OKAY;
1033}
1034
1035/** creates an event for the addition of a linear row to the LP */
1037 SCIP_EVENT** event, /**< pointer to store the event */
1038 BMS_BLKMEM* blkmem, /**< block memory */
1039 SCIP_ROW* row /**< row that was added to the LP */
1040 )
1041{
1042 assert(event != NULL);
1043 assert(blkmem != NULL);
1044 assert(row != NULL);
1045
1046 /* create event data */
1047 SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
1048 (*event)->eventtype = SCIP_EVENTTYPE_ROWADDEDLP;
1049 (*event)->data.eventrowaddedlp.row = row;
1050
1051 return SCIP_OKAY;
1052}
1053
1054/** creates an event for the deletion of a linear row from the LP */
1056 SCIP_EVENT** event, /**< pointer to store the event */
1057 BMS_BLKMEM* blkmem, /**< block memory */
1058 SCIP_ROW* row /**< row that was deleted from the LP */
1059 )
1060{
1061 assert(event != NULL);
1062 assert(blkmem != NULL);
1063 assert(row != NULL);
1064
1065 /* create event data */
1066 SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
1067 (*event)->eventtype = SCIP_EVENTTYPE_ROWDELETEDLP;
1068 (*event)->data.eventrowdeletedlp.row = row;
1069
1070 return SCIP_OKAY;
1071}
1072
1073/** creates an event for the change of a coefficient in a linear row */
1075 SCIP_EVENT** event, /**< pointer to store the event */
1076 BMS_BLKMEM* blkmem, /**< block memory */
1077 SCIP_ROW* row, /**< row in which a coefficient changed */
1078 SCIP_COL* col, /**< column which coefficient changed */
1079 SCIP_Real oldval, /**< old value of coefficient */
1080 SCIP_Real newval /**< new value of coefficient */
1081 )
1082{
1083 assert(event != NULL);
1084 assert(blkmem != NULL);
1085 assert(row != NULL);
1086
1087 /* create event data */
1088 SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
1089 (*event)->eventtype = SCIP_EVENTTYPE_ROWCOEFCHANGED;
1090 (*event)->data.eventrowcoefchanged.row = row;
1091 (*event)->data.eventrowcoefchanged.col = col;
1092 (*event)->data.eventrowcoefchanged.oldval = oldval;
1093 (*event)->data.eventrowcoefchanged.newval = newval;
1094
1095 return SCIP_OKAY;
1096}
1097
1098/** creates an event for the change of a constant in a linear row */
1100 SCIP_EVENT** event, /**< pointer to store the event */
1101 BMS_BLKMEM* blkmem, /**< block memory */
1102 SCIP_ROW* row, /**< row in which the constant changed */
1103 SCIP_Real oldval, /**< old value of constant */
1104 SCIP_Real newval /**< new value of constant */
1105 )
1106{
1107 assert(event != NULL);
1108 assert(blkmem != NULL);
1109 assert(row != NULL);
1110
1111 /* create event data */
1112 SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
1113 (*event)->eventtype = SCIP_EVENTTYPE_ROWCONSTCHANGED;
1114 (*event)->data.eventrowconstchanged.row = row;
1115 (*event)->data.eventrowconstchanged.oldval = oldval;
1116 (*event)->data.eventrowconstchanged.newval = newval;
1117
1118 return SCIP_OKAY;
1119}
1120
1121/** creates an event for the change of a side of a linear row */
1123 SCIP_EVENT** event, /**< pointer to store the event */
1124 BMS_BLKMEM* blkmem, /**< block memory */
1125 SCIP_ROW* row, /**< row which side has changed */
1126 SCIP_SIDETYPE side, /**< which side has changed */
1127 SCIP_Real oldval, /**< old value of side */
1128 SCIP_Real newval /**< new value of side */
1129 )
1130{
1131 assert(event != NULL);
1132 assert(blkmem != NULL);
1133 assert(row != NULL);
1134
1135 /* create event data */
1136 SCIP_ALLOC( BMSallocBlockMemory(blkmem, event) );
1137 (*event)->eventtype = SCIP_EVENTTYPE_ROWSIDECHANGED;
1138 (*event)->data.eventrowsidechanged.row = row;
1139 (*event)->data.eventrowsidechanged.side = side;
1140 (*event)->data.eventrowsidechanged.oldval = oldval;
1141 (*event)->data.eventrowsidechanged.newval = newval;
1142
1143 return SCIP_OKAY;
1144}
1145
1147 SCIP_EVENT* event, /**< event to free */
1148 BMS_BLKMEM* blkmem /**< block memory buffer */
1149 )
1150{
1151 assert(event != NULL);
1152 assert(blkmem != NULL);
1153
1154 if( ((event)->eventtype & (SCIP_EVENTTYPE_BOUNDCHANGED | SCIP_EVENTTYPE_GBDCHANGED)) && (event)->data.eventbdchg.newboundexact != NULL )
1155 {
1156 SCIPrationalFreeBlock(blkmem, &(event)->data.eventbdchg.newboundexact);
1157 SCIPrationalFreeBlock(blkmem, &(event)->data.eventbdchg.oldboundexact);
1158 }
1159
1160 if( ((event)->eventtype & SCIP_EVENTTYPE_OBJCHANGED) && (event)->data.eventobjchg.newobjexact != NULL )
1161 {
1162 SCIPrationalFreeBlock(blkmem, &(event)->data.eventobjchg.newobjexact);
1163 SCIPrationalFreeBlock(blkmem, &(event)->data.eventobjchg.oldobjexact);
1164 }
1165}
1166
1167/** frees an event */
1169 SCIP_EVENT** event, /**< event to free */
1170 BMS_BLKMEM* blkmem /**< block memory buffer */
1171 )
1172{
1173 assert(event != NULL);
1174 assert(blkmem != NULL);
1175
1176 eventFreeExactData(*event, blkmem);
1177 BMSfreeBlockMemory(blkmem, event);
1178
1179 return SCIP_OKAY;
1180}
1181
1182/** disables an event */
1183static
1185 SCIP_EVENT* event /**< event to disable */
1186 )
1187{
1188 assert(event != NULL);
1189
1190 event->eventtype = SCIP_EVENTTYPE_DISABLED;
1191}
1192
1193/** gets type of event */
1195 SCIP_EVENT* event /**< event */
1196 )
1197{
1198 assert(event != NULL);
1199
1200 return event->eventtype;
1201}
1202
1203/** sets type of event */
1205 SCIP_EVENT* event, /**< event */
1206 SCIP_EVENTTYPE eventtype /**< new event type */
1207 )
1208{
1209 assert(event != NULL);
1210
1211 event->eventtype = eventtype;
1212
1213 return SCIP_OKAY;
1214}
1215
1216/** gets variable for a variable event (var added, var deleted, var fixed, objective value or domain change) */
1218 SCIP_EVENT* event /**< event */
1219 )
1220{
1221 assert(event != NULL);
1222
1223 switch( event->eventtype )
1224 {
1226 assert(event->data.eventvaradded.var != NULL);
1227 return event->data.eventvaradded.var;
1228
1230 assert(event->data.eventvardeleted.var != NULL);
1231 return event->data.eventvardeleted.var;
1232
1234 assert(event->data.eventvarfixed.var != NULL);
1235 return event->data.eventvarfixed.var;
1236
1238 assert(event->data.eventvarunlocked.var != NULL);
1239 return event->data.eventvarunlocked.var;
1240
1242 assert(event->data.eventobjchg.var != NULL);
1243 return event->data.eventobjchg.var;
1244
1251 assert(event->data.eventbdchg.var != NULL);
1252 return event->data.eventbdchg.var;
1253
1258 assert(event->data.eventhole.var != NULL);
1259 return event->data.eventhole.var;
1260
1262 assert(event->data.eventimpladd.var != NULL);
1263 return event->data.eventimpladd.var;
1264
1266 assert(event->data.eventtypechg.var != NULL);
1267 return event->data.eventtypechg.var;
1268
1270 assert(event->data.eventimpltypechg.var != NULL);
1271 return event->data.eventimpltypechg.var;
1272
1273 default:
1274 SCIPerrorMessage("event does not belong to a variable\n");
1275 SCIPABORT();
1276 return NULL; /*lint !e527*/
1277 } /*lint !e788*/
1278}
1279
1280/** sets variable for a variable event */
1282 SCIP_EVENT* event, /**< event */
1283 SCIP_VAR* var /**< new variable */
1284 )
1285{
1286 assert(event != NULL);
1287
1288 switch( event->eventtype )
1289 {
1291 assert(event->data.eventvaradded.var != NULL);
1292 event->data.eventvaradded.var = var;
1293 break;
1294
1296 assert(event->data.eventvardeleted.var != NULL);
1297 event->data.eventvardeleted.var = var;
1298 break;
1299
1301 assert(event->data.eventvarfixed.var != NULL);
1302 event->data.eventvarfixed.var = var;
1303 break;
1304
1306 assert(event->data.eventvarunlocked.var != NULL);
1307 event->data.eventvarunlocked.var = var;
1308 break;
1309
1311 assert(event->data.eventobjchg.var != NULL);
1312 event->data.eventobjchg.var = var;
1313 break;
1314
1321 assert(event->data.eventbdchg.var != NULL);
1322 event->data.eventbdchg.var = var;
1323 break;
1324
1329 assert(event->data.eventhole.var != NULL);
1330 event->data.eventhole.var = var;
1331 break;
1332
1334 assert(event->data.eventimpladd.var != NULL);
1335 event->data.eventimpladd.var = var;
1336 break;
1337
1339 assert(event->data.eventtypechg.var != NULL);
1340 event->data.eventtypechg.var = var;
1341 break;
1342
1344 assert(event->data.eventimpltypechg.var != NULL);
1345 event->data.eventimpltypechg.var = var;
1346 break;
1347
1348 default:
1349 SCIPerrorMessage("event does not belong to a variable\n");
1350 return SCIP_INVALIDDATA;
1351 } /*lint !e788*/
1352
1353 return SCIP_OKAY;
1354}
1355
1356/** gets old objective value for an objective value change event */
1358 SCIP_EVENT* event /**< event */
1359 )
1360{
1361 assert(event != NULL);
1362
1363 if( event->eventtype != SCIP_EVENTTYPE_OBJCHANGED )
1364 {
1365 SCIPerrorMessage("event is not an objective value change event\n");
1366 SCIPABORT();
1367 return SCIP_INVALID; /*lint !e527*/
1368 }
1369
1370 return event->data.eventobjchg.oldobj;
1371}
1372
1373/** gets new objective value for an objective value change event */
1375 SCIP_EVENT* event /**< event */
1376 )
1377{
1378 assert(event != NULL);
1379
1380 if( event->eventtype != SCIP_EVENTTYPE_OBJCHANGED )
1381 {
1382 SCIPerrorMessage("event is not an objective value change event\n");
1383 SCIPABORT();
1384 return SCIP_INVALID; /*lint !e527*/
1385 }
1386
1387 return event->data.eventobjchg.newobj;
1388}
1389
1390/** gets old bound for a bound change event */
1392 SCIP_EVENT* event /**< event */
1393 )
1394{
1395 assert(event != NULL);
1396
1397 switch( event->eventtype )
1398 {
1405 return event->data.eventbdchg.oldbound;
1406
1407 default:
1408 SCIPerrorMessage("event is not a bound change event\n");
1409 SCIPABORT();
1410 return 0.0; /*lint !e527*/
1411 } /*lint !e788*/
1412}
1413
1414/** gets new bound for a bound change event */
1416 SCIP_EVENT* event /**< event */
1417 )
1418{
1419 assert(event != NULL);
1420
1421 switch( event->eventtype )
1422 {
1429 return event->data.eventbdchg.newbound;
1430
1431 default:
1432 SCIPerrorMessage("event is not a bound change event\n");
1433 SCIPABORT();
1434 return 0.0; /*lint !e527*/
1435 } /*lint !e788*/
1436}
1437
1438/** gets new bound for a bound change event */
1440 SCIP_EVENT* event /**< event */
1441 )
1442{
1443 assert(event != NULL);
1444 switch( event->eventtype )
1445 {
1452 return event->data.eventbdchg.oldboundexact;
1453
1454 default:
1455 SCIPerrorMessage("event is not a bound change event\n");
1456 SCIPABORT();
1457 return NULL;
1458 } /*lint !e788*/
1459}
1460
1461/** gets old variable type for a variable type change event */
1463 SCIP_EVENT* event /**< event */
1464 )
1465{
1466 assert(event != NULL);
1467
1469 {
1470 SCIPerrorMessage("event is not an variable type change event\n");
1471 SCIPABORT();
1472 return SCIP_VARTYPE_CONTINUOUS; /*lint !e527*/
1473 }
1474
1475 return event->data.eventtypechg.oldtype;
1476}
1477
1478/** gets new variable type for a variable type change event */
1480 SCIP_EVENT* event /**< event */
1481 )
1482{
1483 assert(event != NULL);
1484
1486 {
1487 SCIPerrorMessage("event is not an variable type change event\n");
1488 SCIPABORT();
1489 return SCIP_VARTYPE_CONTINUOUS; /*lint !e527*/
1490 }
1491
1492 return event->data.eventtypechg.newtype;
1493}
1494
1495/** gets old implied integral type for an implied integral type change event */
1497 SCIP_EVENT* event /**< event */
1498 )
1499{
1500 assert(event != NULL);
1501
1503 {
1504 SCIPerrorMessage("event is not an implied integral type change event\n");
1505 SCIPABORT();
1506 return SCIP_IMPLINTTYPE_NONE; /*lint !e527*/
1507 }
1508
1509 return event->data.eventimpltypechg.oldtype;
1510}
1511
1512/** gets new implied integral type for an implied integral type change event */
1514 SCIP_EVENT* event /**< event */
1515 )
1516{
1517 assert(event != NULL);
1518
1520 {
1521 SCIPerrorMessage("event is not an implied integral type change event\n");
1522 SCIPABORT();
1523 return SCIP_IMPLINTTYPE_NONE; /*lint !e527*/
1524 }
1525
1526 return event->data.eventimpltypechg.newtype;
1527}
1528
1529/** gets node for a node or LP event */
1531 SCIP_EVENT* event /**< event */
1532 )
1533{
1534 assert(event != NULL);
1535
1537 {
1538 SCIPerrorMessage("event is neither node nor LP event\n");
1539 SCIPABORT();
1540 return NULL; /*lint !e527*/
1541 }
1542
1543 return event->data.node;
1544}
1545
1546/** sets node for a node or LP event */
1548 SCIP_EVENT* event, /**< event */
1549 SCIP_NODE* node /**< new node */
1550 )
1551{
1552 assert(event != NULL);
1553
1555 {
1556 SCIPerrorMessage("event is neither node nor LP event\n");
1557 SCIPABORT();
1558 return SCIP_INVALIDDATA; /*lint !e527*/
1559 }
1560
1561 event->data.node = node;
1562
1563 return SCIP_OKAY;
1564}
1565
1566/** gets solution for a primal solution event */
1568 SCIP_EVENT* event /**< event */
1569 )
1570{
1571 assert(event != NULL);
1572
1573 if( (event->eventtype & SCIP_EVENTTYPE_SOLEVENT) == 0 )
1574 {
1575 SCIPerrorMessage("event is not a primal solution event\n");
1576 SCIPABORT();
1577 return NULL; /*lint !e527*/
1578 }
1579
1580 return event->data.sol;
1581}
1582
1583/** sets solution for a primal solution event */
1585 SCIP_EVENT* event, /**< event */
1586 SCIP_SOL* sol /**< new primal solution */
1587 )
1588{
1589 assert(event != NULL);
1590
1591 if( (event->eventtype & SCIP_EVENTTYPE_SOLEVENT) == 0 )
1592 {
1593 SCIPerrorMessage("event is not a primal solution event\n");
1594 SCIPABORT();
1595 return SCIP_INVALIDDATA; /*lint !e527*/
1596 }
1597
1598 event->data.sol = sol;
1599
1600 return SCIP_OKAY;
1601}
1602
1603/** gets the left bound of open interval in the hole */
1605 SCIP_EVENT* event /**< event */
1606 )
1607{
1608 assert(event != NULL);
1609
1610 if( (event->eventtype & SCIP_EVENTTYPE_HOLECHANGED) == 0 )
1611 {
1612 SCIPerrorMessage("event is not a hole added or removed event\n");
1613 SCIPABORT();
1614 return SCIP_INVALID; /*lint !e527*/
1615 }
1616
1617 return event->data.eventhole.left;
1618}
1619
1620/** gets the right bound of open interval in the hole */
1622 SCIP_EVENT* event /**< event */
1623 )
1624{
1625 assert(event != NULL);
1626
1627 if( (event->eventtype & SCIP_EVENTTYPE_HOLECHANGED) == 0 )
1628 {
1629 SCIPerrorMessage("event is not a hole added or removed event\n");
1630 SCIPABORT();
1631 return SCIP_INVALID; /*lint !e527*/
1632 }
1633
1634 return event->data.eventhole.right;
1635}
1636
1637/** gets row for a row event */
1639 SCIP_EVENT* event /**< event */
1640 )
1641{
1642 assert(event != NULL);
1643
1644 switch( event->eventtype )
1645 {
1647 return event->data.eventrowaddedsepa.row;
1649 return event->data.eventrowdeletedsepa.row;
1651 return event->data.eventrowaddedlp.row;
1652 case SCIP_EVENTTYPE_ROWDELETEDLP: /*lint !e30 !e142*/
1653 return event->data.eventrowdeletedlp.row;
1654 case SCIP_EVENTTYPE_ROWCOEFCHANGED: /*lint !e30 !e142*/
1655 return event->data.eventrowcoefchanged.row;
1656 case SCIP_EVENTTYPE_ROWCONSTCHANGED: /*lint !e30 !e142*/
1657 return event->data.eventrowconstchanged.row;
1658 case SCIP_EVENTTYPE_ROWSIDECHANGED: /*lint !e30 !e142*/
1659 return event->data.eventrowsidechanged.row;
1660 default:
1661 SCIPerrorMessage("event does not belong to a row\n");
1662 SCIPABORT();
1663 return NULL; /*lint !e527*/
1664 }
1665}
1666
1667/** gets column for a row change coefficient event */
1669 SCIP_EVENT* event /**< event */
1670 )
1671{
1672 assert(event != NULL);
1673
1674 if( (event->eventtype & SCIP_EVENTTYPE_ROWCOEFCHANGED) == 0 ) /*lint !e587*/
1675 {
1676 SCIPerrorMessage("event is not a row coefficient changed event\n");
1677 SCIPABORT();
1678 return NULL; /*lint !e527*/
1679 }
1680
1681 return event->data.eventrowcoefchanged.col;
1682}
1683
1684/** gets old coefficient value for a row change coefficient event */
1686 SCIP_EVENT* event /**< event */
1687 )
1688{
1689 assert(event != NULL);
1690
1691 if( (event->eventtype & SCIP_EVENTTYPE_ROWCOEFCHANGED) == 0 ) /*lint !e587*/
1692 {
1693 SCIPerrorMessage("event is not a row coefficient changed event\n");
1694 SCIPABORT();
1695 return SCIP_INVALID; /*lint !e527*/
1696 }
1697
1698 return event->data.eventrowcoefchanged.oldval;
1699}
1700
1701/** gets new coefficient value for a row change coefficient event */
1703 SCIP_EVENT* event /**< event */
1704 )
1705{
1706 assert(event != NULL);
1707
1708 if( (event->eventtype & SCIP_EVENTTYPE_ROWCOEFCHANGED) == 0 ) /*lint !e587*/
1709 {
1710 SCIPerrorMessage("event is not a row coefficient changed event\n");
1711 SCIPABORT();
1712 return SCIP_INVALID; /*lint !e527*/
1713 }
1714
1715 return event->data.eventrowcoefchanged.newval;
1716}
1717
1718/** gets old constant value for a row change constant event */
1720 SCIP_EVENT* event /**< event */
1721 )
1722{
1723 assert(event != NULL);
1724
1726 {
1727 SCIPerrorMessage("event is not a row coefficient changed event\n");
1728 SCIPABORT();
1729 return SCIP_INVALID; /*lint !e527*/
1730 }
1731
1732 return event->data.eventrowconstchanged.oldval;
1733}
1734
1735/** gets new constant value for a row change constant event */
1737 SCIP_EVENT* event /**< event */
1738 )
1739{
1740 assert(event != NULL);
1741
1743 {
1744 SCIPerrorMessage("event is not a row coefficient changed event\n");
1745 SCIPABORT();
1746 return SCIP_INVALID; /*lint !e527*/
1747 }
1748
1749 return event->data.eventrowconstchanged.newval;
1750}
1751
1752/** gets side for a row change side event */
1754 SCIP_EVENT* event /**< event */
1755 )
1756{
1757 assert(event != NULL);
1758
1760 {
1761 SCIPerrorMessage("event is not a row side changed event\n");
1762 SCIPABORT();
1763 return SCIP_SIDETYPE_LEFT; /*lint !e527*/
1764 }
1765
1766 return event->data.eventrowsidechanged.side;
1767}
1768
1769/** gets old side value for a row change side event */
1771 SCIP_EVENT* event /**< event */
1772 )
1773{
1774 assert(event != NULL);
1775
1777 {
1778 SCIPerrorMessage("event is not a row side changed event\n");
1779 SCIPABORT();
1780 return SCIP_INVALID; /*lint !e527*/
1781 }
1782
1783 return event->data.eventrowsidechanged.oldval;
1784}
1785
1786/** gets new side value for a row change side event */
1788 SCIP_EVENT* event /**< event */
1789 )
1790{
1791 assert(event != NULL);
1792
1794 {
1795 SCIPerrorMessage("event is not a row side changed event\n");
1796 SCIPABORT();
1797 return SCIP_INVALID; /*lint !e527*/
1798 }
1799
1800 return event->data.eventrowsidechanged.newval;
1801}
1802
1803/** processes event by calling the appropriate event handlers */
1805 SCIP_EVENT* event, /**< event */
1806 SCIP_SET* set, /**< global SCIP settings */
1807 SCIP_PRIMAL* primal, /**< primal data; only needed for objchanged events, or NULL */
1808 SCIP_LP* lp, /**< current LP data; only needed for obj/boundchanged events, or NULL */
1809 SCIP_BRANCHCAND* branchcand, /**< branching candidate storage; only needed for bound change events, or NULL */
1810 SCIP_EVENTFILTER* eventfilter /**< event filter for global events; not needed for variable specific events */
1811 )
1812{
1813 SCIP_VAR* var;
1814
1815 assert(event != NULL);
1816 assert((event->eventtype & SCIP_EVENTTYPE_OBJCHANGED) == 0 || primal != NULL);
1817 assert((event->eventtype & (SCIP_EVENTTYPE_BOUNDCHANGED | SCIP_EVENTTYPE_OBJCHANGED)) == 0 || lp != NULL);
1818 assert((event->eventtype & SCIP_EVENTTYPE_BOUNDCHANGED) == 0 || branchcand != NULL);
1819
1820 SCIPsetDebugMsg(set, "processing event of type 0x%" SCIP_EVENTTYPE_FORMAT "\n", event->eventtype);
1821
1822 switch( event->eventtype )
1823 {
1825 break;
1826
1842 case SCIP_EVENTTYPE_ROWDELETEDLP: /*lint !e30 !e142*/
1843 case SCIP_EVENTTYPE_ROWCOEFCHANGED: /*lint !e30 !e142*/
1844 case SCIP_EVENTTYPE_ROWCONSTCHANGED: /*lint !e30 !e142*/
1845 case SCIP_EVENTTYPE_ROWSIDECHANGED: /*lint !e30 !e142*/
1846 case SCIP_EVENTTYPE_SYNC: /*lint !e30 !e142*/
1847 SCIP_CALL( SCIPeventfilterProcess(eventfilter, set, event) );
1848 break;
1849
1851 var = event->data.eventvardeleted.var;
1852 assert(var != NULL);
1853
1854 /* process variable's event filter */
1856 break;
1857
1859 var = event->data.eventvarfixed.var;
1860 assert(var != NULL);
1861
1862 /* process variable's event filter */
1864 break;
1865
1867 var = event->data.eventvarunlocked.var;
1868 assert(var != NULL);
1869
1870 /* process variable's event filter */
1872 break;
1873
1875 var = event->data.eventobjchg.var;
1876 assert(var != NULL);
1877 assert(var->eventqueueindexobj == -1);
1879
1880 /* inform LP about the objective change */
1881 if( SCIPvarGetProbindex(var) >= 0 )
1882 {
1884 {
1886 }
1888 }
1889
1890 /* if in exact solving mode, adjust rational lp data */
1891 if( set->exact_enable )
1892 {
1893 SCIP_RATIONAL* newobj;
1894 SCIP_RATIONAL* oldobj;
1895
1896 if( event->data.eventobjchg.newobjexact != NULL )
1897 {
1898 newobj = event->data.eventobjchg.newobjexact;
1899 oldobj = event->data.eventobjchg.oldobjexact;
1900 }
1901 else
1902 {
1903 SCIP_CALL( SCIPrationalCreateBuffer(set->buffer, &newobj) );
1904 SCIP_CALL( SCIPrationalCreateBuffer(set->buffer, &oldobj) );
1907 }
1908
1910 {
1912 }
1913 SCIP_CALL( SCIPlpExactUpdateVarObj(set, lp->lpexact, var, oldobj, newobj) );
1914
1915 if( event->data.eventobjchg.newobjexact == NULL )
1916 {
1917 SCIPrationalFreeBuffer(set->buffer, &oldobj);
1918 SCIPrationalFreeBuffer(set->buffer, &newobj);
1919 }
1920 }
1921
1922 /* inform all existing primal solutions about the objective change (only if this is not a temporary change in
1923 * probing mode)
1924 */
1925 if( ! lp->divingobjchg )
1926 {
1928 }
1929
1930 /* process variable's event filter */
1932 break;
1933
1935 var = event->data.eventbdchg.var;
1936 assert(var != NULL);
1937
1938 /* inform LP about global bound change */
1940 {
1941 assert(SCIPvarGetProbindex(var) >= 0);
1943 event->data.eventbdchg.newbound) );
1944
1945 if( event->data.eventbdchg.newboundexact != NULL )
1946 {
1948 event->data.eventbdchg.newboundexact) );
1949 }
1950 }
1951
1952 /* process variable's event filter */
1954 break;
1955
1957 var = event->data.eventbdchg.var;
1958 assert(var != NULL);
1959
1960 /* inform LP about global bound change */
1962 {
1963 assert(SCIPvarGetProbindex(var) >= 0);
1965 event->data.eventbdchg.newbound) );
1966
1967 if( event->data.eventbdchg.newboundexact != NULL )
1968 {
1970 event->data.eventbdchg.newboundexact) );
1971 }
1972 }
1973
1974 /* process variable's event filter */
1976 break;
1977
1980 var = event->data.eventbdchg.var;
1981 assert(var != NULL);
1982 assert(var->eventqueueindexlb == -1);
1983
1984 /* inform LP about bound change and update branching candidates */
1986 {
1987 assert(SCIPvarGetProbindex(var) >= 0);
1989 {
1991 }
1993 event->data.eventbdchg.newbound) );
1994
1995 if( !lp->probing )
1996 {
1997 if( event->data.eventbdchg.newboundexact != NULL )
1998 {
2000 {
2002 }
2003
2005 event->data.eventbdchg.newboundexact) );
2006 }
2007 else
2008 {
2010 }
2011 }
2012
2013 SCIP_CALL( SCIPbranchcandUpdateVar(branchcand, set, var) );
2014 }
2015
2016 /* process variable's event filter */
2018 break;
2019
2022 var = event->data.eventbdchg.var;
2023 assert(var != NULL);
2024 assert(var->eventqueueindexub == -1);
2025
2026 /* inform LP about bound change and update branching candidates */
2028 {
2029 assert(SCIPvarGetProbindex(var) >= 0);
2031 {
2033 }
2035 event->data.eventbdchg.newbound) );
2036
2037 if( !lp->probing )
2038 {
2039 if( event->data.eventbdchg.newboundexact != NULL )
2040 {
2042 {
2044 }
2045
2047 event->data.eventbdchg.newboundexact) );
2048 }
2049 else
2050 {
2051 SCIP_CALL( updateLpExactBoundChange(var, lp->lpexact, set, event, TRUE, FALSE) );
2052 }
2053 }
2054
2055 SCIP_CALL( SCIPbranchcandUpdateVar(branchcand, set, var) );
2056 }
2057
2058 /* process variable's event filter */
2060 break;
2061
2066 var = event->data.eventhole.var;
2067 assert(var != NULL);
2068
2069 /* process variable's event filter */
2071 break;
2072
2074 var = event->data.eventimpladd.var;
2075 assert(var != NULL);
2076 assert(!var->eventqueueimpl);
2077
2078 /* process variable's event filter */
2080 break;
2081
2083 var = event->data.eventtypechg.var;
2084 assert(var != NULL);
2085
2086 /* process variable's event filter */
2088 break;
2089
2091 var = event->data.eventimpltypechg.var;
2092 assert(var != NULL);
2093
2094 /* process variable's event filter */
2096 break;
2097
2098 default:
2099 SCIPerrorMessage("unknown event type <%" SCIP_EVENTTYPE_FORMAT ">\n", event->eventtype);
2100 return SCIP_INVALIDDATA;
2101 }
2102
2103 return SCIP_OKAY;
2104}
2105
2106
2107
2108/*
2109 * Event filter methods
2110 */
2111
2112/** resizes eventfilter arrays to be able to store at least num entries */
2113static
2115 SCIP_EVENTFILTER* eventfilter, /**< event filter */
2116 BMS_BLKMEM* blkmem, /**< block memory buffer */
2117 SCIP_SET* set, /**< global SCIP settings */
2118 int num /**< minimal number of node slots in array */
2119 )
2120{
2121 assert(eventfilter != NULL);
2122 assert(blkmem != NULL);
2123 assert(set != NULL);
2124
2125 if( num > eventfilter->size )
2126 {
2127 int newsize;
2128
2129 newsize = SCIPsetCalcMemGrowSize(set, num);
2130 SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &eventfilter->eventtypes, eventfilter->size, newsize) );
2131 SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &eventfilter->eventhdlrs, eventfilter->size, newsize) );
2132 SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &eventfilter->eventdata, eventfilter->size, newsize) );
2133 SCIP_ALLOC( BMSreallocBlockMemoryArray(blkmem, &eventfilter->nextpos, eventfilter->size, newsize) );
2134 eventfilter->size = newsize;
2135 }
2136 assert(num <= eventfilter->size);
2137
2138 return SCIP_OKAY;
2139}
2140
2141/** creates an event filter */
2143 SCIP_EVENTFILTER** eventfilter, /**< pointer to store the event filter */
2144 BMS_BLKMEM* blkmem /**< block memory buffer */
2145 )
2146{
2147 assert(eventfilter != NULL);
2148 assert(blkmem != NULL);
2149
2150 SCIP_ALLOC( BMSallocBlockMemory(blkmem, eventfilter) );
2151 (*eventfilter)->eventtypes = NULL;
2152 (*eventfilter)->eventhdlrs = NULL;
2153 (*eventfilter)->eventdata = NULL;
2154 (*eventfilter)->nextpos = NULL;
2155 (*eventfilter)->size = 0;
2156 (*eventfilter)->len = 0;
2157 (*eventfilter)->firstfreepos = -1;
2158 (*eventfilter)->firstdeletedpos = -1;
2159 (*eventfilter)->eventmask = SCIP_EVENTTYPE_DISABLED;
2160 (*eventfilter)->delayedeventmask = SCIP_EVENTTYPE_DISABLED;
2161 (*eventfilter)->delayupdates = FALSE;
2162
2163 return SCIP_OKAY;
2164}
2165
2166/** frees an event filter and the associated event data entries */
2168 SCIP_EVENTFILTER** eventfilter, /**< pointer to store the event filter */
2169 BMS_BLKMEM* blkmem, /**< block memory buffer */
2170 SCIP_SET* set /**< global SCIP settings */
2171 )
2172{
2173 int i;
2174
2175 assert(eventfilter != NULL);
2176 assert(*eventfilter != NULL);
2177 assert(!(*eventfilter)->delayupdates);
2178 assert(blkmem != NULL);
2179 assert(set != NULL);
2180 assert(set->scip != NULL);
2181
2182 /* free event data */
2183 for( i = 0; i < (*eventfilter)->len; ++i )
2184 {
2185 if( (*eventfilter)->eventtypes[i] != SCIP_EVENTTYPE_DISABLED )
2186 {
2187 assert((*eventfilter)->eventhdlrs[i] != NULL);
2188 if( (*eventfilter)->eventhdlrs[i]->eventdelete != NULL )
2189 {
2190 SCIP_CALL( (*eventfilter)->eventhdlrs[i]->eventdelete(set->scip, (*eventfilter)->eventhdlrs[i],
2191 &(*eventfilter)->eventdata[i]) );
2192 }
2193 }
2194 }
2195
2196 /* free event filter data */
2197 BMSfreeBlockMemoryArrayNull(blkmem, &(*eventfilter)->eventtypes, (*eventfilter)->size);
2198 BMSfreeBlockMemoryArrayNull(blkmem, &(*eventfilter)->eventhdlrs, (*eventfilter)->size);
2199 BMSfreeBlockMemoryArrayNull(blkmem, &(*eventfilter)->eventdata, (*eventfilter)->size);
2200 BMSfreeBlockMemoryArrayNull(blkmem, &(*eventfilter)->nextpos, (*eventfilter)->size);
2201 BMSfreeBlockMemory(blkmem, eventfilter);
2202
2203 return SCIP_OKAY;
2204}
2205
2206/** adds element to event filter */
2208 SCIP_EVENTFILTER* eventfilter, /**< event filter */
2209 BMS_BLKMEM* blkmem, /**< block memory buffer */
2210 SCIP_SET* set, /**< global SCIP settings */
2211 SCIP_EVENTTYPE eventtype, /**< event type to catch */
2212 SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
2213 SCIP_EVENTDATA* eventdata, /**< event data to pass to the event handler for the event processing */
2214 int* filterpos /**< pointer to store position of event filter entry, or NULL */
2215 )
2216{
2217 int pos;
2218
2219 assert(eventfilter != NULL);
2220 assert(blkmem != NULL);
2221 assert(set != NULL);
2222 assert(eventhdlr != NULL);
2223
2224 if( eventfilter->delayupdates )
2225 {
2226 /* insert addition to the end of the arrays;
2227 * in delayed addition we have to add to the end of the arrays, in order to not destroy the validity of the
2228 * arrays we are currently iterating over
2229 */
2230 SCIP_CALL( eventfilterEnsureMem(eventfilter, blkmem, set, eventfilter->len + 1) );
2231 pos = eventfilter->len;
2232 eventfilter->len++;
2233
2234 /* update delayed event filter mask */
2235 eventfilter->delayedeventmask |= eventtype;
2236 }
2237 else
2238 {
2239 if( eventfilter->firstfreepos == -1 )
2240 {
2241 /* insert addition to the end of the arrays */
2242 SCIP_CALL( eventfilterEnsureMem(eventfilter, blkmem, set, eventfilter->len + 1) );
2243 pos = eventfilter->len;
2244 eventfilter->len++;
2245 }
2246 else
2247 {
2248 /* use the first free slot to store the added event filter entry */
2249 pos = eventfilter->firstfreepos;
2250 assert(0 <= pos && pos < eventfilter->len);
2251 assert(eventfilter->eventtypes[pos] == SCIP_EVENTTYPE_DISABLED);
2252 eventfilter->firstfreepos = eventfilter->nextpos[pos];
2253 assert(-1 <= eventfilter->firstfreepos && eventfilter->firstfreepos < eventfilter->len);
2254 }
2255
2256 /* update event filter mask */
2257 eventfilter->eventmask |= eventtype;
2258 }
2259 assert(0 <= pos && pos < eventfilter->len);
2260
2261 eventfilter->eventtypes[pos] = eventtype;
2262 eventfilter->eventhdlrs[pos] = eventhdlr;
2263 eventfilter->eventdata[pos] = eventdata;
2264 eventfilter->nextpos[pos] = -2;
2265
2266 if( filterpos != NULL )
2267 *filterpos = pos;
2268
2269 return SCIP_OKAY;
2270}
2271
2272/** linear search for the given entry in event filter */
2273static
2275 SCIP_EVENTFILTER*const eventfilter, /**< event filter */
2276 SCIP_EVENTTYPE const eventtype, /**< event type */
2277 SCIP_EVENTHDLR*const eventhdlr, /**< event handler to call for the event processing */
2278 SCIP_EVENTDATA*const eventdata /**< event data to pass to the event handler for the event processing */
2279 )
2280{
2281 int i;
2282
2283 assert(eventfilter != NULL);
2284 assert(eventtype != SCIP_EVENTTYPE_DISABLED);
2285 assert(eventhdlr != NULL);
2286
2287 for( i = eventfilter->len - 1; i >= 0; --i )
2288 {
2289 if( eventdata == eventfilter->eventdata[i]
2290 && eventhdlr == eventfilter->eventhdlrs[i]
2291 && eventtype == eventfilter->eventtypes[i]
2292 && eventfilter->nextpos[i] == -2 )
2293 return i;
2294 }
2295
2296 return -1;
2297}
2298
2299/** deletes element from event filter */
2301 SCIP_EVENTFILTER* eventfilter, /**< event filter */
2302 BMS_BLKMEM* blkmem, /**< block memory buffer */
2303 SCIP_SET* set, /**< global SCIP settings */
2304 SCIP_EVENTTYPE eventtype, /**< event type */
2305 SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
2306 SCIP_EVENTDATA* eventdata, /**< event data to pass to the event handler for the event processing */
2307 int filterpos /**< position of event filter entry, or -1 if unknown */
2308 )
2309{
2310 assert(eventfilter != NULL);
2311 assert(blkmem != NULL);
2312 assert(set != NULL);
2313 assert(eventtype != SCIP_EVENTTYPE_DISABLED);
2314 assert(eventhdlr != NULL);
2315 assert(-1 <= filterpos && filterpos < eventfilter->len);
2316
2317 /* search position of event filter entry, if not given by the user */
2318 if( filterpos == -1 )
2319 filterpos = eventfilterSearch(eventfilter, eventtype, eventhdlr, eventdata);
2320 if( filterpos == -1 )
2321 {
2322 SCIPerrorMessage("no event for event handler %p with data %p and event mask %" SCIP_EVENTTYPE_FORMAT " found in event filter %p\n",
2323 (void*)eventhdlr, (void*)eventdata, eventtype, (void*)eventfilter);
2324 return SCIP_INVALIDDATA;
2325 }
2326 assert(0 <= filterpos && filterpos < eventfilter->len);
2327 assert(eventfilter->eventtypes[filterpos] == eventtype);
2328 assert(eventfilter->eventhdlrs[filterpos] == eventhdlr);
2329 assert(eventfilter->eventdata[filterpos] == eventdata);
2330 assert(eventfilter->nextpos[filterpos] == -2);
2331
2332 /* if updates are delayed, insert entry into the list of delayed deletions;
2333 * otherwise, delete the entry from the filter directly and add the slot to the free list
2334 */
2335 if( eventfilter->delayupdates )
2336 {
2337 /* append filterpos to the list of deleted entries */
2338 eventfilter->nextpos[filterpos] = eventfilter->firstdeletedpos;
2339 eventfilter->firstdeletedpos = filterpos;
2340 }
2341 else
2342 {
2343 /* disable the entry in the filter and add the slot to the free list */
2344 assert(eventfilter->nextpos[filterpos] == -2);
2345 eventfilter->eventtypes[filterpos] = SCIP_EVENTTYPE_DISABLED;
2346 eventfilter->nextpos[filterpos] = eventfilter->firstfreepos;
2347 eventfilter->firstfreepos = filterpos;
2348 }
2349
2350 return SCIP_OKAY;
2351}
2352
2353/** makes the event filter to delay and buffer all updates until eventfilterProcessUpdates() is called */
2354static
2356 SCIP_EVENTFILTER* eventfilter /**< event filter */
2357 )
2358{
2359 assert(eventfilter != NULL);
2360 assert(!eventfilter->delayupdates);
2361 assert(eventfilter->delayedeventmask == SCIP_EVENTTYPE_DISABLED);
2362
2363 eventfilter->delayupdates = TRUE;
2364}
2365
2366/** processes all delayed additions and deletions */
2367static
2369 SCIP_EVENTFILTER* eventfilter /**< event filter */
2370 )
2371{
2372 int pos;
2373 int nextpos;
2374
2375 assert(eventfilter != NULL);
2376 assert(eventfilter->delayupdates);
2377
2378 /* move deleted entries into the free list and disable them */
2379 pos = eventfilter->firstdeletedpos;
2380 while( pos != -1 )
2381 {
2382 assert(0 <= pos && pos < eventfilter->len);
2383 assert(eventfilter->eventtypes[pos] != SCIP_EVENTTYPE_DISABLED);
2384 assert(eventfilter->nextpos[pos] >= -1);
2385
2386 nextpos = eventfilter->nextpos[pos];
2387 eventfilter->nextpos[pos] = eventfilter->firstfreepos;
2388 eventfilter->firstfreepos = pos;
2389 eventfilter->eventtypes[pos] = SCIP_EVENTTYPE_DISABLED;
2390 pos = nextpos;
2391 }
2392 eventfilter->firstdeletedpos = -1;
2393
2394 /* update event mask */
2395 eventfilter->eventmask |= eventfilter->delayedeventmask;
2397
2398 /* mark the event filter updates to be no longer delayed */
2399 eventfilter->delayupdates = FALSE;
2400}
2401
2402/** processes the event with all event handlers with matching filter setting */
2404 SCIP_EVENTFILTER* eventfilter, /**< event filter */
2405 SCIP_SET* set, /**< global SCIP settings */
2406 SCIP_EVENT* event /**< event to process */
2407 )
2408{
2409 SCIP_EVENTTYPE eventtype;
2410 SCIP_EVENTTYPE* eventtypes;
2411 SCIP_Bool processed;
2412 int len;
2413 int i;
2414
2415 assert(eventfilter != NULL);
2416 assert(set != NULL);
2417 assert(event != NULL);
2418
2419 SCIPsetDebugMsg(set, "processing event filter %p (len %d, mask 0x%" SCIP_EVENTTYPE_FORMAT ") with event type 0x%" SCIP_EVENTTYPE_FORMAT "\n",
2420 (void*)eventfilter, eventfilter->len, eventfilter->eventmask, event->eventtype);
2421
2422 eventtype = event->eventtype;
2423
2424 /* check if there may be any event handler for specific event */
2425 if( (eventtype & eventfilter->eventmask) == 0 )
2426 return SCIP_OKAY;
2427
2428 /* delay the updates on this eventfilter, such that changes during event processing to the event filter
2429 * don't destroy necessary information of the arrays we are currently using
2430 */
2431 eventfilterDelayUpdates(eventfilter);
2432
2433 /* process the event by calling the event handlers */
2434 processed = FALSE;
2435 len = eventfilter->len;
2436 eventtypes = eventfilter->eventtypes;
2437 for( i = 0; i < len; ++i )
2438 {
2439 /* check, if event is applicable for the filter element */
2440 if( (eventtype & eventtypes[i]) != 0 )
2441 {
2442 /* call event handler */
2443 SCIP_CALL( SCIPeventhdlrExec(eventfilter->eventhdlrs[i], set, event, eventfilter->eventdata[i]) );
2444 processed = TRUE;
2445 }
2446 }
2447
2448 /* update eventfilter mask, if event was not processed by any event handler */
2449 if( !processed )
2450 {
2451 eventfilter->eventmask &= ~event->eventtype;
2452 SCIPsetDebugMsg(set, " -> event type 0x%" SCIP_EVENTTYPE_FORMAT " not processed. new mask of event filter %p: 0x%" SCIP_EVENTTYPE_FORMAT "\n",
2453 event->eventtype, (void*)eventfilter, eventfilter->eventmask);
2454 }
2455
2456 /* process delayed events on this eventfilter */
2457 eventfilterProcessUpdates(eventfilter);
2458
2459 return SCIP_OKAY;
2460}
2461
2462
2463
2464/*
2465 * Event queue methods
2466 */
2467
2468/*
2469 * simple functions implemented as defines
2470 */
2471
2472/* In debug mode, the following methods are implemented as function calls to ensure
2473 * type validity.
2474 * In optimized mode, the methods are implemented as defines to improve performance.
2475 * However, we want to have them in the library anyways, so we have to undef the defines.
2476 */
2477
2478#undef SCIPeventqueueIsDelayed
2479
2480/** resizes events array to be able to store at least num entries */
2481static
2483 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
2484 SCIP_SET* set, /**< global SCIP settings */
2485 int num /**< minimal number of node slots in array */
2486 )
2487{
2488 assert(eventqueue != NULL);
2489 assert(set != NULL);
2490
2491 if( num > eventqueue->eventssize )
2492 {
2493 int newsize;
2494
2495 newsize = SCIPsetCalcMemGrowSize(set, num);
2496 SCIP_ALLOC( BMSreallocMemoryArray(&eventqueue->events, newsize) );
2497 eventqueue->eventssize = newsize;
2498 }
2499 assert(num <= eventqueue->eventssize);
2500
2501 return SCIP_OKAY;
2502}
2503
2504/** creates an event queue */
2506 SCIP_EVENTQUEUE** eventqueue /**< pointer to store the event queue */
2507 )
2508{
2509 assert(eventqueue != NULL);
2510
2511 SCIP_ALLOC( BMSallocMemory(eventqueue) );
2512 (*eventqueue)->events = NULL;
2513 (*eventqueue)->eventssize = 0;
2514 (*eventqueue)->nevents = 0;
2515 (*eventqueue)->delayevents = FALSE;
2516
2517 return SCIP_OKAY;
2518}
2519
2520/** frees event queue; there must not be any unprocessed events in the queue! */
2522 SCIP_EVENTQUEUE** eventqueue /**< pointer to the event queue */
2523 )
2524{
2525 assert(eventqueue != NULL);
2526 assert(*eventqueue != NULL);
2527 assert((*eventqueue)->nevents == 0);
2528
2529 BMSfreeMemoryArrayNull(&(*eventqueue)->events);
2530 BMSfreeMemory(eventqueue);
2531
2532 return SCIP_OKAY;
2533}
2534
2535/** appends event to the event queue; sets event to NULL afterwards */
2536static
2538 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
2539 SCIP_SET* set, /**< global SCIP settings */
2540 SCIP_EVENT** event /**< pointer to event to append to the queue */
2541 )
2542{
2543 assert(eventqueue != NULL);
2544 assert(eventqueue->delayevents);
2545 assert(event != NULL);
2546 assert(*event != NULL);
2547
2548 SCIPsetDebugMsg(set, "appending event %p of type 0x%" SCIP_EVENTTYPE_FORMAT " to event queue %p at position %d\n",
2549 (void*)*event, (*event)->eventtype, (void*)eventqueue, eventqueue->nevents);
2550
2551 SCIP_CALL( eventqueueEnsureEventsMem(eventqueue, set, eventqueue->nevents+1) );
2552 eventqueue->events[eventqueue->nevents] = *event;
2553 eventqueue->nevents++;
2554
2555 *event = NULL;
2556
2557 return SCIP_OKAY;
2558}
2559
2560/** processes event or adds event to the event queue */
2562 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
2563 BMS_BLKMEM* blkmem, /**< block memory buffer */
2564 SCIP_SET* set, /**< global SCIP settings */
2565 SCIP_PRIMAL* primal, /**< primal data; only needed for objchanged events, or NULL */
2566 SCIP_LP* lp, /**< current LP data; only needed for obj/boundchanged events, or NULL */
2567 SCIP_BRANCHCAND* branchcand, /**< branching candidate storage; only needed for bound change events, or NULL */
2568 SCIP_EVENTFILTER* eventfilter, /**< event filter for global events; not needed for variable specific events */
2569 SCIP_EVENT** event /**< pointer to event to add to the queue; will be NULL after queue addition */
2570 )
2571{
2572 SCIP_VAR* var;
2573 SCIP_EVENT* qevent;
2574 int pos;
2575
2576 assert(eventqueue != NULL);
2577 assert(event != NULL);
2578 assert(*event != NULL);
2579 assert(((*event)->eventtype & SCIP_EVENTTYPE_OBJCHANGED) == 0 || primal != NULL);
2580 assert(((*event)->eventtype & (SCIP_EVENTTYPE_BOUNDCHANGED | SCIP_EVENTTYPE_OBJCHANGED)) == 0 || lp != NULL);
2581 assert(((*event)->eventtype & SCIP_EVENTTYPE_BOUNDCHANGED) == 0 || branchcand != NULL);
2582
2583 if( !eventqueue->delayevents )
2584 {
2585 SCIP_CALL( SCIPeventqueueDelay(eventqueue) );
2586
2587 /* immediately process event */
2588 SCIP_CALL( SCIPeventProcess(*event, set, primal, lp, branchcand, eventfilter) );
2589 SCIP_CALL( SCIPeventFree(event, blkmem) );
2590
2591 SCIP_CALL( SCIPeventqueueProcess(eventqueue, blkmem, set, primal, lp, branchcand, eventfilter) );
2592 }
2593 else
2594 {
2595 /* delay processing of event by appending it to the event queue */
2596 SCIPsetDebugMsg(set, "adding event %p of type 0x%" SCIP_EVENTTYPE_FORMAT " to event queue %p\n", (void*)*event, (*event)->eventtype, (void*)eventqueue);
2597
2598 switch( (*event)->eventtype )
2599 {
2601 SCIPerrorMessage("cannot add a disabled event to the event queue\n");
2602 return SCIP_INVALIDDATA;
2603
2625 case SCIP_EVENTTYPE_ROWADDEDSEPA: /* @todo remove previous DELETEDSEPA event */
2626 case SCIP_EVENTTYPE_ROWDELETEDSEPA: /* @todo remove previous ADDEDSEPA event */
2627 case SCIP_EVENTTYPE_ROWADDEDLP: /* @todo remove previous DELETEDLP event */
2628 case SCIP_EVENTTYPE_ROWDELETEDLP: /* @todo remove previous ADDEDLP event */ /*lint !e30 !e142*/
2629 case SCIP_EVENTTYPE_ROWCOEFCHANGED: /* @todo merge? */ /*lint !e30 !e142*/
2630 case SCIP_EVENTTYPE_ROWCONSTCHANGED: /* @todo merge with previous constchanged event */ /*lint !e30 !e142*/
2631 case SCIP_EVENTTYPE_ROWSIDECHANGED: /* @todo merge with previous sidechanged event */ /*lint !e30 !e142*/
2632 case SCIP_EVENTTYPE_SYNC: /*lint !e30 !e142*/
2633 /* these events cannot (or need not) be merged; just add them to the queue */
2634 SCIP_CALL( eventqueueAppend(eventqueue, set, event) );
2635 break;
2636
2638 /* changes in objective value may be merged with older changes in objective value */
2639 var = (*event)->data.eventobjchg.var;
2640 assert(var != NULL);
2641 pos = var->eventqueueindexobj;
2642 if( pos >= 0 )
2643 {
2644 /* the objective value change event already exists -> modify it accordingly */
2645 assert(pos < eventqueue->nevents);
2646 qevent = eventqueue->events[pos];
2647 assert(qevent != NULL);
2648 assert(qevent->eventtype == SCIP_EVENTTYPE_OBJCHANGED);
2649 assert(qevent->data.eventobjchg.var == var);
2650 assert(SCIPsetIsEQ(set, (*event)->data.eventobjchg.oldobj, qevent->data.eventobjchg.newobj));
2651
2652 SCIPsetDebugMsg(set, " -> merging OBJ event (<%s>,%g -> %g) with event at position %d (<%s>,%g -> %g)\n",
2653 SCIPvarGetName((*event)->data.eventobjchg.var), (*event)->data.eventobjchg.oldobj,
2654 (*event)->data.eventobjchg.newobj,
2655 pos, SCIPvarGetName(qevent->data.eventobjchg.var), qevent->data.eventobjchg.oldobj,
2656 qevent->data.eventobjchg.newobj);
2657
2658 qevent->data.eventobjchg.newobj = (*event)->data.eventobjchg.newobj;
2659 if( qevent->data.eventobjchg.newobj == qevent->data.eventobjchg.oldobj ) /*lint !e777*/
2660 {
2661 /* the queued objective value change was reversed -> disable the event in the queue */
2662 eventFreeExactData(qevent, blkmem);
2663 eventDisable(qevent);
2664 var->eventqueueindexobj = -1;
2665 SCIPsetDebugMsg(set, " -> event disabled\n");
2666 }
2667
2668 /* free the event that is of no use any longer */
2669 SCIP_CALL( SCIPeventFree(event, blkmem) );
2670 }
2671 else
2672 {
2673 /* the objective value change event doesn't exist -> add it to the queue, and remember the array index */
2674 var->eventqueueindexobj = eventqueue->nevents;
2675 SCIP_CALL( eventqueueAppend(eventqueue, set, event) );
2676 }
2677 break;
2678
2681 /* changes in lower bound may be merged with older changes in lower bound */
2682 var = (*event)->data.eventbdchg.var;
2683 assert(var != NULL);
2684 pos = var->eventqueueindexlb;
2685 if( pos >= 0 )
2686 {
2687 /* the lower bound change event already exists -> modify it accordingly */
2688 assert(pos < eventqueue->nevents);
2689 qevent = eventqueue->events[pos];
2690 assert(qevent != NULL);
2692 assert(qevent->data.eventbdchg.var == var);
2693 assert(SCIPsetIsEQ(set, (*event)->data.eventbdchg.oldbound, qevent->data.eventbdchg.newbound));
2694
2695 SCIPsetDebugMsg(set, " -> merging LB event (<%s>,%g -> %g) with event at position %d (<%s>,%g -> %g)\n",
2696 SCIPvarGetName((*event)->data.eventbdchg.var), (*event)->data.eventbdchg.oldbound,
2697 (*event)->data.eventbdchg.newbound,
2698 pos, SCIPvarGetName(qevent->data.eventbdchg.var), qevent->data.eventbdchg.oldbound,
2699 qevent->data.eventbdchg.newbound);
2700
2701 qevent->data.eventbdchg.newbound = (*event)->data.eventbdchg.newbound;
2702
2703 /* possibly update exact bound */
2704 if( (*event)->data.eventbdchg.newboundexact != NULL )
2705 {
2706 if( qevent->data.eventbdchg.newboundexact == NULL )
2707 {
2708 SCIP_CALL( SCIPeventAddExactBdChg(qevent, blkmem, (*event)->data.eventbdchg.oldboundexact, (*event)->data.eventbdchg.newboundexact) );
2709 }
2710 else
2711 SCIPrationalSetRational(qevent->data.eventbdchg.newboundexact, (*event)->data.eventbdchg.newboundexact);
2712 }
2713 else
2714 {
2715 if( qevent->data.eventbdchg.newboundexact != NULL )
2716 {
2719 }
2720 }
2721
2722 /*if( SCIPsetIsLT(set, qevent->data.eventbdchg.newbound, qevent->data.eventbdchg.oldbound) )*/
2723 if( qevent->data.eventbdchg.newbound < qevent->data.eventbdchg.oldbound )
2725 /*else if( SCIPsetIsGT(set, qevent->data.eventbdchg.newbound, qevent->data.eventbdchg.oldbound) )*/
2726 else if( qevent->data.eventbdchg.newbound > qevent->data.eventbdchg.oldbound )
2728 else
2729 {
2730 /* the queued bound change was reversed -> disable the event in the queue */
2731 assert(qevent->data.eventbdchg.newbound == qevent->data.eventbdchg.oldbound); /*lint !e777*/
2732 eventFreeExactData(qevent, blkmem);
2733 eventDisable(qevent);
2734 var->eventqueueindexlb = -1;
2735 SCIPsetDebugMsg(set, " -> event disabled\n");
2736 }
2737
2738 /* free the event that is of no use any longer */
2739 SCIP_CALL( SCIPeventFree(event, blkmem) );
2740 }
2741 else
2742 {
2743 /* the lower bound change event doesn't exist -> add it to the queue, and remember the array index */
2744 var->eventqueueindexlb = eventqueue->nevents;
2745 SCIP_CALL( eventqueueAppend(eventqueue, set, event) );
2746 }
2747 break;
2748
2751 /* changes in upper bound may be merged with older changes in upper bound */
2752 var = (*event)->data.eventbdchg.var;
2753 assert(var != NULL);
2754 pos = var->eventqueueindexub;
2755 if( pos >= 0 )
2756 {
2757 /* the upper bound change event already exists -> modify it accordingly */
2758 assert(pos < eventqueue->nevents);
2759 qevent = eventqueue->events[pos];
2760 assert(qevent != NULL);
2762 assert(qevent->data.eventbdchg.var == var);
2763 assert(SCIPsetIsEQ(set, (*event)->data.eventbdchg.oldbound, qevent->data.eventbdchg.newbound));
2764
2765 SCIPsetDebugMsg(set, " -> merging UB event (<%s>,%g -> %g) with event at position %d (<%s>,%g -> %g)\n",
2766 SCIPvarGetName((*event)->data.eventbdchg.var), (*event)->data.eventbdchg.oldbound,
2767 (*event)->data.eventbdchg.newbound,
2768 pos, SCIPvarGetName(qevent->data.eventbdchg.var), qevent->data.eventbdchg.oldbound,
2769 qevent->data.eventbdchg.newbound);
2770
2771 qevent->data.eventbdchg.newbound = (*event)->data.eventbdchg.newbound;
2772
2773 /* possibly update exact bound */
2774 if( (*event)->data.eventbdchg.newboundexact != NULL )
2775 {
2776 if( qevent->data.eventbdchg.newboundexact == NULL )
2777 {
2778 SCIP_CALL( SCIPeventAddExactBdChg(qevent, blkmem, (*event)->data.eventbdchg.oldboundexact, (*event)->data.eventbdchg.newboundexact) );
2779 }
2780 else
2781 SCIPrationalSetRational(qevent->data.eventbdchg.newboundexact, (*event)->data.eventbdchg.newboundexact);
2782 }
2783 else
2784 {
2785 if( qevent->data.eventbdchg.newboundexact != NULL )
2786 {
2789 }
2790 }
2791
2792 /*if( SCIPsetIsLT(set, qevent->data.eventbdchg.newbound, qevent->data.eventbdchg.oldbound) )*/
2793 if( qevent->data.eventbdchg.newbound < qevent->data.eventbdchg.oldbound )
2795 /*else if( SCIPsetIsGT(set, qevent->data.eventbdchg.newbound, qevent->data.eventbdchg.oldbound) )*/
2796 else if( qevent->data.eventbdchg.newbound > qevent->data.eventbdchg.oldbound )
2798 else
2799 {
2800 /* the queued bound change was reversed -> disable the event in the queue */
2801 assert(qevent->data.eventbdchg.newbound == qevent->data.eventbdchg.oldbound); /*lint !e777*/
2802 eventFreeExactData(qevent, blkmem);
2803 eventDisable(qevent);
2804 var->eventqueueindexub = -1;
2805 SCIPsetDebugMsg(set, " -> event disabled\n");
2806 }
2807
2808 /* free the event that is of no use any longer */
2809 SCIP_CALL( SCIPeventFree(event, blkmem) );
2810 }
2811 else
2812 {
2813 /* the upper bound change event doesn't exist -> add it to the queue, and remember the array index */
2814 var->eventqueueindexub = eventqueue->nevents;
2815 SCIP_CALL( eventqueueAppend(eventqueue, set, event) );
2816 }
2817 break;
2818
2820 var = (*event)->data.eventimpladd.var;
2821 assert(var != NULL);
2822 if( var->eventqueueimpl )
2823 {
2824 /* free the event that is of no use any longer */
2825 SCIP_CALL( SCIPeventFree(event, blkmem) );
2826 }
2827 else
2828 {
2829 var->eventqueueimpl = TRUE;
2830 SCIP_CALL( eventqueueAppend(eventqueue, set, event) );
2831 }
2832 break;
2833
2834 default:
2835 SCIPerrorMessage("unknown event type <%" SCIP_EVENTTYPE_FORMAT ">\n", (*event)->eventtype);
2836 return SCIP_INVALIDDATA;
2837 }
2838 }
2839
2840 assert(*event == NULL);
2841
2842 return SCIP_OKAY;
2843}
2844
2845/** marks queue to delay incoming events until a call to SCIPeventqueueProcess() */
2847 SCIP_EVENTQUEUE* eventqueue /**< event queue */
2848 )
2849{
2850 assert(eventqueue != NULL);
2851 assert(!eventqueue->delayevents);
2852
2853 SCIPdebugMessage("event processing is delayed\n");
2854
2855 eventqueue->delayevents = TRUE;
2856
2857 return SCIP_OKAY;
2858}
2859
2860/** processes all delayed events, marks queue to process events immediately */
2862 SCIP_EVENTQUEUE* eventqueue, /**< event queue */
2863 BMS_BLKMEM* blkmem, /**< block memory buffer */
2864 SCIP_SET* set, /**< global SCIP settings */
2865 SCIP_PRIMAL* primal, /**< primal data */
2866 SCIP_LP* lp, /**< current LP data */
2867 SCIP_BRANCHCAND* branchcand, /**< branching candidate storage */
2868 SCIP_EVENTFILTER* eventfilter /**< global event filter */
2869 )
2870{
2871 SCIP_EVENT* event;
2872 int i;
2873
2874 assert(eventqueue != NULL);
2875 assert(eventqueue->delayevents);
2876
2877 SCIPsetDebugMsg(set, "processing %d queued events\n", eventqueue->nevents);
2878
2879 /* pass events to the responsible event filters
2880 * During event processing, new events may be raised. We have to loop to the mutable eventqueue->nevents.
2881 * A loop to something like "nevents = eventqueue->nevents; for(...; i < nevents; ...)" would miss the
2882 * newly created events. The same holds for eventqueue->events, which can be moved in memory due to
2883 * memory reallocation in eventqueueAppend().
2884 */
2885 for( i = 0; i < eventqueue->nevents; ++i )
2886 {
2887 event = eventqueue->events[i];
2888 assert(event != NULL);
2889
2890 SCIPsetDebugMsg(set, "processing event %d of %d events in queue: eventtype=0x%" SCIP_EVENTTYPE_FORMAT "\n", i, eventqueue->nevents, event->eventtype);
2891
2892 /* unmark the event queue index of a variable with changed objective value or bounds, and unmark the event queue
2893 * member flag of a variable with added implication
2894 */
2895 if( (event->eventtype & SCIP_EVENTTYPE_OBJCHANGED) != 0 )
2896 {
2897 assert(event->data.eventobjchg.var->eventqueueindexobj == i);
2898 event->data.eventobjchg.var->eventqueueindexobj = -1;
2899 }
2900 else if( (event->eventtype & SCIP_EVENTTYPE_LBCHANGED) != 0 )
2901 {
2902 assert(event->data.eventbdchg.var->eventqueueindexlb == i);
2903 event->data.eventbdchg.var->eventqueueindexlb = -1;
2904 }
2905 else if( (event->eventtype & SCIP_EVENTTYPE_UBCHANGED) != 0 )
2906 {
2907 assert(event->data.eventbdchg.var->eventqueueindexub == i);
2908 event->data.eventbdchg.var->eventqueueindexub = -1;
2909 }
2910 else if( (event->eventtype & SCIP_EVENTTYPE_IMPLADDED) != 0 )
2911 {
2912 assert(event->data.eventimpladd.var->eventqueueimpl);
2913 event->data.eventimpladd.var->eventqueueimpl = FALSE;
2914 }
2915
2916 /* process event */
2917 SCIP_CALL( SCIPeventProcess(event, set, primal, lp, branchcand, eventfilter) );
2918
2919 /* free the event immediately, because additionally raised events during event processing
2920 * can lead to a large event queue
2921 */
2922 SCIP_CALL( SCIPeventFree(&eventqueue->events[i], blkmem) );
2923 }
2924
2925 assert(i == eventqueue->nevents);
2926 eventqueue->nevents = 0;
2927 eventqueue->delayevents = FALSE;
2928
2929 return SCIP_OKAY;
2930}
2931
2932/** returns TRUE iff events of the queue are delayed until the next SCIPeventqueueProcess() call */
2934 SCIP_EVENTQUEUE* eventqueue /**< event queue */
2935 )
2936{
2937 assert(eventqueue != NULL);
2938
2939 return eventqueue->delayevents;
2940}
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:1169
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:248
#define SCIP_INVALID
Definition: def.h:178
#define SCIP_Bool
Definition: def.h:91
#define SCIP_ALLOC(x)
Definition: def.h:366
#define SCIP_Real
Definition: def.h:156
#define TRUE
Definition: def.h:93
#define FALSE
Definition: def.h:94
#define SCIPABORT()
Definition: def.h:327
#define SCIP_CALL(x)
Definition: def.h:355
#define SCIP_CALL_FINALLY(x, y)
Definition: def.h:397
SCIP_RETCODE SCIPeventhdlrCopyInclude(SCIP_EVENTHDLR *eventhdlr, SCIP_SET *set)
Definition: event.c:62
static void eventFreeExactData(SCIP_EVENT *event, BMS_BLKMEM *blkmem)
Definition: event.c:1146
SCIP_RETCODE SCIPeventFree(SCIP_EVENT **event, BMS_BLKMEM *blkmem)
Definition: event.c:1168
static SCIP_RETCODE eventqueueAppend(SCIP_EVENTQUEUE *eventqueue, SCIP_SET *set, SCIP_EVENT **event)
Definition: event.c:2537
SCIP_RETCODE SCIPeventCreateLbChanged(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_VAR *var, SCIP_Real oldbound, SCIP_Real newbound)
Definition: event.c:752
static void eventfilterProcessUpdates(SCIP_EVENTFILTER *eventfilter)
Definition: event.c:2368
SCIP_RETCODE SCIPeventCreateVarFixed(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_VAR *var)
Definition: event.c:634
SCIP_RETCODE SCIPeventhdlrInitsol(SCIP_EVENTHDLR *eventhdlr, SCIP_SET *set)
Definition: event.c:318
SCIP_RETCODE SCIPeventCreateVarAdded(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_VAR *var)
Definition: event.c:598
SCIP_RETCODE SCIPeventCreateRowDeletedLP(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_ROW *row)
Definition: event.c:1055
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:195
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:152
SCIP_RETCODE SCIPeventqueueFree(SCIP_EVENTQUEUE **eventqueue)
Definition: event.c:2521
void SCIPeventhdlrSetFree(SCIP_EVENTHDLR *eventhdlr, SCIP_DECL_EVENTFREE((*eventfree)))
Definition: event.c:438
SCIP_RETCODE SCIPeventCreateGholeRemoved(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_VAR *var, SCIP_Real left, SCIP_Real right)
Definition: event.c:867
SCIP_RETCODE SCIPeventhdlrExitsol(SCIP_EVENTHDLR *eventhdlr, SCIP_SET *set)
Definition: event.c:342
SCIP_RETCODE SCIPeventCreateUbChanged(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_VAR *var, SCIP_Real oldbound, SCIP_Real newbound)
Definition: event.c:780
void SCIPeventhdlrEnableOrDisableClocks(SCIP_EVENTHDLR *eventhdlr, SCIP_Bool enable)
Definition: event.c:514
void SCIPeventhdlrSetExitsol(SCIP_EVENTHDLR *eventhdlr, SCIP_DECL_EVENTEXITSOL((*eventexitsol)))
Definition: event.c:482
SCIP_RETCODE SCIPeventCreateVarUnlocked(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_VAR *var)
Definition: event.c:656
SCIP_RETCODE SCIPeventhdlrExit(SCIP_EVENTHDLR *eventhdlr, SCIP_SET *set)
Definition: event.c:288
SCIP_RETCODE SCIPeventChgSol(SCIP_EVENT *event, SCIP_SOL *sol)
Definition: event.c:1584
static SCIP_RETCODE eventqueueEnsureEventsMem(SCIP_EVENTQUEUE *eventqueue, SCIP_SET *set, int num)
Definition: event.c:2482
SCIP_RETCODE SCIPeventAddExactObjChg(SCIP_EVENT *event, BMS_BLKMEM *blkmem, SCIP_RATIONAL *oldobj, SCIP_RATIONAL *newobj)
Definition: event.c:827
void SCIPeventhdlrSetInitsol(SCIP_EVENTHDLR *eventhdlr, SCIP_DECL_EVENTINITSOL((*eventinitsol)))
Definition: event.c:471
static SCIP_RETCODE updateLpExactBoundChange(SCIP_VAR *var, SCIP_LPEXACT *lp, SCIP_SET *set, SCIP_EVENT *event, SCIP_Bool isUb, SCIP_Bool isGlb)
Definition: event.c:82
SCIP_RETCODE SCIPeventCreateObjChanged(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_VAR *var, SCIP_Real oldobj, SCIP_Real newobj)
Definition: event.c:677
SCIP_RETCODE SCIPeventChgNode(SCIP_EVENT *event, SCIP_NODE *node)
Definition: event.c:1547
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:2561
SCIP_RETCODE SCIPeventhdlrFree(SCIP_EVENTHDLR **eventhdlr, SCIP_SET *set)
Definition: event.c:221
SCIP_RETCODE SCIPeventfilterFree(SCIP_EVENTFILTER **eventfilter, BMS_BLKMEM *blkmem, SCIP_SET *set)
Definition: event.c:2167
SCIP_RETCODE SCIPeventCreateRowSideChanged(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_ROW *row, SCIP_SIDETYPE side, SCIP_Real oldval, SCIP_Real newval)
Definition: event.c:1122
SCIP_RETCODE SCIPeventCreateRowAddedSepa(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_ROW *row)
Definition: event.c:998
SCIP_Bool SCIPeventqueueIsDelayed(SCIP_EVENTQUEUE *eventqueue)
Definition: event.c:2933
SCIP_RETCODE SCIPeventAddExactBdChg(SCIP_EVENT *event, BMS_BLKMEM *blkmem, SCIP_RATIONAL *oldbound, SCIP_RATIONAL *newbound)
Definition: event.c:808
SCIP_RETCODE SCIPeventCreateGholeAdded(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_VAR *var, SCIP_Real left, SCIP_Real right)
Definition: event.c:845
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:2861
SCIP_RETCODE SCIPeventCreateRowDeletedSepa(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_ROW *row)
Definition: event.c:1017
void SCIPeventhdlrSetCopy(SCIP_EVENTHDLR *eventhdlr, SCIP_DECL_EVENTCOPY((*eventcopy)))
Definition: event.c:427
SCIP_RETCODE SCIPeventCreateLholeAdded(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_VAR *var, SCIP_Real left, SCIP_Real right)
Definition: event.c:889
void SCIPeventhdlrSetInit(SCIP_EVENTHDLR *eventhdlr, SCIP_DECL_EVENTINIT((*eventinit)))
Definition: event.c:449
SCIP_RETCODE SCIPeventhdlrInit(SCIP_EVENTHDLR *eventhdlr, SCIP_SET *set)
Definition: event.c:252
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:2300
SCIP_RETCODE SCIPeventfilterCreate(SCIP_EVENTFILTER **eventfilter, BMS_BLKMEM *blkmem)
Definition: event.c:2142
void SCIPeventhdlrSetDelete(SCIP_EVENTHDLR *eventhdlr, SCIP_DECL_EVENTDELETE((*eventdelete)))
Definition: event.c:493
void SCIPeventhdlrSetExit(SCIP_EVENTHDLR *eventhdlr, SCIP_DECL_EVENTEXIT((*eventexit)))
Definition: event.c:460
SCIP_RETCODE SCIPeventhdlrExec(SCIP_EVENTHDLR *eventhdlr, SCIP_SET *set, SCIP_EVENT *event, SCIP_EVENTDATA *eventdata)
Definition: event.c:366
SCIP_RETCODE SCIPeventChgVar(SCIP_EVENT *event, SCIP_VAR *var)
Definition: event.c:1281
SCIP_RETCODE SCIPeventCreateRowConstChanged(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_ROW *row, SCIP_Real oldval, SCIP_Real newval)
Definition: event.c:1099
SCIP_RETCODE SCIPeventProcess(SCIP_EVENT *event, SCIP_SET *set, SCIP_PRIMAL *primal, SCIP_LP *lp, SCIP_BRANCHCAND *branchcand, SCIP_EVENTFILTER *eventfilter)
Definition: event.c:1804
SCIP_RETCODE SCIPeventCreateSync(SCIP_EVENT **event, BMS_BLKMEM *blkmem)
Definition: event.c:555
static SCIP_RETCODE eventfilterEnsureMem(SCIP_EVENTFILTER *eventfilter, BMS_BLKMEM *blkmem, SCIP_SET *set, int num)
Definition: event.c:2114
SCIP_RETCODE SCIPeventCreateImplAdded(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_VAR *var)
Definition: event.c:933
SCIP_RETCODE SCIPeventChgType(SCIP_EVENT *event, SCIP_EVENTTYPE eventtype)
Definition: event.c:1204
SCIP_RETCODE SCIPeventqueueCreate(SCIP_EVENTQUEUE **eventqueue)
Definition: event.c:2505
SCIP_RETCODE SCIPeventfilterProcess(SCIP_EVENTFILTER *eventfilter, SCIP_SET *set, SCIP_EVENT *event)
Definition: event.c:2403
SCIP_RETCODE SCIPeventCreateImplTypeChanged(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_VAR *var, SCIP_IMPLINTTYPE oldtype, SCIP_IMPLINTTYPE newtype)
Definition: event.c:975
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:2207
SCIP_RETCODE SCIPeventCreateVarDeleted(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_VAR *var)
Definition: event.c:616
SCIP_RETCODE SCIPeventCreateRowCoefChanged(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_ROW *row, SCIP_COL *col, SCIP_Real oldval, SCIP_Real newval)
Definition: event.c:1074
SCIP_RETCODE SCIPeventCreateGubChanged(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_VAR *var, SCIP_Real oldbound, SCIP_Real newbound)
Definition: event.c:727
SCIP_RETCODE SCIPeventCreateGlbChanged(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_VAR *var, SCIP_Real oldbound, SCIP_Real newbound)
Definition: event.c:702
SCIP_RETCODE SCIPeventqueueDelay(SCIP_EVENTQUEUE *eventqueue)
Definition: event.c:2846
SCIP_RETCODE SCIPeventCreateLholeRemoved(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_VAR *var, SCIP_Real left, SCIP_Real right)
Definition: event.c:911
SCIP_RETCODE SCIPeventCreateTypeChanged(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_VAR *var, SCIP_VARTYPE oldtype, SCIP_VARTYPE newtype)
Definition: event.c:952
static int eventfilterSearch(SCIP_EVENTFILTER *const eventfilter, SCIP_EVENTTYPE const eventtype, SCIP_EVENTHDLR *const eventhdlr, SCIP_EVENTDATA *const eventdata)
Definition: event.c:2274
static void eventfilterDelayUpdates(SCIP_EVENTFILTER *eventfilter)
Definition: event.c:2355
SCIP_RETCODE SCIPeventCreateRowAddedLP(SCIP_EVENT **event, BMS_BLKMEM *blkmem, SCIP_ROW *row)
Definition: event.c:1036
static void eventDisable(SCIP_EVENT *event)
Definition: event.c:1184
internal methods for managing events
SCIP_Real SCIPeventhdlrGetSetupTime(SCIP_EVENTHDLR *eventhdlr)
Definition: event.c:526
SCIP_Bool SCIPeventhdlrIsInitialized(SCIP_EVENTHDLR *eventhdlr)
Definition: event.c:504
SCIP_Real SCIPeventhdlrGetTime(SCIP_EVENTHDLR *eventhdlr)
Definition: event.c:538
const char * SCIPeventhdlrGetName(SCIP_EVENTHDLR *eventhdlr)
Definition: event.c:396
SCIP_EVENTHDLRDATA * SCIPeventhdlrGetData(SCIP_EVENTHDLR *eventhdlr)
Definition: event.c:406
void SCIPeventhdlrSetData(SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTHDLRDATA *eventhdlrdata)
Definition: event.c:416
SCIP_Real SCIPeventGetRowOldCoefVal(SCIP_EVENT *event)
Definition: event.c:1685
SCIP_RATIONAL * SCIPeventGetOldboundExact(SCIP_EVENT *event)
Definition: event.c:1439
SCIP_IMPLINTTYPE SCIPeventGetNewImpltype(SCIP_EVENT *event)
Definition: event.c:1513
SCIP_EVENTTYPE SCIPeventGetType(SCIP_EVENT *event)
Definition: event.c:1194
SCIP_SOL * SCIPeventGetSol(SCIP_EVENT *event)
Definition: event.c:1567
SCIP_VARTYPE SCIPeventGetNewtype(SCIP_EVENT *event)
Definition: event.c:1479
SCIP_Real SCIPeventGetHoleRight(SCIP_EVENT *event)
Definition: event.c:1621
SCIP_Real SCIPeventGetHoleLeft(SCIP_EVENT *event)
Definition: event.c:1604
SCIP_Real SCIPeventGetOldobj(SCIP_EVENT *event)
Definition: event.c:1357
SCIP_Real SCIPeventGetOldbound(SCIP_EVENT *event)
Definition: event.c:1391
SCIP_VAR * SCIPeventGetVar(SCIP_EVENT *event)
Definition: event.c:1217
SCIP_Real SCIPeventGetRowNewConstVal(SCIP_EVENT *event)
Definition: event.c:1736
SCIP_COL * SCIPeventGetRowCol(SCIP_EVENT *event)
Definition: event.c:1668
SCIP_Real SCIPeventGetNewobj(SCIP_EVENT *event)
Definition: event.c:1374
SCIP_SIDETYPE SCIPeventGetRowSide(SCIP_EVENT *event)
Definition: event.c:1753
SCIP_Real SCIPeventGetRowOldSideVal(SCIP_EVENT *event)
Definition: event.c:1770
SCIP_IMPLINTTYPE SCIPeventGetOldImpltype(SCIP_EVENT *event)
Definition: event.c:1496
SCIP_Real SCIPeventGetNewbound(SCIP_EVENT *event)
Definition: event.c:1415
SCIP_NODE * SCIPeventGetNode(SCIP_EVENT *event)
Definition: event.c:1530
SCIP_Real SCIPeventGetRowNewCoefVal(SCIP_EVENT *event)
Definition: event.c:1702
SCIP_Real SCIPeventGetRowNewSideVal(SCIP_EVENT *event)
Definition: event.c:1787
SCIP_Real SCIPeventGetRowOldConstVal(SCIP_EVENT *event)
Definition: event.c:1719
SCIP_ROW * SCIPeventGetRow(SCIP_EVENT *event)
Definition: event.c:1638
SCIP_VARTYPE SCIPeventGetOldtype(SCIP_EVENT *event)
Definition: event.c:1462
void SCIPrationalFreeBlock(BMS_BLKMEM *mem, SCIP_RATIONAL **rational)
Definition: rational.cpp:461
void SCIPrationalSetReal(SCIP_RATIONAL *res, SCIP_Real real)
Definition: rational.cpp:603
SCIP_RETCODE SCIPrationalCopyBlock(BMS_BLKMEM *mem, SCIP_RATIONAL **result, SCIP_RATIONAL *src)
Definition: rational.cpp:151
void SCIPrationalFreeBuffer(BMS_BUFMEM *bufmem, SCIP_RATIONAL **rational)
Definition: rational.cpp:473
SCIP_RETCODE SCIPrationalCreateBuffer(BMS_BUFMEM *bufmem, SCIP_RATIONAL **rational)
Definition: rational.cpp:123
void SCIPrationalSetRational(SCIP_RATIONAL *res, SCIP_RATIONAL *src)
Definition: rational.cpp:569
SCIP_Bool SCIPrationalIsEQ(SCIP_RATIONAL *rat1, SCIP_RATIONAL *rat2)
Definition: rational.cpp:1404
SCIP_COL * SCIPvarGetCol(SCIP_VAR *var)
Definition: var.c:23683
SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
Definition: var.c:23386
SCIP_VARSTATUS SCIPvarGetStatusExact(SCIP_VAR *var)
Definition: var.c:23396
SCIP_COLEXACT * SCIPvarGetColExact(SCIP_VAR *var)
Definition: var.c:23694
int SCIPvarGetProbindex(SCIP_VAR *var)
Definition: var.c:23662
const char * SCIPvarGetName(SCIP_VAR *var)
Definition: var.c:23267
SCIP_RETCODE SCIPcolChgUb(SCIP_COL *col, SCIP_SET *set, SCIP_LP *lp, SCIP_Real newub)
Definition: lp.c:3997
SCIP_RETCODE SCIPcolChgLb(SCIP_COL *col, SCIP_SET *set, SCIP_LP *lp, SCIP_Real newlb)
Definition: lp.c:3952
SCIP_RETCODE SCIPlpUpdateVarLb(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldlb, SCIP_Real newlb)
Definition: lp.c:14264
SCIP_RETCODE SCIPlpUpdateVarLbGlobal(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldlb, SCIP_Real newlb)
Definition: lp.c:14226
SCIP_RETCODE SCIPcolChgObj(SCIP_COL *col, SCIP_SET *set, SCIP_LP *lp, SCIP_Real newobj)
Definition: lp.c:3893
SCIP_RETCODE SCIPlpUpdateVarUbGlobal(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldub, SCIP_Real newub)
Definition: lp.c:14305
SCIP_RETCODE SCIPlpUpdateVarUb(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldub, SCIP_Real newub)
Definition: lp.c:14343
SCIP_RETCODE SCIPlpUpdateVarObj(SCIP_LP *lp, SCIP_SET *set, SCIP_VAR *var, SCIP_Real oldobj, SCIP_Real newobj)
Definition: lp.c:14166
internal methods for LP management
SCIP_RETCODE SCIPlpExactUpdateVarObj(SCIP_SET *set, SCIP_LPEXACT *lpexact, SCIP_VAR *var, SCIP_RATIONAL *oldobj, SCIP_RATIONAL *newobj)
Definition: lpexact.c:6422
SCIP_RETCODE SCIPlpExactUpdateVarUb(SCIP_LPEXACT *lpexact, SCIP_SET *set, SCIP_VAR *var, SCIP_RATIONAL *oldub, SCIP_RATIONAL *newub)
Definition: lpexact.c:6568
SCIP_RETCODE SCIPlpExactUpdateVarLbGlobal(SCIP_LPEXACT *lpexact, SCIP_SET *set, SCIP_VAR *var, SCIP_RATIONAL *oldlb, SCIP_RATIONAL *newlb)
Definition: lpexact.c:6469
SCIP_RETCODE SCIPcolExactChgObj(SCIP_COLEXACT *col, SCIP_SET *set, SCIP_LPEXACT *lpexact, SCIP_RATIONAL *newobj)
Definition: lpexact.c:3001
SCIP_RETCODE SCIPlpExactUpdateVarLb(SCIP_LPEXACT *lpexact, SCIP_SET *set, SCIP_VAR *var, SCIP_RATIONAL *oldlb, SCIP_RATIONAL *newlb)
Definition: lpexact.c:6501
SCIP_RETCODE SCIPcolExactChgUb(SCIP_COLEXACT *col, SCIP_SET *set, SCIP_LPEXACT *lpexact, SCIP_RATIONAL *newub)
Definition: lpexact.c:3093
SCIP_RETCODE SCIPcolExactChgLb(SCIP_COLEXACT *col, SCIP_SET *set, SCIP_LPEXACT *lpexact, SCIP_RATIONAL *newlb)
Definition: lpexact.c:3048
SCIP_RETCODE SCIPlpExactUpdateVarUbGlobal(SCIP_LPEXACT *lpexact, SCIP_SET *set, SCIP_VAR *var, SCIP_RATIONAL *oldub, SCIP_RATIONAL *newub)
Definition: lpexact.c:6536
internal methods for exact 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:2054
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
wrapper for rational number arithmetic
SCIP_Bool SCIPsetIsEQ(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6537
int SCIPsetCalcMemGrowSize(SCIP_SET *set, int num)
Definition: set.c:6080
internal methods for global SCIP settings
#define SCIPsetDebugMsg
Definition: set.h:1811
SCIP_Real oldbound
Definition: struct_event.h:85
SCIP_Real newbound
Definition: struct_event.h:86
SCIP_RATIONAL * newboundexact
Definition: struct_event.h:88
SCIP_VAR * var
Definition: struct_event.h:89
SCIP_RATIONAL * oldboundexact
Definition: struct_event.h:87
SCIP_EVENTTYPE delayedeventmask
Definition: struct_event.h:212
SCIP_EVENTHDLR ** eventhdlrs
Definition: struct_event.h:204
SCIP_Bool delayupdates
Definition: struct_event.h:213
SCIP_EVENTTYPE eventmask
Definition: struct_event.h:211
SCIP_EVENTTYPE * eventtypes
Definition: struct_event.h:203
SCIP_EVENTDATA ** eventdata
Definition: struct_event.h:205
SCIP_VAR * var
Definition: struct_event.h:97
SCIP_RATIONAL * newobjexact
Definition: struct_event.h:78
SCIP_Real newobj
Definition: struct_event.h:76
SCIP_RATIONAL * oldobjexact
Definition: struct_event.h:77
SCIP_Real oldobj
Definition: struct_event.h:75
SCIP_VAR * var
Definition: struct_event.h:79
SCIP_EVENT ** events
Definition: struct_event.h:238
SCIP_Bool delayevents
Definition: struct_event.h:241
SCIP_EVENTVARFIXED eventvarfixed
Definition: struct_event.h:179
SCIP_EVENTTYPECHG eventtypechg
Definition: struct_event.h:185
SCIP_EVENTTYPEIMPLCHG eventimpltypechg
Definition: struct_event.h:186
SCIP_EVENTTYPE eventtype
Definition: struct_event.h:197
SCIP_EVENTVARUNLOCKED eventvarunlocked
Definition: struct_event.h:180
SCIP_EVENTBDCHG eventbdchg
Definition: struct_event.h:182
SCIP_EVENTHOLE eventhole
Definition: struct_event.h:183
SCIP_EVENTIMPLADD eventimpladd
Definition: struct_event.h:184
SCIP_EVENTOBJCHG eventobjchg
Definition: struct_event.h:181
SCIP_EVENTVARADDED eventvaradded
Definition: struct_event.h:177
union SCIP_Event::@18 data
SCIP_EVENTVARDELETED eventvardeleted
Definition: struct_event.h:178
SCIP_Bool initialized
Definition: struct_event.h:232
SCIP_CLOCK * setuptime
Definition: struct_event.h:230
SCIP_CLOCK * eventtime
Definition: struct_event.h:231
SCIP_EVENTHDLRDATA * eventhdlrdata
Definition: struct_event.h:229
SCIP_Bool probing
Definition: struct_lp.h:384
SCIP_LPEXACT * lpexact
Definition: struct_lp.h:309
SCIP_Bool divingobjchg
Definition: struct_lp.h:387
SCIP_EVENTFILTER * eventfilter
Definition: struct_var.h:303
int eventqueueindexobj
Definition: struct_var.h:313
unsigned int eventqueueimpl
Definition: struct_var.h:341
int eventqueueindexlb
Definition: struct_var.h:314
int eventqueueindexub
Definition: struct_var.h:315
SCIP_VARDATAEXACT * exactdata
Definition: struct_var.h:290
union SCIP_Var::@24 data
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:101
#define SCIP_EVENTTYPE_NODEFEASIBLE
Definition: type_event.h:94
#define SCIP_EVENTTYPE_BOUNDCHANGED
Definition: type_event.h:127
#define SCIP_EVENTTYPE_VARUNLOCKED
Definition: type_event.h:73
#define SCIP_EVENTTYPE_ROWSIDECHANGED
Definition: type_event.h:115
#define SCIP_EVENTTYPE_SYNC
Definition: type_event.h:118
#define SCIP_EVENTTYPE_ROWADDEDLP
Definition: type_event.h:111
#define SCIP_EVENTTYPE_POORSOLFOUND
Definition: type_event.h:105
#define SCIP_EVENTTYPE_TYPECHANGED
Definition: type_event.h:86
#define SCIP_EVENTTYPE_PRESOLVEROUND
Definition: type_event.h:90
#define SCIP_EVENTTYPE_GUBCHANGED
Definition: type_event.h:76
#define SCIP_EVENTTYPE_GHOLEREMOVED
Definition: type_event.h:82
#define SCIP_EVENTTYPE_GBDCHANGED
Definition: type_event.h:122
struct SCIP_EventData SCIP_EVENTDATA
Definition: type_event.h:179
#define SCIP_EVENTTYPE_UBTIGHTENED
Definition: type_event.h:79
#define SCIP_EVENTTYPE_NODEFOCUSED
Definition: type_event.h:93
#define SCIP_EVENTTYPE_NODEINFEASIBLE
Definition: type_event.h:95
#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:160
#define SCIP_EVENTTYPE_NODEEVENT
Definition: type_event.h:140
#define SCIP_EVENTTYPE_LHOLEREMOVED
Definition: type_event.h:84
#define SCIP_EVENTTYPE_NODEBRANCHED
Definition: type_event.h:96
#define SCIP_DECL_EVENTCOPY(x)
Definition: type_event.h:189
#define SCIP_EVENTTYPE_LBRELAXED
Definition: type_event.h:78
#define SCIP_EVENTTYPE_DUALBOUNDIMPROVED
Definition: type_event.h:98
#define SCIP_EVENTTYPE_BESTSOLFOUND
Definition: type_event.h:106
#define SCIP_EVENTTYPE_FORMAT
Definition: type_event.h:157
#define SCIP_EVENTTYPE_GLBCHANGED
Definition: type_event.h:75
#define SCIP_EVENTTYPE_HOLECHANGED
Definition: type_event.h:130
#define SCIP_EVENTTYPE_ROWDELETEDSEPA
Definition: type_event.h:110
#define SCIP_EVENTTYPE_VARADDED
Definition: type_event.h:70
#define SCIP_EVENTTYPE_LBCHANGED
Definition: type_event.h:123
#define SCIP_EVENTTYPE_ROWDELETEDLP
Definition: type_event.h:112
#define SCIP_EVENTTYPE_UBCHANGED
Definition: type_event.h:124
#define SCIP_EVENTTYPE_LHOLEADDED
Definition: type_event.h:83
uint64_t SCIP_EVENTTYPE
Definition: type_event.h:156
#define SCIP_EVENTTYPE_LPSOLVED
Definition: type_event.h:102
#define SCIP_EVENTTYPE_IMPLADDED
Definition: type_event.h:85
#define SCIP_EVENTTYPE_ROWCOEFCHANGED
Definition: type_event.h:113
#define SCIP_EVENTTYPE_IMPLTYPECHANGED
Definition: type_event.h:87
#define SCIP_EVENTTYPE_ROWADDEDSEPA
Definition: type_event.h:109
#define SCIP_EVENTTYPE_LPEVENT
Definition: type_event.h:143
#define SCIP_EVENTTYPE_NODEDELETE
Definition: type_event.h:97
#define SCIP_EVENTTYPE_DISABLED
Definition: type_event.h:67
#define SCIP_EVENTTYPE_SOLEVENT
Definition: type_event.h:147
#define SCIP_EVENTTYPE_ROWCONSTCHANGED
Definition: type_event.h:114
#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:65
enum SCIP_SideType SCIP_SIDETYPE
Definition: type_lp.h:68
@ 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
enum SCIP_ImplintType SCIP_IMPLINTTYPE
Definition: type_var.h:117
@ SCIP_IMPLINTTYPE_NONE
Definition: type_var.h:90
@ SCIP_VARTYPE_CONTINUOUS
Definition: type_var.h:71
@ SCIP_VARSTATUS_FIXED
Definition: type_var.h:54
@ SCIP_VARSTATUS_COLUMN
Definition: type_var.h:53
@ SCIP_VARSTATUS_MULTAGGR
Definition: type_var.h:56
@ SCIP_VARSTATUS_NEGATED
Definition: type_var.h:57
@ SCIP_VARSTATUS_AGGREGATED
Definition: type_var.h:55
@ SCIP_VARSTATUS_LOOSE
Definition: type_var.h:52
enum SCIP_Vartype SCIP_VARTYPE
Definition: type_var.h:73
internal methods for problem variables