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 prop.c 26 * @ingroup OTHER_CFILES 27 * @brief methods and datastructures for propagators 28 * @author Tobias Achterberg 29 * @author Timo Berthold 30 */ 31 32 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/ 33 34 #include <assert.h> 35 #include <string.h> 36 37 #include "scip/def.h" 38 #include "scip/set.h" 39 #include "scip/stat.h" 40 #include "scip/clock.h" 41 #include "scip/paramset.h" 42 #include "scip/var.h" 43 #include "scip/scip.h" 44 #include "scip/prop.h" 45 #include "scip/pub_message.h" 46 #include "scip/pub_misc.h" 47 48 #include "scip/struct_prop.h" 49 50 51 /** compares two propagators w. r. to their priority */ 52 SCIP_DECL_SORTPTRCOMP(SCIPpropComp) 53 { /*lint --e{715}*/ 54 return ((SCIP_PROP*)elem2)->priority - ((SCIP_PROP*)elem1)->priority; 55 } 56 57 /** compares two propagators w. r. to their priority */ 58 SCIP_DECL_SORTPTRCOMP(SCIPpropCompPresol) 59 { /*lint --e{715}*/ 60 return ((SCIP_PROP*)elem2)->presolpriority - ((SCIP_PROP*)elem1)->presolpriority; 61 } 62 63 /** comparison method for sorting propagators w.r.t. to their name */ 64 SCIP_DECL_SORTPTRCOMP(SCIPpropCompName) 65 { 66 return strcmp(SCIPpropGetName((SCIP_PROP*)elem1), SCIPpropGetName((SCIP_PROP*)elem2)); 67 } 68 69 /** method to call, when the priority of a propagator was changed */ 70 static 71 SCIP_DECL_PARAMCHGD(paramChgdPropPriority) 72 { /*lint --e{715}*/ 73 SCIP_PARAMDATA* paramdata; 74 75 paramdata = SCIPparamGetData(param); 76 assert(paramdata != NULL); 77 78 /* use SCIPsetPropPriority() to mark the props unsorted */ 79 SCIP_CALL( SCIPsetPropPriority(scip, (SCIP_PROP*)paramdata, SCIPparamGetInt(param)) ); /*lint !e740*/ 80 81 return SCIP_OKAY; 82 } 83 84 /** method to call, when the presolving priority of a propagator was changed */ 85 static 86 SCIP_DECL_PARAMCHGD(paramChgdPropPresolPriority) 87 { /*lint --e{715}*/ 88 SCIP_PARAMDATA* paramdata; 89 90 paramdata = SCIPparamGetData(param); 91 assert(paramdata != NULL); 92 93 /* use SCIPsetPropPriority() to mark the props unsorted */ 94 SCIP_CALL( SCIPsetPropPresolPriority(scip, (SCIP_PROP*)paramdata, SCIPparamGetInt(param)) ); /*lint !e740*/ 95 96 return SCIP_OKAY; 97 } 98 99 /** copies the given propagator to a new scip */ 100 SCIP_RETCODE SCIPpropCopyInclude( 101 SCIP_PROP* prop, /**< propagator */ 102 SCIP_SET* set /**< SCIP_SET of SCIP to copy to */ 103 ) 104 { 105 assert(prop != NULL); 106 assert(set != NULL); 107 assert(set->scip != NULL); 108 109 if( prop->propcopy != NULL ) 110 { 111 SCIPsetDebugMsg(set, "including propagator %s in subscip %p\n", SCIPpropGetName(prop), (void*)set->scip); 112 SCIP_CALL( prop->propcopy(set->scip, prop) ); 113 } 114 return SCIP_OKAY; 115 } 116 117 /** internal method for creating a propagator */ 118 static 119 SCIP_RETCODE doPropCreate( 120 SCIP_PROP** prop, /**< pointer to propagator data structure */ 121 SCIP_SET* set, /**< global SCIP settings */ 122 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */ 123 BMS_BLKMEM* blkmem, /**< block memory for parameter settings */ 124 const char* name, /**< name of propagator */ 125 const char* desc, /**< description of propagator */ 126 int priority, /**< priority of the propagator (>= 0: before, < 0: after constraint handlers) */ 127 int freq, /**< frequency for calling propagator */ 128 SCIP_Bool delay, /**< should propagator be delayed, if other propagators found reductions? */ 129 SCIP_PROPTIMING timingmask, /**< positions in the node solving loop where propagator should be executed */ 130 int presolpriority, /**< priority of the propagator (>= 0: before, < 0: after constraint handlers) */ 131 int presolmaxrounds, /**< maximal number of presolving rounds the propagator participates in (-1: no limit) */ 132 SCIP_PRESOLTIMING presoltiming, /**< timing mask of the propagator's presolving method */ 133 SCIP_DECL_PROPCOPY ((*propcopy)), /**< copy method of propagator or NULL if you don't want to copy your plugin into sub-SCIPs */ 134 SCIP_DECL_PROPFREE ((*propfree)), /**< destructor of propagator */ 135 SCIP_DECL_PROPINIT ((*propinit)), /**< initialize propagator */ 136 SCIP_DECL_PROPEXIT ((*propexit)), /**< deinitialize propagator */ 137 SCIP_DECL_PROPINITPRE ((*propinitpre)), /**< presolving initialization method of propagator */ 138 SCIP_DECL_PROPEXITPRE ((*propexitpre)), /**< presolving deinitialization method of propagator */ 139 SCIP_DECL_PROPINITSOL ((*propinitsol)), /**< solving process initialization method of propagator */ 140 SCIP_DECL_PROPEXITSOL ((*propexitsol)), /**< solving process deinitialization method of propagator */ 141 SCIP_DECL_PROPPRESOL ((*proppresol)), /**< presolving method */ 142 SCIP_DECL_PROPEXEC ((*propexec)), /**< execution method of propagator */ 143 SCIP_DECL_PROPRESPROP ((*propresprop)), /**< propagation conflict resolving method */ 144 SCIP_PROPDATA* propdata /**< propagator data */ 145 ) 146 { 147 char paramname[SCIP_MAXSTRLEN]; 148 char paramdesc[SCIP_MAXSTRLEN]; 149 150 assert(prop != NULL); 151 assert(name != NULL); 152 assert(desc != NULL); 153 assert(freq >= -1); 154 assert(propexec != NULL); 155 156 /* the interface change from delay flags to timings cannot be recognized at compile time: Exit with an appropriate 157 * error message 158 */ 159 if( presoltiming < SCIP_PRESOLTIMING_NONE || presoltiming > SCIP_PRESOLTIMING_MAX ) 160 { 161 SCIPmessagePrintError("ERROR: 'PRESOLDELAY'-flag no longer available since SCIP 3.2, use an appropriate " 162 "'SCIP_PRESOLTIMING' for <%s> propagator instead.\n", name); 163 164 return SCIP_PARAMETERWRONGVAL; 165 } 166 167 SCIP_ALLOC( BMSallocMemory(prop) ); 168 BMSclearMemory(*prop); 169 170 SCIP_ALLOC( BMSduplicateMemoryArray(&(*prop)->name, name, strlen(name)+1) ); 171 SCIP_ALLOC( BMSduplicateMemoryArray(&(*prop)->desc, desc, strlen(desc)+1) ); 172 (*prop)->priority = priority; 173 (*prop)->freq = freq; 174 (*prop)->propcopy = propcopy; 175 (*prop)->propfree = propfree; 176 (*prop)->propinit = propinit; 177 (*prop)->propexit = propexit; 178 (*prop)->propinitpre = propinitpre; 179 (*prop)->propexitpre = propexitpre; 180 (*prop)->propinitsol = propinitsol; 181 (*prop)->propexitsol = propexitsol; 182 (*prop)->proppresol = proppresol; 183 (*prop)->propexec = propexec; 184 (*prop)->propresprop = propresprop; 185 (*prop)->propdata = propdata; 186 SCIP_CALL( SCIPclockCreate(&(*prop)->setuptime, SCIP_CLOCKTYPE_DEFAULT) ); 187 SCIP_CALL( SCIPclockCreate(&(*prop)->proptime, SCIP_CLOCKTYPE_DEFAULT) ); 188 SCIP_CALL( SCIPclockCreate(&(*prop)->sbproptime, SCIP_CLOCKTYPE_DEFAULT) ); 189 SCIP_CALL( SCIPclockCreate(&(*prop)->resproptime, SCIP_CLOCKTYPE_DEFAULT) ); 190 SCIP_CALL( SCIPclockCreate(&(*prop)->presoltime, SCIP_CLOCKTYPE_DEFAULT) ); 191 (*prop)->ncalls = 0; 192 (*prop)->nrespropcalls = 0; 193 (*prop)->ncutoffs = 0; 194 (*prop)->ndomredsfound = 0; 195 (*prop)->wasdelayed = FALSE; 196 (*prop)->initialized = FALSE; 197 198 /* add parameters */ 199 (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "propagating/%s/priority", name); 200 (void) SCIPsnprintf(paramdesc, SCIP_MAXSTRLEN, "priority of propagator <%s>", name); 201 SCIP_CALL( SCIPsetAddIntParam(set, messagehdlr, blkmem, paramname, paramdesc, 202 &(*prop)->priority, TRUE, priority, INT_MIN/4, INT_MAX/4, 203 paramChgdPropPriority, (SCIP_PARAMDATA*)(*prop)) ); /*lint !e740*/ 204 205 (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "propagating/%s/freq", name); 206 (void) SCIPsnprintf(paramdesc, SCIP_MAXSTRLEN, "frequency for calling propagator <%s> (-1: never, 0: only in root node)", name); 207 SCIP_CALL( SCIPsetAddIntParam(set, messagehdlr, blkmem, paramname, paramdesc, 208 &(*prop)->freq, FALSE, freq, -1, SCIP_MAXTREEDEPTH, NULL, NULL) ); 209 210 (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "propagating/%s/delay", name); 211 SCIP_CALL( SCIPsetAddBoolParam(set, messagehdlr, blkmem, paramname, 212 "should propagator be delayed, if other propagators found reductions?", 213 &(*prop)->delay, TRUE, delay, NULL, NULL) ); /*lint !e740*/ 214 215 (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "propagating/%s/timingmask", name); 216 (void) SCIPsnprintf(paramdesc, SCIP_MAXSTRLEN, "timing when propagator should be called (%u:BEFORELP, %u:DURINGLPLOOP, %u:AFTERLPLOOP, %u:ALWAYS))", 217 SCIP_PROPTIMING_BEFORELP, SCIP_PROPTIMING_DURINGLPLOOP, SCIP_PROPTIMING_AFTERLPLOOP, SCIP_PROPTIMING_ALWAYS); 218 SCIP_CALL( SCIPsetAddIntParam(set, messagehdlr, blkmem, paramname, paramdesc, 219 (int*)(&(*prop)->timingmask), TRUE, (int) timingmask, (int) SCIP_PROPTIMING_BEFORELP, (int) SCIP_PROPTIMING_ALWAYS, NULL, NULL) ); /*lint !e713*/ 220 221 (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "propagating/%s/presolpriority", name); 222 (void) SCIPsnprintf(paramdesc, SCIP_MAXSTRLEN, "presolving priority of propagator <%s>", name); 223 SCIP_CALL( SCIPsetAddIntParam(set, messagehdlr, blkmem, paramname, paramdesc, 224 &(*prop)->presolpriority, TRUE, presolpriority, INT_MIN/4, INT_MAX/4, 225 paramChgdPropPresolPriority, (SCIP_PARAMDATA*)(*prop)) ); /*lint !e740*/ 226 227 (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "propagating/%s/maxprerounds", name); 228 SCIP_CALL( SCIPsetAddIntParam(set, messagehdlr, blkmem, paramname, 229 "maximal number of presolving rounds the propagator participates in (-1: no limit)", 230 &(*prop)->maxprerounds, FALSE, presolmaxrounds, -1, INT_MAX, NULL, NULL) ); /*lint !e740*/ 231 232 (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "propagating/%s/presoltiming", name); 233 (void) SCIPsnprintf(paramdesc, SCIP_MAXSTRLEN, "timing mask of the presolving method of propagator <%s> (%u:FAST, %u:MEDIUM, %u:EXHAUSTIVE, %u:FINAL)", 234 name, SCIP_PRESOLTIMING_FAST, SCIP_PRESOLTIMING_MEDIUM, SCIP_PRESOLTIMING_EXHAUSTIVE, SCIP_PRESOLTIMING_FINAL); 235 SCIP_CALL( SCIPsetAddIntParam(set, messagehdlr, blkmem, paramname, paramdesc, 236 (int*)&(*prop)->presoltiming, TRUE, (int)presoltiming, (int) SCIP_PRESOLTIMING_NONE, (int) SCIP_PRESOLTIMING_MAX, NULL, NULL) ); /*lint !e740*/ 237 238 return SCIP_OKAY; 239 } 240 241 /** creates a propagator */ 242 SCIP_RETCODE SCIPpropCreate( 243 SCIP_PROP** prop, /**< pointer to propagator data structure */ 244 SCIP_SET* set, /**< global SCIP settings */ 245 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */ 246 BMS_BLKMEM* blkmem, /**< block memory for parameter settings */ 247 const char* name, /**< name of propagator */ 248 const char* desc, /**< description of propagator */ 249 int priority, /**< priority of the propagator (>= 0: before, < 0: after constraint handlers) */ 250 int freq, /**< frequency for calling propagator */ 251 SCIP_Bool delay, /**< should propagator be delayed, if other propagators found reductions? */ 252 SCIP_PROPTIMING timingmask, /**< positions in the node solving loop where propagator should be executed */ 253 int presolpriority, /**< priority of the propagator (>= 0: before, < 0: after constraint handlers) */ 254 int presolmaxrounds, /**< maximal number of presolving rounds the propagator participates in (-1: no limit) */ 255 SCIP_PRESOLTIMING presoltiming, /**< timing mask of the propagator's presolving method */ 256 SCIP_DECL_PROPCOPY ((*propcopy)), /**< copy method of propagator or NULL if you don't want to copy your plugin into sub-SCIPs */ 257 SCIP_DECL_PROPFREE ((*propfree)), /**< destructor of propagator */ 258 SCIP_DECL_PROPINIT ((*propinit)), /**< initialize propagator */ 259 SCIP_DECL_PROPEXIT ((*propexit)), /**< deinitialize propagator */ 260 SCIP_DECL_PROPINITPRE ((*propinitpre)), /**< presolving initialization method of propagator */ 261 SCIP_DECL_PROPEXITPRE ((*propexitpre)), /**< presolving deinitialization method of propagator */ 262 SCIP_DECL_PROPINITSOL ((*propinitsol)), /**< solving process initialization method of propagator */ 263 SCIP_DECL_PROPEXITSOL ((*propexitsol)), /**< solving process deinitialization method of propagator */ 264 SCIP_DECL_PROPPRESOL ((*proppresol)), /**< presolving method */ 265 SCIP_DECL_PROPEXEC ((*propexec)), /**< execution method of propagator */ 266 SCIP_DECL_PROPRESPROP ((*propresprop)), /**< propagation conflict resolving method */ 267 SCIP_PROPDATA* propdata /**< propagator data */ 268 ) 269 { 270 assert(prop != NULL); 271 assert(name != NULL); 272 assert(desc != NULL); 273 assert(freq >= -1); 274 assert(propexec != NULL); 275 276 SCIP_CALL_FINALLY( doPropCreate(prop, set, messagehdlr, blkmem, name, desc, priority, freq, delay, timingmask, 277 presolpriority, presolmaxrounds, presoltiming, propcopy, propfree, propinit, propexit, propinitpre, propexitpre, 278 propinitsol, propexitsol, proppresol, propexec, propresprop, propdata), (void) SCIPpropFree(prop, set) ); 279 280 return SCIP_OKAY; 281 } 282 283 /** calls destructor and frees memory of propagator */ 284 SCIP_RETCODE SCIPpropFree( 285 SCIP_PROP** prop, /**< pointer to propagator data structure */ 286 SCIP_SET* set /**< global SCIP settings */ 287 ) 288 { 289 assert(prop != NULL); 290 if( *prop == NULL ) 291 return SCIP_OKAY; 292 assert(!(*prop)->initialized); 293 assert(set != NULL); 294 295 /* call destructor of propagator */ 296 if( (*prop)->propfree != NULL ) 297 { 298 SCIP_CALL( (*prop)->propfree(set->scip, *prop) ); 299 } 300 301 SCIPclockFree(&(*prop)->presoltime); 302 SCIPclockFree(&(*prop)->resproptime); 303 SCIPclockFree(&(*prop)->sbproptime); 304 SCIPclockFree(&(*prop)->proptime); 305 SCIPclockFree(&(*prop)->setuptime); 306 BMSfreeMemoryArrayNull(&(*prop)->desc); 307 BMSfreeMemoryArrayNull(&(*prop)->name); 308 BMSfreeMemory(prop); 309 310 return SCIP_OKAY; 311 } 312 313 /** initializes propagator */ 314 SCIP_RETCODE SCIPpropInit( 315 SCIP_PROP* prop, /**< propagator */ 316 SCIP_SET* set /**< global SCIP settings */ 317 ) 318 { 319 assert(prop != NULL); 320 assert(set != NULL); 321 322 if( prop->initialized ) 323 { 324 SCIPerrorMessage("propagator <%s> already initialized\n", prop->name); 325 return SCIP_INVALIDCALL; 326 } 327 328 if( set->misc_resetstat ) 329 { 330 SCIPclockReset(prop->proptime); 331 SCIPclockReset(prop->sbproptime); 332 SCIPclockReset(prop->resproptime); 333 SCIPclockReset(prop->presoltime); 334 SCIPclockReset(prop->setuptime); 335 336 prop->ncalls = 0; 337 prop->nrespropcalls = 0; 338 prop->ncutoffs = 0; 339 prop->ndomredsfound = 0; 340 prop->lastnfixedvars = 0; 341 prop->lastnaggrvars = 0; 342 prop->lastnchgvartypes = 0; 343 prop->lastnchgbds = 0; 344 prop->lastnaddholes = 0; 345 prop->lastndelconss = 0; 346 prop->lastnaddconss = 0; 347 prop->lastnupgdconss = 0; 348 prop->lastnchgcoefs = 0; 349 prop->lastnchgsides = 0; 350 prop->nfixedvars = 0; 351 prop->naggrvars = 0; 352 prop->nchgvartypes = 0; 353 prop->nchgbds = 0; 354 prop->naddholes = 0; 355 prop->ndelconss = 0; 356 prop->naddconss = 0; 357 prop->nupgdconss = 0; 358 prop->nchgcoefs = 0; 359 prop->nchgsides = 0; 360 prop->npresolcalls = 0; 361 prop->wasdelayed = FALSE; 362 } 363 364 if( prop->propinit != NULL ) 365 { 366 /* start timing */ 367 SCIPclockStart(prop->setuptime, set); 368 369 SCIP_CALL( prop->propinit(set->scip, prop) ); 370 371 /* stop timing */ 372 SCIPclockStop(prop->setuptime, set); 373 } 374 prop->initialized = TRUE; 375 376 return SCIP_OKAY; 377 } 378 379 /** calls exit method of propagator */ 380 SCIP_RETCODE SCIPpropExit( 381 SCIP_PROP* prop, /**< propagator */ 382 SCIP_SET* set /**< global SCIP settings */ 383 ) 384 { 385 assert(prop != NULL); 386 assert(set != NULL); 387 388 if( !prop->initialized ) 389 { 390 SCIPerrorMessage("propagator <%s> not initialized\n", prop->name); 391 return SCIP_INVALIDCALL; 392 } 393 394 if( prop->propexit != NULL ) 395 { 396 /* start timing */ 397 SCIPclockStart(prop->setuptime, set); 398 399 SCIP_CALL( prop->propexit(set->scip, prop) ); 400 401 /* stop timing */ 402 SCIPclockStop(prop->setuptime, set); 403 } 404 prop->initialized = FALSE; 405 406 return SCIP_OKAY; 407 } 408 409 /** informs propagator that the presolving process is being started */ 410 SCIP_RETCODE SCIPpropInitpre( 411 SCIP_PROP* prop, /**< propagator */ 412 SCIP_SET* set /**< global SCIP settings */ 413 ) 414 { 415 assert(prop != NULL); 416 assert(set != NULL); 417 418 prop->lastnfixedvars = 0; 419 prop->lastnaggrvars = 0; 420 prop->lastnchgvartypes = 0; 421 prop->lastnchgbds = 0; 422 prop->lastnaddholes = 0; 423 prop->lastndelconss = 0; 424 prop->lastnaddconss = 0; 425 prop->lastnupgdconss = 0; 426 prop->lastnchgcoefs = 0; 427 prop->lastnchgsides = 0; 428 prop->wasdelayed = FALSE; 429 430 /* call presolving initialization method of propagator */ 431 if( prop->propinitpre != NULL ) 432 { 433 /* start timing */ 434 SCIPclockStart(prop->setuptime, set); 435 436 SCIP_CALL( prop->propinitpre(set->scip, prop) ); 437 438 /* stop timing */ 439 SCIPclockStop(prop->setuptime, set); 440 } 441 442 return SCIP_OKAY; 443 } 444 445 /** informs propagator that the presolving process is finished */ 446 SCIP_RETCODE SCIPpropExitpre( 447 SCIP_PROP* prop, /**< propagator */ 448 SCIP_SET* set /**< global SCIP settings */ 449 ) 450 { 451 assert(prop != NULL); 452 assert(set != NULL); 453 454 /* call presolving deinitialization method of propagator */ 455 if( prop->propexitpre != NULL ) 456 { 457 /* start timing */ 458 SCIPclockStart(prop->setuptime, set); 459 460 SCIP_CALL( prop->propexitpre(set->scip, prop) ); 461 462 /* stop timing */ 463 SCIPclockStop(prop->setuptime, set); 464 } 465 466 return SCIP_OKAY; 467 } 468 469 /** informs propagator that the prop and bound process is being started */ 470 SCIP_RETCODE SCIPpropInitsol( 471 SCIP_PROP* prop, /**< propagator */ 472 SCIP_SET* set /**< global SCIP settings */ 473 ) 474 { 475 assert(prop != NULL); 476 assert(set != NULL); 477 478 /* call solving process initialization method of propagator */ 479 if( prop->propinitsol != NULL ) 480 { 481 /* start timing */ 482 SCIPclockStart(prop->setuptime, set); 483 484 SCIP_CALL( prop->propinitsol(set->scip, prop) ); 485 486 /* stop timing */ 487 SCIPclockStop(prop->setuptime, set); 488 } 489 490 return SCIP_OKAY; 491 } 492 493 /** informs propagator that the prop and bound process data is being freed */ 494 SCIP_RETCODE SCIPpropExitsol( 495 SCIP_PROP* prop, /**< propagator */ 496 SCIP_SET* set, /**< global SCIP settings */ 497 SCIP_Bool restart /**< was this exit solve call triggered by a restart? */ 498 ) 499 { 500 assert(prop != NULL); 501 assert(set != NULL); 502 503 /* call solving process deinitialization method of propagator */ 504 if( prop->propexitsol != NULL ) 505 { 506 /* start timing */ 507 SCIPclockStart(prop->setuptime, set); 508 509 SCIP_CALL( prop->propexitsol(set->scip, prop, restart) ); 510 511 /* stop timing */ 512 SCIPclockStop(prop->setuptime, set); 513 } 514 515 return SCIP_OKAY; 516 } 517 518 /** executes presolving method of propagator */ 519 SCIP_RETCODE SCIPpropPresol( 520 SCIP_PROP* prop, /**< propagator */ 521 SCIP_SET* set, /**< global SCIP settings */ 522 SCIP_PRESOLTIMING timing, /**< current presolving timing */ 523 int nrounds, /**< number of presolving rounds already done */ 524 int* nfixedvars, /**< pointer to total number of variables fixed of all presolvers */ 525 int* naggrvars, /**< pointer to total number of variables aggregated of all presolvers */ 526 int* nchgvartypes, /**< pointer to total number of variable type changes of all presolvers */ 527 int* nchgbds, /**< pointer to total number of variable bounds tightened of all presolvers */ 528 int* naddholes, /**< pointer to total number of domain holes added of all presolvers */ 529 int* ndelconss, /**< pointer to total number of deleted constraints of all presolvers */ 530 int* naddconss, /**< pointer to total number of added constraints of all presolvers */ 531 int* nupgdconss, /**< pointer to total number of upgraded constraints of all presolvers */ 532 int* nchgcoefs, /**< pointer to total number of changed coefficients of all presolvers */ 533 int* nchgsides, /**< pointer to total number of changed left/right hand sides of all presolvers */ 534 SCIP_RESULT* result /**< pointer to store the result of the callback method */ 535 ) 536 { 537 assert(prop != NULL); 538 assert(set != NULL); 539 assert(nfixedvars != NULL); 540 assert(naggrvars != NULL); 541 assert(nchgvartypes != NULL); 542 assert(nchgbds != NULL); 543 assert(naddholes != NULL); 544 assert(ndelconss != NULL); 545 assert(naddconss != NULL); 546 assert(nupgdconss != NULL); 547 assert(nchgcoefs != NULL); 548 assert(nchgsides != NULL); 549 assert(result != NULL); 550 551 *result = SCIP_DIDNOTRUN; 552 553 if( prop->proppresol == NULL ) 554 return SCIP_OKAY; 555 556 /* check number of presolving rounds */ 557 if( prop->maxprerounds >= 0 && prop->npresolcalls >= prop->maxprerounds ) 558 return SCIP_OKAY; 559 560 /* check, if presolver should be delayed */ 561 if( prop->presoltiming & timing ) 562 { 563 int nnewfixedvars; 564 int nnewaggrvars; 565 int nnewchgvartypes; 566 int nnewchgbds; 567 int nnewaddholes; 568 int nnewdelconss; 569 int nnewaddconss; 570 int nnewupgdconss; 571 int nnewchgcoefs; 572 int nnewchgsides; 573 574 SCIPsetDebugMsg(set, "calling presolving method of propagator <%s>\n", prop->name); 575 576 /* calculate the number of changes since last call */ 577 nnewfixedvars = *nfixedvars - prop->lastnfixedvars; 578 nnewaggrvars = *naggrvars - prop->lastnaggrvars; 579 nnewchgvartypes = *nchgvartypes - prop->lastnchgvartypes; 580 nnewchgbds = *nchgbds - prop->lastnchgbds; 581 nnewaddholes = *naddholes - prop->lastnaddholes; 582 nnewdelconss = *ndelconss - prop->lastndelconss; 583 nnewaddconss = *naddconss - prop->lastnaddconss; 584 nnewupgdconss = *nupgdconss - prop->lastnupgdconss; 585 nnewchgcoefs = *nchgcoefs - prop->lastnchgcoefs; 586 nnewchgsides = *nchgsides - prop->lastnchgsides; 587 588 /* remember the number of changes prior to the call of the presolver method of the propagator */ 589 prop->lastnfixedvars = *nfixedvars; 590 prop->lastnaggrvars = *naggrvars; 591 prop->lastnchgvartypes = *nchgvartypes; 592 prop->lastnchgbds = *nchgbds; 593 prop->lastnaddholes = *naddholes; 594 prop->lastndelconss = *ndelconss; 595 prop->lastnaddconss = *naddconss; 596 prop->lastnupgdconss = *nupgdconss; 597 prop->lastnchgcoefs = *nchgcoefs; 598 prop->lastnchgsides = *nchgsides; 599 600 /* start timing */ 601 SCIPclockStart(prop->presoltime, set); 602 603 /* call external method */ 604 SCIP_CALL( prop->proppresol(set->scip, prop, nrounds, timing, 605 nnewfixedvars, nnewaggrvars, nnewchgvartypes, nnewchgbds, nnewaddholes, 606 nnewdelconss, nnewaddconss, nnewupgdconss, nnewchgcoefs, nnewchgsides, 607 nfixedvars, naggrvars, nchgvartypes, nchgbds, naddholes, 608 ndelconss, naddconss, nupgdconss, nchgcoefs, nchgsides, result) ); 609 610 /* stop timing */ 611 SCIPclockStop(prop->presoltime, set); 612 613 /* add/count the new changes */ 614 prop->nfixedvars += *nfixedvars - prop->lastnfixedvars; 615 prop->naggrvars += *naggrvars - prop->lastnaggrvars; 616 prop->nchgvartypes += *nchgvartypes - prop->lastnchgvartypes; 617 prop->nchgbds += *nchgbds - prop->lastnchgbds; 618 prop->naddholes += *naddholes - prop->lastnaddholes; 619 prop->ndelconss += *ndelconss - prop->lastndelconss; 620 prop->naddconss += *naddconss - prop->lastnaddconss; 621 prop->nupgdconss += *nupgdconss - prop->lastnupgdconss; 622 prop->nchgcoefs += *nchgcoefs - prop->lastnchgcoefs; 623 prop->nchgsides += *nchgsides - prop->lastnchgsides; 624 625 /* check result code of callback method */ 626 if( *result != SCIP_CUTOFF 627 && *result != SCIP_UNBOUNDED 628 && *result != SCIP_SUCCESS 629 && *result != SCIP_DIDNOTFIND 630 && *result != SCIP_DIDNOTRUN ) 631 { 632 SCIPerrorMessage("propagator <%s> returned invalid result <%d>\n", prop->name, *result); 633 return SCIP_INVALIDRESULT; 634 } 635 636 /* increase the number of presolving calls, if the propagator tried to find reductions */ 637 if( *result != SCIP_DIDNOTRUN ) 638 ++(prop->npresolcalls); 639 } 640 641 return SCIP_OKAY; 642 } 643 644 /** calls execution method of propagator */ 645 SCIP_RETCODE SCIPpropExec( 646 SCIP_PROP* prop, /**< propagator */ 647 SCIP_SET* set, /**< global SCIP settings */ 648 SCIP_STAT* stat, /**< dynamic problem statistics */ 649 int depth, /**< depth of current node */ 650 SCIP_Bool execdelayed, /**< execute propagator even if it is marked to be delayed */ 651 SCIP_Bool instrongbranching, /**< are we currently doing strong branching? */ 652 SCIP_PROPTIMING proptiming, /**< current point in the node solving process */ 653 SCIP_RESULT* result /**< pointer to store the result of the callback method */ 654 ) 655 { 656 assert(prop != NULL); 657 assert(prop->propexec != NULL); 658 assert(prop->freq >= -1); 659 assert(set != NULL); 660 assert(set->scip != NULL); 661 assert(stat != NULL); 662 assert(depth >= 0); 663 assert(result != NULL); 664 665 if( (depth == 0 && prop->freq == 0) || (prop->freq > 0 && depth % prop->freq == 0) ) 666 { 667 if( !prop->delay || execdelayed ) 668 { 669 SCIP_Longint oldndomchgs; 670 SCIP_Longint oldnprobdomchgs; 671 672 SCIPsetDebugMsg(set, "executing propagator <%s>\n", prop->name); 673 674 oldndomchgs = stat->nboundchgs + stat->nholechgs; 675 oldnprobdomchgs = stat->nprobboundchgs + stat->nprobholechgs; 676 677 /* start timing */ 678 if( instrongbranching ) 679 SCIPclockStart(prop->sbproptime, set); 680 else 681 SCIPclockStart(prop->proptime, set); 682 683 /* call external propagation method */ 684 SCIP_CALL( prop->propexec(set->scip, prop, proptiming, result) ); 685 686 /* stop timing */ 687 if( instrongbranching ) 688 SCIPclockStop(prop->sbproptime, set); 689 else 690 SCIPclockStop(prop->proptime, set); 691 692 /* update statistics */ 693 if( *result != SCIP_DIDNOTRUN && *result != SCIP_DELAYED ) 694 prop->ncalls++; 695 if( *result == SCIP_CUTOFF ) 696 prop->ncutoffs++; 697 698 /* update domain reductions; therefore remove the domain 699 * reduction counts which were generated in probing mode */ 700 prop->ndomredsfound += stat->nboundchgs + stat->nholechgs - oldndomchgs; 701 prop->ndomredsfound -= (stat->nprobboundchgs + stat->nprobholechgs - oldnprobdomchgs); 702 703 /* evaluate result */ 704 if( *result != SCIP_CUTOFF 705 && *result != SCIP_REDUCEDDOM 706 && *result != SCIP_DIDNOTFIND 707 && *result != SCIP_DIDNOTRUN 708 && *result != SCIP_DELAYED 709 && *result != SCIP_DELAYNODE ) 710 { 711 SCIPerrorMessage("execution method of propagator <%s> returned invalid result <%d>\n", 712 prop->name, *result); 713 return SCIP_INVALIDRESULT; 714 } 715 } 716 else 717 { 718 SCIPsetDebugMsg(set, "propagator <%s> was delayed\n", prop->name); 719 *result = SCIP_DELAYED; 720 } 721 722 /* remember whether propagator was delayed */ 723 prop->wasdelayed = (*result == SCIP_DELAYED); 724 } 725 else 726 *result = SCIP_DIDNOTRUN; 727 728 return SCIP_OKAY; 729 } 730 731 /** resolves the given conflicting bound, that was deduced by the given propagator, by putting all "reason" bounds 732 * leading to the deduction into the conflict queue with calls to SCIPaddConflictLb(), SCIPaddConflictUb(), SCIPaddConflictBd(), 733 * SCIPaddConflictRelaxedLb(), SCIPaddConflictRelaxedUb(), SCIPaddConflictRelaxedBd(), or SCIPaddConflictBinvar(); 734 * 735 * @note it is sufficient to explain the relaxed bound change 736 */ 737 SCIP_RETCODE SCIPpropResolvePropagation( 738 SCIP_PROP* prop, /**< propagator */ 739 SCIP_SET* set, /**< global SCIP settings */ 740 SCIP_VAR* infervar, /**< variable whose bound was deduced by the constraint */ 741 int inferinfo, /**< user inference information attached to the bound change */ 742 SCIP_BOUNDTYPE inferboundtype, /**< bound that was deduced (lower or upper bound) */ 743 SCIP_BDCHGIDX* bdchgidx, /**< bound change index, representing the point of time where change took place */ 744 SCIP_Real relaxedbd, /**< the relaxed bound */ 745 SCIP_RESULT* result /**< pointer to store the result of the callback method */ 746 ) 747 { 748 assert(prop != NULL); 749 assert((inferboundtype == SCIP_BOUNDTYPE_LOWER 750 && SCIPgetVarLbAtIndex(set->scip, infervar, bdchgidx, TRUE) > SCIPvarGetLbGlobal(infervar)) 751 || (inferboundtype == SCIP_BOUNDTYPE_UPPER 752 && SCIPgetVarUbAtIndex(set->scip, infervar, bdchgidx, TRUE) < SCIPvarGetUbGlobal(infervar))); 753 assert(result != NULL); 754 755 *result = SCIP_DIDNOTRUN; 756 757 if( prop->propresprop != NULL ) 758 { 759 /* start timing */ 760 SCIPclockStart(prop->resproptime, set); 761 762 SCIP_CALL( prop->propresprop(set->scip, prop, infervar, inferinfo, inferboundtype, bdchgidx, 763 relaxedbd, result) ); 764 765 /* stop timing */ 766 SCIPclockStop(prop->resproptime, set); 767 768 /* update statistic */ 769 prop->nrespropcalls++; 770 771 /* check result code */ 772 if( *result != SCIP_SUCCESS && *result != SCIP_DIDNOTFIND ) 773 { 774 SCIPerrorMessage("propagation conflict resolving method of propagator <%s> returned invalid result <%d>\n", 775 prop->name, *result); 776 return SCIP_INVALIDRESULT; 777 } 778 } 779 else 780 { 781 SCIPerrorMessage("propagation conflict resolving method of propagator <%s> is not implemented\n", prop->name); 782 return SCIP_PLUGINNOTFOUND; 783 } 784 785 return SCIP_OKAY; 786 } 787 788 /** gets user data of propagator */ 789 SCIP_PROPDATA* SCIPpropGetData( 790 SCIP_PROP* prop /**< propagator */ 791 ) 792 { 793 assert(prop != NULL); 794 795 return prop->propdata; 796 } 797 798 /** sets user data of propagator; user has to free old data in advance! */ 799 void SCIPpropSetData( 800 SCIP_PROP* prop, /**< propagator */ 801 SCIP_PROPDATA* propdata /**< new propagator user data */ 802 ) 803 { 804 assert(prop != NULL); 805 806 prop->propdata = propdata; 807 } 808 809 /** sets copy method of propagator */ 810 void SCIPpropSetCopy( 811 SCIP_PROP* prop, /**< propagator */ 812 SCIP_DECL_PROPCOPY ((*propcopy)) /**< copy method of propagator or NULL if you don't want to copy your plugin into sub-SCIPs */ 813 ) 814 { 815 assert(prop != NULL); 816 817 prop->propcopy = propcopy; 818 } 819 820 /** sets destructor method of propagator */ 821 void SCIPpropSetFree( 822 SCIP_PROP* prop, /**< propagator */ 823 SCIP_DECL_PROPFREE ((*propfree)) /**< destructor of propagator */ 824 ) 825 { 826 assert(prop != NULL); 827 828 prop->propfree = propfree; 829 } 830 831 /** sets initialization method of propagator */ 832 void SCIPpropSetInit( 833 SCIP_PROP* prop, /**< propagator */ 834 SCIP_DECL_PROPINIT ((*propinit)) /**< initialize propagator */ 835 ) 836 { 837 assert(prop != NULL); 838 839 prop->propinit = propinit; 840 } 841 842 /** sets deinitialization method of propagator */ 843 void SCIPpropSetExit( 844 SCIP_PROP* prop, /**< propagator */ 845 SCIP_DECL_PROPEXIT ((*propexit)) /**< deinitialize propagator */ 846 ) 847 { 848 assert(prop != NULL); 849 850 prop->propexit = propexit; 851 } 852 853 /** sets solving process initialization method of propagator */ 854 void SCIPpropSetInitsol( 855 SCIP_PROP* prop, /**< propagator */ 856 SCIP_DECL_PROPINITSOL((*propinitsol)) /**< solving process initialization method of propagator */ 857 ) 858 { 859 assert(prop != NULL); 860 861 prop->propinitsol = propinitsol; 862 } 863 864 /** sets solving process deinitialization method of propagator */ 865 void SCIPpropSetExitsol( 866 SCIP_PROP* prop, /**< propagator */ 867 SCIP_DECL_PROPEXITSOL ((*propexitsol)) /**< solving process deinitialization method of propagator */ 868 ) 869 { 870 assert(prop != NULL); 871 872 prop->propexitsol = propexitsol; 873 } 874 875 /** sets preprocessing initialization method of propagator */ 876 void SCIPpropSetInitpre( 877 SCIP_PROP* prop, /**< propagator */ 878 SCIP_DECL_PROPINITPRE((*propinitpre)) /**< preprocessing initialization method of propagator */ 879 ) 880 { 881 assert(prop != NULL); 882 883 prop->propinitpre = propinitpre; 884 } 885 886 887 888 /** sets preprocessing deinitialization method of propagator */ 889 void SCIPpropSetExitpre( 890 SCIP_PROP* prop, /**< propagator */ 891 SCIP_DECL_PROPEXITPRE((*propexitpre)) /**< preprocessing deinitialization method of propagator */ 892 ) 893 { 894 assert(prop != NULL); 895 896 prop->propexitpre = propexitpre; 897 } 898 899 /** sets presolving method of propagator */ 900 SCIP_RETCODE SCIPpropSetPresol( 901 SCIP_PROP* prop, /**< propagator */ 902 SCIP_DECL_PROPPRESOL ((*proppresol)), /**< presolving method */ 903 int presolpriority, /**< presolving priority of the propagator (>= 0: before, < 0: after constraint handlers) */ 904 int presolmaxrounds, /**< maximal number of presolving rounds the propagator participates in (-1: no limit) */ 905 SCIP_PRESOLTIMING presoltiming /**< timing mask of the propagator's presolving method */ 906 ) 907 { 908 assert(prop != NULL); 909 910 prop->proppresol = proppresol; 911 prop->presolpriority = presolpriority; 912 /* the interface change from delay flags to timings cannot be recognized at compile time: Exit with an appropriate 913 * error message 914 */ 915 if( presoltiming < SCIP_PRESOLTIMING_FAST || presoltiming > SCIP_PRESOLTIMING_MAX ) 916 { 917 SCIPmessagePrintError("ERROR: 'PRESOLDELAY'-flag no longer available since SCIP 3.2, use an appropriate " 918 "'SCIP_PRESOLTIMING' for <%s> constraint handler instead.\n", prop->name); 919 920 return SCIP_PARAMETERWRONGVAL; 921 } 922 923 prop->presoltiming = presoltiming; 924 prop->maxprerounds = presolmaxrounds; 925 926 return SCIP_OKAY; 927 } 928 929 /** sets propagation conflict resolving callback of propagator */ 930 void SCIPpropSetResprop( 931 SCIP_PROP* prop, /**< propagator */ 932 SCIP_DECL_PROPRESPROP ((*propresprop)) /**< propagation conflict resolving callback */ 933 ) 934 { 935 assert(prop != NULL); 936 937 prop->propresprop = propresprop; 938 } 939 940 /** gets name of propagator */ 941 const char* SCIPpropGetName( 942 SCIP_PROP* prop /**< propagator */ 943 ) 944 { 945 assert(prop != NULL); 946 947 return prop->name; 948 } 949 950 /** gets description of propagator */ 951 const char* SCIPpropGetDesc( 952 SCIP_PROP* prop /**< propagator */ 953 ) 954 { 955 assert(prop != NULL); 956 957 return prop->desc; 958 } 959 960 /** gets priority of propagator */ 961 int SCIPpropGetPriority( 962 SCIP_PROP* prop /**< propagator */ 963 ) 964 { 965 assert(prop != NULL); 966 967 return prop->priority; 968 } 969 970 /** gets presolving priority of propagator */ 971 int SCIPpropGetPresolPriority( 972 SCIP_PROP* prop /**< propagator */ 973 ) 974 { 975 assert(prop != NULL); 976 977 return prop->presolpriority; 978 } 979 980 /** sets priority of propagator */ 981 void SCIPpropSetPriority( 982 SCIP_PROP* prop, /**< propagator */ 983 SCIP_SET* set, /**< global SCIP settings */ 984 int priority /**< new priority of the propagator */ 985 ) 986 { 987 assert(prop != NULL); 988 assert(set != NULL); 989 990 prop->priority = priority; 991 set->propssorted = FALSE; 992 } 993 994 /** sets presolving priority of propagator */ 995 void SCIPpropSetPresolPriority( 996 SCIP_PROP* prop, /**< propagator */ 997 SCIP_SET* set, /**< global SCIP settings */ 998 int presolpriority /**< new priority of the propagator */ 999 ) 1000 { 1001 assert(prop != NULL); 1002 assert(set != NULL); 1003 1004 prop->presolpriority = presolpriority; 1005 set->propspresolsorted = FALSE; 1006 } 1007 1008 /** gets frequency of propagator */ 1009 int SCIPpropGetFreq( 1010 SCIP_PROP* prop /**< propagator */ 1011 ) 1012 { 1013 assert(prop != NULL); 1014 1015 return prop->freq; 1016 } 1017 1018 /** enables or disables all clocks of \p prop, depending on the value of the flag */ 1019 void SCIPpropEnableOrDisableClocks( 1020 SCIP_PROP* prop, /**< the propagator for which all clocks should be enabled or disabled */ 1021 SCIP_Bool enable /**< should the clocks of the propagator be enabled? */ 1022 ) 1023 { 1024 assert(prop != NULL); 1025 1026 SCIPclockEnableOrDisable(prop->setuptime, enable); 1027 SCIPclockEnableOrDisable(prop->presoltime, enable); 1028 SCIPclockEnableOrDisable(prop->proptime, enable); 1029 SCIPclockEnableOrDisable(prop->resproptime, enable); 1030 SCIPclockEnableOrDisable(prop->sbproptime, enable); 1031 } 1032 1033 /** gets time in seconds used for setting up this propagator for new stages */ 1034 SCIP_Real SCIPpropGetSetupTime( 1035 SCIP_PROP* prop /**< propagator */ 1036 ) 1037 { 1038 assert(prop != NULL); 1039 1040 return SCIPclockGetTime(prop->setuptime); 1041 } 1042 1043 /** sets frequency of propagator */ 1044 void SCIPpropSetFreq( 1045 SCIP_PROP* prop, /**< propagator */ 1046 int freq /**< new frequency of propagator */ 1047 ) 1048 { 1049 assert(prop != NULL); 1050 assert(freq >= -1); 1051 1052 prop->freq = freq; 1053 } 1054 1055 /** gets time in seconds used in this propagator for propagation */ 1056 SCIP_Real SCIPpropGetTime( 1057 SCIP_PROP* prop /**< propagator */ 1058 ) 1059 { 1060 assert(prop != NULL); 1061 1062 return SCIPclockGetTime(prop->proptime); 1063 } 1064 1065 /** gets time in seconds used in this propagator for propagation during strong branching */ 1066 SCIP_Real SCIPpropGetStrongBranchPropTime( 1067 SCIP_PROP* prop /**< propagator */ 1068 ) 1069 { 1070 assert(prop != NULL); 1071 1072 return SCIPclockGetTime(prop->sbproptime); 1073 } 1074 1075 /** gets time in seconds used in this propagator for resolve propagation */ 1076 SCIP_Real SCIPpropGetRespropTime( 1077 SCIP_PROP* prop /**< propagator */ 1078 ) 1079 { 1080 assert(prop != NULL); 1081 1082 return SCIPclockGetTime(prop->resproptime); 1083 } 1084 1085 /** gets time in seconds used in this propagator for presolving */ 1086 SCIP_Real SCIPpropGetPresolTime( 1087 SCIP_PROP* prop /**< propagator */ 1088 ) 1089 { 1090 assert(prop != NULL); 1091 1092 return SCIPclockGetTime(prop->presoltime); 1093 } 1094 1095 /** gets the total number of times, the propagator was called */ 1096 SCIP_Longint SCIPpropGetNCalls( 1097 SCIP_PROP* prop /**< propagator */ 1098 ) 1099 { 1100 assert(prop != NULL); 1101 1102 return prop->ncalls; 1103 } 1104 1105 /** gets the total number of times, the propagator was called for resolving a propagation */ 1106 SCIP_Longint SCIPpropGetNRespropCalls( 1107 SCIP_PROP* prop /**< propagator */ 1108 ) 1109 { 1110 assert(prop != NULL); 1111 1112 return prop->nrespropcalls; 1113 } 1114 1115 /** gets total number of times, this propagator detected a cutoff */ 1116 SCIP_Longint SCIPpropGetNCutoffs( 1117 SCIP_PROP* prop /**< propagator */ 1118 ) 1119 { 1120 assert(prop != NULL); 1121 1122 return prop->ncutoffs; 1123 } 1124 1125 /** gets total number of domain reductions found by this propagator */ 1126 SCIP_Longint SCIPpropGetNDomredsFound( 1127 SCIP_PROP* prop /**< propagator */ 1128 ) 1129 { 1130 assert(prop != NULL); 1131 1132 return prop->ndomredsfound; 1133 } 1134 1135 /** should propagator be delayed, if other propagators found reductions? */ 1136 SCIP_Bool SCIPpropIsDelayed( 1137 SCIP_PROP* prop /**< propagator */ 1138 ) 1139 { 1140 assert(prop != NULL); 1141 1142 return prop->delay; 1143 } 1144 1145 /** was propagator delayed at the last call? */ 1146 SCIP_Bool SCIPpropWasDelayed( 1147 SCIP_PROP* prop /**< propagator */ 1148 ) 1149 { 1150 assert(prop != NULL); 1151 1152 return prop->wasdelayed; 1153 } 1154 1155 /** is propagator initialized? */ 1156 SCIP_Bool SCIPpropIsInitialized( 1157 SCIP_PROP* prop /**< propagator */ 1158 ) 1159 { 1160 assert(prop != NULL); 1161 1162 return prop->initialized; 1163 } 1164 1165 /** gets number of variables fixed during presolving of propagator */ 1166 int SCIPpropGetNFixedVars( 1167 SCIP_PROP* prop /**< propagator */ 1168 ) 1169 { 1170 assert(prop != NULL); 1171 1172 return prop->nfixedvars; 1173 } 1174 1175 /** gets number of variables aggregated during presolving of propagator */ 1176 int SCIPpropGetNAggrVars( 1177 SCIP_PROP* prop /**< propagator */ 1178 ) 1179 { 1180 assert(prop != NULL); 1181 1182 return prop->naggrvars; 1183 } 1184 1185 /** gets number of variable types changed during presolving of propagator */ 1186 int SCIPpropGetNChgVarTypes( 1187 SCIP_PROP* prop /**< propagator */ 1188 ) 1189 { 1190 assert(prop != NULL); 1191 1192 return prop->nchgvartypes; 1193 } 1194 1195 /** gets number of bounds changed during presolving of propagator */ 1196 int SCIPpropGetNChgBds( 1197 SCIP_PROP* prop /**< propagator */ 1198 ) 1199 { 1200 assert(prop != NULL); 1201 1202 return prop->nchgbds; 1203 } 1204 1205 /** gets number of holes added to domains of variables during presolving of propagator */ 1206 int SCIPpropGetNAddHoles( 1207 SCIP_PROP* prop /**< propagator */ 1208 ) 1209 { 1210 assert(prop != NULL); 1211 1212 return prop->naddholes; 1213 } 1214 1215 /** gets number of constraints deleted during presolving of propagator */ 1216 int SCIPpropGetNDelConss( 1217 SCIP_PROP* prop /**< propagator */ 1218 ) 1219 { 1220 assert(prop != NULL); 1221 1222 return prop->ndelconss; 1223 } 1224 1225 /** gets number of constraints added during presolving of propagator */ 1226 int SCIPpropGetNAddConss( 1227 SCIP_PROP* prop /**< propagator */ 1228 ) 1229 { 1230 assert(prop != NULL); 1231 1232 return prop->naddconss; 1233 } 1234 1235 /** gets number of constraints upgraded during presolving of propagator */ 1236 int SCIPpropGetNUpgdConss( 1237 SCIP_PROP* prop /**< propagator */ 1238 ) 1239 { 1240 assert(prop != NULL); 1241 1242 return prop->nupgdconss; 1243 } 1244 1245 /** gets number of coefficients changed during presolving of propagator */ 1246 int SCIPpropGetNChgCoefs( 1247 SCIP_PROP* prop /**< propagator */ 1248 ) 1249 { 1250 assert(prop != NULL); 1251 1252 return prop->nchgcoefs; 1253 } 1254 1255 /** gets number of constraint sides changed during presolving of propagator */ 1256 int SCIPpropGetNChgSides( 1257 SCIP_PROP* prop /**< propagator */ 1258 ) 1259 { 1260 assert(prop != NULL); 1261 1262 return prop->nchgsides; 1263 } 1264 1265 /** gets number of times the propagator was called in presolving and tried to find reductions */ 1266 int SCIPpropGetNPresolCalls( 1267 SCIP_PROP* prop /**< propagator */ 1268 ) 1269 { 1270 assert(prop != NULL); 1271 1272 return prop->npresolcalls; 1273 } 1274 1275 /** returns the timing mask of the propagator */ 1276 SCIP_PROPTIMING SCIPpropGetTimingmask( 1277 SCIP_PROP* prop /**< propagator */ 1278 ) 1279 { 1280 assert(prop != NULL); 1281 1282 return prop->timingmask; 1283 } 1284 1285 /** does the propagator perform presolving? */ 1286 SCIP_Bool SCIPpropDoesPresolve( 1287 SCIP_PROP* prop /**< propagator */ 1288 ) 1289 { 1290 assert(prop != NULL); 1291 1292 return (prop->proppresol != NULL); 1293 } 1294 1295 /** returns the timing mask of the presolving method of the propagator */ 1296 SCIP_PRESOLTIMING SCIPpropGetPresolTiming( 1297 SCIP_PROP* prop /**< propagator */ 1298 ) 1299 { 1300 assert(prop != NULL); 1301 1302 return prop->presoltiming; 1303 } 1304 1305 /** sets the timing mask of the presolving method of the propagator */ 1306 void SCIPpropSetPresolTiming( 1307 SCIP_PROP* prop, /**< propagator */ 1308 SCIP_PRESOLTIMING presoltiming /** timing mask to be set */ 1309 ) 1310 { 1311 assert(prop != NULL); 1312 1313 prop->presoltiming = presoltiming; 1314 } 1315