Scippy

SCIP

Solving Constraint Integer Programs

xternal_eventhdlr.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-2017 Konrad-Zuse-Zentrum */
7 /* fuer Informationstechnik Berlin */
8 /* */
9 /* SCIP is distributed under the terms of the ZIB Academic License. */
10 /* */
11 /* You should have received a copy of the ZIB Academic License */
12 /* along with SCIP; see the file COPYING. If not email to scip@zib.de. */
13 /* */
14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15 
16 /**@file examples/Eventhdlr/doc/xternal_eventhdlr.c
17  * @brief main document page
18  * @author Stefan Heinz
19  */
20 
21 /*--+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
22 
23 /**@page EVENTHDLR_MAIN
24  * @author Stefan Heinz
25  *
26  * This example illustrates the use of an event handler within \SCIP. It extends the
27  * default plugins of \SCIP by two additional plugins, namely an event handler which
28  * reacts on new best solutions and an event handler acting on processed nodes. You should also read the section
29  * \ref EVENT which explains event handling in general.
30  *
31  * The event handlers event_bestsol.c and event_boundwriting.c show how the create a customized event handler in \SCIP.
32  * In case of an event handler, there are two important questions to answer:
33  * -# When to \a install the event handler and
34  * -# When to \a remove the event handler.
35  *
36  * <b>Note:</b> You can replace the event type in this example with any none-variable event. See
37  * in the type_event.h in the SCIP documentation for a
38  * complete list.
39  *
40  * The remainder of this page focusses on the best solution event handler. See event_boundwriting.c for
41  * a documentation of the bound writing event handler.
42  *
43  * @section INSTALL_EVENTHDLR Installing the event handler
44  *
45  * In the following we describe the use of the callback methods of all event handler
46  * for the installation of our event handler.
47  *
48  * In this example, we want to install an event handler which reacts on a new best solution.
49  *
50  * Our goal is to specify that our event_bestsol.c event handler reacts
51  * on the SCIP_EVENTTYPE_BESTSOLFOUND which already exists in SCIP. The main methods for changing the way
52  * SCIP notifies the event handler about an event are
53  * - SCIPcatchEvent() to be informed about new events
54  * - SCIPdropEvent() to drop the event
55  *
56  * The right callback
57  * event handler in the callback SCIP_DECL_EVENTINIT. At that point the problem was tranformed. Note that there are
58  * heuristics which are called before even the presolving starts as for example the trivial heuristic. This means the callback
59  * SCIP_DECL_EVENTINTSOL is too late to install the solution event because at that stage, we might have already missed
60  * several solutions.
61  *
62  * \code
63  * static
64  * SCIP_DECL_EVENTINIT(eventInitBestsol)
65  * {
66  * assert(scip != NULL);
67  * assert(eventhdlr != NULL);
68  * assert(strcmp(SCIPeventhdlrGetName(eventhdlr), EVENTHDLR_NAME) == 0);
69  *
70  * SCIP_CALL( SCIPcatchEvent( scip, SCIP_EVENTTYPE_BESTSOLFOUND, eventhdlr, NULL, NULL) );
71  *
72  * return SCIP_OKAY;
73  * }
74  * \endcode
75  *
76  * The method SCIPcatchEvent() notifies \SCIP that we want to react on the event type best solution found.
77  *
78  * @section REMOVE Remove the event handler
79  *
80  * With respect to dropping the event handling, we perform that action in SCIP_DECL_EVENTEXIT which is the counter part
81  * of SCIP_DECL_EVENTINIT. The callback SCIP_DECL_EVENTEXITSOL which is the counter part to SCIP_DECL_EVENTINTSOL does
82  * not work because it will be called before the branch-and-bound process is freed. This, however, is not only done
83  * after the problem is solved. It also happens when a restart is performed. Dropping the event handler within this
84  * method would cause our event handler not to be informed about every new solution found after the first restart.
85  * Therefore, the right
86  * place to drop that event handler is the callback SCIP_DECL_EVENTEXIT. Below you find the source code.
87  *
88  * \code
89  * static
90  * SCIP_DECL_EVENTEXIT(eventExitBestsol)
91  * {
92  * assert(scip != NULL);
93  * assert(eventhdlr != NULL);
94  * assert(strcmp(SCIPeventhdlrGetName(eventhdlr), EVENTHDLR_NAME) == 0);
95  *
96  * SCIP_CALL( SCIPdropEvent( scip, SCIP_EVENTTYPE_BESTSOLFOUND, eventhdlr, NULL, -1) );
97  * return SCIP_OKAY;
98  * }
99  * \endcode
100  *
101  * The method SCIPdropEvent() tells SCIP that we want to drop the event type SCIP_EVENTTYPE_BESTSOLFOUND of belonging
102  * to the event handler.
103  *
104  * @section REACT React on events
105  *
106  * In the callback SCIP_DECL_EVENTEXEC, which is the execution method of the event handler, you can specify how the
107  * event handler reacts on an event it catches. In this case, we just want to output a line to the console
108  * every time a new best solution is found.
109  *
110  * \code
111  * static
112  * SCIP_DECL_EVENTEXEC(eventExecBestsol)
113  * {
114  * SCIP_SOL* bestsol;
115  * SCIP_Real solvalue;
116  *
117  * assert(eventhdlr != NULL);
118  * assert(strcmp(SCIPeventhdlrGetName(eventhdlr), EVENTHDLR_NAME) == 0);
119  * assert(event != NULL);
120  * assert(scip != NULL);
121  * assert(SCIPeventGetType(event) == SCIP_EVENTTYPE_BESTSOLFOUND);
122  *
123  * SCIPdebugMessage("exec method of event handler for best solution found\n");
124  *
125  * bestsol = SCIPgetBestSol(scip);
126  * assert(bestsol != NULL);
127  * solvalue = SCIPgetSolOrigObj(scip, bestsol);
128  *
129  * SCIPinfoMessage(scip, NULL, "found new best solution with solution value <%g>\n", solvalue);
130  *
131  * return SCIP_OKAY;
132  * }
133  * \endcode
134  *
135  *
136  * @section ADDING Including the event handler plugin
137  *
138  * \SCIP is plugin-based. This means that all plugins which should be used have be
139  * included into the \SCIP environment. In the case of the event handler, we are doing
140  * this after the \SCIP environment was created (see cmain.c).
141  *
142  * \code
143  * static
144  * SCIP_RETCODE runShell(
145  * int argc,
146  * char** argv,
147  * const char* defaultsetname
148  * )
149  * {
150  * SCIP* scip = NULL;
151  *
152  * SCIP_CALL( SCIPcreate(&scip) );
153  *
154  * SCIP_CALL( SCIPincludeDefaultPlugins(scip) );
155  *
156  * SCIP_CALL( SCIPincludeEventHdlrBestsol(scip) );
157  * SCIP_CALL( SCIPincludeEventHdlrBoundwriting(scip) );
158  *
159  * SCIP_CALL( SCIPprocessShellArguments(scip, argc, argv, defaultsetname) );
160  *
161  * SCIP_CALL( SCIPfree(&scip) );
162  *
163  * BMScheckEmptyMemory();
164  *
165  * return SCIP_OKAY;
166  * }
167  * \endcode
168  *
169  */