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