1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2 /* */
3 /* This file is part of the program and library */
4 /* SCIP --- Solving Constraint Integer Programs */
5 /* */
6 /* Copyright (C) 2002-2021 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 visit scipopt.org. */
13 /* */
14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15
16 /**@file scip_nodesel.c
17 * @ingroup OTHER_CFILES
18 * @brief public methods for node selector plugins
19 * @author Tobias Achterberg
20 * @author Timo Berthold
21 * @author Gerald Gamrath
22 * @author Leona Gottwald
23 * @author Stefan Heinz
24 * @author Gregor Hendel
25 * @author Thorsten Koch
26 * @author Alexander Martin
27 * @author Marc Pfetsch
28 * @author Michael Winkler
29 * @author Kati Wolter
30 *
31 * @todo check all SCIP_STAGE_* switches, and include the new stages TRANSFORMED and INITSOLVE
32 */
33
34 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
35
36 #include "scip/debug.h"
37 #include "scip/nodesel.h"
38 #include "scip/pub_message.h"
39 #include "scip/scip_nodesel.h"
40 #include "scip/set.h"
41 #include "scip/struct_mem.h"
42 #include "scip/struct_scip.h"
43 #include "scip/struct_set.h"
44
45 /** creates a node selector and includes it in SCIP.
46 *
47 * @note method has all node selector callbacks as arguments and is thus changed every time a new
48 * callback is added in future releases; consider using SCIPincludeNodeselBasic() and setter functions
49 * if you seek for a method which is less likely to change in future releases
50 */
SCIPincludeNodesel(SCIP * scip,const char * name,const char * desc,int stdpriority,int memsavepriority,SCIP_DECL_NODESELCOPY ((* nodeselcopy)),SCIP_DECL_NODESELFREE ((* nodeselfree)),SCIP_DECL_NODESELINIT ((* nodeselinit)),SCIP_DECL_NODESELEXIT ((* nodeselexit)),SCIP_DECL_NODESELINITSOL ((* nodeselinitsol)),SCIP_DECL_NODESELEXITSOL ((* nodeselexitsol)),SCIP_DECL_NODESELSELECT ((* nodeselselect)),SCIP_DECL_NODESELCOMP ((* nodeselcomp)),SCIP_NODESELDATA * nodeseldata)51 SCIP_RETCODE SCIPincludeNodesel(
52 SCIP* scip, /**< SCIP data structure */
53 const char* name, /**< name of node selector */
54 const char* desc, /**< description of node selector */
55 int stdpriority, /**< priority of the node selector in standard mode */
56 int memsavepriority, /**< priority of the node selector in memory saving mode */
57 SCIP_DECL_NODESELCOPY ((*nodeselcopy)), /**< copy method of node selector or NULL if you don't want to copy your plugin into sub-SCIPs */
58 SCIP_DECL_NODESELFREE ((*nodeselfree)), /**< destructor of node selector */
59 SCIP_DECL_NODESELINIT ((*nodeselinit)), /**< initialize node selector */
60 SCIP_DECL_NODESELEXIT ((*nodeselexit)), /**< deinitialize node selector */
61 SCIP_DECL_NODESELINITSOL((*nodeselinitsol)),/**< solving process initialization method of node selector */
62 SCIP_DECL_NODESELEXITSOL((*nodeselexitsol)),/**< solving process deinitialization method of node selector */
63 SCIP_DECL_NODESELSELECT((*nodeselselect)),/**< node selection method */
64 SCIP_DECL_NODESELCOMP ((*nodeselcomp)), /**< node comparison method */
65 SCIP_NODESELDATA* nodeseldata /**< node selector data */
66 )
67 {
68 SCIP_NODESEL* nodesel;
69
70 SCIP_CALL( SCIPcheckStage(scip, "SCIPincludeNodesel", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
71
72 /* check whether node selector is already present */
73 if( SCIPfindNodesel(scip, name) != NULL )
74 {
75 SCIPerrorMessage("node selector <%s> already included.\n", name);
76 return SCIP_INVALIDDATA;
77 }
78
79 SCIP_CALL( SCIPnodeselCreate(&nodesel, scip->set, scip->messagehdlr, scip->mem->setmem, name, desc, stdpriority, memsavepriority,
80 nodeselcopy, nodeselfree, nodeselinit, nodeselexit, nodeselinitsol, nodeselexitsol,
81 nodeselselect, nodeselcomp, nodeseldata) );
82 SCIP_CALL( SCIPsetIncludeNodesel(scip->set, nodesel) );
83
84 return SCIP_OKAY;
85 }
86
87 /** Creates a node selector and includes it in SCIP with its most fundamental callbacks. All non-fundamental
88 * (or optional) callbacks as, e.g., init and exit callbacks, will be set to NULL.
89 * Optional callbacks can be set via specific setter functions, see SCIPsetNodeselCopy(), SCIPsetNodeselFree(),
90 * SCIPsetNodeselInit(), SCIPsetNodeselExit(), SCIPsetNodeselInitsol(), and SCIPsetNodeselExitsol()
91 *
92 * @note if you want to set all callbacks with a single method call, consider using SCIPincludeNodesel() instead
93 */
SCIPincludeNodeselBasic(SCIP * scip,SCIP_NODESEL ** nodesel,const char * name,const char * desc,int stdpriority,int memsavepriority,SCIP_DECL_NODESELSELECT ((* nodeselselect)),SCIP_DECL_NODESELCOMP ((* nodeselcomp)),SCIP_NODESELDATA * nodeseldata)94 SCIP_RETCODE SCIPincludeNodeselBasic(
95 SCIP* scip, /**< SCIP data structure */
96 SCIP_NODESEL** nodesel, /**< reference to a node selector, or NULL */
97 const char* name, /**< name of node selector */
98 const char* desc, /**< description of node selector */
99 int stdpriority, /**< priority of the node selector in standard mode */
100 int memsavepriority, /**< priority of the node selector in memory saving mode */
101 SCIP_DECL_NODESELSELECT((*nodeselselect)),/**< node selection method */
102 SCIP_DECL_NODESELCOMP ((*nodeselcomp)), /**< node comparison method */
103 SCIP_NODESELDATA* nodeseldata /**< node selector data */
104 )
105 {
106 SCIP_NODESEL* nodeselptr;
107
108 SCIP_CALL( SCIPcheckStage(scip, "SCIPincludeNodeselBasic", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
109
110 /* check whether node selector is already present */
111 if( SCIPfindNodesel(scip, name) != NULL )
112 {
113 SCIPerrorMessage("node selector <%s> already included.\n", name);
114 return SCIP_INVALIDDATA;
115 }
116
117 SCIP_CALL( SCIPnodeselCreate(&nodeselptr, scip->set, scip->messagehdlr, scip->mem->setmem, name, desc, stdpriority, memsavepriority,
118 NULL, NULL, NULL, NULL, NULL, NULL,
119 nodeselselect, nodeselcomp, nodeseldata) );
120 SCIP_CALL( SCIPsetIncludeNodesel(scip->set, nodeselptr) );
121
122 if( nodesel != NULL )
123 *nodesel = nodeselptr;
124
125 return SCIP_OKAY;
126 }
127
128 /** sets copy method of node selector */
SCIPsetNodeselCopy(SCIP * scip,SCIP_NODESEL * nodesel,SCIP_DECL_NODESELCOPY ((* nodeselcopy)))129 SCIP_RETCODE SCIPsetNodeselCopy(
130 SCIP* scip, /**< SCIP data structure */
131 SCIP_NODESEL* nodesel, /**< node selector */
132 SCIP_DECL_NODESELCOPY ((*nodeselcopy)) /**< copy method of node selector or NULL if you don't want to copy your plugin into sub-SCIPs */
133 )
134 {
135 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetNodeselCopy", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
136
137 assert(nodesel != NULL);
138
139 SCIPnodeselSetCopy(nodesel, nodeselcopy);
140
141 return SCIP_OKAY;
142 }
143
144 /** sets destructor method of node selector */
SCIPsetNodeselFree(SCIP * scip,SCIP_NODESEL * nodesel,SCIP_DECL_NODESELFREE ((* nodeselfree)))145 SCIP_RETCODE SCIPsetNodeselFree(
146 SCIP* scip, /**< SCIP data structure */
147 SCIP_NODESEL* nodesel, /**< node selector */
148 SCIP_DECL_NODESELFREE ((*nodeselfree)) /**< destructor of node selector */
149 )
150 {
151 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetNodeselFree", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
152
153 assert(nodesel != NULL);
154
155 SCIPnodeselSetFree(nodesel, nodeselfree);
156
157 return SCIP_OKAY;
158 }
159
160 /** sets initialization method of node selector */
SCIPsetNodeselInit(SCIP * scip,SCIP_NODESEL * nodesel,SCIP_DECL_NODESELINIT ((* nodeselinit)))161 SCIP_RETCODE SCIPsetNodeselInit(
162 SCIP* scip, /**< SCIP data structure */
163 SCIP_NODESEL* nodesel, /**< node selector */
164 SCIP_DECL_NODESELINIT ((*nodeselinit)) /**< initialize node selector */
165 )
166 {
167 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetNodeselInit", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
168
169 assert(nodesel != NULL);
170
171 SCIPnodeselSetInit(nodesel, nodeselinit);
172
173 return SCIP_OKAY;
174 }
175
176 /** sets deinitialization method of node selector */
SCIPsetNodeselExit(SCIP * scip,SCIP_NODESEL * nodesel,SCIP_DECL_NODESELEXIT ((* nodeselexit)))177 SCIP_RETCODE SCIPsetNodeselExit(
178 SCIP* scip, /**< SCIP data structure */
179 SCIP_NODESEL* nodesel, /**< node selector */
180 SCIP_DECL_NODESELEXIT ((*nodeselexit)) /**< deinitialize node selector */
181 )
182 {
183 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetNodeselExit", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
184
185 assert(nodesel != NULL);
186
187 SCIPnodeselSetExit(nodesel, nodeselexit);
188
189 return SCIP_OKAY;
190 }
191
192 /** sets solving process initialization method of node selector */
SCIPsetNodeselInitsol(SCIP * scip,SCIP_NODESEL * nodesel,SCIP_DECL_NODESELINITSOL ((* nodeselinitsol)))193 SCIP_RETCODE SCIPsetNodeselInitsol(
194 SCIP* scip, /**< SCIP data structure */
195 SCIP_NODESEL* nodesel, /**< node selector */
196 SCIP_DECL_NODESELINITSOL ((*nodeselinitsol))/**< solving process initialization method of node selector */
197 )
198 {
199 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetNodeselInitsol", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
200
201 assert(nodesel != NULL);
202
203 SCIPnodeselSetInitsol(nodesel, nodeselinitsol);
204
205 return SCIP_OKAY;
206 }
207
208 /** sets solving process deinitialization method of node selector */
SCIPsetNodeselExitsol(SCIP * scip,SCIP_NODESEL * nodesel,SCIP_DECL_NODESELEXITSOL ((* nodeselexitsol)))209 SCIP_RETCODE SCIPsetNodeselExitsol(
210 SCIP* scip, /**< SCIP data structure */
211 SCIP_NODESEL* nodesel, /**< node selector */
212 SCIP_DECL_NODESELEXITSOL ((*nodeselexitsol))/**< solving process deinitialization method of node selector */
213 )
214 {
215 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetNodeselExitsol", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
216
217 assert(nodesel != NULL);
218
219 SCIPnodeselSetExitsol(nodesel, nodeselexitsol);
220
221 return SCIP_OKAY;
222 }
223
224 /** returns the node selector of the given name, or NULL if not existing */
SCIPfindNodesel(SCIP * scip,const char * name)225 SCIP_NODESEL* SCIPfindNodesel(
226 SCIP* scip, /**< SCIP data structure */
227 const char* name /**< name of node selector */
228 )
229 {
230 assert(scip != NULL);
231 assert(scip->set != NULL);
232 assert(name != NULL);
233
234 return SCIPsetFindNodesel(scip->set, name);
235 }
236
237 /** returns the array of currently available node selectors */
SCIPgetNodesels(SCIP * scip)238 SCIP_NODESEL** SCIPgetNodesels(
239 SCIP* scip /**< SCIP data structure */
240 )
241 {
242 assert(scip != NULL);
243 assert(scip->set != NULL);
244
245 return scip->set->nodesels;
246 }
247
248 /** returns the number of currently available node selectors */
SCIPgetNNodesels(SCIP * scip)249 int SCIPgetNNodesels(
250 SCIP* scip /**< SCIP data structure */
251 )
252 {
253 assert(scip != NULL);
254 assert(scip->set != NULL);
255
256 return scip->set->nnodesels;
257 }
258
259 /** sets the priority of a node selector in standard mode */
SCIPsetNodeselStdPriority(SCIP * scip,SCIP_NODESEL * nodesel,int priority)260 SCIP_RETCODE SCIPsetNodeselStdPriority(
261 SCIP* scip, /**< SCIP data structure */
262 SCIP_NODESEL* nodesel, /**< node selector */
263 int priority /**< new standard priority of the node selector */
264 )
265 {
266 assert(scip != NULL);
267 assert(scip->set != NULL);
268
269 SCIPnodeselSetStdPriority(nodesel, scip->set, priority);
270
271 return SCIP_OKAY;
272 }
273
274 /** sets the priority of a node selector in memory saving mode */
SCIPsetNodeselMemsavePriority(SCIP * scip,SCIP_NODESEL * nodesel,int priority)275 SCIP_RETCODE SCIPsetNodeselMemsavePriority(
276 SCIP* scip, /**< SCIP data structure */
277 SCIP_NODESEL* nodesel, /**< node selector */
278 int priority /**< new memory saving priority of the node selector */
279 )
280 {
281 assert(scip != NULL);
282 assert(scip->set != NULL);
283
284 SCIPnodeselSetMemsavePriority(nodesel, scip->set, priority);
285
286 return SCIP_OKAY;
287 }
288
289 /** returns the currently used node selector */
SCIPgetNodesel(SCIP * scip)290 SCIP_NODESEL* SCIPgetNodesel(
291 SCIP* scip /**< SCIP data structure */
292 )
293 {
294 assert(scip != NULL);
295 assert(scip->set != NULL);
296
297 return SCIPsetGetNodesel(scip->set, scip->stat);
298 }
299