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_prob.c 26 * @ingroup OTHER_CFILES 27 * @brief public methods for global and local (sub)problems 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 "blockmemshell/memory.h" 46 #include "scip/benders.h" 47 #include "scip/clock.h" 48 #include "scip/concurrent.h" 49 #include "scip/conflictstore.h" 50 #include "scip/cons.h" 51 #include "scip/dcmp.h" 52 #include "scip/debug.h" 53 #include "scip/lp.h" 54 #include "scip/pricer.h" 55 #include "scip/pricestore.h" 56 #include "scip/primal.h" 57 #include "scip/prob.h" 58 #include "scip/pub_cons.h" 59 #include "scip/pub_event.h" 60 #include "scip/pub_message.h" 61 #include "scip/pub_misc.h" 62 #include "scip/pub_reader.h" 63 #include "scip/pub_sol.h" 64 #include "scip/pub_tree.h" 65 #include "scip/pub_var.h" 66 #include "scip/reader.h" 67 #include "scip/reopt.h" 68 #include "scip/scip_cons.h" 69 #include "scip/scip_general.h" 70 #include "scip/scip_mem.h" 71 #include "scip/scip_message.h" 72 #include "scip/scip_numerics.h" 73 #include "scip/scip_param.h" 74 #include "scip/scip_prob.h" 75 #include "scip/scip_randnumgen.h" 76 #include "scip/scip_sol.h" 77 #include "scip/scip_solve.h" 78 #include "scip/scip_solvingstats.h" 79 #include "scip/scip_timing.h" 80 #include "scip/scip_var.h" 81 #include "scip/set.h" 82 #include "scip/stat.h" 83 #include "scip/struct_cons.h" 84 #include "scip/struct_lp.h" 85 #include "scip/struct_mem.h" 86 #include "scip/struct_primal.h" 87 #include "scip/struct_prob.h" 88 #include "scip/struct_scip.h" 89 #include "scip/struct_set.h" 90 #include "scip/struct_stat.h" 91 #include "scip/struct_var.h" 92 #include "scip/syncstore.h" 93 #include "scip/tree.h" 94 #include <stdio.h> 95 #include <string.h> 96 97 /** creates empty problem and initializes all solving data structures (the objective sense is set to MINIMIZE) 98 * If the problem type requires the use of variable pricers, these pricers should be added to the problem with calls 99 * to SCIPactivatePricer(). These pricers are automatically deactivated, when the problem is freed. 100 * 101 * @return \ref SCIP_OKAY is returned if everything worked. otherwise a suitable error code is passed. see \ref 102 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 103 * 104 * @pre This method can be called if @p scip is in one of the following stages: 105 * - \ref SCIP_STAGE_INIT 106 * - \ref SCIP_STAGE_PROBLEM 107 * - \ref SCIP_STAGE_TRANSFORMED 108 * - \ref SCIP_STAGE_PRESOLVING 109 * - \ref SCIP_STAGE_PRESOLVED 110 * - \ref SCIP_STAGE_SOLVING 111 * - \ref SCIP_STAGE_SOLVED 112 * - \ref SCIP_STAGE_FREE 113 * 114 * @post After calling this method, \SCIP reaches the following stage: 115 * - \ref SCIP_STAGE_PROBLEM 116 */ 117 SCIP_RETCODE SCIPcreateProb( 118 SCIP* scip, /**< SCIP data structure */ 119 const char* name, /**< problem name */ 120 SCIP_DECL_PROBDELORIG ((*probdelorig)), /**< frees user data of original problem */ 121 SCIP_DECL_PROBTRANS ((*probtrans)), /**< creates user data of transformed problem by transforming original user data */ 122 SCIP_DECL_PROBDELTRANS((*probdeltrans)), /**< frees user data of transformed problem */ 123 SCIP_DECL_PROBINITSOL ((*probinitsol)), /**< solving process initialization method of transformed data */ 124 SCIP_DECL_PROBEXITSOL ((*probexitsol)), /**< solving process deinitialization method of transformed data */ 125 SCIP_DECL_PROBCOPY ((*probcopy)), /**< copies user data if you want to copy it to a subscip, or NULL */ 126 SCIP_PROBDATA* probdata /**< user problem data set by the reader */ 127 ) 128 { 129 SCIP_CALL( SCIPcheckStage(scip, "SCIPcreateProb", TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE) ); 130 131 /* free old problem */ 132 SCIP_CALL( SCIPfreeProb(scip) ); 133 assert(scip->set->stage == SCIP_STAGE_INIT); 134 135 /* switch stage to PROBLEM */ 136 scip->set->stage = SCIP_STAGE_PROBLEM; 137 138 SCIP_CALL( SCIPstatCreate(&scip->stat, scip->mem->probmem, scip->set, NULL, NULL, scip->messagehdlr) ); 139 140 SCIP_CALL( SCIPprobCreate(&scip->origprob, scip->mem->probmem, scip->set, name, 141 probdelorig, probtrans, probdeltrans, probinitsol, probexitsol, probcopy, probdata, FALSE) ); 142 143 /* create solution pool for original solution candidates */ 144 SCIP_CALL( SCIPprimalCreate(&scip->origprimal) ); 145 146 /* create conflict pool for storing conflict constraints */ 147 SCIP_CALL( SCIPconflictstoreCreate(&scip->conflictstore, scip->set) ); 148 149 /* initialize reoptimization structure, if needed */ 150 SCIP_CALL( SCIPenableReoptimization(scip, scip->set->reopt_enable) ); 151 152 SCIP_CALL( SCIPdecompstoreCreate(&scip->decompstore, SCIPblkmem(scip), SCIP_DECOMPSTORE_CAPA) ); 153 154 return SCIP_OKAY; 155 } 156 157 /** creates empty problem and initializes all solving data structures (the objective sense is set to MINIMIZE) 158 * all callback methods will be set to NULL and can be set afterwards, if needed, via SCIPsetProbDelorig(), 159 * SCIPsetProbTrans(), SCIPsetProbDeltrans(), SCIPsetProbInitsol(), SCIPsetProbExitsol(), and 160 * SCIPsetProbCopy() 161 * If the problem type requires the use of variable pricers, these pricers should be added to the problem with calls 162 * to SCIPactivatePricer(). These pricers are automatically deactivated, when the problem is freed. 163 * 164 * @return \ref SCIP_OKAY is returned if everything worked. otherwise a suitable error code is passed. see \ref 165 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 166 * 167 * @pre This method can be called if @p scip is in one of the following stages: 168 * - \ref SCIP_STAGE_INIT 169 * - \ref SCIP_STAGE_PROBLEM 170 * - \ref SCIP_STAGE_TRANSFORMED 171 * - \ref SCIP_STAGE_PRESOLVING 172 * - \ref SCIP_STAGE_PRESOLVED 173 * - \ref SCIP_STAGE_SOLVING 174 * - \ref SCIP_STAGE_SOLVED 175 * - \ref SCIP_STAGE_FREE 176 * 177 * @post After calling this method, \SCIP reaches the following stage: 178 * - \ref SCIP_STAGE_PROBLEM 179 */ 180 SCIP_RETCODE SCIPcreateProbBasic( 181 SCIP* scip, /**< SCIP data structure */ 182 const char* name /**< problem name */ 183 ) 184 { 185 SCIP_CALL( SCIPcheckStage(scip, "SCIPcreateProbBasic", TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE) ); 186 187 SCIP_CALL( SCIPcreateProb(scip, name, NULL, NULL, NULL, NULL, NULL, NULL, NULL) ); 188 189 return SCIP_OKAY; 190 } 191 192 /** sets callback to free user data of original problem 193 * 194 * @return \ref SCIP_OKAY is returned if everything worked. otherwise a suitable error code is passed. see \ref 195 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 196 * 197 * @pre This method can be called if @p scip is in one of the following stages: 198 * - \ref SCIP_STAGE_PROBLEM 199 */ 200 SCIP_RETCODE SCIPsetProbDelorig( 201 SCIP* scip, /**< SCIP data structure */ 202 SCIP_DECL_PROBDELORIG ((*probdelorig)) /**< frees user data of original problem */ 203 ) 204 { 205 assert(scip != NULL); 206 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetProbDelorig", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) ); 207 208 SCIPprobSetDelorig(scip->origprob, probdelorig); 209 210 return SCIP_OKAY; 211 } 212 213 /** sets callback to create user data of transformed problem by transforming original user data 214 * 215 * @return \ref SCIP_OKAY is returned if everything worked. otherwise a suitable error code is passed. see \ref 216 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 217 * 218 * @pre This method can be called if @p scip is in one of the following stages: 219 * - \ref SCIP_STAGE_PROBLEM 220 */ 221 SCIP_RETCODE SCIPsetProbTrans( 222 SCIP* scip, /**< SCIP data structure */ 223 SCIP_DECL_PROBTRANS ((*probtrans)) /**< creates user data of transformed problem by transforming original user data */ 224 ) 225 { 226 assert(scip != NULL); 227 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetProbTrans", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) ); 228 229 SCIPprobSetTrans(scip->origprob, probtrans); 230 231 return SCIP_OKAY; 232 } 233 234 /** sets callback to free user data of transformed problem 235 * 236 * @return \ref SCIP_OKAY is returned if everything worked. otherwise a suitable error code is passed. see \ref 237 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 238 * 239 * @pre This method can be called if @p scip is in one of the following stages: 240 * - \ref SCIP_STAGE_PROBLEM 241 */ 242 SCIP_RETCODE SCIPsetProbDeltrans( 243 SCIP* scip, /**< SCIP data structure */ 244 SCIP_DECL_PROBDELTRANS((*probdeltrans)) /**< frees user data of transformed problem */ 245 ) 246 { 247 assert(scip != NULL); 248 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetProbDeltrans", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) ); 249 250 SCIPprobSetDeltrans(scip->origprob, probdeltrans); 251 252 return SCIP_OKAY; 253 } 254 255 /** sets solving process initialization callback of transformed data 256 * 257 * @return \ref SCIP_OKAY is returned if everything worked. otherwise a suitable error code is passed. see \ref 258 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 259 * 260 * @pre This method can be called if @p scip is in one of the following stages: 261 * - \ref SCIP_STAGE_PROBLEM 262 */ 263 SCIP_RETCODE SCIPsetProbInitsol( 264 SCIP* scip, /**< SCIP data structure */ 265 SCIP_DECL_PROBINITSOL ((*probinitsol)) /**< solving process initialization method of transformed data */ 266 ) 267 { 268 assert(scip != NULL); 269 270 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetProbInitsol", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) ); 271 272 SCIPprobSetInitsol(scip->origprob, probinitsol); 273 274 return SCIP_OKAY; 275 } 276 277 /** sets solving process deinitialization callback of transformed data 278 * 279 * @return \ref SCIP_OKAY is returned if everything worked. otherwise a suitable error code is passed. see \ref 280 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 281 * 282 * @pre This method can be called if @p scip is in one of the following stages: 283 * - \ref SCIP_STAGE_PROBLEM 284 */ 285 SCIP_RETCODE SCIPsetProbExitsol( 286 SCIP* scip, /**< SCIP data structure */ 287 SCIP_DECL_PROBEXITSOL ((*probexitsol)) /**< solving process deinitialization method of transformed data */ 288 ) 289 { 290 assert(scip != NULL); 291 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetProbExitsol", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) ); 292 293 SCIPprobSetExitsol(scip->origprob, probexitsol); 294 295 return SCIP_OKAY; 296 } 297 298 /** sets callback to copy user data to a subscip 299 * 300 * @return \ref SCIP_OKAY is returned if everything worked. otherwise a suitable error code is passed. see \ref 301 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 302 * 303 * @pre This method can be called if @p scip is in one of the following stages: 304 * - \ref SCIP_STAGE_PROBLEM 305 */ 306 SCIP_RETCODE SCIPsetProbCopy( 307 SCIP* scip, /**< SCIP data structure */ 308 SCIP_DECL_PROBCOPY ((*probcopy)) /**< copies user data if you want to copy it to a subscip, or NULL */ 309 ) 310 { 311 assert(scip != NULL); 312 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetProbCopy", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) ); 313 314 SCIPprobSetCopy(scip->origprob, probcopy); 315 316 return SCIP_OKAY; 317 } 318 319 /** reads problem from file and initializes all solving data structures 320 * 321 * @return \ref SCIP_OKAY is returned if everything worked. otherwise a suitable error code is passed. see \ref 322 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 323 * 324 * @pre This method can be called if @p scip is in one of the following stages: 325 * - \ref SCIP_STAGE_INIT 326 * - \ref SCIP_STAGE_PROBLEM 327 * - \ref SCIP_STAGE_TRANSFORMED 328 * - \ref SCIP_STAGE_INITPRESOLVE 329 * - \ref SCIP_STAGE_PRESOLVING 330 * - \ref SCIP_STAGE_EXITPRESOLVE 331 * - \ref SCIP_STAGE_PRESOLVED 332 * - \ref SCIP_STAGE_SOLVING 333 * - \ref SCIP_STAGE_EXITSOLVE 334 * 335 * @post After the method was called, \SCIP is in one of the following stages: 336 * - \ref SCIP_STAGE_INIT if reading failed (usually, when a SCIP_READERROR occurs) 337 * - \ref SCIP_STAGE_PROBLEM if the problem file was successfully read 338 */ 339 SCIP_RETCODE SCIPreadProb( 340 SCIP* scip, /**< SCIP data structure */ 341 const char* filename, /**< problem file name */ 342 const char* extension /**< extension of the desired file reader, 343 * or NULL if file extension should be used */ 344 ) 345 { 346 SCIP_RETCODE retcode; 347 SCIP_RESULT result; 348 SCIP_Bool usevartable; 349 SCIP_Bool useconstable; 350 int i; 351 char* tmpfilename; 352 char* fileextension; 353 354 assert(scip != NULL); 355 assert(filename != NULL); 356 357 SCIP_CALL( SCIPcheckStage(scip, "SCIPreadProb", TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 358 359 SCIP_CALL( SCIPgetBoolParam(scip, "misc/usevartable", &usevartable) ); 360 SCIP_CALL( SCIPgetBoolParam(scip, "misc/useconstable", &useconstable) ); 361 362 if( !usevartable || !useconstable ) 363 { 364 SCIPerrorMessage("Cannot read problem if vartable or constable is disabled. Make sure parameters 'misc/usevartable' and 'misc/useconstable' are set to TRUE.\n"); 365 return SCIP_READERROR; 366 } 367 368 /* try all readers until one could read the file */ 369 result = SCIP_DIDNOTRUN; 370 371 /* copy filename */ 372 SCIP_CALL( SCIPduplicateBufferArray(scip, &tmpfilename, filename, (int)strlen(filename)+1) ); 373 374 fileextension = NULL; 375 if( extension == NULL ) 376 { 377 /* get extension from filename */ 378 SCIPsplitFilename(tmpfilename, NULL, NULL, &fileextension, NULL); 379 } 380 381 for( i = 0; i < scip->set->nreaders && result == SCIP_DIDNOTRUN; ++i ) 382 { 383 retcode = SCIPreaderRead(scip->set->readers[i], scip->set, filename, 384 extension != NULL ? extension : fileextension, &result); 385 386 /* check for reader errors */ 387 if( retcode == SCIP_NOFILE || retcode == SCIP_READERROR ) 388 goto TERMINATE; 389 SCIP_CALL( retcode ); 390 } 391 392 switch( result ) 393 { 394 case SCIP_DIDNOTRUN: 395 retcode = SCIP_PLUGINNOTFOUND; 396 break; 397 case SCIP_SUCCESS: 398 if( scip->origprob != NULL ) 399 { 400 SCIP_Real readingtime; 401 402 SCIPmessagePrintVerbInfo(scip->messagehdlr, scip->set->disp_verblevel, SCIP_VERBLEVEL_NORMAL, 403 "original problem has %d variables (%d bin, %d int, %d impl, %d cont) and %d constraints\n", 404 scip->origprob->nvars, scip->origprob->nbinvars, scip->origprob->nintvars, 405 scip->origprob->nimplvars, scip->origprob->ncontvars, 406 scip->origprob->nconss); 407 408 /* in full verbose mode we will also print the number of constraints per constraint handler */ 409 if( scip->set->disp_verblevel == SCIP_VERBLEVEL_FULL ) 410 { 411 int* nconss; 412 int c; 413 int h; 414 415 SCIP_CALL( SCIPallocClearBufferArray(scip, &nconss, scip->set->nconshdlrs) ); 416 417 /* loop over all constraints and constraint-handlers to count for each type the amount of original 418 * constraints 419 */ 420 for( c = scip->origprob->nconss - 1; c >= 0; --c ) 421 { 422 for( h = scip->set->nconshdlrs - 1; h >= 0; --h ) 423 { 424 if( scip->origprob->conss[c]->conshdlr == scip->set->conshdlrs[h] ) 425 { 426 ++(nconss[h]); 427 break; 428 } 429 } 430 /* constraint handler should be found */ 431 assert(h >= 0); 432 } 433 434 /* loop over all constraints handlers for printing the number of original constraints */ 435 for( h = 0; h < scip->set->nconshdlrs; ++h ) 436 { 437 if( nconss[h] > 0 ) 438 { 439 SCIPmessagePrintVerbInfo(scip->messagehdlr, scip->set->disp_verblevel, SCIP_VERBLEVEL_FULL, 440 "%7d constraints of type <%s>\n", nconss[h], SCIPconshdlrGetName(scip->set->conshdlrs[h])); 441 } 442 } 443 444 SCIPfreeBufferArray(scip, &nconss); 445 } 446 447 /* in case the permutation seed is different to 0, permute the original problem */ 448 if( scip->set->random_permutationseed > 0 ) 449 { 450 SCIP_Bool permuteconss; 451 SCIP_Bool permutevars; 452 int permutationseed; 453 454 permuteconss = scip->set->random_permuteconss; 455 permutevars = scip->set->random_permutevars; 456 permutationseed = scip->set->random_permutationseed; 457 458 SCIP_CALL( SCIPpermuteProb(scip, (unsigned int)permutationseed, permuteconss, permutevars, permutevars, permutevars, permutevars) ); 459 } 460 461 /* get reading time */ 462 readingtime = SCIPgetReadingTime(scip); 463 464 /* display timing statistics */ 465 SCIPmessagePrintVerbInfo(scip->messagehdlr, scip->set->disp_verblevel, SCIP_VERBLEVEL_FULL, 466 "Reading Time: %.2f\n", readingtime); 467 468 /* add reading time to solving time, if requested */ 469 if( scip->set->time_reading ) 470 SCIPclockSetTime(scip->stat->solvingtime, readingtime); 471 } 472 retcode = SCIP_OKAY; 473 break; 474 default: 475 assert(i < scip->set->nreaders); 476 SCIPerrorMessage("invalid result code <%d> from reader <%s> reading file <%s>\n", 477 result, SCIPreaderGetName(scip->set->readers[i]), filename); 478 retcode = SCIP_READERROR; 479 } /*lint !e788*/ 480 481 TERMINATE: 482 /* free buffer array */ 483 SCIPfreeBufferArray(scip, &tmpfilename); 484 485 return retcode; 486 } 487 488 /** write original or transformed problem */ 489 static 490 SCIP_RETCODE writeProblem( 491 SCIP* scip, /**< SCIP data structure */ 492 const char* filename, /**< output file (or NULL for standard output) */ 493 const char* extension, /**< extension of the desired file reader, 494 * or NULL if file extension should be used */ 495 SCIP_Bool transformed, /**< output the transformed problem? */ 496 SCIP_Bool genericnames /**< using generic variable and constraint names? */ 497 ) 498 { 499 SCIP_RETCODE retcode; 500 char* tmpfilename; 501 char* fileextension; 502 char* compression; 503 FILE* file; 504 505 assert(scip != NULL ); 506 507 fileextension = NULL; 508 compression = NULL; 509 file = NULL; 510 tmpfilename = NULL; 511 512 if( filename != NULL && filename[0] != '\0' ) 513 { 514 int success; 515 516 file = fopen(filename, "w"); 517 if( file == NULL ) 518 { 519 SCIPerrorMessage("cannot create file <%s> for writing\n", filename); 520 SCIPprintSysError(filename); 521 return SCIP_FILECREATEERROR; 522 } 523 524 /* get extension from filename, 525 * if an error occurred, close the file before returning */ 526 if( BMSduplicateMemoryArray(&tmpfilename, filename, strlen(filename)+1) == NULL ) 527 { 528 (void) fclose(file); 529 SCIPerrorMessage("Error <%d> in function call\n", SCIP_NOMEMORY); 530 return SCIP_NOMEMORY; 531 } 532 533 SCIPsplitFilename(tmpfilename, NULL, NULL, &fileextension, &compression); 534 535 if( compression != NULL ) 536 { 537 SCIPmessagePrintWarning(scip->messagehdlr, "currently it is not possible to write files with any compression\n"); 538 BMSfreeMemoryArray(&tmpfilename); 539 (void) fclose(file); 540 return SCIP_FILECREATEERROR; 541 } 542 543 if( extension == NULL && fileextension == NULL ) 544 { 545 SCIPmessagePrintWarning(scip->messagehdlr, "filename <%s> has no file extension, select default <cip> format for writing\n", filename); 546 } 547 548 if( transformed ) 549 retcode = SCIPprintTransProblem(scip, file, extension != NULL ? extension : fileextension, genericnames); 550 else 551 retcode = SCIPprintOrigProblem(scip, file, extension != NULL ? extension : fileextension, genericnames); 552 553 BMSfreeMemoryArray(&tmpfilename); 554 555 success = fclose(file); 556 if( success != 0 ) 557 { 558 SCIPerrorMessage("An error occurred while closing file <%s>\n", filename); 559 return SCIP_FILECREATEERROR; 560 } 561 } 562 else 563 { 564 /* print to stdout */ 565 if( transformed ) 566 retcode = SCIPprintTransProblem(scip, NULL, extension, genericnames); 567 else 568 retcode = SCIPprintOrigProblem(scip, NULL, extension, genericnames); 569 } 570 571 /* check for write errors */ 572 if( retcode == SCIP_WRITEERROR || retcode == SCIP_PLUGINNOTFOUND ) 573 return retcode; 574 else 575 { 576 SCIP_CALL( retcode ); 577 } 578 579 return SCIP_OKAY; 580 } 581 582 /** writes original problem to file 583 * 584 * @return \ref SCIP_OKAY is returned if everything worked. otherwise a suitable error code is passed. see \ref 585 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 586 * 587 * @pre This method can be called if @p scip is in one of the following stages: 588 * - \ref SCIP_STAGE_PROBLEM 589 * - \ref SCIP_STAGE_TRANSFORMING 590 * - \ref SCIP_STAGE_TRANSFORMED 591 * - \ref SCIP_STAGE_INITPRESOLVE 592 * - \ref SCIP_STAGE_PRESOLVING 593 * - \ref SCIP_STAGE_EXITPRESOLVE 594 * - \ref SCIP_STAGE_PRESOLVED 595 * - \ref SCIP_STAGE_INITSOLVE 596 * - \ref SCIP_STAGE_SOLVING 597 * - \ref SCIP_STAGE_SOLVED 598 * - \ref SCIP_STAGE_EXITSOLVE 599 * - \ref SCIP_STAGE_FREETRANS 600 */ 601 SCIP_RETCODE SCIPwriteOrigProblem( 602 SCIP* scip, /**< SCIP data structure */ 603 const char* filename, /**< output file (or NULL for standard output) */ 604 const char* extension, /**< extension of the desired file reader, 605 * or NULL if file extension should be used */ 606 SCIP_Bool genericnames /**< using generic variable and constraint names? */ 607 ) 608 { 609 SCIP_RETCODE retcode; 610 611 SCIP_CALL( SCIPcheckStage(scip, "SCIPwriteOrigProblem", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) ); 612 613 assert( scip != NULL ); 614 assert( scip->origprob != NULL ); 615 616 retcode = writeProblem(scip, filename, extension, FALSE, genericnames); 617 618 /* check for write errors */ 619 if( retcode == SCIP_FILECREATEERROR || retcode == SCIP_WRITEERROR || retcode == SCIP_PLUGINNOTFOUND ) 620 return retcode; 621 else 622 { 623 SCIP_CALL( retcode ); 624 } 625 626 return SCIP_OKAY; 627 } 628 629 /** writes transformed problem which are valid in the current node to file 630 * 631 * @return \ref SCIP_OKAY is returned if everything worked. otherwise a suitable error code is passed. see \ref 632 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 633 * 634 * @pre This method can be called if @p scip is in one of the following stages: 635 * - \ref SCIP_STAGE_TRANSFORMED 636 * - \ref SCIP_STAGE_INITPRESOLVE 637 * - \ref SCIP_STAGE_PRESOLVING 638 * - \ref SCIP_STAGE_EXITPRESOLVE 639 * - \ref SCIP_STAGE_PRESOLVED 640 * - \ref SCIP_STAGE_INITSOLVE 641 * - \ref SCIP_STAGE_SOLVING 642 * - \ref SCIP_STAGE_SOLVED 643 * - \ref SCIP_STAGE_EXITSOLVE 644 * 645 * @note If you want the write all constraints (including the once which are redundant for example), you need to set 646 * the parameter <write/allconss> to TRUE 647 */ 648 SCIP_RETCODE SCIPwriteTransProblem( 649 SCIP* scip, /**< SCIP data structure */ 650 const char* filename, /**< output file (or NULL for standard output) */ 651 const char* extension, /**< extension of the desired file reader, 652 * or NULL if file extension should be used */ 653 SCIP_Bool genericnames /**< using generic variable and constraint names? */ 654 ) 655 { 656 SCIP_RETCODE retcode; 657 658 SCIP_CALL( SCIPcheckStage(scip, "SCIPwriteTransProblem", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) ); 659 660 assert( scip != NULL ); 661 assert( scip->transprob != NULL ); 662 663 retcode = writeProblem(scip, filename, extension, TRUE, genericnames); 664 665 /* check for write errors */ 666 if( retcode == SCIP_FILECREATEERROR || retcode == SCIP_WRITEERROR || retcode == SCIP_PLUGINNOTFOUND ) 667 return retcode; 668 else 669 { 670 SCIP_CALL( retcode ); 671 } 672 673 return SCIP_OKAY; 674 } 675 676 /** frees problem and solution process data 677 * 678 * @return \ref SCIP_OKAY is returned if everything worked. otherwise a suitable error code is passed. see \ref 679 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 680 * 681 * @pre This method can be called if @p scip is in one of the following stages: 682 * - \ref SCIP_STAGE_INIT 683 * - \ref SCIP_STAGE_PROBLEM 684 * - \ref SCIP_STAGE_TRANSFORMED 685 * - \ref SCIP_STAGE_PRESOLVING 686 * - \ref SCIP_STAGE_PRESOLVED 687 * - \ref SCIP_STAGE_SOLVING 688 * - \ref SCIP_STAGE_SOLVED 689 * - \ref SCIP_STAGE_FREE 690 * 691 * @post After this method was called, SCIP is in the following stage: 692 * - \ref SCIP_STAGE_INIT 693 */ 694 SCIP_RETCODE SCIPfreeProb( 695 SCIP* scip /**< SCIP data structure */ 696 ) 697 { 698 SCIP_Bool transsolorig; 699 700 SCIP_CALL( SCIPcheckStage(scip, "SCIPfreeProb", TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE) ); 701 702 /* if we free the problem, we do not have to transfer transformed solutions to the original space, so temporarily disable it */ 703 transsolorig = scip->set->misc_transsolsorig; 704 scip->set->misc_transsolsorig = FALSE; 705 706 SCIP_CALL( SCIPfreeTransform(scip) ); 707 /* for some reason the free transform can generate events caught in the globalbnd eventhander 708 * which requires the concurrent so it must be freed afterwards this happened o instance fiber 709 */ 710 SCIP_CALL( SCIPfreeConcurrent(scip) ); 711 712 assert(scip->set->stage == SCIP_STAGE_INIT || scip->set->stage == SCIP_STAGE_PROBLEM); 713 scip->set->misc_transsolsorig = transsolorig; 714 715 if( scip->set->stage == SCIP_STAGE_PROBLEM ) 716 { 717 int i; 718 719 /* free concsolvers and deinitialize the syncstore */ 720 if( scip->set->nconcsolvers > 0 ) 721 { 722 assert(SCIPsyncstoreIsInitialized(scip->syncstore)); 723 724 SCIP_CALL( SCIPsetFreeConcsolvers(scip->set) ); 725 SCIP_CALL( SCIPsyncstoreExit(scip->syncstore) ); 726 } 727 728 /* deactivate all pricers */ 729 for( i = scip->set->nactivepricers-1; i >= 0; --i ) 730 { 731 SCIP_CALL( SCIPpricerDeactivate(scip->set->pricers[i], scip->set) ); 732 } 733 assert(scip->set->nactivepricers == 0); 734 735 /* deactivate all Benders' decomposition */ 736 for( i = scip->set->nactivebenders-1; i >= 0; --i ) 737 { 738 SCIP_CALL( SCIPbendersDeactivate(scip->set->benders[i], scip->set) ); 739 } 740 assert(scip->set->nactivebenders == 0); 741 742 /* free all debug data */ 743 SCIP_CALL( SCIPdebugFreeDebugData(scip->set) ); 744 745 /* free original primal solution candidate pool, original problem and problem statistics data structures */ 746 if( scip->reopt != NULL ) 747 { 748 SCIP_CALL( SCIPreoptFree(&scip->reopt, scip->set, scip->origprimal, scip->mem->probmem) ); 749 } 750 SCIPdecompstoreFree(&scip->decompstore, SCIPblkmem(scip)); 751 SCIP_CALL( SCIPconflictstoreFree(&scip->conflictstore, scip->mem->probmem, scip->set, scip->stat, scip->reopt) ); 752 SCIP_CALL( SCIPprimalFree(&scip->origprimal, scip->mem->probmem) ); 753 SCIP_CALL( SCIPprobFree(&scip->origprob, scip->messagehdlr, scip->mem->probmem, scip->set, scip->stat, scip->eventqueue, scip->lp) ); 754 SCIP_CALL( SCIPstatFree(&scip->stat, scip->mem->probmem) ); 755 756 /* readers */ 757 for( i = 0; i < scip->set->nreaders; ++i ) 758 { 759 SCIP_CALL( SCIPreaderResetReadingTime(scip->set->readers[i]) ); 760 } 761 762 /* switch stage to INIT */ 763 scip->set->stage = SCIP_STAGE_INIT; 764 } 765 assert(scip->set->stage == SCIP_STAGE_INIT); 766 767 return SCIP_OKAY; 768 } 769 770 /** permutes parts of the problem data structure 771 * 772 * @return \ref SCIP_OKAY is returned if everything worked. otherwise a suitable error code is passed. see \ref 773 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 774 * 775 * @pre This method can be called if @p scip is in one of the following stages: 776 * - \ref SCIP_STAGE_PROBLEM 777 * - \ref SCIP_STAGE_TRANSFORMED 778 * 779 * @todo This need to be changed to use the new random number generator implemented in random.c 780 */ 781 SCIP_RETCODE SCIPpermuteProb( 782 SCIP* scip, /**< SCIP data structure */ 783 unsigned int randseed, /**< seed value for random generator */ 784 SCIP_Bool permuteconss, /**< should the list of constraints in each constraint handler be permuted? */ 785 SCIP_Bool permutebinvars, /**< should the list of binary variables be permuted? */ 786 SCIP_Bool permuteintvars, /**< should the list of integer variables be permuted? */ 787 SCIP_Bool permuteimplvars, /**< should the list of implicit integer variables be permuted? */ 788 SCIP_Bool permutecontvars /**< should the list of continuous integer variables be permuted? */ 789 ) 790 { 791 SCIP_VAR** vars; 792 SCIP_CONSHDLR** conshdlrs; 793 SCIP_RANDNUMGEN* randnumgen; 794 SCIP_Bool permuted; 795 int nconshdlrs; 796 int nbinvars; 797 int nintvars; 798 int nimplvars; 799 int nvars; 800 int j; 801 802 assert(scip != NULL); 803 SCIP_CALL( SCIPcheckStage(scip, "SCIPpermuteProb", FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) ); 804 805 SCIP_CALL( SCIPgetVarsData(scip, &vars, &nvars, &nbinvars, &nintvars, &nimplvars, NULL) ); 806 807 assert(nvars == 0 || vars != NULL); 808 assert(nvars == nbinvars+nintvars+nimplvars+SCIPgetNContVars(scip)); 809 810 conshdlrs = SCIPgetConshdlrs(scip); 811 nconshdlrs = SCIPgetNConshdlrs(scip); 812 assert(nconshdlrs == 0 || conshdlrs != NULL); 813 814 /* create a random number generator */ 815 SCIP_CALL( SCIPcreateRandom(scip, &randnumgen, randseed, TRUE) ); 816 817 /* The constraint handler should not be permuted since they are called w.r.t. to certain properties; besides 818 * that the "conshdlrs" array should stay in the order as it is since this array is used to copy the plugins for 819 * sub-SCIPs and contains the dependencies between the constraint handlers; for example the linear constraint 820 * handler stays in front of all constraint handler which can upgrade a linear constraint (such as logicor, 821 * setppc, and knapsack). 822 */ 823 824 permuted = FALSE; 825 826 /* for each constraint handler, permute its constraints */ 827 if( permuteconss ) 828 { 829 int i; 830 831 /* we must only permute active constraints */ 832 if( SCIPisTransformed(scip) && !SCIPprobIsPermuted(scip->transprob) ) 833 { 834 /* loop over all constraint handlers */ 835 for( i = 0; i < nconshdlrs; ++i ) 836 { 837 SCIP_CONS** conss; 838 int nconss; 839 840 conss = SCIPconshdlrGetConss(conshdlrs[i]); 841 nconss = SCIPconshdlrGetNActiveConss(conshdlrs[i]); 842 843 assert(nconss == 0 || conss != NULL); 844 845 SCIPrandomPermuteArray(randnumgen, (void**)conss, 0, nconss); 846 847 /* readjust the mapping of constraints to array positions */ 848 for( j = 0; j < nconss; ++j ) 849 conss[j]->consspos = j; 850 851 permuted = TRUE; 852 } 853 } 854 else if( !SCIPisTransformed(scip) && !SCIPprobIsPermuted(scip->origprob) ) 855 { 856 SCIP_CONS** conss = scip->origprob->conss; 857 int nconss = scip->origprob->nconss; 858 859 SCIPrandomPermuteArray(randnumgen, (void**)conss, 0, nconss); 860 861 for( j = 0; j < nconss; ++j ) 862 { 863 assert(conss[j]->consspos == -1); 864 conss[j]->addarraypos = j; 865 } 866 867 permuted = TRUE; 868 } 869 } 870 871 /* permute binary variables */ 872 if( permutebinvars && !SCIPprobIsPermuted(scip->origprob) ) 873 { 874 SCIPrandomPermuteArray(randnumgen, (void**)vars, 0, nbinvars); 875 876 /* readjust the mapping of variables to array positions */ 877 for( j = 0; j < nbinvars; ++j ) 878 vars[j]->probindex = j; 879 880 permuted = TRUE; 881 } 882 883 /* permute general integer variables */ 884 if( permuteintvars && !SCIPprobIsPermuted(scip->origprob) ) 885 { 886 SCIPrandomPermuteArray(randnumgen, (void**)vars, nbinvars, nbinvars+nintvars); 887 888 /* readjust the mapping of variables to array positions */ 889 for( j = nbinvars; j < nbinvars+nintvars; ++j ) 890 vars[j]->probindex = j; 891 892 permuted = TRUE; 893 } 894 895 /* permute general integer variables */ 896 if( permuteimplvars && !SCIPprobIsPermuted(scip->origprob) ) 897 { 898 SCIPrandomPermuteArray(randnumgen, (void**)vars, nbinvars+nintvars, nbinvars+nintvars+nimplvars); 899 900 /* readjust the mapping of variables to array positions */ 901 for( j = nbinvars+nintvars; j < nbinvars+nintvars+nimplvars; ++j ) 902 vars[j]->probindex = j; 903 904 permuted = TRUE; 905 } 906 907 /* permute general integer variables */ 908 if( permutecontvars && !SCIPprobIsPermuted(scip->origprob) ) 909 { 910 SCIPrandomPermuteArray(randnumgen, (void**)vars, nbinvars+nintvars+nimplvars, nvars); 911 912 /* readjust the mapping of variables to array positions */ 913 for( j = nbinvars+nintvars+nimplvars; j < nvars; ++j ) 914 vars[j]->probindex = j; 915 916 permuted = TRUE; 917 } 918 919 if( permuted && SCIPisTransformed(scip) ) 920 { 921 assert(!SCIPprobIsPermuted(scip->transprob)); 922 923 /* mark tranformed problem as permuted */ 924 SCIPprobMarkPermuted(scip->transprob); 925 926 SCIPmessagePrintVerbInfo(scip->messagehdlr, scip->set->disp_verblevel, SCIP_VERBLEVEL_HIGH, 927 "permute transformed problem using random seed %u\n", randseed); 928 } 929 else if( permuted && !SCIPisTransformed(scip) ) 930 { 931 assert(!SCIPprobIsPermuted(scip->origprob)); 932 933 /* mark original problem as permuted */ 934 SCIPprobMarkPermuted(scip->origprob); 935 936 SCIPmessagePrintVerbInfo(scip->messagehdlr, scip->set->disp_verblevel, SCIP_VERBLEVEL_HIGH, 937 "permute original problem using random seed %u\n", randseed); 938 } 939 940 /* free random number generator */ 941 SCIPfreeRandom(scip, &randnumgen); 942 943 return SCIP_OKAY; 944 } 945 946 /** gets user problem data 947 * 948 * @return a SCIP_PROBDATA pointer, or NULL if no problem data was allocated 949 * 950 * @pre This method can be called if @p scip is in one of the following stages: 951 * - \ref SCIP_STAGE_PROBLEM 952 * - \ref SCIP_STAGE_TRANSFORMING 953 * - \ref SCIP_STAGE_TRANSFORMED 954 * - \ref SCIP_STAGE_INITPRESOLVE 955 * - \ref SCIP_STAGE_PRESOLVING 956 * - \ref SCIP_STAGE_EXITPRESOLVE 957 * - \ref SCIP_STAGE_PRESOLVED 958 * - \ref SCIP_STAGE_INITSOLVE 959 * - \ref SCIP_STAGE_SOLVING 960 * - \ref SCIP_STAGE_SOLVED 961 * - \ref SCIP_STAGE_EXITSOLVE 962 * - \ref SCIP_STAGE_FREETRANS 963 */ 964 SCIP_PROBDATA* SCIPgetProbData( 965 SCIP* scip /**< SCIP data structure */ 966 ) 967 { 968 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetProbData", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) ); 969 970 switch( scip->set->stage ) 971 { 972 case SCIP_STAGE_PROBLEM: 973 return SCIPprobGetData(scip->origprob); 974 975 case SCIP_STAGE_TRANSFORMING: 976 case SCIP_STAGE_TRANSFORMED: 977 case SCIP_STAGE_INITPRESOLVE: 978 case SCIP_STAGE_PRESOLVING: 979 case SCIP_STAGE_EXITPRESOLVE: 980 case SCIP_STAGE_PRESOLVED: 981 case SCIP_STAGE_INITSOLVE: 982 case SCIP_STAGE_SOLVING: 983 case SCIP_STAGE_SOLVED: 984 case SCIP_STAGE_EXITSOLVE: 985 case SCIP_STAGE_FREETRANS: 986 return SCIPprobGetData(scip->transprob); 987 988 default: 989 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage); 990 SCIPABORT(); 991 return NULL; /*lint !e527*/ 992 } /*lint !e788*/ 993 } 994 995 /** sets user problem data 996 * 997 * @return \ref SCIP_OKAY is returned if everything worked. otherwise a suitable error code is passed. see \ref 998 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 999 * 1000 * @pre This method can be called if @p scip is in one of the following stages: 1001 * - \ref SCIP_STAGE_PROBLEM 1002 * - \ref SCIP_STAGE_TRANSFORMING 1003 * - \ref SCIP_STAGE_TRANSFORMED 1004 * - \ref SCIP_STAGE_INITPRESOLVE 1005 * - \ref SCIP_STAGE_PRESOLVING 1006 * - \ref SCIP_STAGE_EXITPRESOLVE 1007 * - \ref SCIP_STAGE_PRESOLVED 1008 * - \ref SCIP_STAGE_INITSOLVE 1009 * - \ref SCIP_STAGE_SOLVING 1010 * - \ref SCIP_STAGE_SOLVED 1011 * - \ref SCIP_STAGE_EXITSOLVE 1012 * - \ref SCIP_STAGE_FREETRANS 1013 */ 1014 SCIP_RETCODE SCIPsetProbData( 1015 SCIP* scip, /**< SCIP data structure */ 1016 SCIP_PROBDATA* probdata /**< user problem data to use */ 1017 ) 1018 { 1019 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetProbData", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) ); 1020 1021 switch( scip->set->stage ) 1022 { 1023 case SCIP_STAGE_PROBLEM: 1024 SCIPprobSetData(scip->origprob, probdata); 1025 return SCIP_OKAY; 1026 1027 case SCIP_STAGE_TRANSFORMING: 1028 case SCIP_STAGE_TRANSFORMED: 1029 case SCIP_STAGE_INITPRESOLVE: 1030 case SCIP_STAGE_PRESOLVING: 1031 case SCIP_STAGE_EXITPRESOLVE: 1032 case SCIP_STAGE_PRESOLVED: 1033 case SCIP_STAGE_INITSOLVE: 1034 case SCIP_STAGE_SOLVING: 1035 case SCIP_STAGE_SOLVED: 1036 case SCIP_STAGE_EXITSOLVE: 1037 case SCIP_STAGE_FREETRANS: 1038 SCIPprobSetData(scip->transprob, probdata); 1039 return SCIP_OKAY; 1040 1041 case SCIP_STAGE_INIT: 1042 case SCIP_STAGE_FREE: 1043 default: 1044 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage); 1045 return SCIP_INVALIDCALL; 1046 } 1047 } 1048 1049 /** returns name of the current problem instance 1050 * 1051 * @return name of the current problem instance 1052 * 1053 * @pre This method can be called if @p scip is in one of the following stages: 1054 * - \ref SCIP_STAGE_PROBLEM 1055 * - \ref SCIP_STAGE_TRANSFORMING 1056 * - \ref SCIP_STAGE_TRANSFORMED 1057 * - \ref SCIP_STAGE_INITPRESOLVE 1058 * - \ref SCIP_STAGE_PRESOLVING 1059 * - \ref SCIP_STAGE_EXITPRESOLVE 1060 * - \ref SCIP_STAGE_PRESOLVED 1061 * - \ref SCIP_STAGE_INITSOLVE 1062 * - \ref SCIP_STAGE_SOLVING 1063 * - \ref SCIP_STAGE_SOLVED 1064 * - \ref SCIP_STAGE_EXITSOLVE 1065 * - \ref SCIP_STAGE_FREETRANS 1066 */ 1067 const char* SCIPgetProbName( 1068 SCIP* scip /**< SCIP data structure */ 1069 ) 1070 { 1071 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetProbName", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) ); 1072 1073 return SCIPprobGetName(scip->origprob); 1074 } 1075 1076 /** sets name of the current problem instance 1077 * 1078 * @return \ref SCIP_OKAY is returned if everything worked. otherwise a suitable error code is passed. see \ref 1079 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 1080 * 1081 * @pre This method can be called if @p scip is in one of the following stages: 1082 * - \ref SCIP_STAGE_PROBLEM 1083 * - \ref SCIP_STAGE_TRANSFORMING 1084 * - \ref SCIP_STAGE_TRANSFORMED 1085 * - \ref SCIP_STAGE_INITPRESOLVE 1086 * - \ref SCIP_STAGE_PRESOLVING 1087 * - \ref SCIP_STAGE_EXITPRESOLVE 1088 * - \ref SCIP_STAGE_PRESOLVED 1089 * - \ref SCIP_STAGE_INITSOLVE 1090 * - \ref SCIP_STAGE_SOLVING 1091 * - \ref SCIP_STAGE_SOLVED 1092 * - \ref SCIP_STAGE_EXITSOLVE 1093 * - \ref SCIP_STAGE_FREETRANS 1094 */ 1095 SCIP_RETCODE SCIPsetProbName( 1096 SCIP* scip, /**< SCIP data structure */ 1097 const char* name /**< name to be set */ 1098 ) 1099 { 1100 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetProbName", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) ); 1101 1102 return SCIPprobSetName(scip->origprob, name); 1103 } 1104 1105 /** changes the objective function of the original problem. 1106 * 1107 * @return \ref SCIP_OKAY is returned if everything worked. otherwise a suitable error code is passed. see \ref 1108 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 1109 * 1110 * @pre This method can be called if @p scip is in one of the following stages: 1111 * - \ref SCIP_STAGE_PROBLEM 1112 * - \ref SCIP_STAGE_PRESOLVED 1113 * 1114 * @note This method should be only used to change the objective function during two reoptimization runs and is only 1115 * recommended to an experienced user. 1116 * 1117 * @note All variables not given in \p vars array are assumed to have an objective coefficient of zero. 1118 */ 1119 SCIP_RETCODE SCIPchgReoptObjective( 1120 SCIP* scip, /**< SCIP data structure */ 1121 SCIP_OBJSENSE objsense, /**< new objective function */ 1122 SCIP_VAR** vars, /**< original problem variables */ 1123 SCIP_Real* coefs, /**< objective coefficients */ 1124 int nvars /**< variables in vars array */ 1125 ) 1126 { 1127 SCIP_VAR** origvars; 1128 int norigvars; 1129 int i; 1130 1131 SCIP_CALL( SCIPcheckStage(scip, "SCIPchgReoptObjective", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) ); 1132 1133 assert(nvars == 0 || vars != NULL); 1134 assert(nvars == 0 || coefs != NULL); 1135 1136 origvars = scip->origprob->vars; 1137 norigvars = scip->origprob->nvars; 1138 1139 #ifdef SCIP_MORE_DEBUG 1140 SCIPdebugMsg(scip, "objective function need to be set:\n"); 1141 for( i = 0; i < nvars; i++ ) 1142 { 1143 if( !SCIPisZero(scip, coefs[i]) ) 1144 SCIPdebugMsg(scip, "%s%g <%s> ", SCIPisPositive(scip, coefs[i]) ? "+" : "", coefs[i], SCIPvarGetName(vars[i])); 1145 } 1146 SCIPdebugMsg(scip, "\n"); 1147 #endif 1148 1149 /* Set all coefficients of original variables to 0, since we will add the new objective coefficients later. */ 1150 for( i = 0; i < norigvars; i++ ) 1151 { 1152 SCIP_CALL( SCIPchgVarObj(scip, origvars[i], 0.0) ); 1153 } 1154 1155 if( scip->set->stage >= SCIP_STAGE_TRANSFORMED ) 1156 { 1157 /* In order to avoid numerical troubles, also explicitly set all transformed objective coefficients to 0. */ 1158 for( i = 0; i < scip->transprob->nvars; i++ ) 1159 { 1160 SCIP_CALL( SCIPchgVarObj(scip, scip->transprob->vars[i], 0.0) ); 1161 } 1162 } 1163 1164 /* reset objective data of original problem */ 1165 scip->origprob->objscale = 1.0; 1166 scip->origprob->objsense = objsense; 1167 scip->origprob->objoffset = 0.0; 1168 scip->origprob->objisintegral = FALSE; 1169 1170 if( scip->set->stage >= SCIP_STAGE_TRANSFORMED ) 1171 { 1172 /* reset objective data of transformed problem */ 1173 scip->transprob->objscale = 1.0; 1174 scip->transprob->objsense = objsense; 1175 scip->transprob->objoffset = 0.0; 1176 scip->transprob->objisintegral = FALSE; 1177 } 1178 1179 /* set new objective values */ 1180 for( i = 0; i < nvars; ++i ) 1181 { 1182 if( !SCIPvarIsOriginal(vars[i]) ) 1183 { 1184 SCIPerrorMessage("Cannot handle variable <%s> (status: %d) in SCIPchgReoptObjective().\n", 1185 SCIPvarGetName(vars[i]), SCIPvarGetStatus(vars[i])); 1186 return SCIP_INVALIDDATA; 1187 } 1188 1189 /* Add coefficients because this gets transferred to the transformed problem (the coefficients were set to 0 above). */ 1190 SCIP_CALL( SCIPaddVarObj(scip, vars[i], coefs[i]) ); 1191 } 1192 1193 #ifdef SCIP_MORE_DEBUG 1194 SCIPdebugMsg(scip, "new objective function:\n"); 1195 for( i = 0; i < norigvars; i++ ) 1196 { 1197 SCIP_Real objval = SCIPvarGetObj(origvars[i]); 1198 if( !SCIPisZero(scip, objval) ) 1199 SCIPdebugMsg(scip, "%s%g <%s> ", SCIPisPositive(scip, objval) ? "+" : "", objval, SCIPvarGetName(origvars[i])); 1200 } 1201 SCIPdebugMsg(scip, "\n"); 1202 #endif 1203 1204 return SCIP_OKAY; 1205 } 1206 1207 /** returns objective sense of original problem 1208 * 1209 * @return objective sense of original problem 1210 * 1211 * @pre This method can be called if @p scip is in one of the following stages: 1212 * - \ref SCIP_STAGE_PROBLEM 1213 * - \ref SCIP_STAGE_TRANSFORMING 1214 * - \ref SCIP_STAGE_TRANSFORMED 1215 * - \ref SCIP_STAGE_INITPRESOLVE 1216 * - \ref SCIP_STAGE_PRESOLVING 1217 * - \ref SCIP_STAGE_EXITPRESOLVE 1218 * - \ref SCIP_STAGE_PRESOLVED 1219 * - \ref SCIP_STAGE_INITSOLVE 1220 * - \ref SCIP_STAGE_SOLVING 1221 * - \ref SCIP_STAGE_SOLVED 1222 * - \ref SCIP_STAGE_EXITSOLVE 1223 * - \ref SCIP_STAGE_FREETRANS 1224 */ 1225 SCIP_OBJSENSE SCIPgetObjsense( 1226 SCIP* scip /**< SCIP data structure */ 1227 ) 1228 { 1229 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetObjsense", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) ); 1230 1231 return scip->origprob->objsense; 1232 } 1233 1234 /** sets objective sense of problem 1235 * 1236 * @return \ref SCIP_OKAY is returned if everything worked. otherwise a suitable error code is passed. see \ref 1237 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 1238 * 1239 * @pre This method can be called if @p scip is in one of the following stages: 1240 * - \ref SCIP_STAGE_PROBLEM 1241 */ 1242 SCIP_RETCODE SCIPsetObjsense( 1243 SCIP* scip, /**< SCIP data structure */ 1244 SCIP_OBJSENSE objsense /**< new objective sense */ 1245 ) 1246 { 1247 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetObjsense", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) ); 1248 1249 if( objsense != SCIP_OBJSENSE_MAXIMIZE && objsense != SCIP_OBJSENSE_MINIMIZE ) 1250 { 1251 SCIPerrorMessage("invalid objective sense\n"); 1252 return SCIP_INVALIDDATA; 1253 } 1254 1255 SCIPprobSetObjsense(scip->origprob, objsense); 1256 1257 return SCIP_OKAY; 1258 } 1259 1260 /** adds offset of objective function 1261 * 1262 * @return \ref SCIP_OKAY is returned if everything worked. otherwise a suitable error code is passed. see \ref 1263 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 1264 * 1265 * @pre This method can be called if @p scip is in one of the following stages: 1266 * - \ref SCIP_STAGE_PRESOLVING 1267 */ 1268 SCIP_RETCODE SCIPaddObjoffset( 1269 SCIP* scip, /**< SCIP data structure */ 1270 SCIP_Real addval /**< value to add to objective offset */ 1271 ) 1272 { 1273 SCIP_CALL( SCIPcheckStage(scip, "SCIPaddObjoffset", FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) ); 1274 1275 SCIPprobAddObjoffset(scip->transprob, addval); 1276 SCIP_CALL( SCIPprimalUpdateObjoffset(scip->primal, SCIPblkmem(scip), scip->set, scip->stat, scip->eventfilter, 1277 scip->eventqueue, scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp) ); 1278 1279 return SCIP_OKAY; 1280 } 1281 1282 /** adds offset of objective function to original problem and to all existing solution in original space 1283 * 1284 * @return \ref SCIP_OKAY is returned if everything worked. otherwise a suitable error code is passed. see \ref 1285 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 1286 * 1287 * @pre This method can be called if @p scip is in one of the following stages: 1288 * - \ref SCIP_STAGE_PROBLEM 1289 */ 1290 SCIP_RETCODE SCIPaddOrigObjoffset( 1291 SCIP* scip, /**< SCIP data structure */ 1292 SCIP_Real addval /**< value to add to objective offset */ 1293 ) 1294 { 1295 SCIP_CALL( SCIPcheckStage(scip, "SCIPaddOrigObjoffset", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) ); 1296 1297 scip->origprob->objoffset += addval; 1298 SCIPprimalAddOrigObjoffset(scip->origprimal, scip->set, addval); 1299 1300 return SCIP_OKAY; 1301 } 1302 1303 /** returns the objective offset of the original problem 1304 * 1305 * @return the objective offset of the original problem 1306 * 1307 * @pre This method can be called if @p scip is in one of the following stages: 1308 * - \ref SCIP_STAGE_PROBLEM 1309 * - \ref SCIP_STAGE_TRANSFORMING 1310 * - \ref SCIP_STAGE_TRANSFORMED 1311 * - \ref SCIP_STAGE_INITPRESOLVE 1312 * - \ref SCIP_STAGE_PRESOLVING 1313 * - \ref SCIP_STAGE_EXITPRESOLVE 1314 * - \ref SCIP_STAGE_PRESOLVED 1315 * - \ref SCIP_STAGE_INITSOLVE 1316 * - \ref SCIP_STAGE_SOLVING 1317 * - \ref SCIP_STAGE_SOLVED 1318 */ 1319 SCIP_Real SCIPgetOrigObjoffset( 1320 SCIP* scip /**< SCIP data structure */ 1321 ) 1322 { 1323 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetOrigObjoffset", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 1324 1325 return scip->origprob->objoffset; 1326 } 1327 1328 /** returns the objective scale of the original problem 1329 * 1330 * @return the objective scale of the original problem 1331 * 1332 * @pre This method can be called if @p scip is in one of the following stages: 1333 * - \ref SCIP_STAGE_PROBLEM 1334 * - \ref SCIP_STAGE_TRANSFORMING 1335 * - \ref SCIP_STAGE_TRANSFORMED 1336 * - \ref SCIP_STAGE_INITPRESOLVE 1337 * - \ref SCIP_STAGE_PRESOLVING 1338 * - \ref SCIP_STAGE_EXITPRESOLVE 1339 * - \ref SCIP_STAGE_PRESOLVED 1340 * - \ref SCIP_STAGE_INITSOLVE 1341 * - \ref SCIP_STAGE_SOLVING 1342 * - \ref SCIP_STAGE_SOLVED 1343 */ 1344 SCIP_Real SCIPgetOrigObjscale( 1345 SCIP* scip /**< SCIP data structure */ 1346 ) 1347 { 1348 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetOrigObjscale", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 1349 1350 return scip->origprob->objscale; 1351 } 1352 1353 /** returns the objective offset of the transformed problem 1354 * 1355 * @return the objective offset of the transformed problem 1356 * 1357 * @pre This method can be called if @p scip is in one of the following stages: 1358 * - \ref SCIP_STAGE_TRANSFORMED 1359 * - \ref SCIP_STAGE_INITPRESOLVE 1360 * - \ref SCIP_STAGE_PRESOLVING 1361 * - \ref SCIP_STAGE_EXITPRESOLVE 1362 * - \ref SCIP_STAGE_PRESOLVED 1363 * - \ref SCIP_STAGE_INITSOLVE 1364 * - \ref SCIP_STAGE_SOLVING 1365 * - \ref SCIP_STAGE_SOLVED 1366 */ 1367 SCIP_Real SCIPgetTransObjoffset( 1368 SCIP* scip /**< SCIP data structure */ 1369 ) 1370 { 1371 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetTransObjoffset", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 1372 1373 return scip->transprob->objoffset; 1374 } 1375 1376 /** returns the objective scale of the transformed problem 1377 * 1378 * @return the objective scale of the transformed problem 1379 * 1380 * @pre This method can be called if @p scip is in one of the following stages: 1381 * - \ref SCIP_STAGE_TRANSFORMED 1382 * - \ref SCIP_STAGE_INITPRESOLVE 1383 * - \ref SCIP_STAGE_PRESOLVING 1384 * - \ref SCIP_STAGE_EXITPRESOLVE 1385 * - \ref SCIP_STAGE_PRESOLVED 1386 * - \ref SCIP_STAGE_INITSOLVE 1387 * - \ref SCIP_STAGE_SOLVING 1388 * - \ref SCIP_STAGE_SOLVED 1389 */ 1390 SCIP_Real SCIPgetTransObjscale( 1391 SCIP* scip /**< SCIP data structure */ 1392 ) 1393 { 1394 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetTransObjscale", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 1395 1396 return scip->transprob->objscale; 1397 } 1398 1399 /** sets limit on objective function, such that only solutions better than this limit are accepted 1400 * 1401 * @note SCIP will only look for solutions with a strictly better objective value, thus, e.g., prune 1402 * all branch-and-bound nodes with dual bound equal or worse to the objective limit. 1403 * However, SCIP will also collect solutions with objective value worse than the objective limit and 1404 * use them to run improvement heuristics on them. 1405 * @note If SCIP can prove that there exists no solution with a strictly better objective value, the solving status 1406 * will normally be infeasible (the objective limit is interpreted as part of the problem). 1407 * The only exception is that by chance, SCIP found a solution with the same objective value and thus 1408 * proved the optimality of this solution, resulting in solution status optimal. 1409 * 1410 * @return \ref SCIP_OKAY is returned if everything worked. otherwise a suitable error code is passed. see \ref 1411 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 1412 * 1413 * @pre This method can be called if @p scip is in one of the following stages: 1414 * - \ref SCIP_STAGE_PROBLEM 1415 * - \ref SCIP_STAGE_TRANSFORMED 1416 * - \ref SCIP_STAGE_INITPRESOLVE 1417 * - \ref SCIP_STAGE_PRESOLVING 1418 * - \ref SCIP_STAGE_EXITPRESOLVE 1419 * - \ref SCIP_STAGE_PRESOLVED 1420 * - \ref SCIP_STAGE_SOLVING 1421 */ 1422 SCIP_RETCODE SCIPsetObjlimit( 1423 SCIP* scip, /**< SCIP data structure */ 1424 SCIP_Real objlimit /**< new primal objective limit */ 1425 ) 1426 { 1427 SCIP_Real oldobjlimit; 1428 1429 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetObjlimit", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 1430 1431 switch( scip->set->stage ) 1432 { 1433 case SCIP_STAGE_PROBLEM: 1434 SCIPprobSetObjlim(scip->origprob, objlimit); 1435 break; 1436 case SCIP_STAGE_PRESOLVED: 1437 oldobjlimit = SCIPprobGetObjlim(scip->origprob, scip->set); 1438 assert(oldobjlimit == SCIPprobGetObjlim(scip->transprob, scip->set)); /*lint !e777*/ 1439 if( SCIPtransformObj(scip, objlimit) > SCIPprobInternObjval(scip->transprob, scip->origprob, scip->set, oldobjlimit) && ! scip->set->reopt_enable) 1440 { 1441 SCIPerrorMessage("cannot relax objective limit from %.15g to %.15g in presolved stage.\n", oldobjlimit, objlimit); 1442 return SCIP_INVALIDDATA; 1443 } 1444 SCIPprobSetObjlim(scip->origprob, objlimit); 1445 SCIPprobSetObjlim(scip->transprob, objlimit); 1446 SCIP_CALL( SCIPprimalUpdateObjlimit(scip->primal, scip->mem->probmem, scip->set, scip->stat, scip->eventfilter, 1447 scip->eventqueue, scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp) ); 1448 break; 1449 1450 case SCIP_STAGE_TRANSFORMED: 1451 case SCIP_STAGE_INITPRESOLVE: 1452 case SCIP_STAGE_PRESOLVING: 1453 case SCIP_STAGE_EXITPRESOLVE: 1454 case SCIP_STAGE_SOLVING: 1455 oldobjlimit = SCIPprobGetObjlim(scip->origprob, scip->set); 1456 assert(oldobjlimit == SCIPprobGetObjlim(scip->transprob, scip->set)); /*lint !e777*/ 1457 if( SCIPtransformObj(scip, objlimit) > SCIPprobInternObjval(scip->transprob, scip->origprob, scip->set, oldobjlimit) ) 1458 { 1459 SCIPerrorMessage("cannot relax objective limit from %.15g to %.15g after problem was transformed.\n", oldobjlimit, objlimit); 1460 return SCIP_INVALIDDATA; 1461 } 1462 SCIPprobSetObjlim(scip->origprob, objlimit); 1463 SCIPprobSetObjlim(scip->transprob, objlimit); 1464 SCIP_CALL( SCIPprimalUpdateObjlimit(scip->primal, scip->mem->probmem, scip->set, scip->stat, scip->eventfilter, 1465 scip->eventqueue, scip->transprob, scip->origprob, scip->tree, scip->reopt, scip->lp) ); 1466 break; 1467 1468 default: 1469 SCIPerrorMessage("method is not callable in SCIP stage <%d>\n", scip->set->stage); 1470 return SCIP_INVALIDCALL; 1471 } /*lint !e788*/ 1472 1473 return SCIP_OKAY; 1474 } 1475 1476 /** returns current limit on objective function 1477 * 1478 * @return the current objective limit of the original problem 1479 * 1480 * @pre This method can be called if @p scip is in one of the following stages: 1481 * - \ref SCIP_STAGE_PROBLEM 1482 * - \ref SCIP_STAGE_TRANSFORMING 1483 * - \ref SCIP_STAGE_TRANSFORMED 1484 * - \ref SCIP_STAGE_INITPRESOLVE 1485 * - \ref SCIP_STAGE_PRESOLVING 1486 * - \ref SCIP_STAGE_EXITPRESOLVE 1487 * - \ref SCIP_STAGE_PRESOLVED 1488 * - \ref SCIP_STAGE_INITSOLVE 1489 * - \ref SCIP_STAGE_SOLVING 1490 * - \ref SCIP_STAGE_SOLVED 1491 */ 1492 SCIP_Real SCIPgetObjlimit( 1493 SCIP* scip /**< SCIP data structure */ 1494 ) 1495 { 1496 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetObjlimit", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 1497 1498 return SCIPprobGetObjlim(scip->origprob, scip->set); 1499 } 1500 1501 /** informs SCIP, that the objective value is always integral in every feasible solution 1502 * 1503 * @return \ref SCIP_OKAY is returned if everything worked. otherwise a suitable error code is passed. see \ref 1504 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 1505 * 1506 * @pre This method can be called if @p scip is in one of the following stages: 1507 * - \ref SCIP_STAGE_PROBLEM 1508 * - \ref SCIP_STAGE_TRANSFORMING 1509 * - \ref SCIP_STAGE_INITPRESOLVE 1510 * - \ref SCIP_STAGE_EXITPRESOLVE 1511 * - \ref SCIP_STAGE_SOLVING 1512 * 1513 * @note This function should be used to inform SCIP that the objective function is integral, helping to improve the 1514 * performance. This is useful when using column generation. If no column generation (pricing) is used, SCIP 1515 * automatically detects whether the objective function is integral or can be scaled to be integral. However, in 1516 * any case, the user has to make sure that no variable is added during the solving process that destroys this 1517 * property. 1518 */ 1519 SCIP_RETCODE SCIPsetObjIntegral( 1520 SCIP* scip /**< SCIP data structure */ 1521 ) 1522 { 1523 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetObjIntegral", FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 1524 1525 switch( scip->set->stage ) 1526 { 1527 case SCIP_STAGE_PROBLEM: 1528 SCIPprobSetObjIntegral(scip->origprob); 1529 return SCIP_OKAY; 1530 1531 case SCIP_STAGE_TRANSFORMING: 1532 case SCIP_STAGE_PRESOLVING: 1533 case SCIP_STAGE_PRESOLVED: 1534 case SCIP_STAGE_SOLVING: 1535 SCIPprobSetObjIntegral(scip->transprob); 1536 return SCIP_OKAY; 1537 1538 default: 1539 SCIPerrorMessage("method is not callable in SCIP stage <%d>\n", scip->set->stage); 1540 return SCIP_INVALIDCALL; 1541 } /*lint !e788*/ 1542 } 1543 1544 /** returns whether the objective value is known to be integral in every feasible solution 1545 * 1546 * @return TRUE, if objective value is known to be always integral, otherwise FALSE 1547 * 1548 * @pre This method can be called if @p scip is in one of the following stages: 1549 * - \ref SCIP_STAGE_PROBLEM 1550 * - \ref SCIP_STAGE_TRANSFORMING 1551 * - \ref SCIP_STAGE_INITPRESOLVE 1552 * - \ref SCIP_STAGE_PRESOLVING 1553 * - \ref SCIP_STAGE_EXITPRESOLVE 1554 * - \ref SCIP_STAGE_PRESOLVED 1555 * - \ref SCIP_STAGE_SOLVING 1556 * 1557 * @note If no pricing is performed, SCIP automatically detects whether the objective function is integral or can be 1558 * scaled to be integral, helping to improve performance. This function returns the result. Otherwise 1559 * SCIPsetObjIntegral() can be used to inform SCIP. However, in any case, the user has to make sure that no 1560 * variable is added during the solving process that destroys this property. 1561 */ 1562 SCIP_Bool SCIPisObjIntegral( 1563 SCIP* scip /**< SCIP data structure */ 1564 ) 1565 { 1566 int v; 1567 1568 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPisObjIntegral", FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 1569 1570 switch( scip->set->stage ) 1571 { 1572 case SCIP_STAGE_PROBLEM: 1573 /* if the user explicitly added the information that there is an integral objective, return TRUE */ 1574 if( SCIPprobIsObjIntegral(scip->origprob) ) 1575 return TRUE; 1576 1577 /* if there exist unknown variables, we cannot conclude that the objective value is always integral */ 1578 if ( scip->set->nactivepricers != 0 ) 1579 return FALSE; 1580 1581 /* if the objective value offset is fractional, the value itself is possibly fractional */ 1582 if ( ! SCIPisIntegral(scip, scip->origprob->objoffset) ) 1583 return FALSE; 1584 1585 /* scan through the variables */ 1586 for (v = 0; v < scip->origprob->nvars; ++v) 1587 { 1588 SCIP_Real obj; 1589 1590 /* get objective value of variable */ 1591 obj = SCIPvarGetObj(scip->origprob->vars[v]); 1592 1593 /* check, if objective value is non-zero */ 1594 if ( ! SCIPisZero(scip, obj) ) 1595 { 1596 /* if variable's objective value is fractional, the problem's objective value may also be fractional */ 1597 if ( ! SCIPisIntegral(scip, obj) ) 1598 break; 1599 1600 /* if variable with non-zero objective value is continuous, the problem's objective value may be fractional */ 1601 if ( SCIPvarGetType(scip->origprob->vars[v]) == SCIP_VARTYPE_CONTINUOUS ) 1602 break; 1603 } 1604 } 1605 1606 /* we do not store the result, since we assume that the original problem might be changed */ 1607 if ( v == scip->origprob->nvars ) 1608 return TRUE; 1609 return FALSE; 1610 1611 case SCIP_STAGE_TRANSFORMING: 1612 case SCIP_STAGE_INITPRESOLVE: 1613 case SCIP_STAGE_PRESOLVING: 1614 case SCIP_STAGE_EXITPRESOLVE: 1615 case SCIP_STAGE_PRESOLVED: 1616 case SCIP_STAGE_SOLVING: 1617 return SCIPprobIsObjIntegral(scip->transprob); 1618 1619 default: 1620 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage); 1621 SCIPABORT(); 1622 return FALSE; /*lint !e527*/ 1623 } /*lint !e788*/ 1624 } 1625 1626 /** returns the Euclidean norm of the objective function vector (available only for transformed problem) 1627 * 1628 * @return the Euclidean norm of the transformed objective function vector 1629 * 1630 * @pre This method can be called if @p scip is in one of the following stages: 1631 * - \ref SCIP_STAGE_TRANSFORMED 1632 * - \ref SCIP_STAGE_INITPRESOLVE 1633 * - \ref SCIP_STAGE_PRESOLVING 1634 * - \ref SCIP_STAGE_EXITPRESOLVE 1635 * - \ref SCIP_STAGE_PRESOLVED 1636 * - \ref SCIP_STAGE_INITSOLVE 1637 * - \ref SCIP_STAGE_SOLVING 1638 * - \ref SCIP_STAGE_SOLVED 1639 * - \ref SCIP_STAGE_EXITSOLVE 1640 */ 1641 SCIP_Real SCIPgetObjNorm( 1642 SCIP* scip /**< SCIP data structure */ 1643 ) 1644 { 1645 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetObjNorm", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) ); 1646 1647 if( scip->lp->objsqrnormunreliable ) 1648 SCIPlpRecalculateObjSqrNorm(scip->set, scip->lp); 1649 assert(!scip->lp->objsqrnormunreliable); 1650 1651 return SCIPlpGetObjNorm(scip->lp); 1652 } 1653 1654 /** adds variable to the problem 1655 * 1656 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 1657 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 1658 * 1659 * @pre This method can be called if @p scip is in one of the following stages: 1660 * - \ref SCIP_STAGE_PROBLEM 1661 * - \ref SCIP_STAGE_TRANSFORMING 1662 * - \ref SCIP_STAGE_INITPRESOLVE 1663 * - \ref SCIP_STAGE_PRESOLVING 1664 * - \ref SCIP_STAGE_EXITPRESOLVE 1665 * - \ref SCIP_STAGE_PRESOLVED 1666 * - \ref SCIP_STAGE_SOLVING 1667 */ 1668 SCIP_RETCODE SCIPaddVar( 1669 SCIP* scip, /**< SCIP data structure */ 1670 SCIP_VAR* var /**< variable to add */ 1671 ) 1672 { 1673 SCIP_CALL( SCIPcheckStage(scip, "SCIPaddVar", FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 1674 1675 /* avoid inserting the same variable twice */ 1676 if( SCIPvarGetProbindex(var) != -1 ) 1677 return SCIP_OKAY; 1678 1679 /* insert the negation variable x instead of the negated variable x' in x' = offset - x */ 1680 if( SCIPvarGetStatus(var) == SCIP_VARSTATUS_NEGATED ) 1681 { 1682 assert(SCIPvarGetNegationVar(var) != NULL); 1683 SCIP_CALL( SCIPaddVar(scip, SCIPvarGetNegationVar(var)) ); 1684 return SCIP_OKAY; 1685 } 1686 1687 switch( scip->set->stage ) 1688 { 1689 case SCIP_STAGE_PROBLEM: 1690 if( SCIPvarGetStatus(var) != SCIP_VARSTATUS_ORIGINAL ) 1691 { 1692 SCIPerrorMessage("cannot add transformed variables to original problem\n"); 1693 return SCIP_INVALIDDATA; 1694 } 1695 SCIP_CALL( SCIPprobAddVar(scip->origprob, scip->mem->probmem, scip->set, scip->lp, scip->branchcand, 1696 scip->eventfilter, scip->eventqueue, var) ); 1697 return SCIP_OKAY; 1698 1699 case SCIP_STAGE_TRANSFORMING: 1700 case SCIP_STAGE_INITPRESOLVE: 1701 case SCIP_STAGE_PRESOLVING: 1702 case SCIP_STAGE_EXITPRESOLVE: 1703 case SCIP_STAGE_PRESOLVED: 1704 case SCIP_STAGE_SOLVING: 1705 /* check variable's status */ 1706 if( SCIPvarGetStatus(var) == SCIP_VARSTATUS_ORIGINAL ) 1707 { 1708 SCIPerrorMessage("cannot add original variables to transformed problem\n"); 1709 return SCIP_INVALIDDATA; 1710 } 1711 else if( SCIPvarGetStatus(var) != SCIP_VARSTATUS_LOOSE && SCIPvarGetStatus(var) != SCIP_VARSTATUS_COLUMN ) 1712 { 1713 SCIPerrorMessage("cannot add fixed or aggregated variables to transformed problem\n"); 1714 return SCIP_INVALIDDATA; 1715 } 1716 SCIP_CALL( SCIPprobAddVar(scip->transprob, scip->mem->probmem, scip->set, scip->lp, 1717 scip->branchcand, scip->eventfilter, scip->eventqueue, var) ); 1718 return SCIP_OKAY; 1719 1720 default: 1721 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage); 1722 return SCIP_INVALIDCALL; 1723 } /*lint !e788*/ 1724 } 1725 1726 /** adds variable to the problem and uses it as pricing candidate to enter the LP 1727 * 1728 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 1729 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 1730 * 1731 * @pre This method can only be called if @p scip is in stage \ref SCIP_STAGE_SOLVING 1732 */ 1733 SCIP_RETCODE SCIPaddPricedVar( 1734 SCIP* scip, /**< SCIP data structure */ 1735 SCIP_VAR* var, /**< variable to add */ 1736 SCIP_Real score /**< pricing score of variable (the larger, the better the variable) */ 1737 ) 1738 { 1739 SCIP_CALL( SCIPcheckStage(scip, "SCIPaddPricedVar", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 1740 1741 /* insert the negation variable x instead of the negated variable x' in x' = offset - x */ 1742 if( SCIPvarGetStatus(var) == SCIP_VARSTATUS_NEGATED ) 1743 { 1744 assert(SCIPvarGetNegationVar(var) != NULL); 1745 SCIP_CALL( SCIPaddPricedVar(scip, SCIPvarGetNegationVar(var), score) ); 1746 return SCIP_OKAY; 1747 } 1748 1749 /* add variable to problem if not yet inserted */ 1750 if( SCIPvarGetProbindex(var) == -1 ) 1751 { 1752 /* check variable's status */ 1753 if( SCIPvarGetStatus(var) == SCIP_VARSTATUS_ORIGINAL ) 1754 { 1755 SCIPerrorMessage("cannot add original variables to transformed problem\n"); 1756 return SCIP_INVALIDDATA; 1757 } 1758 else if( SCIPvarGetStatus(var) != SCIP_VARSTATUS_LOOSE && SCIPvarGetStatus(var) != SCIP_VARSTATUS_COLUMN ) 1759 { 1760 SCIPerrorMessage("cannot add fixed or aggregated variables to transformed problem\n"); 1761 return SCIP_INVALIDDATA; 1762 } 1763 SCIP_CALL( SCIPprobAddVar(scip->transprob, scip->mem->probmem, scip->set, scip->lp, 1764 scip->branchcand, scip->eventfilter, scip->eventqueue, var) ); 1765 } 1766 1767 /* add variable to pricing storage */ 1768 SCIP_CALL( SCIPpricestoreAddVar(scip->pricestore, scip->mem->probmem, scip->set, scip->eventqueue, scip->lp, var, score, 1769 (SCIPtreeGetCurrentDepth(scip->tree) == 0)) ); 1770 1771 return SCIP_OKAY; 1772 } 1773 1774 /** removes variable from the problem 1775 * 1776 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 1777 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 1778 * 1779 * @pre This method can be called if @p scip is in one of the following stages: 1780 * - \ref SCIP_STAGE_PROBLEM 1781 * - \ref SCIP_STAGE_TRANSFORMING 1782 * - \ref SCIP_STAGE_TRANSFORMED 1783 * - \ref SCIP_STAGE_PRESOLVING 1784 * - \ref SCIP_STAGE_FREETRANS 1785 * 1786 * @warning The variable is not deleted from the constraints when in SCIP_STAGE_PROBLEM. In this stage, it is the 1787 * user's responsibility to ensure the variable has been removed from all constraints or the constraints 1788 * deleted. 1789 */ 1790 SCIP_RETCODE SCIPdelVar( 1791 SCIP* scip, /**< SCIP data structure */ 1792 SCIP_VAR* var, /**< variable to delete */ 1793 SCIP_Bool* deleted /**< pointer to store whether marking variable to be deleted was successful */ 1794 ) 1795 { 1796 assert(scip != NULL); 1797 assert(var != NULL); 1798 assert(deleted != NULL); 1799 1800 SCIP_CALL( SCIPcheckStage(scip, "SCIPdelVar", FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE) ); 1801 1802 switch( scip->set->stage ) 1803 { 1804 case SCIP_STAGE_PROBLEM: 1805 if( SCIPvarGetStatus(var) != SCIP_VARSTATUS_ORIGINAL ) 1806 { 1807 SCIPerrorMessage("cannot remove transformed variables from original problem\n"); 1808 return SCIP_INVALIDDATA; 1809 } 1810 SCIP_CALL( SCIPprobDelVar(scip->origprob, scip->mem->probmem, scip->set, scip->eventqueue, var, deleted) ); 1811 1812 /* delete the variables from the problems that were marked to be deleted */ 1813 SCIP_CALL( SCIPprobPerformVarDeletions(scip->origprob, scip->mem->probmem, scip->set, scip->stat, scip->eventqueue, scip->cliquetable, scip->lp, scip->branchcand) ); 1814 1815 return SCIP_OKAY; 1816 1817 case SCIP_STAGE_TRANSFORMING: 1818 case SCIP_STAGE_TRANSFORMED: 1819 case SCIP_STAGE_PRESOLVING: 1820 /* check variable's status */ 1821 if( SCIPvarGetStatus(var) == SCIP_VARSTATUS_ORIGINAL ) 1822 { 1823 SCIPerrorMessage("cannot remove original variables from transformed problem\n"); 1824 return SCIP_INVALIDDATA; 1825 } 1826 else if( SCIPvarGetStatus(var) != SCIP_VARSTATUS_LOOSE && SCIPvarGetStatus(var) != SCIP_VARSTATUS_COLUMN ) 1827 { 1828 SCIPerrorMessage("cannot remove fixed or aggregated variables from transformed problem\n"); 1829 return SCIP_INVALIDDATA; 1830 } 1831 1832 SCIP_CALL( SCIPprobDelVar(scip->transprob, scip->mem->probmem, scip->set, scip->eventqueue, var, deleted) ); 1833 1834 return SCIP_OKAY; 1835 case SCIP_STAGE_FREETRANS: 1836 /* in FREETRANS stage, we don't need to remove the variable, because the transformed problem is freed anyways */ 1837 *deleted = FALSE; 1838 1839 return SCIP_OKAY; 1840 default: 1841 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage); 1842 return SCIP_INVALIDCALL; 1843 } /*lint !e788*/ 1844 } 1845 1846 /** gets variables of the problem along with the numbers of different variable types; data may become invalid after 1847 * calls to SCIPchgVarType(), SCIPfixVar(), SCIPaggregateVars(), and SCIPmultiaggregateVar() 1848 * 1849 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 1850 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 1851 * 1852 * @pre This method can be called if @p scip is in one of the following stages: 1853 * - \ref SCIP_STAGE_PROBLEM 1854 * - \ref SCIP_STAGE_TRANSFORMED 1855 * - \ref SCIP_STAGE_INITPRESOLVE 1856 * - \ref SCIP_STAGE_PRESOLVING 1857 * - \ref SCIP_STAGE_EXITPRESOLVE 1858 * - \ref SCIP_STAGE_PRESOLVED 1859 * - \ref SCIP_STAGE_INITSOLVE 1860 * - \ref SCIP_STAGE_SOLVING 1861 * - \ref SCIP_STAGE_SOLVED 1862 * - \ref SCIP_STAGE_EXITSOLVE 1863 * 1864 * @note Variables in the vars array are ordered: binaries first, then integers, implicit integers and continuous last. 1865 */ 1866 SCIP_RETCODE SCIPgetVarsData( 1867 SCIP* scip, /**< SCIP data structure */ 1868 SCIP_VAR*** vars, /**< pointer to store variables array or NULL if not needed */ 1869 int* nvars, /**< pointer to store number of variables or NULL if not needed */ 1870 int* nbinvars, /**< pointer to store number of binary variables or NULL if not needed */ 1871 int* nintvars, /**< pointer to store number of integer variables or NULL if not needed */ 1872 int* nimplvars, /**< pointer to store number of implicit integral vars or NULL if not needed */ 1873 int* ncontvars /**< pointer to store number of continuous variables or NULL if not needed */ 1874 ) 1875 { 1876 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetVarsData", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) ); 1877 1878 switch( scip->set->stage ) 1879 { 1880 case SCIP_STAGE_PROBLEM: 1881 if( vars != NULL ) 1882 *vars = scip->origprob->vars; 1883 if( nvars != NULL ) 1884 *nvars = scip->origprob->nvars; 1885 if( nbinvars != NULL ) 1886 *nbinvars = scip->origprob->nbinvars; 1887 if( nintvars != NULL ) 1888 *nintvars = scip->origprob->nintvars; 1889 if( nimplvars != NULL ) 1890 *nimplvars = scip->origprob->nimplvars; 1891 if( ncontvars != NULL ) 1892 *ncontvars = scip->origprob->ncontvars; 1893 return SCIP_OKAY; 1894 1895 case SCIP_STAGE_TRANSFORMED: 1896 case SCIP_STAGE_INITPRESOLVE: 1897 case SCIP_STAGE_PRESOLVING: 1898 case SCIP_STAGE_EXITPRESOLVE: 1899 case SCIP_STAGE_PRESOLVED: 1900 case SCIP_STAGE_INITSOLVE: 1901 case SCIP_STAGE_SOLVING: 1902 case SCIP_STAGE_SOLVED: 1903 case SCIP_STAGE_EXITSOLVE: 1904 if( vars != NULL ) 1905 *vars = scip->transprob->vars; 1906 if( nvars != NULL ) 1907 *nvars = scip->transprob->nvars; 1908 if( nbinvars != NULL ) 1909 *nbinvars = scip->transprob->nbinvars; 1910 if( nintvars != NULL ) 1911 *nintvars = scip->transprob->nintvars; 1912 if( nimplvars != NULL ) 1913 *nimplvars = scip->transprob->nimplvars; 1914 if( ncontvars != NULL ) 1915 *ncontvars = scip->transprob->ncontvars; 1916 return SCIP_OKAY; 1917 1918 default: 1919 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage); 1920 return SCIP_INVALIDCALL; 1921 } /*lint !e788*/ 1922 } 1923 1924 /** gets array with active problem variables 1925 * 1926 * @return array with active problem variables 1927 * 1928 * @pre This method can be called if @p scip is in one of the following stages: 1929 * - \ref SCIP_STAGE_PROBLEM 1930 * - \ref SCIP_STAGE_TRANSFORMED 1931 * - \ref SCIP_STAGE_INITPRESOLVE 1932 * - \ref SCIP_STAGE_PRESOLVING 1933 * - \ref SCIP_STAGE_EXITPRESOLVE 1934 * - \ref SCIP_STAGE_PRESOLVED 1935 * - \ref SCIP_STAGE_INITSOLVE 1936 * - \ref SCIP_STAGE_SOLVING 1937 * - \ref SCIP_STAGE_SOLVED 1938 * - \ref SCIP_STAGE_EXITSOLVE 1939 * 1940 * @note Variables in the array are ordered: binaries first, then integers, implicit integers and continuous last. 1941 * 1942 * @warning If your are using the methods which add or change bound of variables (e.g., SCIPchgVarType(), SCIPfixVar(), 1943 * SCIPaggregateVars(), and SCIPmultiaggregateVar()), it can happen that the internal variable array (which is 1944 * accessed via this method) gets resized and/or resorted. This can invalid the data pointer which is returned 1945 * by this method. 1946 */ 1947 SCIP_VAR** SCIPgetVars( 1948 SCIP* scip /**< SCIP data structure */ 1949 ) 1950 { 1951 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetVars", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) ); 1952 1953 switch( scip->set->stage ) 1954 { 1955 case SCIP_STAGE_PROBLEM: 1956 return scip->origprob->vars; 1957 1958 case SCIP_STAGE_TRANSFORMED: 1959 case SCIP_STAGE_INITPRESOLVE: 1960 case SCIP_STAGE_PRESOLVING: 1961 case SCIP_STAGE_EXITPRESOLVE: 1962 case SCIP_STAGE_PRESOLVED: 1963 case SCIP_STAGE_INITSOLVE: 1964 case SCIP_STAGE_SOLVING: 1965 case SCIP_STAGE_SOLVED: 1966 case SCIP_STAGE_EXITSOLVE: 1967 return scip->transprob->vars; 1968 1969 default: 1970 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage); 1971 SCIPABORT(); 1972 return NULL; /*lint !e527*/ 1973 } /*lint !e788*/ 1974 } 1975 1976 /** gets number of active problem variables 1977 * 1978 * @return the number of active problem variables 1979 * 1980 * @pre This method can be called if @p scip is in one of the following stages: 1981 * - \ref SCIP_STAGE_PROBLEM 1982 * - \ref SCIP_STAGE_TRANSFORMED 1983 * - \ref SCIP_STAGE_INITPRESOLVE 1984 * - \ref SCIP_STAGE_PRESOLVING 1985 * - \ref SCIP_STAGE_EXITPRESOLVE 1986 * - \ref SCIP_STAGE_PRESOLVED 1987 * - \ref SCIP_STAGE_INITSOLVE 1988 * - \ref SCIP_STAGE_SOLVING 1989 * - \ref SCIP_STAGE_SOLVED 1990 * - \ref SCIP_STAGE_EXITSOLVE 1991 */ 1992 int SCIPgetNVars( 1993 SCIP* scip /**< SCIP data structure */ 1994 ) 1995 { 1996 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNVars", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) ); 1997 1998 switch( scip->set->stage ) 1999 { 2000 case SCIP_STAGE_PROBLEM: 2001 return scip->origprob->nvars; 2002 2003 case SCIP_STAGE_TRANSFORMED: 2004 case SCIP_STAGE_INITPRESOLVE: 2005 case SCIP_STAGE_PRESOLVING: 2006 case SCIP_STAGE_EXITPRESOLVE: 2007 case SCIP_STAGE_PRESOLVED: 2008 case SCIP_STAGE_INITSOLVE: 2009 case SCIP_STAGE_SOLVING: 2010 case SCIP_STAGE_SOLVED: 2011 case SCIP_STAGE_EXITSOLVE: 2012 return scip->transprob->nvars; 2013 2014 default: 2015 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage); 2016 SCIPABORT(); 2017 return 0; /*lint !e527*/ 2018 } /*lint !e788*/ 2019 } 2020 2021 /** gets number of binary active problem variables 2022 * 2023 * @return the number of binary active problem variables 2024 * 2025 * @pre This method can be called if @p scip is in one of the following stages: 2026 * - \ref SCIP_STAGE_PROBLEM 2027 * - \ref SCIP_STAGE_TRANSFORMED 2028 * - \ref SCIP_STAGE_INITPRESOLVE 2029 * - \ref SCIP_STAGE_PRESOLVING 2030 * - \ref SCIP_STAGE_EXITPRESOLVE 2031 * - \ref SCIP_STAGE_PRESOLVED 2032 * - \ref SCIP_STAGE_INITSOLVE 2033 * - \ref SCIP_STAGE_SOLVING 2034 * - \ref SCIP_STAGE_SOLVED 2035 * - \ref SCIP_STAGE_EXITSOLVE 2036 */ 2037 int SCIPgetNBinVars( 2038 SCIP* scip /**< SCIP data structure */ 2039 ) 2040 { 2041 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNBinVars", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) ); 2042 2043 switch( scip->set->stage ) 2044 { 2045 case SCIP_STAGE_PROBLEM: 2046 return scip->origprob->nbinvars; 2047 2048 case SCIP_STAGE_TRANSFORMED: 2049 case SCIP_STAGE_INITPRESOLVE: 2050 case SCIP_STAGE_PRESOLVING: 2051 case SCIP_STAGE_EXITPRESOLVE: 2052 case SCIP_STAGE_PRESOLVED: 2053 case SCIP_STAGE_INITSOLVE: 2054 case SCIP_STAGE_SOLVING: 2055 case SCIP_STAGE_SOLVED: 2056 case SCIP_STAGE_EXITSOLVE: 2057 return scip->transprob->nbinvars; 2058 2059 default: 2060 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage); 2061 SCIPABORT(); 2062 return 0; /*lint !e527*/ 2063 } /*lint !e788*/ 2064 } 2065 2066 /** gets number of integer active problem variables 2067 * 2068 * @return the number of integer active problem variables 2069 * 2070 * @pre This method can be called if @p scip is in one of the following stages: 2071 * - \ref SCIP_STAGE_PROBLEM 2072 * - \ref SCIP_STAGE_TRANSFORMED 2073 * - \ref SCIP_STAGE_INITPRESOLVE 2074 * - \ref SCIP_STAGE_PRESOLVING 2075 * - \ref SCIP_STAGE_EXITPRESOLVE 2076 * - \ref SCIP_STAGE_PRESOLVED 2077 * - \ref SCIP_STAGE_INITSOLVE 2078 * - \ref SCIP_STAGE_SOLVING 2079 * - \ref SCIP_STAGE_SOLVED 2080 * - \ref SCIP_STAGE_EXITSOLVE 2081 */ 2082 int SCIPgetNIntVars( 2083 SCIP* scip /**< SCIP data structure */ 2084 ) 2085 { 2086 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNIntVars", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) ); 2087 2088 switch( scip->set->stage ) 2089 { 2090 case SCIP_STAGE_PROBLEM: 2091 return scip->origprob->nintvars; 2092 2093 case SCIP_STAGE_TRANSFORMED: 2094 case SCIP_STAGE_INITPRESOLVE: 2095 case SCIP_STAGE_PRESOLVING: 2096 case SCIP_STAGE_EXITPRESOLVE: 2097 case SCIP_STAGE_PRESOLVED: 2098 case SCIP_STAGE_INITSOLVE: 2099 case SCIP_STAGE_SOLVING: 2100 case SCIP_STAGE_SOLVED: 2101 case SCIP_STAGE_EXITSOLVE: 2102 return scip->transprob->nintvars; 2103 2104 default: 2105 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage); 2106 SCIPABORT(); 2107 return 0; /*lint !e527*/ 2108 } /*lint !e788*/ 2109 } 2110 2111 /** gets number of implicit integer active problem variables 2112 * 2113 * @return the number of implicit integer active problem variables 2114 * 2115 * @pre This method can be called if @p scip is in one of the following stages: 2116 * - \ref SCIP_STAGE_PROBLEM 2117 * - \ref SCIP_STAGE_TRANSFORMED 2118 * - \ref SCIP_STAGE_INITPRESOLVE 2119 * - \ref SCIP_STAGE_PRESOLVING 2120 * - \ref SCIP_STAGE_EXITPRESOLVE 2121 * - \ref SCIP_STAGE_PRESOLVED 2122 * - \ref SCIP_STAGE_INITSOLVE 2123 * - \ref SCIP_STAGE_SOLVING 2124 * - \ref SCIP_STAGE_SOLVED 2125 * - \ref SCIP_STAGE_EXITSOLVE 2126 */ 2127 int SCIPgetNImplVars( 2128 SCIP* scip /**< SCIP data structure */ 2129 ) 2130 { 2131 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNImplVars", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) ); 2132 2133 switch( scip->set->stage ) 2134 { 2135 case SCIP_STAGE_PROBLEM: 2136 return scip->origprob->nimplvars; 2137 2138 case SCIP_STAGE_TRANSFORMED: 2139 case SCIP_STAGE_INITPRESOLVE: 2140 case SCIP_STAGE_PRESOLVING: 2141 case SCIP_STAGE_EXITPRESOLVE: 2142 case SCIP_STAGE_PRESOLVED: 2143 case SCIP_STAGE_INITSOLVE: 2144 case SCIP_STAGE_SOLVING: 2145 case SCIP_STAGE_SOLVED: 2146 case SCIP_STAGE_EXITSOLVE: 2147 return scip->transprob->nimplvars; 2148 2149 default: 2150 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage); 2151 SCIPABORT(); 2152 return 0; /*lint !e527*/ 2153 } /*lint !e788*/ 2154 } 2155 2156 /** gets number of continuous active problem variables 2157 * 2158 * @return the number of continuous active problem variables 2159 * 2160 * @pre This method can be called if @p scip is in one of the following stages: 2161 * - \ref SCIP_STAGE_PROBLEM 2162 * - \ref SCIP_STAGE_TRANSFORMED 2163 * - \ref SCIP_STAGE_INITPRESOLVE 2164 * - \ref SCIP_STAGE_PRESOLVING 2165 * - \ref SCIP_STAGE_EXITPRESOLVE 2166 * - \ref SCIP_STAGE_PRESOLVED 2167 * - \ref SCIP_STAGE_INITSOLVE 2168 * - \ref SCIP_STAGE_SOLVING 2169 * - \ref SCIP_STAGE_SOLVED 2170 * - \ref SCIP_STAGE_EXITSOLVE 2171 */ 2172 int SCIPgetNContVars( 2173 SCIP* scip /**< SCIP data structure */ 2174 ) 2175 { 2176 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNContVars", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) ); 2177 2178 switch( scip->set->stage ) 2179 { 2180 case SCIP_STAGE_PROBLEM: 2181 return scip->origprob->ncontvars; 2182 2183 case SCIP_STAGE_TRANSFORMED: 2184 case SCIP_STAGE_INITPRESOLVE: 2185 case SCIP_STAGE_PRESOLVING: 2186 case SCIP_STAGE_EXITPRESOLVE: 2187 case SCIP_STAGE_PRESOLVED: 2188 case SCIP_STAGE_INITSOLVE: 2189 case SCIP_STAGE_SOLVING: 2190 case SCIP_STAGE_SOLVED: 2191 case SCIP_STAGE_EXITSOLVE: 2192 return scip->transprob->ncontvars; 2193 2194 default: 2195 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage); 2196 SCIPABORT(); 2197 return 0; /*lint !e527*/ 2198 } /*lint !e788*/ 2199 } 2200 2201 2202 /** gets number of active problem variables with a non-zero objective coefficient 2203 * 2204 * @note In case of the original problem the number of variables is counted. In case of the transformed problem the 2205 * number of variables is just returned since it is stored internally 2206 * 2207 * @return the number of active problem variables with a non-zero objective coefficient 2208 * 2209 * @pre This method can be called if @p scip is in one of the following stages: 2210 * - \ref SCIP_STAGE_PROBLEM 2211 * - \ref SCIP_STAGE_TRANSFORMED 2212 * - \ref SCIP_STAGE_INITPRESOLVE 2213 * - \ref SCIP_STAGE_PRESOLVING 2214 * - \ref SCIP_STAGE_EXITPRESOLVE 2215 * - \ref SCIP_STAGE_PRESOLVED 2216 * - \ref SCIP_STAGE_INITSOLVE 2217 * - \ref SCIP_STAGE_SOLVING 2218 * - \ref SCIP_STAGE_SOLVED 2219 */ 2220 int SCIPgetNObjVars( 2221 SCIP* scip /**< SCIP data structure */ 2222 ) 2223 { 2224 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNObjVars", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 2225 2226 switch( scip->set->stage ) 2227 { 2228 case SCIP_STAGE_PROBLEM: 2229 return SCIPprobGetNObjVars(scip->origprob, scip->set); 2230 2231 case SCIP_STAGE_TRANSFORMED: 2232 case SCIP_STAGE_INITPRESOLVE: 2233 case SCIP_STAGE_PRESOLVING: 2234 case SCIP_STAGE_EXITPRESOLVE: 2235 case SCIP_STAGE_PRESOLVED: 2236 case SCIP_STAGE_INITSOLVE: 2237 case SCIP_STAGE_SOLVING: 2238 case SCIP_STAGE_SOLVED: 2239 return SCIPprobGetNObjVars(scip->transprob, scip->set); 2240 2241 default: 2242 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage); 2243 SCIPABORT(); 2244 return 0; /*lint !e527*/ 2245 } /*lint !e788*/ 2246 } 2247 2248 2249 /** gets array with fixed and aggregated problem variables; data may become invalid after 2250 * calls to SCIPfixVar(), SCIPaggregateVars(), and SCIPmultiaggregateVar() 2251 * 2252 * @return an array with fixed and aggregated problem variables; data may become invalid after 2253 * calls to SCIPfixVar(), SCIPaggregateVars(), and SCIPmultiaggregateVar() 2254 * 2255 * @pre This method can be called if @p scip is in one of the following stages: 2256 * - \ref SCIP_STAGE_PROBLEM 2257 * - \ref SCIP_STAGE_TRANSFORMED 2258 * - \ref SCIP_STAGE_INITPRESOLVE 2259 * - \ref SCIP_STAGE_PRESOLVING 2260 * - \ref SCIP_STAGE_EXITPRESOLVE 2261 * - \ref SCIP_STAGE_PRESOLVED 2262 * - \ref SCIP_STAGE_INITSOLVE 2263 * - \ref SCIP_STAGE_SOLVING 2264 * - \ref SCIP_STAGE_SOLVED 2265 */ 2266 SCIP_VAR** SCIPgetFixedVars( 2267 SCIP* scip /**< SCIP data structure */ 2268 ) 2269 { 2270 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetFixedVars", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 2271 2272 switch( scip->set->stage ) 2273 { 2274 case SCIP_STAGE_PROBLEM: 2275 return NULL; 2276 2277 case SCIP_STAGE_TRANSFORMED: 2278 case SCIP_STAGE_INITPRESOLVE: 2279 case SCIP_STAGE_PRESOLVING: 2280 case SCIP_STAGE_EXITPRESOLVE: 2281 case SCIP_STAGE_PRESOLVED: 2282 case SCIP_STAGE_INITSOLVE: 2283 case SCIP_STAGE_SOLVING: 2284 case SCIP_STAGE_SOLVED: 2285 return scip->transprob->fixedvars; 2286 2287 default: 2288 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage); 2289 SCIPABORT(); 2290 return NULL; /*lint !e527*/ 2291 } /*lint !e788*/ 2292 } 2293 2294 /** gets number of fixed or aggregated problem variables 2295 * 2296 * @return the number of fixed or aggregated problem variables 2297 * 2298 * @pre This method can be called if @p scip is in one of the following stages: 2299 * - \ref SCIP_STAGE_PROBLEM 2300 * - \ref SCIP_STAGE_TRANSFORMED 2301 * - \ref SCIP_STAGE_INITPRESOLVE 2302 * - \ref SCIP_STAGE_PRESOLVING 2303 * - \ref SCIP_STAGE_EXITPRESOLVE 2304 * - \ref SCIP_STAGE_PRESOLVED 2305 * - \ref SCIP_STAGE_INITSOLVE 2306 * - \ref SCIP_STAGE_SOLVING 2307 * - \ref SCIP_STAGE_SOLVED 2308 */ 2309 int SCIPgetNFixedVars( 2310 SCIP* scip /**< SCIP data structure */ 2311 ) 2312 { 2313 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNFixedVars", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 2314 2315 switch( scip->set->stage ) 2316 { 2317 case SCIP_STAGE_PROBLEM: 2318 return 0; 2319 2320 case SCIP_STAGE_TRANSFORMED: 2321 case SCIP_STAGE_INITPRESOLVE: 2322 case SCIP_STAGE_PRESOLVING: 2323 case SCIP_STAGE_EXITPRESOLVE: 2324 case SCIP_STAGE_PRESOLVED: 2325 case SCIP_STAGE_INITSOLVE: 2326 case SCIP_STAGE_SOLVING: 2327 case SCIP_STAGE_SOLVED: 2328 return scip->transprob->nfixedvars; 2329 2330 default: 2331 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage); 2332 SCIPABORT(); 2333 return 0; /*lint !e527*/ 2334 } /*lint !e788*/ 2335 } 2336 2337 /** gets variables of the original problem along with the numbers of different variable types; data may become invalid 2338 * after a call to SCIPchgVarType() 2339 * 2340 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 2341 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 2342 * 2343 * @pre This method can be called if @p scip is in one of the following stages: 2344 * - \ref SCIP_STAGE_PROBLEM 2345 * - \ref SCIP_STAGE_TRANSFORMING 2346 * - \ref SCIP_STAGE_TRANSFORMED 2347 * - \ref SCIP_STAGE_INITPRESOLVE 2348 * - \ref SCIP_STAGE_PRESOLVING 2349 * - \ref SCIP_STAGE_EXITPRESOLVE 2350 * - \ref SCIP_STAGE_PRESOLVED 2351 * - \ref SCIP_STAGE_INITSOLVE 2352 * - \ref SCIP_STAGE_SOLVING 2353 * - \ref SCIP_STAGE_SOLVED 2354 * - \ref SCIP_STAGE_EXITSOLVE 2355 * - \ref SCIP_STAGE_FREETRANS 2356 */ 2357 SCIP_RETCODE SCIPgetOrigVarsData( 2358 SCIP* scip, /**< SCIP data structure */ 2359 SCIP_VAR*** vars, /**< pointer to store variables array or NULL if not needed */ 2360 int* nvars, /**< pointer to store number of variables or NULL if not needed */ 2361 int* nbinvars, /**< pointer to store number of binary variables or NULL if not needed */ 2362 int* nintvars, /**< pointer to store number of integer variables or NULL if not needed */ 2363 int* nimplvars, /**< pointer to store number of implicit integral vars or NULL if not needed */ 2364 int* ncontvars /**< pointer to store number of continuous variables or NULL if not needed */ 2365 ) 2366 { 2367 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetOrigVarsData", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) ); 2368 2369 if( vars != NULL ) 2370 *vars = scip->origprob->vars; 2371 if( nvars != NULL ) 2372 *nvars = scip->origprob->nvars; 2373 if( nbinvars != NULL ) 2374 *nbinvars = scip->origprob->nbinvars; 2375 if( nintvars != NULL ) 2376 *nintvars = scip->origprob->nintvars; 2377 if( nimplvars != NULL ) 2378 *nimplvars = scip->origprob->nimplvars; 2379 if( ncontvars != NULL ) 2380 *ncontvars = scip->origprob->ncontvars; 2381 2382 return SCIP_OKAY; 2383 } 2384 2385 /** gets array with original problem variables; data may become invalid after 2386 * a call to SCIPchgVarType() 2387 * 2388 * @return an array with original problem variables; data may become invalid after 2389 * a call to SCIPchgVarType() 2390 * 2391 * @pre This method can be called if @p scip is in one of the following stages: 2392 * - \ref SCIP_STAGE_PROBLEM 2393 * - \ref SCIP_STAGE_TRANSFORMING 2394 * - \ref SCIP_STAGE_TRANSFORMED 2395 * - \ref SCIP_STAGE_INITPRESOLVE 2396 * - \ref SCIP_STAGE_PRESOLVING 2397 * - \ref SCIP_STAGE_EXITPRESOLVE 2398 * - \ref SCIP_STAGE_PRESOLVED 2399 * - \ref SCIP_STAGE_INITSOLVE 2400 * - \ref SCIP_STAGE_SOLVING 2401 * - \ref SCIP_STAGE_SOLVED 2402 * - \ref SCIP_STAGE_EXITSOLVE 2403 * - \ref SCIP_STAGE_FREETRANS 2404 */ 2405 SCIP_VAR** SCIPgetOrigVars( 2406 SCIP* scip /**< SCIP data structure */ 2407 ) 2408 { 2409 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetOrigVars", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) ); 2410 2411 return scip->origprob->vars; 2412 } 2413 2414 /** gets number of original problem variables 2415 * 2416 * @return the number of original problem variables 2417 * 2418 * @pre This method can be called if @p scip is in one of the following stages: 2419 * - \ref SCIP_STAGE_PROBLEM 2420 * - \ref SCIP_STAGE_TRANSFORMING 2421 * - \ref SCIP_STAGE_TRANSFORMED 2422 * - \ref SCIP_STAGE_INITPRESOLVE 2423 * - \ref SCIP_STAGE_PRESOLVING 2424 * - \ref SCIP_STAGE_EXITPRESOLVE 2425 * - \ref SCIP_STAGE_PRESOLVED 2426 * - \ref SCIP_STAGE_INITSOLVE 2427 * - \ref SCIP_STAGE_SOLVING 2428 * - \ref SCIP_STAGE_SOLVED 2429 * - \ref SCIP_STAGE_EXITSOLVE 2430 * - \ref SCIP_STAGE_FREETRANS 2431 */ 2432 int SCIPgetNOrigVars( 2433 SCIP* scip /**< SCIP data structure */ 2434 ) 2435 { 2436 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNOrigVars", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) ); 2437 2438 return scip->origprob->nvars; 2439 } 2440 2441 /** gets number of binary variables in the original problem 2442 * 2443 * @return the number of binary variables in the original problem 2444 * 2445 * @pre This method can be called if @p scip is in one of the following stages: 2446 * - \ref SCIP_STAGE_PROBLEM 2447 * - \ref SCIP_STAGE_TRANSFORMING 2448 * - \ref SCIP_STAGE_TRANSFORMED 2449 * - \ref SCIP_STAGE_INITPRESOLVE 2450 * - \ref SCIP_STAGE_PRESOLVING 2451 * - \ref SCIP_STAGE_EXITPRESOLVE 2452 * - \ref SCIP_STAGE_PRESOLVED 2453 * - \ref SCIP_STAGE_INITSOLVE 2454 * - \ref SCIP_STAGE_SOLVING 2455 * - \ref SCIP_STAGE_SOLVED 2456 * - \ref SCIP_STAGE_EXITSOLVE 2457 * - \ref SCIP_STAGE_FREETRANS 2458 */ 2459 int SCIPgetNOrigBinVars( 2460 SCIP* scip /**< SCIP data structure */ 2461 ) 2462 { 2463 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNOrigBinVars", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) ); 2464 2465 return scip->origprob->nbinvars; 2466 } 2467 2468 /** gets the number of integer variables in the original problem 2469 * 2470 * @return the number of integer variables in the original problem 2471 * 2472 * @pre This method can be called if @p scip is in one of the following stages: 2473 * - \ref SCIP_STAGE_PROBLEM 2474 * - \ref SCIP_STAGE_TRANSFORMING 2475 * - \ref SCIP_STAGE_TRANSFORMED 2476 * - \ref SCIP_STAGE_INITPRESOLVE 2477 * - \ref SCIP_STAGE_PRESOLVING 2478 * - \ref SCIP_STAGE_EXITPRESOLVE 2479 * - \ref SCIP_STAGE_PRESOLVED 2480 * - \ref SCIP_STAGE_INITSOLVE 2481 * - \ref SCIP_STAGE_SOLVING 2482 * - \ref SCIP_STAGE_SOLVED 2483 * - \ref SCIP_STAGE_EXITSOLVE 2484 * - \ref SCIP_STAGE_FREETRANS 2485 */ 2486 int SCIPgetNOrigIntVars( 2487 SCIP* scip /**< SCIP data structure */ 2488 ) 2489 { 2490 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNOrigIntVars", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) ); 2491 2492 return scip->origprob->nintvars; 2493 } 2494 2495 /** gets number of implicit integer variables in the original problem 2496 * 2497 * @return the number of implicit integer variables in the original problem 2498 * 2499 * @pre This method can be called if @p scip is in one of the following stages: 2500 * - \ref SCIP_STAGE_PROBLEM 2501 * - \ref SCIP_STAGE_TRANSFORMING 2502 * - \ref SCIP_STAGE_TRANSFORMED 2503 * - \ref SCIP_STAGE_INITPRESOLVE 2504 * - \ref SCIP_STAGE_PRESOLVING 2505 * - \ref SCIP_STAGE_EXITPRESOLVE 2506 * - \ref SCIP_STAGE_PRESOLVED 2507 * - \ref SCIP_STAGE_INITSOLVE 2508 * - \ref SCIP_STAGE_SOLVING 2509 * - \ref SCIP_STAGE_SOLVED 2510 * - \ref SCIP_STAGE_EXITSOLVE 2511 * - \ref SCIP_STAGE_FREETRANS 2512 */ 2513 int SCIPgetNOrigImplVars( 2514 SCIP* scip /**< SCIP data structure */ 2515 ) 2516 { 2517 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNOrigImplVars", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) ); 2518 2519 return scip->origprob->nimplvars; 2520 } 2521 2522 /** gets number of continuous variables in the original problem 2523 * 2524 * @return the number of continuous variables in the original problem 2525 * 2526 * @pre This method can be called if @p scip is in one of the following stages: 2527 * - \ref SCIP_STAGE_PROBLEM 2528 * - \ref SCIP_STAGE_TRANSFORMING 2529 * - \ref SCIP_STAGE_TRANSFORMED 2530 * - \ref SCIP_STAGE_INITPRESOLVE 2531 * - \ref SCIP_STAGE_PRESOLVING 2532 * - \ref SCIP_STAGE_EXITPRESOLVE 2533 * - \ref SCIP_STAGE_PRESOLVED 2534 * - \ref SCIP_STAGE_INITSOLVE 2535 * - \ref SCIP_STAGE_SOLVING 2536 * - \ref SCIP_STAGE_SOLVED 2537 * - \ref SCIP_STAGE_EXITSOLVE 2538 * - \ref SCIP_STAGE_FREETRANS 2539 */ 2540 int SCIPgetNOrigContVars( 2541 SCIP* scip /**< SCIP data structure */ 2542 ) 2543 { 2544 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNOrigContVars", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) ); 2545 2546 return scip->origprob->ncontvars; 2547 } 2548 2549 /** gets number of all problem variables created during creation and solving of problem; 2550 * this includes also variables that were deleted in the meantime 2551 * 2552 * @return the number of all problem variables created during creation and solving of problem; 2553 * this includes also variables that were deleted in the meantime 2554 * 2555 * @pre This method can be called if @p scip is in one of the following stages: 2556 * - \ref SCIP_STAGE_PROBLEM 2557 * - \ref SCIP_STAGE_TRANSFORMING 2558 * - \ref SCIP_STAGE_TRANSFORMED 2559 * - \ref SCIP_STAGE_INITPRESOLVE 2560 * - \ref SCIP_STAGE_PRESOLVING 2561 * - \ref SCIP_STAGE_EXITPRESOLVE 2562 * - \ref SCIP_STAGE_PRESOLVED 2563 * - \ref SCIP_STAGE_INITSOLVE 2564 * - \ref SCIP_STAGE_SOLVING 2565 * - \ref SCIP_STAGE_SOLVED 2566 * - \ref SCIP_STAGE_EXITSOLVE 2567 * - \ref SCIP_STAGE_FREETRANS 2568 */ 2569 int SCIPgetNTotalVars( 2570 SCIP* scip /**< SCIP data structure */ 2571 ) 2572 { 2573 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNTotalVars", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) ); 2574 2575 assert(scip->stat != NULL); 2576 2577 switch( scip->set->stage ) 2578 { 2579 case SCIP_STAGE_PROBLEM: 2580 case SCIP_STAGE_TRANSFORMING: 2581 case SCIP_STAGE_TRANSFORMED: 2582 case SCIP_STAGE_INITPRESOLVE: 2583 case SCIP_STAGE_PRESOLVING: 2584 case SCIP_STAGE_EXITPRESOLVE: 2585 case SCIP_STAGE_PRESOLVED: 2586 case SCIP_STAGE_INITSOLVE: 2587 case SCIP_STAGE_SOLVING: 2588 case SCIP_STAGE_SOLVED: 2589 case SCIP_STAGE_EXITSOLVE: 2590 case SCIP_STAGE_FREETRANS: 2591 return scip->stat->nvaridx; 2592 2593 default: 2594 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage); 2595 SCIPABORT(); 2596 return 0; /*lint !e527*/ 2597 } /*lint !e788*/ 2598 } 2599 2600 2601 /** gets variables of the original or transformed problem along with the numbers of different variable types; 2602 * the returned problem space (original or transformed) corresponds to the given solution; 2603 * data may become invalid after calls to SCIPchgVarType(), SCIPfixVar(), SCIPaggregateVars(), and 2604 * SCIPmultiaggregateVar() 2605 * 2606 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 2607 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 2608 * 2609 * @pre This method can be called if @p scip is in one of the following stages: 2610 * - \ref SCIP_STAGE_PROBLEM 2611 * - \ref SCIP_STAGE_TRANSFORMED 2612 * - \ref SCIP_STAGE_INITPRESOLVE 2613 * - \ref SCIP_STAGE_PRESOLVING 2614 * - \ref SCIP_STAGE_EXITPRESOLVE 2615 * - \ref SCIP_STAGE_PRESOLVED 2616 * - \ref SCIP_STAGE_INITSOLVE 2617 * - \ref SCIP_STAGE_SOLVING 2618 * - \ref SCIP_STAGE_SOLVED 2619 */ 2620 SCIP_RETCODE SCIPgetSolVarsData( 2621 SCIP* scip, /**< SCIP data structure */ 2622 SCIP_SOL* sol, /**< primal solution that selects the problem space, NULL for current solution */ 2623 SCIP_VAR*** vars, /**< pointer to store variables array or NULL if not needed */ 2624 int* nvars, /**< pointer to store number of variables or NULL if not needed */ 2625 int* nbinvars, /**< pointer to store number of binary variables or NULL if not needed */ 2626 int* nintvars, /**< pointer to store number of integer variables or NULL if not needed */ 2627 int* nimplvars, /**< pointer to store number of implicit integral vars or NULL if not needed */ 2628 int* ncontvars /**< pointer to store number of continuous variables or NULL if not needed */ 2629 ) 2630 { 2631 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetSolVarsData", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 2632 2633 if( scip->set->stage == SCIP_STAGE_PROBLEM || (sol != NULL && SCIPsolIsOriginal(sol)) ) 2634 { 2635 if( vars != NULL ) 2636 *vars = scip->origprob->vars; 2637 if( nvars != NULL ) 2638 *nvars = scip->origprob->nvars; 2639 if( nbinvars != NULL ) 2640 *nbinvars = scip->origprob->nbinvars; 2641 if( nintvars != NULL ) 2642 *nintvars = scip->origprob->nintvars; 2643 if( nimplvars != NULL ) 2644 *nimplvars = scip->origprob->nimplvars; 2645 if( ncontvars != NULL ) 2646 *ncontvars = scip->origprob->ncontvars; 2647 } 2648 else 2649 { 2650 if( vars != NULL ) 2651 *vars = scip->transprob->vars; 2652 if( nvars != NULL ) 2653 *nvars = scip->transprob->nvars; 2654 if( nbinvars != NULL ) 2655 *nbinvars = scip->transprob->nbinvars; 2656 if( nintvars != NULL ) 2657 *nintvars = scip->transprob->nintvars; 2658 if( nimplvars != NULL ) 2659 *nimplvars = scip->transprob->nimplvars; 2660 if( ncontvars != NULL ) 2661 *ncontvars = scip->transprob->ncontvars; 2662 } 2663 2664 return SCIP_OKAY; 2665 } 2666 2667 /** returns variable of given name in the problem, or NULL if not existing 2668 * 2669 * @return variable of given name in the problem, or NULL if not existing 2670 * 2671 * @pre This method can be called if @p scip is in one of the following stages: 2672 * - \ref SCIP_STAGE_PROBLEM 2673 * - \ref SCIP_STAGE_TRANSFORMING 2674 * - \ref SCIP_STAGE_TRANSFORMED 2675 * - \ref SCIP_STAGE_INITPRESOLVE 2676 * - \ref SCIP_STAGE_PRESOLVING 2677 * - \ref SCIP_STAGE_EXITPRESOLVE 2678 * - \ref SCIP_STAGE_PRESOLVED 2679 * - \ref SCIP_STAGE_INITSOLVE 2680 * - \ref SCIP_STAGE_SOLVING 2681 * - \ref SCIP_STAGE_SOLVED 2682 * - \ref SCIP_STAGE_EXITSOLVE 2683 * - \ref SCIP_STAGE_FREETRANS 2684 */ 2685 SCIP_VAR* SCIPfindVar( 2686 SCIP* scip, /**< SCIP data structure */ 2687 const char* name /**< name of variable to find */ 2688 ) 2689 { 2690 SCIP_VAR* var; 2691 2692 assert(name != NULL); 2693 2694 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPfindVar", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) ); 2695 2696 switch( scip->set->stage ) 2697 { 2698 case SCIP_STAGE_PROBLEM: 2699 return SCIPprobFindVar(scip->origprob, name); 2700 2701 case SCIP_STAGE_TRANSFORMING: 2702 case SCIP_STAGE_TRANSFORMED: 2703 case SCIP_STAGE_INITPRESOLVE: 2704 case SCIP_STAGE_PRESOLVING: 2705 case SCIP_STAGE_EXITPRESOLVE: 2706 case SCIP_STAGE_PRESOLVED: 2707 case SCIP_STAGE_INITSOLVE: 2708 case SCIP_STAGE_SOLVING: 2709 case SCIP_STAGE_SOLVED: 2710 case SCIP_STAGE_EXITSOLVE: 2711 case SCIP_STAGE_FREETRANS: 2712 var = SCIPprobFindVar(scip->transprob, name); 2713 if( var == NULL ) 2714 return SCIPprobFindVar(scip->origprob, name); 2715 else 2716 return var; 2717 2718 default: 2719 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage); 2720 SCIPABORT(); 2721 return NULL; /*lint !e527*/ 2722 } /*lint !e788*/ 2723 } 2724 2725 /** returns TRUE iff all potential variables exist in the problem, and FALSE, if there may be additional variables, 2726 * that will be added in pricing and improve the objective value 2727 * 2728 * @return TRUE, if all potential variables exist in the problem; FALSE, otherwise 2729 * 2730 * @pre This method can be called if @p scip is in one of the following stages: 2731 * - \ref SCIP_STAGE_TRANSFORMING 2732 * - \ref SCIP_STAGE_TRANSFORMED 2733 * - \ref SCIP_STAGE_INITPRESOLVE 2734 * - \ref SCIP_STAGE_PRESOLVING 2735 * - \ref SCIP_STAGE_EXITPRESOLVE 2736 * - \ref SCIP_STAGE_PRESOLVED 2737 * - \ref SCIP_STAGE_INITSOLVE 2738 * - \ref SCIP_STAGE_SOLVING 2739 * - \ref SCIP_STAGE_SOLVED 2740 * - \ref SCIP_STAGE_EXITSOLVE 2741 * - \ref SCIP_STAGE_FREETRANS 2742 */ 2743 SCIP_Bool SCIPallVarsInProb( 2744 SCIP* scip /**< SCIP data structure */ 2745 ) 2746 { 2747 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPallVarsInProb", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) ); 2748 2749 return (scip->set->nactivepricers == 0); 2750 } 2751 2752 /** adds constraint to the problem; if constraint is only valid locally, it is added to the local subproblem of the 2753 * current node (and all of its subnodes); otherwise it is added to the global problem; 2754 * if a local constraint is added at the root node, it is automatically upgraded into a global constraint 2755 * 2756 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 2757 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 2758 * 2759 * @pre This method can be called if @p scip is in one of the following stages: 2760 * - \ref SCIP_STAGE_PROBLEM 2761 * - \ref SCIP_STAGE_TRANSFORMED 2762 * - \ref SCIP_STAGE_INITPRESOLVE 2763 * - \ref SCIP_STAGE_PRESOLVING 2764 * - \ref SCIP_STAGE_EXITPRESOLVE 2765 * - \ref SCIP_STAGE_PRESOLVED 2766 * - \ref SCIP_STAGE_INITSOLVE 2767 * - \ref SCIP_STAGE_SOLVING 2768 * - \ref SCIP_STAGE_EXITSOLVE 2769 */ 2770 SCIP_RETCODE SCIPaddCons( 2771 SCIP* scip, /**< SCIP data structure */ 2772 SCIP_CONS* cons /**< constraint to add */ 2773 ) 2774 { 2775 assert(cons != NULL); 2776 2777 SCIP_CALL( SCIPcheckStage(scip, "SCIPaddCons", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE) ); 2778 2779 switch( scip->set->stage ) 2780 { 2781 case SCIP_STAGE_PROBLEM: 2782 { 2783 SCIP_CALL( SCIPprobAddCons(scip->origprob, scip->set, scip->stat, cons) ); 2784 2785 if( scip->set->reopt_enable ) 2786 { 2787 SCIP_CALL( SCIPreoptAddCons(scip->reopt, scip->set, scip->mem->probmem, cons) ); 2788 } 2789 } 2790 return SCIP_OKAY; 2791 2792 case SCIP_STAGE_TRANSFORMED: 2793 SCIP_CALL( SCIPprobAddCons(scip->transprob, scip->set, scip->stat, cons) ); 2794 return SCIP_OKAY; 2795 2796 case SCIP_STAGE_INITPRESOLVE: 2797 case SCIP_STAGE_PRESOLVING: 2798 case SCIP_STAGE_EXITPRESOLVE: 2799 case SCIP_STAGE_PRESOLVED: 2800 case SCIP_STAGE_INITSOLVE: 2801 case SCIP_STAGE_SOLVING: 2802 assert( SCIPtreeGetCurrentDepth(scip->tree) >= 0 || scip->set->stage == SCIP_STAGE_PRESOLVED 2803 || scip->set->stage == SCIP_STAGE_INITSOLVE ); 2804 if( SCIPtreeGetCurrentDepth(scip->tree) <= SCIPtreeGetEffectiveRootDepth(scip->tree) ) 2805 SCIPconsSetLocal(cons, FALSE); 2806 if( SCIPconsIsGlobal(cons) ) 2807 { 2808 SCIP_CALL( SCIPprobAddCons(scip->transprob, scip->set, scip->stat, cons) ); 2809 } 2810 else 2811 { 2812 assert(SCIPtreeGetCurrentDepth(scip->tree) > SCIPtreeGetEffectiveRootDepth(scip->tree)); 2813 SCIP_CALL( SCIPnodeAddCons(SCIPtreeGetCurrentNode(scip->tree), scip->mem->probmem, scip->set, scip->stat, 2814 scip->tree, cons) ); 2815 } 2816 return SCIP_OKAY; 2817 2818 case SCIP_STAGE_EXITSOLVE: 2819 SCIP_CALL( SCIPprobAddCons(scip->transprob, scip->set, scip->stat, cons) ); 2820 return SCIP_OKAY; 2821 2822 default: 2823 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage); 2824 return SCIP_INVALIDCALL; 2825 } /*lint !e788*/ 2826 } 2827 2828 /** globally removes constraint from all subproblems; removes constraint from the constraint set change data of the 2829 * node, where it was added, or from the problem, if it was a problem constraint 2830 * 2831 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 2832 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 2833 * 2834 * @pre This method can be called if @p scip is in one of the following stages: 2835 * - \ref SCIP_STAGE_PROBLEM 2836 * - \ref SCIP_STAGE_INITPRESOLVE 2837 * - \ref SCIP_STAGE_PRESOLVING 2838 * - \ref SCIP_STAGE_EXITPRESOLVE 2839 * - \ref SCIP_STAGE_INITSOLVE 2840 * - \ref SCIP_STAGE_SOLVING 2841 * - \ref SCIP_STAGE_EXITSOLVE 2842 */ 2843 SCIP_RETCODE SCIPdelCons( 2844 SCIP* scip, /**< SCIP data structure */ 2845 SCIP_CONS* cons /**< constraint to delete */ 2846 ) 2847 { 2848 assert(cons != NULL); 2849 2850 SCIP_CALL( SCIPcheckStage(scip, "SCIPdelCons", FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE) ); 2851 2852 switch( scip->set->stage ) 2853 { 2854 case SCIP_STAGE_PROBLEM: 2855 assert(cons->addconssetchg == NULL); 2856 SCIP_CALL( SCIPconsDelete(cons, scip->mem->probmem, scip->set, scip->stat, scip->origprob, scip->reopt) ); 2857 return SCIP_OKAY; 2858 2859 /* only added constraints can be removed in (de-)initialization process of presolving, otherwise the reduction 2860 * might be wrong 2861 */ 2862 case SCIP_STAGE_INITPRESOLVE: 2863 case SCIP_STAGE_EXITPRESOLVE: 2864 assert(SCIPconsIsAdded(cons)); 2865 /*lint -fallthrough*/ 2866 2867 case SCIP_STAGE_PRESOLVING: 2868 case SCIP_STAGE_INITSOLVE: 2869 case SCIP_STAGE_SOLVING: 2870 case SCIP_STAGE_EXITSOLVE: 2871 SCIP_CALL( SCIPconsDelete(cons, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->reopt) ); 2872 return SCIP_OKAY; 2873 2874 default: 2875 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage); 2876 return SCIP_INVALIDCALL; 2877 } /*lint !e788*/ 2878 } 2879 2880 /** returns original constraint of given name in the problem, or NULL if not existing 2881 * 2882 * @return original constraint of given name in the problem, or NULL if not existing 2883 * 2884 * @pre This method can be called if @p scip is in one of the following stages: 2885 * - \ref SCIP_STAGE_PROBLEM 2886 * - \ref SCIP_STAGE_TRANSFORMING 2887 * - \ref SCIP_STAGE_TRANSFORMED 2888 * - \ref SCIP_STAGE_INITPRESOLVE 2889 * - \ref SCIP_STAGE_PRESOLVING 2890 * - \ref SCIP_STAGE_EXITPRESOLVE 2891 * - \ref SCIP_STAGE_PRESOLVED 2892 * - \ref SCIP_STAGE_INITSOLVE 2893 * - \ref SCIP_STAGE_SOLVING 2894 * - \ref SCIP_STAGE_SOLVED 2895 * - \ref SCIP_STAGE_EXITSOLVE 2896 * - \ref SCIP_STAGE_FREETRANS 2897 */ 2898 SCIP_CONS* SCIPfindOrigCons( 2899 SCIP* scip, /**< SCIP data structure */ 2900 const char* name /**< name of constraint to find */ 2901 ) 2902 { 2903 assert(name != NULL); 2904 2905 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPfindOrigCons", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) ); 2906 2907 switch( scip->set->stage ) 2908 { 2909 case SCIP_STAGE_PROBLEM: 2910 case SCIP_STAGE_TRANSFORMING: 2911 case SCIP_STAGE_TRANSFORMED: 2912 case SCIP_STAGE_INITPRESOLVE: 2913 case SCIP_STAGE_PRESOLVING: 2914 case SCIP_STAGE_EXITPRESOLVE: 2915 case SCIP_STAGE_PRESOLVED: 2916 case SCIP_STAGE_SOLVING: 2917 case SCIP_STAGE_SOLVED: 2918 case SCIP_STAGE_EXITSOLVE: 2919 case SCIP_STAGE_FREETRANS: 2920 return SCIPprobFindCons(scip->origprob, name); 2921 2922 default: 2923 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage); 2924 SCIPABORT(); 2925 return NULL; /*lint !e527*/ 2926 } /*lint !e788*/ 2927 } 2928 2929 /** returns constraint of given name in the problem, or NULL if not existing 2930 * 2931 * @return constraint of given name in the problem, or NULL if not existing 2932 * 2933 * @pre This method can be called if @p scip is in one of the following stages: 2934 * - \ref SCIP_STAGE_PROBLEM 2935 * - \ref SCIP_STAGE_TRANSFORMING 2936 * - \ref SCIP_STAGE_TRANSFORMED 2937 * - \ref SCIP_STAGE_INITPRESOLVE 2938 * - \ref SCIP_STAGE_PRESOLVING 2939 * - \ref SCIP_STAGE_EXITPRESOLVE 2940 * - \ref SCIP_STAGE_PRESOLVED 2941 * - \ref SCIP_STAGE_INITSOLVE 2942 * - \ref SCIP_STAGE_SOLVING 2943 * - \ref SCIP_STAGE_SOLVED 2944 * - \ref SCIP_STAGE_EXITSOLVE 2945 * - \ref SCIP_STAGE_FREETRANS 2946 */ 2947 SCIP_CONS* SCIPfindCons( 2948 SCIP* scip, /**< SCIP data structure */ 2949 const char* name /**< name of constraint to find */ 2950 ) 2951 { 2952 SCIP_CONS* cons; 2953 2954 assert(name != NULL); 2955 2956 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPfindCons", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) ); 2957 2958 switch( scip->set->stage ) 2959 { 2960 case SCIP_STAGE_PROBLEM: 2961 return SCIPprobFindCons(scip->origprob, name); 2962 2963 case SCIP_STAGE_TRANSFORMING: 2964 case SCIP_STAGE_TRANSFORMED: 2965 case SCIP_STAGE_INITPRESOLVE: 2966 case SCIP_STAGE_PRESOLVING: 2967 case SCIP_STAGE_EXITPRESOLVE: 2968 case SCIP_STAGE_PRESOLVED: 2969 case SCIP_STAGE_SOLVING: 2970 case SCIP_STAGE_SOLVED: 2971 case SCIP_STAGE_EXITSOLVE: 2972 case SCIP_STAGE_FREETRANS: 2973 cons = SCIPprobFindCons(scip->transprob, name); 2974 if( cons == NULL ) 2975 return SCIPprobFindCons(scip->origprob, name); 2976 else 2977 return cons; 2978 2979 default: 2980 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage); 2981 SCIPABORT(); 2982 return NULL; /*lint !e527*/ 2983 } /*lint !e788*/ 2984 } 2985 2986 /** gets number of upgraded constraints 2987 * 2988 * @return number of upgraded constraints 2989 * 2990 * @pre This method can be called if @p scip is in one of the following stages: 2991 * - \ref SCIP_STAGE_PROBLEM 2992 * - \ref SCIP_STAGE_TRANSFORMED 2993 * - \ref SCIP_STAGE_INITPRESOLVE 2994 * - \ref SCIP_STAGE_PRESOLVING 2995 * - \ref SCIP_STAGE_PRESOLVED 2996 * - \ref SCIP_STAGE_EXITPRESOLVE 2997 * - \ref SCIP_STAGE_SOLVING 2998 * - \ref SCIP_STAGE_SOLVED 2999 */ 3000 int SCIPgetNUpgrConss( 3001 SCIP* scip /**< SCIP data structure */ 3002 ) 3003 { 3004 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNUpgrConss", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 3005 3006 switch( scip->set->stage ) 3007 { 3008 case SCIP_STAGE_PROBLEM: 3009 return 0; 3010 3011 case SCIP_STAGE_TRANSFORMED: 3012 case SCIP_STAGE_INITPRESOLVE: 3013 case SCIP_STAGE_PRESOLVING: 3014 case SCIP_STAGE_EXITPRESOLVE: 3015 case SCIP_STAGE_PRESOLVED: 3016 case SCIP_STAGE_SOLVING: 3017 case SCIP_STAGE_SOLVED: 3018 return scip->stat->npresolupgdconss; 3019 3020 default: 3021 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage); 3022 SCIPABORT(); 3023 return 0; /*lint !e527*/ 3024 } /*lint !e788*/ 3025 } 3026 3027 /** gets total number of globally valid constraints currently in the problem 3028 * 3029 * @return total number of globally valid constraints currently in the problem 3030 * 3031 * @pre This method can be called if @p scip is in one of the following stages: 3032 * - \ref SCIP_STAGE_PROBLEM 3033 * - \ref SCIP_STAGE_TRANSFORMED 3034 * - \ref SCIP_STAGE_INITPRESOLVE 3035 * - \ref SCIP_STAGE_PRESOLVING 3036 * - \ref SCIP_STAGE_EXITPRESOLVE 3037 * - \ref SCIP_STAGE_PRESOLVED 3038 * - \ref SCIP_STAGE_INITSOLVE 3039 * - \ref SCIP_STAGE_SOLVING 3040 * - \ref SCIP_STAGE_SOLVED 3041 */ 3042 int SCIPgetNConss( 3043 SCIP* scip /**< SCIP data structure */ 3044 ) 3045 { 3046 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNConss", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 3047 3048 switch( scip->set->stage ) 3049 { 3050 case SCIP_STAGE_PROBLEM: 3051 return scip->origprob->nconss; 3052 3053 case SCIP_STAGE_TRANSFORMED: 3054 case SCIP_STAGE_INITPRESOLVE: 3055 case SCIP_STAGE_PRESOLVING: 3056 case SCIP_STAGE_EXITPRESOLVE: 3057 case SCIP_STAGE_PRESOLVED: 3058 case SCIP_STAGE_INITSOLVE: 3059 case SCIP_STAGE_SOLVING: 3060 case SCIP_STAGE_SOLVED: 3061 return scip->transprob->nconss; 3062 3063 default: 3064 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage); 3065 SCIPABORT(); 3066 return 0; /*lint !e527*/ 3067 } /*lint !e788*/ 3068 } 3069 3070 /** gets array of globally valid constraints currently in the problem 3071 * 3072 * @return array of globally valid constraints currently in the problem 3073 * 3074 * @pre This method can be called if @p scip is in one of the following stages: 3075 * - \ref SCIP_STAGE_PROBLEM 3076 * - \ref SCIP_STAGE_TRANSFORMED 3077 * - \ref SCIP_STAGE_INITPRESOLVE 3078 * - \ref SCIP_STAGE_PRESOLVING 3079 * - \ref SCIP_STAGE_EXITPRESOLVE 3080 * - \ref SCIP_STAGE_PRESOLVED 3081 * - \ref SCIP_STAGE_INITSOLVE 3082 * - \ref SCIP_STAGE_SOLVING 3083 * - \ref SCIP_STAGE_SOLVED 3084 * 3085 * @warning If your are using the method SCIPaddCons(), it can happen that the internal constraint array (which is 3086 * accessed via this method) gets resized. This can invalid the pointer which is returned by this method. 3087 */ 3088 SCIP_CONS** SCIPgetConss( 3089 SCIP* scip /**< SCIP data structure */ 3090 ) 3091 { 3092 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetConss", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 3093 3094 switch( scip->set->stage ) 3095 { 3096 case SCIP_STAGE_PROBLEM: 3097 return scip->origprob->conss; 3098 3099 case SCIP_STAGE_TRANSFORMED: 3100 case SCIP_STAGE_INITPRESOLVE: 3101 case SCIP_STAGE_PRESOLVING: 3102 case SCIP_STAGE_EXITPRESOLVE: 3103 case SCIP_STAGE_PRESOLVED: 3104 case SCIP_STAGE_INITSOLVE: 3105 case SCIP_STAGE_SOLVING: 3106 case SCIP_STAGE_SOLVED: 3107 return scip->transprob->conss; 3108 3109 default: 3110 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage); 3111 SCIPABORT(); 3112 return NULL; /*lint !e527*/ 3113 } /*lint !e788*/ 3114 } 3115 3116 /** gets total number of constraints in the original problem 3117 * 3118 * @return total number of constraints in the original problem 3119 * 3120 * @pre This method can be called if @p scip is in one of the following stages: 3121 * - \ref SCIP_STAGE_PROBLEM 3122 * - \ref SCIP_STAGE_TRANSFORMING 3123 * - \ref SCIP_STAGE_TRANSFORMED 3124 * - \ref SCIP_STAGE_INITPRESOLVE 3125 * - \ref SCIP_STAGE_PRESOLVING 3126 * - \ref SCIP_STAGE_EXITPRESOLVE 3127 * - \ref SCIP_STAGE_PRESOLVED 3128 * - \ref SCIP_STAGE_INITSOLVE 3129 * - \ref SCIP_STAGE_SOLVING 3130 * - \ref SCIP_STAGE_SOLVED 3131 * - \ref SCIP_STAGE_EXITSOLVE 3132 * - \ref SCIP_STAGE_FREETRANS 3133 */ 3134 int SCIPgetNOrigConss( 3135 SCIP* scip /**< SCIP data structure */ 3136 ) 3137 { 3138 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNOrigConss", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) ); 3139 3140 return scip->origprob->nconss; 3141 } 3142 3143 /** gets array of constraints in the original problem 3144 * 3145 * @return array of constraints in the original problem 3146 * 3147 * @pre This method can be called if @p scip is in one of the following stages: 3148 * - \ref SCIP_STAGE_PROBLEM 3149 * - \ref SCIP_STAGE_TRANSFORMING 3150 * - \ref SCIP_STAGE_TRANSFORMED 3151 * - \ref SCIP_STAGE_INITPRESOLVE 3152 * - \ref SCIP_STAGE_PRESOLVING 3153 * - \ref SCIP_STAGE_EXITPRESOLVE 3154 * - \ref SCIP_STAGE_PRESOLVED 3155 * - \ref SCIP_STAGE_INITSOLVE 3156 * - \ref SCIP_STAGE_SOLVING 3157 * - \ref SCIP_STAGE_SOLVED 3158 * - \ref SCIP_STAGE_EXITSOLVE 3159 * - \ref SCIP_STAGE_FREETRANS 3160 */ 3161 SCIP_CONS** SCIPgetOrigConss( 3162 SCIP* scip /**< SCIP data structure */ 3163 ) 3164 { 3165 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetOrigConss", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) ); 3166 3167 return scip->origprob->conss; 3168 } 3169 3170 /** computes the number of check constraint in the current node (loop over all constraint handler and cumulates the 3171 * number of check constraints) 3172 * 3173 * @return returns the number of check constraints 3174 * 3175 * @pre This method can be called if @p scip is in one of the following stages: 3176 * - \ref SCIP_STAGE_TRANSFORMED 3177 * - \ref SCIP_STAGE_INITPRESOLVE 3178 * - \ref SCIP_STAGE_PRESOLVING 3179 * - \ref SCIP_STAGE_EXITPRESOLVE 3180 * - \ref SCIP_STAGE_PRESOLVED 3181 * - \ref SCIP_STAGE_INITSOLVE 3182 * - \ref SCIP_STAGE_SOLVING 3183 */ 3184 int SCIPgetNCheckConss( 3185 SCIP* scip /**< SCIP data structure */ 3186 ) 3187 { 3188 SCIP_CONSHDLR** conshdlrs; 3189 int nconshdlrs; 3190 int ncheckconss; 3191 int c; 3192 3193 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNCheckConss", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 3194 3195 nconshdlrs = SCIPgetNConshdlrs(scip); 3196 conshdlrs = SCIPgetConshdlrs(scip); 3197 assert(conshdlrs != NULL); 3198 3199 ncheckconss = 0; 3200 3201 /* loop over all constraint handler and collect the number of constraints which need to be checked */ 3202 for( c = 0; c < nconshdlrs; ++c ) 3203 { 3204 assert(conshdlrs[c] != NULL); 3205 ncheckconss += SCIPconshdlrGetNCheckConss(conshdlrs[c]); 3206 } 3207 3208 return ncheckconss; 3209 } 3210 3211 /* 3212 * local subproblem methods 3213 */ 3214 3215 /** adds a conflict to a given node or globally to the problem if @p node == NULL. 3216 * 3217 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 3218 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 3219 * 3220 * @pre this method can be called in one of the following stages of the SCIP solving process: 3221 * - \ref SCIP_STAGE_INITPRESOLVE 3222 * - \ref SCIP_STAGE_PRESOLVING 3223 * - \ref SCIP_STAGE_EXITPRESOLVE 3224 * - \ref SCIP_STAGE_SOLVING 3225 * 3226 * @note this method will release the constraint 3227 */ 3228 SCIP_RETCODE SCIPaddConflict( 3229 SCIP* scip, /**< SCIP data structure */ 3230 SCIP_NODE* node, /**< node to add conflict (or NULL if global) */ 3231 SCIP_CONS* cons, /**< constraint representing the conflict */ 3232 SCIP_NODE* validnode, /**< node at whichaddConf the constraint is valid (or NULL) */ 3233 SCIP_CONFTYPE conftype, /**< type of the conflict */ 3234 SCIP_Bool iscutoffinvolved /**< is a cutoff bound involved in this conflict */ 3235 ) 3236 { 3237 SCIP_Real primalbound; 3238 3239 assert(scip != NULL); 3240 assert(cons != NULL); 3241 assert(scip->conflictstore != NULL); 3242 assert(conftype != SCIP_CONFTYPE_BNDEXCEEDING || iscutoffinvolved); 3243 3244 SCIP_CALL( SCIPcheckStage(scip, "SCIPaddConflict", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 3245 3246 if( iscutoffinvolved ) 3247 primalbound = SCIPgetCutoffbound(scip); 3248 else 3249 primalbound = -SCIPinfinity(scip); 3250 3251 /* add a global conflict */ 3252 if( node == NULL ) 3253 { 3254 SCIP_CALL( SCIPaddCons(scip, cons) ); 3255 } 3256 /* add a local conflict */ 3257 else 3258 { 3259 SCIP_CALL( SCIPaddConsNode(scip, node, cons, validnode) ); 3260 } 3261 3262 if( node == NULL || SCIPnodeGetType(node) != SCIP_NODETYPE_PROBINGNODE ) 3263 { 3264 /* add the conflict to the conflict store */ 3265 SCIP_CALL( SCIPconflictstoreAddConflict(scip->conflictstore, scip->mem->probmem, scip->set, scip->stat, scip->tree, 3266 scip->transprob, scip->reopt, cons, conftype, iscutoffinvolved, primalbound) ); 3267 } 3268 3269 /* mark constraint to be a conflict */ 3270 SCIPconsMarkConflict(cons); 3271 3272 SCIP_CALL( SCIPreleaseCons(scip, &cons) ); 3273 3274 return SCIP_OKAY; 3275 } 3276 3277 /** tries to remove conflicts depending on an old cutoff bound if the improvement of the new incumbent is good enough 3278 * 3279 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 3280 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 3281 * 3282 * @pre this method can be called in one of the following stages of the SCIP solving process: 3283 * - \ref SCIP_STAGE_PRESOLVING 3284 * - \ref SCIP_STAGE_SOLVING 3285 */ 3286 SCIP_RETCODE SCIPclearConflictStore( 3287 SCIP* scip, /**< SCIP data structure */ 3288 SCIP_EVENT* event /**< event data */ 3289 ) 3290 { 3291 assert(scip != NULL); 3292 assert(event != NULL); 3293 assert(SCIPeventGetType(event) == SCIP_EVENTTYPE_BESTSOLFOUND); 3294 assert(SCIPeventGetSol(event) != NULL); 3295 3296 SCIP_CALL( SCIPcheckStage(scip, "SCIPclearConflictStore", FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 3297 3298 SCIP_CALL( SCIPconflictstoreCleanNewIncumbent(scip->conflictstore, scip->set, scip->stat, scip->mem->probmem, 3299 scip->transprob, scip->reopt, scip->primal->cutoffbound) ); 3300 3301 return SCIP_OKAY; 3302 } 3303 3304 /** adds constraint to the given node (and all of its subnodes), even if it is a global constraint; 3305 * It is sometimes desirable to add the constraint to a more local node (i.e., a node of larger depth) even if 3306 * the constraint is also valid higher in the tree, for example, if one wants to produce a constraint which is 3307 * only active in a small part of the tree although it is valid in a larger part. 3308 * In this case, one should pass the more global node where the constraint is valid as "validnode". 3309 * Note that the same constraint cannot be added twice to the branching tree with different "validnode" parameters. 3310 * If the constraint is valid at the same node as it is inserted (the usual case), one should pass NULL as "validnode". 3311 * If the "validnode" is the root node, it is automatically upgraded into a global constraint, but still only added to 3312 * the given node. If a local constraint is added to the root node, it is added to the global problem instead. 3313 * 3314 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 3315 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 3316 * 3317 * @pre this method can be called in one of the following stages of the SCIP solving process: 3318 * - \ref SCIP_STAGE_INITPRESOLVE 3319 * - \ref SCIP_STAGE_PRESOLVING 3320 * - \ref SCIP_STAGE_EXITPRESOLVE 3321 * - \ref SCIP_STAGE_SOLVING 3322 */ 3323 SCIP_RETCODE SCIPaddConsNode( 3324 SCIP* scip, /**< SCIP data structure */ 3325 SCIP_NODE* node, /**< node to add constraint to */ 3326 SCIP_CONS* cons, /**< constraint to add */ 3327 SCIP_NODE* validnode /**< node at which the constraint is valid, or NULL */ 3328 ) 3329 { 3330 assert(cons != NULL); 3331 assert(node != NULL); 3332 3333 SCIP_CALL( SCIPcheckStage(scip, "SCIPaddConsNode", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 3334 3335 if( validnode != NULL ) 3336 { 3337 int validdepth; 3338 3339 validdepth = SCIPnodeGetDepth(validnode); 3340 if( validdepth > SCIPnodeGetDepth(node) ) 3341 { 3342 SCIPerrorMessage("cannot add constraint <%s> valid in depth %d to a node of depth %d\n", 3343 SCIPconsGetName(cons), validdepth, SCIPnodeGetDepth(node)); 3344 return SCIP_INVALIDDATA; 3345 } 3346 if( cons->validdepth != -1 && cons->validdepth != validdepth ) 3347 { 3348 SCIPerrorMessage("constraint <%s> is already marked to be valid in depth %d - cannot mark it to be valid in depth %d\n", 3349 SCIPconsGetName(cons), cons->validdepth, validdepth); 3350 return SCIP_INVALIDDATA; 3351 } 3352 if( validdepth <= SCIPtreeGetEffectiveRootDepth(scip->tree) ) 3353 SCIPconsSetLocal(cons, FALSE); 3354 else 3355 cons->validdepth = validdepth; 3356 } 3357 3358 if( SCIPnodeGetDepth(node) <= SCIPtreeGetEffectiveRootDepth(scip->tree) ) 3359 { 3360 SCIPconsSetLocal(cons, FALSE); 3361 SCIP_CALL( SCIPprobAddCons(scip->transprob, scip->set, scip->stat, cons) ); 3362 } 3363 else 3364 { 3365 SCIP_CALL( SCIPnodeAddCons(node, scip->mem->probmem, scip->set, scip->stat, scip->tree, cons) ); 3366 } 3367 3368 return SCIP_OKAY; 3369 } 3370 3371 /** adds constraint locally to the current node (and all of its subnodes), even if it is a global constraint; 3372 * It is sometimes desirable to add the constraint to a more local node (i.e., a node of larger depth) even if 3373 * the constraint is also valid higher in the tree, for example, if one wants to produce a constraint which is 3374 * only active in a small part of the tree although it is valid in a larger part. 3375 * 3376 * If the constraint is valid at the same node as it is inserted (the usual case), one should pass NULL as "validnode". 3377 * If the "validnode" is the root node, it is automatically upgraded into a global constraint, but still only added to 3378 * the given node. If a local constraint is added to the root node, it is added to the global problem instead. 3379 * 3380 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 3381 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 3382 * 3383 * @pre this method can be called in one of the following stages of the SCIP solving process: 3384 * - \ref SCIP_STAGE_INITPRESOLVE 3385 * - \ref SCIP_STAGE_PRESOLVING 3386 * - \ref SCIP_STAGE_EXITPRESOLVE 3387 * - \ref SCIP_STAGE_SOLVING 3388 * 3389 * @note The same constraint cannot be added twice to the branching tree with different "validnode" parameters. This is 3390 * the case due to internal data structures and performance issues. In such a case you should try to realize your 3391 * issue using the method SCIPdisableCons() and SCIPenableCons() and control these via the event system of SCIP. 3392 */ 3393 SCIP_RETCODE SCIPaddConsLocal( 3394 SCIP* scip, /**< SCIP data structure */ 3395 SCIP_CONS* cons, /**< constraint to add */ 3396 SCIP_NODE* validnode /**< node at which the constraint is valid, or NULL */ 3397 ) 3398 { 3399 assert(cons != NULL); 3400 3401 SCIP_CALL( SCIPcheckStage(scip, "SCIPaddConsLocal", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 3402 3403 SCIP_CALL( SCIPaddConsNode(scip, SCIPtreeGetCurrentNode(scip->tree), cons, validnode) ); 3404 3405 return SCIP_OKAY; 3406 } 3407 3408 /** disables constraint's separation, enforcing, and propagation capabilities at the given node (and all subnodes); 3409 * if the method is called at the root node, the constraint is globally deleted from the problem; 3410 * the constraint deletion is being remembered at the given node, s.t. after leaving the node's subtree, the constraint 3411 * is automatically enabled again, and after entering the node's subtree, it is automatically disabled; 3412 * this may improve performance because redundant checks on this constraint are avoided, but it consumes memory; 3413 * alternatively, use SCIPdisableCons() 3414 * 3415 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 3416 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 3417 * 3418 * @pre this method can be called in one of the following stages of the SCIP solving process: 3419 * - \ref SCIP_STAGE_INITPRESOLVE 3420 * - \ref SCIP_STAGE_PRESOLVING 3421 * - \ref SCIP_STAGE_EXITPRESOLVE 3422 * - \ref SCIP_STAGE_SOLVING 3423 */ 3424 SCIP_RETCODE SCIPdelConsNode( 3425 SCIP* scip, /**< SCIP data structure */ 3426 SCIP_NODE* node, /**< node to disable constraint in */ 3427 SCIP_CONS* cons /**< constraint to locally delete */ 3428 ) 3429 { 3430 assert(cons != NULL); 3431 3432 SCIP_CALL( SCIPcheckStage(scip, "SCIPdelConsNode", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 3433 3434 /* only added constraints can be removed in (de-)initialization process of presolving, otherwise the reduction 3435 * might be wrong 3436 */ 3437 if( scip->set->stage == SCIP_STAGE_INITPRESOLVE || scip->set->stage == SCIP_STAGE_EXITPRESOLVE ) 3438 assert(SCIPconsIsAdded(cons)); 3439 3440 if( SCIPnodeGetDepth(node) <= SCIPtreeGetEffectiveRootDepth(scip->tree) ) 3441 { 3442 SCIP_CALL( SCIPconsDelete(cons, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->reopt) ); 3443 } 3444 else 3445 { 3446 SCIP_CALL( SCIPnodeDelCons(node, scip->mem->probmem, scip->set, scip->stat, scip->tree, cons) ); 3447 } 3448 3449 return SCIP_OKAY; 3450 } 3451 3452 /** disables constraint's separation, enforcing, and propagation capabilities at the current node (and all subnodes); 3453 * if the method is called during problem modification or at the root node, the constraint is globally deleted from 3454 * the problem; 3455 * the constraint deletion is being remembered at the current node, s.t. after leaving the current subtree, the 3456 * constraint is automatically enabled again, and after reentering the current node's subtree, it is automatically 3457 * disabled again; 3458 * this may improve performance because redundant checks on this constraint are avoided, but it consumes memory; 3459 * alternatively, use SCIPdisableCons() 3460 * 3461 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 3462 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 3463 * 3464 * @pre this method can be called in one of the following stages of the SCIP solving process: 3465 * - \ref SCIP_STAGE_PROBLEM 3466 * - \ref SCIP_STAGE_INITPRESOLVE 3467 * - \ref SCIP_STAGE_PRESOLVING 3468 * - \ref SCIP_STAGE_EXITPRESOLVE 3469 * - \ref SCIP_STAGE_SOLVING 3470 * 3471 * @note SCIP stage does not get changed 3472 * 3473 */ 3474 SCIP_RETCODE SCIPdelConsLocal( 3475 SCIP* scip, /**< SCIP data structure */ 3476 SCIP_CONS* cons /**< constraint to locally delete */ 3477 ) 3478 { 3479 SCIP_NODE* node; 3480 3481 assert(cons != NULL); 3482 3483 SCIP_CALL( SCIPcheckStage(scip, "SCIPdelConsLocal", FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 3484 3485 switch( scip->set->stage ) 3486 { 3487 case SCIP_STAGE_PROBLEM: 3488 assert(cons->addconssetchg == NULL); 3489 SCIP_CALL( SCIPconsDelete(cons, scip->mem->probmem, scip->set, scip->stat, scip->origprob, scip->reopt) ); 3490 return SCIP_OKAY; 3491 3492 /* only added constraints can be removed in (de-)initialization process of presolving, otherwise the reduction 3493 * might be wrong 3494 */ 3495 case SCIP_STAGE_INITPRESOLVE: 3496 case SCIP_STAGE_EXITPRESOLVE: 3497 assert(SCIPconsIsAdded(cons)); 3498 /*lint -fallthrough*/ 3499 3500 case SCIP_STAGE_PRESOLVING: 3501 case SCIP_STAGE_SOLVING: 3502 node = SCIPtreeGetCurrentNode(scip->tree); 3503 3504 if( SCIPnodeGetDepth(node) <= SCIPtreeGetEffectiveRootDepth(scip->tree) ) 3505 { 3506 SCIP_CALL( SCIPconsDelete(cons, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->reopt) ); 3507 } 3508 else 3509 { 3510 SCIP_CALL( SCIPnodeDelCons(node, scip->mem->probmem, scip->set, scip->stat, scip->tree, cons) ); 3511 } 3512 return SCIP_OKAY; 3513 3514 default: 3515 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage); 3516 return SCIP_INVALIDCALL; 3517 } /*lint !e788*/ 3518 } 3519 3520 /** gets estimate of best primal solution w.r.t. original problem contained in current subtree 3521 * 3522 * @return estimate of best primal solution w.r.t. original problem contained in current subtree 3523 * 3524 * @pre this method can be called in one of the following stages of the SCIP solving process: 3525 * - \ref SCIP_STAGE_SOLVING 3526 */ 3527 SCIP_Real SCIPgetLocalOrigEstimate( 3528 SCIP* scip /**< SCIP data structure */ 3529 ) 3530 { 3531 SCIP_NODE* node; 3532 3533 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetLocalOrigEstimate", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 3534 3535 node = SCIPtreeGetCurrentNode(scip->tree); 3536 return node != NULL ? SCIPprobExternObjval(scip->transprob, scip->origprob, scip->set, SCIPnodeGetEstimate(node)) : SCIP_INVALID; 3537 } 3538 3539 /** gets estimate of best primal solution w.r.t. transformed problem contained in current subtree 3540 * 3541 * @return estimate of best primal solution w.r.t. transformed problem contained in current subtree 3542 * 3543 * @pre this method can be called in one of the following stages of the SCIP solving process: 3544 * - \ref SCIP_STAGE_SOLVING 3545 */ 3546 SCIP_Real SCIPgetLocalTransEstimate( 3547 SCIP* scip /**< SCIP data structure */ 3548 ) 3549 { 3550 SCIP_NODE* node; 3551 3552 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetLocalTransEstimate", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 3553 3554 node = SCIPtreeGetCurrentNode(scip->tree); 3555 3556 return node != NULL ? SCIPnodeGetEstimate(node) : SCIP_INVALID; 3557 } 3558 3559 /** gets dual bound of current node 3560 * 3561 * @return dual bound of current node 3562 * 3563 * @pre this method can be called in one of the following stages of the SCIP solving process: 3564 * - \ref SCIP_STAGE_SOLVING 3565 */ 3566 SCIP_Real SCIPgetLocalDualbound( 3567 SCIP* scip /**< SCIP data structure */ 3568 ) 3569 { 3570 SCIP_NODE* node; 3571 3572 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetLocalDualbound", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 3573 3574 node = SCIPtreeGetCurrentNode(scip->tree); 3575 return node != NULL ? SCIPprobExternObjval(scip->transprob, scip->origprob, scip->set, SCIPnodeGetLowerbound(node)) : SCIP_INVALID; 3576 } 3577 3578 /** gets lower bound of current node in transformed problem 3579 * 3580 * @return lower bound of current node in transformed problem 3581 * 3582 * @pre this method can be called in one of the following stages of the SCIP solving process: 3583 * - \ref SCIP_STAGE_SOLVING 3584 */ 3585 SCIP_Real SCIPgetLocalLowerbound( 3586 SCIP* scip /**< SCIP data structure */ 3587 ) 3588 { 3589 SCIP_NODE* node; 3590 3591 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetLocalLowerbound", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 3592 3593 node = SCIPtreeGetCurrentNode(scip->tree); 3594 3595 return node != NULL ? SCIPnodeGetLowerbound(node) : SCIP_INVALID; 3596 } 3597 3598 /** gets dual bound of given node 3599 * 3600 * @return dual bound of a given node 3601 * 3602 * @pre this method can be called in one of the following stages of the SCIP solving process: 3603 * - \ref SCIP_STAGE_SOLVING 3604 */ 3605 SCIP_Real SCIPgetNodeDualbound( 3606 SCIP* scip, /**< SCIP data structure */ 3607 SCIP_NODE* node /**< node to get dual bound for */ 3608 ) 3609 { 3610 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNodeDualbound", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 3611 3612 return SCIPprobExternObjval(scip->transprob, scip->origprob, scip->set, SCIPnodeGetLowerbound(node)); 3613 } 3614 3615 /** gets lower bound of given node in transformed problem 3616 * 3617 * @return lower bound of given node in transformed problem 3618 * 3619 * @pre this method can be called in one of the following stages of the SCIP solving process: 3620 * - \ref SCIP_STAGE_SOLVING 3621 */ 3622 SCIP_Real SCIPgetNodeLowerbound( 3623 SCIP* scip, /**< SCIP data structure */ 3624 SCIP_NODE* node /**< node to get dual bound for */ 3625 ) 3626 { 3627 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNodeLowerbound", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 3628 3629 return SCIPnodeGetLowerbound(node); 3630 } 3631 3632 /** if given value is tighter (larger for minimization, smaller for maximization) than the current node's dual bound (in 3633 * original problem space), sets the current node's dual bound to the new value 3634 * 3635 * @note the given new bound has to be a dual bound, i.e., it has to be valid for the original problem. 3636 * 3637 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 3638 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 3639 * 3640 * @pre this method can be called in one of the following stages of the SCIP solving process: 3641 * - \ref SCIP_STAGE_PROBLEM 3642 * - \ref SCIP_STAGE_PRESOLVING 3643 * - \ref SCIP_STAGE_PRESOLVED 3644 * - \ref SCIP_STAGE_SOLVING 3645 */ 3646 SCIP_RETCODE SCIPupdateLocalDualbound( 3647 SCIP* scip, /**< SCIP data structure */ 3648 SCIP_Real newbound /**< new dual bound for the node (if it's tighter than the old one) */ 3649 ) 3650 { 3651 SCIP_CALL( SCIPcheckStage(scip, "SCIPupdateLocalDualbound", FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 3652 3653 switch( scip->set->stage ) 3654 { 3655 case SCIP_STAGE_PROBLEM: 3656 /* since no root node, for which we could update the dual bound, has been create yet, update the dual bound stored in 3657 * the problem data 3658 */ 3659 SCIPprobUpdateDualbound(scip->origprob, newbound); 3660 break; 3661 3662 case SCIP_STAGE_PRESOLVING: 3663 case SCIP_STAGE_PRESOLVED: 3664 /* since no root node, for which we could update the dual bound, has been create yet, update the dual bound stored in 3665 * the problem data 3666 */ 3667 SCIPprobUpdateDualbound(scip->transprob, SCIPprobExternObjval(scip->transprob, scip->origprob, scip->set, newbound)); 3668 break; 3669 3670 case SCIP_STAGE_SOLVING: 3671 SCIP_CALL( SCIPupdateNodeLowerbound(scip, SCIPtreeGetCurrentNode(scip->tree), SCIPprobInternObjval(scip->transprob, scip->origprob, scip->set, newbound)) ); 3672 break; 3673 3674 default: 3675 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage); 3676 SCIPABORT(); 3677 return SCIP_INVALIDCALL; /*lint !e527*/ 3678 } /*lint !e788*/ 3679 3680 return SCIP_OKAY; 3681 } 3682 3683 /** if given value is larger than the current node's lower bound (in transformed problem), sets the current node's 3684 * lower bound to the new value 3685 * 3686 * @note the given new bound has to be a lower bound, i.e., it has to be valid for the transformed problem. 3687 * 3688 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 3689 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 3690 * 3691 * @pre this method can be called in one of the following stages of the SCIP solving process: 3692 * - \ref SCIP_STAGE_PRESOLVING 3693 * - \ref SCIP_STAGE_PRESOLVED 3694 * - \ref SCIP_STAGE_SOLVING 3695 */ 3696 SCIP_RETCODE SCIPupdateLocalLowerbound( 3697 SCIP* scip, /**< SCIP data structure */ 3698 SCIP_Real newbound /**< new lower bound for the node (if it's larger than the old one) */ 3699 ) 3700 { 3701 SCIP_CALL( SCIPcheckStage(scip, "SCIPupdateLocalLowerbound", FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 3702 3703 switch( scip->set->stage ) 3704 { 3705 case SCIP_STAGE_PRESOLVING: 3706 case SCIP_STAGE_PRESOLVED: 3707 /* since no root node, for which we could update the lower bound, has been created yet, update the dual bound stored 3708 * in the problem data 3709 */ 3710 SCIPprobUpdateDualbound(scip->transprob, SCIPprobExternObjval(scip->transprob, scip->origprob, scip->set, newbound)); 3711 break; 3712 3713 case SCIP_STAGE_SOLVING: 3714 SCIP_CALL( SCIPupdateNodeLowerbound(scip, SCIPtreeGetCurrentNode(scip->tree), newbound) ); 3715 break; 3716 3717 default: 3718 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage); 3719 SCIPABORT(); 3720 return SCIP_INVALIDCALL; /*lint !e527*/ 3721 } /*lint !e788*/ 3722 3723 return SCIP_OKAY; 3724 } 3725 3726 /** if given value is tighter (larger for minimization, smaller for maximization) than the node's dual bound, 3727 * sets the node's dual bound to the new value 3728 * 3729 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 3730 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 3731 * 3732 * @pre this method can be called in one of the following stages of the SCIP solving process: 3733 * - \ref SCIP_STAGE_SOLVING 3734 */ 3735 SCIP_RETCODE SCIPupdateNodeDualbound( 3736 SCIP* scip, /**< SCIP data structure */ 3737 SCIP_NODE* node, /**< node to update dual bound for */ 3738 SCIP_Real newbound /**< new dual bound for the node (if it's tighter than the old one) */ 3739 ) 3740 { 3741 SCIP_CALL( SCIPcheckStage(scip, "SCIPupdateNodeDualbound", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 3742 3743 SCIP_CALL( SCIPupdateNodeLowerbound(scip, node, SCIPprobInternObjval(scip->transprob, scip->origprob, scip->set, newbound)) ); 3744 3745 return SCIP_OKAY; 3746 } 3747 3748 /** if given value is larger than the node's lower bound (in transformed problem), sets the node's lower bound 3749 * to the new value 3750 * 3751 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 3752 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 3753 * 3754 * @pre this method can be called in one of the following stages of the SCIP solving process: 3755 * - \ref SCIP_STAGE_SOLVING 3756 */ 3757 SCIP_RETCODE SCIPupdateNodeLowerbound( 3758 SCIP* scip, /**< SCIP data structure */ 3759 SCIP_NODE* node, /**< node to update lower bound for */ 3760 SCIP_Real newbound /**< new lower bound for the node (if it's larger than the old one) */ 3761 ) 3762 { 3763 SCIP_CALL( SCIPcheckStage(scip, "SCIPupdateNodeLowerbound", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 3764 3765 SCIPnodeUpdateLowerbound(node, scip->stat, scip->set, scip->tree, scip->transprob, scip->origprob, newbound); 3766 3767 /* if lowerbound exceeds the cutoffbound the node will be marked to be cutoff 3768 * 3769 * If the node is an inner node (,not a child node,) we need to cutoff the node manually if we exceed the 3770 * cutoffbound. This is only relevant if a user updates the lower bound; in the main solving process of SCIP the 3771 * lowerbound is only changed before branching and the given node is always a child node. Therefore, we only check 3772 * for a cutoff here in the user function instead of in SCIPnodeUpdateLowerbound(). 3773 */ 3774 if( SCIPisGE(scip, newbound, scip->primal->cutoffbound) ) 3775 { 3776 SCIP_CALL( SCIPnodeCutoff(node, scip->set, scip->stat, scip->tree, scip->transprob, scip->origprob, scip->reopt, 3777 scip->lp, scip->mem->probmem) ); 3778 } 3779 3780 return SCIP_OKAY; 3781 } 3782 3783 /** change the node selection priority of the given child 3784 * 3785 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 3786 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 3787 * 3788 * @pre this method can be called in one of the following stages of the SCIP solving process: 3789 * - \ref SCIP_STAGE_SOLVING 3790 */ 3791 SCIP_RETCODE SCIPchgChildPrio( 3792 SCIP* scip, /**< SCIP data structure */ 3793 SCIP_NODE* child, /**< child to update the node selection priority */ 3794 SCIP_Real priority /**< node selection priority value */ 3795 ) 3796 { 3797 SCIP_CALL( SCIPcheckStage(scip, "SCIPchgChildPrio", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 3798 3799 if( SCIPnodeGetType(child) != SCIP_NODETYPE_CHILD ) 3800 return SCIP_INVALIDDATA; 3801 3802 SCIPchildChgNodeselPrio(scip->tree, child, priority); 3803 3804 return SCIP_OKAY; 3805 } 3806