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