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_prop.c 26 * @ingroup OTHER_CFILES 27 * @brief public methods for propagator 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/prop.h" 47 #include "scip/pub_message.h" 48 #include "scip/pub_misc.h" 49 #include "scip/pub_prop.h" 50 #include "scip/scip_prop.h" 51 #include "scip/set.h" 52 #include "scip/struct_mem.h" 53 #include "scip/struct_scip.h" 54 #include "scip/struct_set.h" 55 56 /** creates a propagator and includes it in SCIP. 57 * 58 * @note method has all propagator callbacks as arguments and is thus changed every time a new 59 * callback is added in future releases; consider using SCIPincludePropBasic() and setter functions 60 * if you seek for a method which is less likely to change in future releases 61 */ 62 SCIP_RETCODE SCIPincludeProp( 63 SCIP* scip, /**< SCIP data structure */ 64 const char* name, /**< name of propagator */ 65 const char* desc, /**< description of propagator */ 66 int priority, /**< priority of the propagator (>= 0: before, < 0: after constraint handlers) */ 67 int freq, /**< frequency for calling propagator */ 68 SCIP_Bool delay, /**< should propagator be delayed, if other propagators found reductions? */ 69 SCIP_PROPTIMING timingmask, /**< positions in the node solving loop where propagator should be executed */ 70 int presolpriority, /**< presolving priority of the propagator (>= 0: before, < 0: after constraint handlers) */ 71 int presolmaxrounds, /**< maximal number of presolving rounds the propagator participates in (-1: no limit) */ 72 SCIP_PRESOLTIMING presoltiming, /**< timing mask of the propagator's presolving method */ 73 SCIP_DECL_PROPCOPY ((*propcopy)), /**< copy method of propagator or NULL if you don't want to copy your plugin into sub-SCIPs */ 74 SCIP_DECL_PROPFREE ((*propfree)), /**< destructor of propagator */ 75 SCIP_DECL_PROPINIT ((*propinit)), /**< initialize propagator */ 76 SCIP_DECL_PROPEXIT ((*propexit)), /**< deinitialize propagator */ 77 SCIP_DECL_PROPINITPRE ((*propinitpre)), /**< presolving initialization method of propagator */ 78 SCIP_DECL_PROPEXITPRE ((*propexitpre)), /**< presolving deinitialization method of propagator */ 79 SCIP_DECL_PROPINITSOL ((*propinitsol)), /**< solving process initialization method of propagator */ 80 SCIP_DECL_PROPEXITSOL ((*propexitsol)), /**< solving process deinitialization method of propagator */ 81 SCIP_DECL_PROPPRESOL ((*proppresol)), /**< presolving method */ 82 SCIP_DECL_PROPEXEC ((*propexec)), /**< execution method of propagator */ 83 SCIP_DECL_PROPRESPROP ((*propresprop)), /**< propagation conflict resolving method */ 84 SCIP_PROPDATA* propdata /**< propagator data */ 85 ) 86 { 87 SCIP_PROP* prop; 88 89 SCIP_CALL( SCIPcheckStage(scip, "SCIPincludeProp", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) ); 90 91 /* check whether propagator is already present */ 92 if( SCIPfindProp(scip, name) != NULL ) 93 { 94 SCIPerrorMessage("propagator <%s> already included.\n", name); 95 return SCIP_INVALIDDATA; 96 } 97 98 SCIP_CALL( SCIPpropCreate(&prop, scip->set, scip->messagehdlr, scip->mem->setmem, 99 name, desc, priority, freq, delay, timingmask, presolpriority, presolmaxrounds, presoltiming, 100 propcopy, propfree, propinit, propexit, propinitpre, propexitpre, propinitsol, propexitsol, 101 proppresol, propexec, propresprop, propdata) ); 102 SCIP_CALL( SCIPsetIncludeProp(scip->set, prop) ); 103 104 return SCIP_OKAY; 105 } 106 107 /** creates a propagator and includes it in SCIP. All non-fundamental (or optional) callbacks will be set to NULL. 108 * Optional callbacks can be set via specific setter functions, see SCIPsetPropInit(), SCIPsetPropExit(), 109 * SCIPsetPropCopy(), SCIPsetPropFree(), SCIPsetPropInitsol(), SCIPsetPropExitsol(), 110 * SCIPsetPropInitpre(), SCIPsetPropExitpre(), SCIPsetPropPresol(), and SCIPsetPropResprop(). 111 * 112 * @note if you want to set all callbacks with a single method call, consider using SCIPincludeProp() instead 113 */ 114 SCIP_RETCODE SCIPincludePropBasic( 115 SCIP* scip, /**< SCIP data structure */ 116 SCIP_PROP** propptr, /**< reference to a propagator pointer, or NULL */ 117 const char* name, /**< name of propagator */ 118 const char* desc, /**< description of propagator */ 119 int priority, /**< priority of the propagator (>= 0: before, < 0: after constraint handlers) */ 120 int freq, /**< frequency for calling propagator */ 121 SCIP_Bool delay, /**< should propagator be delayed, if other propagators found reductions? */ 122 SCIP_PROPTIMING timingmask, /**< positions in the node solving loop where propagators should be executed */ 123 SCIP_DECL_PROPEXEC ((*propexec)), /**< execution method of propagator */ 124 SCIP_PROPDATA* propdata /**< propagator data */ 125 ) 126 { 127 SCIP_PROP* prop; 128 129 SCIP_CALL( SCIPcheckStage(scip, "SCIPincludePropBasic", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) ); 130 131 /* check whether propagator is already present */ 132 if( SCIPfindProp(scip, name) != NULL ) 133 { 134 SCIPerrorMessage("propagator <%s> already included.\n", name); 135 return SCIP_INVALIDDATA; 136 } 137 138 SCIP_CALL( SCIPpropCreate(&prop, scip->set, scip->messagehdlr, scip->mem->setmem, 139 name, desc, priority, freq, delay, timingmask, 0, -1, SCIP_PRESOLTIMING_ALWAYS, 140 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 141 NULL, propexec, NULL, propdata) ); 142 SCIP_CALL( SCIPsetIncludeProp(scip->set, prop) ); 143 144 if( propptr != NULL ) 145 *propptr = prop; 146 147 return SCIP_OKAY; 148 } 149 150 /** sets copy method of propagator */ 151 SCIP_RETCODE SCIPsetPropCopy( 152 SCIP* scip, /**< SCIP data structure */ 153 SCIP_PROP* prop, /**< propagator */ 154 SCIP_DECL_PROPCOPY ((*propcopy)) /**< copy method of propagator or NULL if you don't want to copy your plugin into sub-SCIPs */ 155 ) 156 { 157 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetPropCopy", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) ); 158 159 assert(prop != NULL); 160 161 SCIPpropSetCopy(prop, propcopy); 162 163 return SCIP_OKAY; 164 } 165 166 /** sets destructor method of propagator */ 167 SCIP_RETCODE SCIPsetPropFree( 168 SCIP* scip, /**< SCIP data structure */ 169 SCIP_PROP* prop, /**< propagator */ 170 SCIP_DECL_PROPFREE ((*propfree)) /**< destructor of propagator */ 171 ) 172 { 173 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetPropFree", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) ); 174 175 assert(prop != NULL); 176 177 SCIPpropSetFree(prop, propfree); 178 179 return SCIP_OKAY; 180 } 181 182 /** sets initialization method of propagator */ 183 SCIP_RETCODE SCIPsetPropInit( 184 SCIP* scip, /**< SCIP data structure */ 185 SCIP_PROP* prop, /**< propagator */ 186 SCIP_DECL_PROPINIT ((*propinit)) /**< initialize propagator */ 187 ) 188 { 189 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetPropInit", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) ); 190 191 assert(prop != NULL); 192 193 SCIPpropSetInit(prop, propinit); 194 195 return SCIP_OKAY; 196 } 197 198 /** sets deinitialization method of propagator */ 199 SCIP_RETCODE SCIPsetPropExit( 200 SCIP* scip, /**< SCIP data structure */ 201 SCIP_PROP* prop, /**< propagator */ 202 SCIP_DECL_PROPEXIT ((*propexit)) /**< deinitialize propagator */ 203 ) 204 { 205 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetPropExit", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) ); 206 207 assert(prop != NULL); 208 209 SCIPpropSetExit(prop, propexit); 210 211 return SCIP_OKAY; 212 } 213 214 /** sets solving process initialization method of propagator */ 215 SCIP_RETCODE SCIPsetPropInitsol( 216 SCIP* scip, /**< SCIP data structure */ 217 SCIP_PROP* prop, /**< propagator */ 218 SCIP_DECL_PROPINITSOL((*propinitsol)) /**< solving process initialization method of propagator */ 219 ) 220 { 221 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetPropInitsol", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) ); 222 223 assert(prop != NULL); 224 225 SCIPpropSetInitsol(prop, propinitsol); 226 227 return SCIP_OKAY; 228 } 229 230 /** sets solving process deinitialization method of propagator */ 231 SCIP_RETCODE SCIPsetPropExitsol( 232 SCIP* scip, /**< SCIP data structure */ 233 SCIP_PROP* prop, /**< propagator */ 234 SCIP_DECL_PROPEXITSOL ((*propexitsol)) /**< solving process deinitialization method of propagator */ 235 ) 236 { 237 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetPropExitsol", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) ); 238 239 assert(prop != NULL); 240 241 SCIPpropSetExitsol(prop, propexitsol); 242 243 return SCIP_OKAY; 244 } 245 246 /** sets preprocessing initialization method of propagator */ 247 SCIP_RETCODE SCIPsetPropInitpre( 248 SCIP* scip, /**< SCIP data structure */ 249 SCIP_PROP* prop, /**< propagator */ 250 SCIP_DECL_PROPINITPRE((*propinitpre)) /**< preprocessing initialization method of propagator */ 251 ) 252 { 253 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetPropInitpre", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) ); 254 255 assert(prop != NULL); 256 257 SCIPpropSetInitpre(prop, propinitpre); 258 259 return SCIP_OKAY; 260 } 261 262 /** sets preprocessing deinitialization method of propagator */ 263 SCIP_RETCODE SCIPsetPropExitpre( 264 SCIP* scip, /**< SCIP data structure */ 265 SCIP_PROP* prop, /**< propagator */ 266 SCIP_DECL_PROPEXITPRE((*propexitpre)) /**< preprocessing deinitialization method of propagator */ 267 ) 268 { 269 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetPropExitpre", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) ); 270 271 assert(prop != NULL); 272 273 SCIPpropSetExitpre(prop, propexitpre); 274 275 return SCIP_OKAY; 276 } 277 278 /** sets presolving method of propagator */ 279 SCIP_RETCODE SCIPsetPropPresol( 280 SCIP* scip, /**< SCIP data structure */ 281 SCIP_PROP* prop, /**< propagator */ 282 SCIP_DECL_PROPPRESOL((*proppresol)), /**< presolving method of propagator */ 283 int presolpriority, /**< presolving priority of the propagator (>= 0: before, < 0: after constraint handlers) */ 284 int presolmaxrounds, /**< maximal number of presolving rounds the propagator participates in (-1: no limit) */ 285 SCIP_PRESOLTIMING presoltiming /**< timing mask of the propagator's presolving method */ 286 ) 287 { 288 const char* name; 289 char paramname[SCIP_MAXSTRLEN]; 290 291 assert(scip != NULL); 292 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetPropPresol", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) ); 293 294 assert(prop != NULL); 295 SCIP_CALL( SCIPpropSetPresol(prop, proppresol, presolpriority, presolmaxrounds, presoltiming) ); 296 297 name = SCIPpropGetName(prop); 298 299 (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "propagating/%s/maxprerounds", name); 300 SCIP_CALL( SCIPsetSetDefaultIntParam(scip->set, paramname, presolmaxrounds) ); 301 302 (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "propagating/%s/presolpriority", name); 303 SCIP_CALL( SCIPsetSetDefaultIntParam(scip->set, paramname, presolpriority) ); 304 305 (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "propagating/%s/presoltiming", name); 306 SCIP_CALL( SCIPsetSetDefaultIntParam(scip->set, paramname, (int) presoltiming) ); 307 308 return SCIP_OKAY; 309 } 310 311 /** sets propagation conflict resolving callback of propagator */ 312 SCIP_RETCODE SCIPsetPropResprop( 313 SCIP* scip, /**< SCIP data structure */ 314 SCIP_PROP* prop, /**< propagator */ 315 SCIP_DECL_PROPRESPROP ((*propresprop)) /**< propagation conflict resolving callback */ 316 ) 317 { 318 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetPropResprop", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) ); 319 320 assert(prop != NULL); 321 322 SCIPpropSetResprop(prop, propresprop); 323 324 return SCIP_OKAY; 325 } 326 327 328 /** returns the propagator of the given name, or NULL if not existing */ 329 SCIP_PROP* SCIPfindProp( 330 SCIP* scip, /**< SCIP data structure */ 331 const char* name /**< name of propagator */ 332 ) 333 { 334 assert(scip != NULL); 335 assert(scip->set != NULL); 336 assert(name != NULL); 337 338 return SCIPsetFindProp(scip->set, name); 339 } 340 341 /** returns the array of currently available propagators */ 342 SCIP_PROP** SCIPgetProps( 343 SCIP* scip /**< SCIP data structure */ 344 ) 345 { 346 assert(scip != NULL); 347 assert(scip->set != NULL); 348 349 SCIPsetSortProps(scip->set); 350 351 return scip->set->props; 352 } 353 354 /** returns the number of currently available propagators */ 355 int SCIPgetNProps( 356 SCIP* scip /**< SCIP data structure */ 357 ) 358 { 359 assert(scip != NULL); 360 assert(scip->set != NULL); 361 362 return scip->set->nprops; 363 } 364 365 /** sets the priority of a propagator */ 366 SCIP_RETCODE SCIPsetPropPriority( 367 SCIP* scip, /**< SCIP data structure */ 368 SCIP_PROP* prop, /**< propagator */ 369 int priority /**< new priority of the propagator */ 370 ) 371 { 372 assert(scip != NULL); 373 assert(scip->set != NULL); 374 375 SCIPpropSetPriority(prop, scip->set, priority); 376 377 return SCIP_OKAY; 378 } 379 380 /** sets the presolving priority of a propagator */ 381 SCIP_RETCODE SCIPsetPropPresolPriority( 382 SCIP* scip, /**< SCIP data structure */ 383 SCIP_PROP* prop, /**< propagator */ 384 int presolpriority /**< new presol priority of the propagator */ 385 ) 386 { 387 assert(scip != NULL); 388 assert(scip->set != NULL); 389 390 SCIPpropSetPresolPriority(prop, scip->set, presolpriority); 391 392 return SCIP_OKAY; 393 } 394