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_sol.c 26 * @ingroup OTHER_CFILES 27 * @brief public methods for solutions 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 <string.h> 46 #if defined(_WIN32) || defined(_WIN64) 47 #else 48 #include <strings.h> /*lint --e{766}*/ 49 #endif 50 51 #include "blockmemshell/memory.h" 52 #include "scip/cons.h" 53 #include "scip/cons_linear.h" 54 #include "scip/debug.h" 55 #include "scip/lp.h" 56 #include "scip/nlp.h" 57 #include "scip/primal.h" 58 #include "scip/prob.h" 59 #include "scip/pub_cons.h" 60 #include "scip/pub_fileio.h" 61 #include "scip/pub_message.h" 62 #include "scip/pub_misc.h" 63 #include "scip/pub_sol.h" 64 #include "scip/pub_var.h" 65 #include "scip/relax.h" 66 #include "scip/scip_cons.h" 67 #include "scip/scip_copy.h" 68 #include "scip/scip_general.h" 69 #include "scip/scip_mem.h" 70 #include "scip/scip_message.h" 71 #include "scip/scip_nlp.h" 72 #include "scip/scip_numerics.h" 73 #include "scip/scip_param.h" 74 #include "scip/scip_prob.h" 75 #include "scip/scip_sol.h" 76 #include "scip/scip_solve.h" 77 #include "scip/scip_solvingstats.h" 78 #include "scip/scip_var.h" 79 #include "scip/set.h" 80 #include "scip/sol.h" 81 #include "scip/struct_lp.h" 82 #include "scip/struct_mem.h" 83 #include "scip/struct_primal.h" 84 #include "scip/struct_prob.h" 85 #include "scip/struct_scip.h" 86 #include "scip/struct_set.h" 87 #include "scip/struct_stat.h" 88 #include "scip/struct_var.h" 89 #include "scip/tree.h" 90 #include "xml/xml.h" 91 92 93 /** update integrality violation of a solution */ 94 void SCIPupdateSolIntegralityViolation( 95 SCIP* scip, /**< SCIP data structure */ 96 SCIP_SOL* sol, /**< primal CIP solution */ 97 SCIP_Real absviol /**< absolute violation */ 98 ) 99 { 100 if( SCIPprimalUpdateViolations(scip->origprimal) ) 101 SCIPsolUpdateIntegralityViolation(sol, absviol); 102 } 103 104 /** update bound violation of a solution */ 105 void SCIPupdateSolBoundViolation( 106 SCIP* scip, /**< SCIP data structure */ 107 SCIP_SOL* sol, /**< primal CIP solution */ 108 SCIP_Real absviol, /**< absolute violation */ 109 SCIP_Real relviol /**< relative violation */ 110 ) 111 { 112 if( SCIPprimalUpdateViolations(scip->origprimal) ) 113 SCIPsolUpdateBoundViolation(sol, absviol, relviol); 114 } 115 116 /** update LP row violation of a solution */ 117 void SCIPupdateSolLPRowViolation( 118 SCIP* scip, /**< SCIP data structure */ 119 SCIP_SOL* sol, /**< primal CIP solution */ 120 SCIP_Real absviol, /**< absolute violation */ 121 SCIP_Real relviol /**< relative violation */ 122 ) 123 { 124 if( SCIPprimalUpdateViolations(scip->origprimal) ) 125 SCIPsolUpdateLPRowViolation(sol, absviol, relviol); 126 } 127 128 /** update constraint violation of a solution */ 129 void SCIPupdateSolConsViolation( 130 SCIP* scip, /**< SCIP data structure */ 131 SCIP_SOL* sol, /**< primal CIP solution */ 132 SCIP_Real absviol, /**< absolute violation */ 133 SCIP_Real relviol /**< relative violation */ 134 ) 135 { 136 if( SCIPprimalUpdateViolations(scip->origprimal) ) 137 SCIPsolUpdateConsViolation(sol, absviol, relviol); 138 } 139 140 /** update LP row and constraint violations of a solution */ 141 void SCIPupdateSolLPConsViolation( 142 SCIP* scip, /**< SCIP data structure */ 143 SCIP_SOL* sol, /**< primal CIP solution */ 144 SCIP_Real absviol, /**< absolute violation */ 145 SCIP_Real relviol /**< relative violation */ 146 ) 147 { 148 if( SCIPprimalUpdateViolations(scip->origprimal) ) 149 SCIPsolUpdateLPConsViolation(sol, absviol, relviol); 150 } 151 152 /** allow violation updates */ 153 void SCIPactivateSolViolationUpdates( 154 SCIP* scip /**< SCIP data structure */ 155 ) 156 { 157 SCIPprimalSetUpdateViolations(scip->origprimal, TRUE); 158 } 159 160 /** disallow violation updates */ 161 void SCIPdeactivateSolViolationUpdates( 162 SCIP* scip /**< SCIP data structure */ 163 ) 164 { 165 SCIPprimalSetUpdateViolations(scip->origprimal, FALSE); 166 } 167 168 /** creates a primal solution, initialized to zero 169 * 170 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 171 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 172 * 173 * @pre This method can be called if SCIP is in one of the following stages: 174 * - \ref SCIP_STAGE_PROBLEM 175 * - \ref SCIP_STAGE_TRANSFORMING 176 * - \ref SCIP_STAGE_TRANSFORMED 177 * - \ref SCIP_STAGE_INITPRESOLVE 178 * - \ref SCIP_STAGE_PRESOLVING 179 * - \ref SCIP_STAGE_EXITPRESOLVE 180 * - \ref SCIP_STAGE_PRESOLVED 181 * - \ref SCIP_STAGE_INITSOLVE 182 * - \ref SCIP_STAGE_SOLVING 183 */ 184 SCIP_RETCODE SCIPcreateSol( 185 SCIP* scip, /**< SCIP data structure */ 186 SCIP_SOL** sol, /**< pointer to store the solution */ 187 SCIP_HEUR* heur /**< heuristic that found the solution (or NULL if it's from the tree) */ 188 ) 189 { 190 SCIP_CALL( SCIPcheckStage(scip, "SCIPcreateSol", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 191 192 switch( scip->set->stage ) 193 { 194 case SCIP_STAGE_PROBLEM: 195 SCIP_CALL( SCIPsolCreateOriginal(sol, scip->mem->probmem, scip->set, scip->stat, scip->origprob, scip->origprimal, NULL, heur) ); 196 return SCIP_OKAY; 197 198 case SCIP_STAGE_TRANSFORMING: 199 case SCIP_STAGE_TRANSFORMED: 200 case SCIP_STAGE_INITPRESOLVE: 201 case SCIP_STAGE_PRESOLVING: 202 case SCIP_STAGE_EXITPRESOLVE: 203 case SCIP_STAGE_PRESOLVED: 204 case SCIP_STAGE_INITSOLVE: 205 case SCIP_STAGE_SOLVING: 206 SCIP_CALL( SCIPsolCreate(sol, scip->mem->probmem, scip->set, scip->stat, scip->primal, scip->tree, heur) ); 207 return SCIP_OKAY; 208 209 case SCIP_STAGE_SOLVED: 210 case SCIP_STAGE_EXITSOLVE: 211 case SCIP_STAGE_FREETRANS: 212 default: 213 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage); 214 return SCIP_INVALIDDATA; 215 } /*lint !e788*/ 216 } 217 218 /** creates a primal solution, initialized to the current LP solution 219 * 220 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 221 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 222 * 223 * @pre This method can be called if SCIP is in one of the following stages: 224 * - \ref SCIP_STAGE_SOLVING 225 */ 226 SCIP_RETCODE SCIPcreateLPSol( 227 SCIP* scip, /**< SCIP data structure */ 228 SCIP_SOL** sol, /**< pointer to store the solution */ 229 SCIP_HEUR* heur /**< heuristic that found the solution (or NULL if it's from the tree) */ 230 ) 231 { 232 SCIP_CALL( SCIPcheckStage(scip, "SCIPcreateLPSol", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 233 234 if( !SCIPtreeHasCurrentNodeLP(scip->tree) ) 235 { 236 SCIPerrorMessage("LP solution does not exist\n"); 237 return SCIP_INVALIDCALL; 238 } 239 240 SCIP_CALL( SCIPsolCreateLPSol(sol, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->primal, 241 scip->tree, scip->lp, heur) ); 242 243 return SCIP_OKAY; 244 } 245 246 /** creates a primal solution, initialized to the current NLP solution 247 * 248 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 249 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 250 * 251 * @pre This method can be called if SCIP is in one of the following stages: 252 * - \ref SCIP_STAGE_SOLVING 253 */ 254 SCIP_RETCODE SCIPcreateNLPSol( 255 SCIP* scip, /**< SCIP data structure */ 256 SCIP_SOL** sol, /**< pointer to store the solution */ 257 SCIP_HEUR* heur /**< heuristic that found the solution (or NULL if it's from the tree) */ 258 ) 259 { 260 SCIP_CALL( SCIPcheckStage(scip, "SCIPcreateNLPSol", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 261 262 if( !SCIPisNLPConstructed(scip) ) 263 { 264 SCIPerrorMessage("NLP does not exist\n"); 265 return SCIP_INVALIDCALL; 266 } 267 assert(scip->nlp != NULL); 268 269 if( !SCIPnlpHasSolution(scip->nlp) ) 270 { 271 SCIPerrorMessage("NLP solution does not exist\n"); 272 return SCIP_INVALIDCALL; 273 } 274 275 SCIP_CALL( SCIPsolCreateNLPSol(sol, scip->mem->probmem, scip->set, scip->stat, scip->primal, scip->tree, scip->nlp, 276 heur) ); 277 278 return SCIP_OKAY; 279 } 280 281 /** creates a primal solution, initialized to the current relaxation solution 282 * 283 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 284 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 285 * 286 * @pre This method can be called if SCIP is in one of the following stages: 287 * - \ref SCIP_STAGE_SOLVING 288 */ 289 SCIP_RETCODE SCIPcreateRelaxSol( 290 SCIP* scip, /**< SCIP data structure */ 291 SCIP_SOL** sol, /**< pointer to store the solution */ 292 SCIP_HEUR* heur /**< heuristic that found the solution (or NULL if it's from the tree) */ 293 ) 294 { 295 SCIP_CALL( SCIPcheckStage(scip, "SCIPcreateRelaxSol", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 296 297 if( !SCIPrelaxationIsSolValid(scip->relaxation) ) 298 { 299 SCIPerrorMessage("relaxation solution is not valid\n"); 300 return SCIP_INVALIDCALL; 301 } 302 303 SCIP_CALL( SCIPsolCreateRelaxSol(sol, scip->mem->probmem, scip->set, scip->stat, scip->primal, scip->tree, scip->relaxation, heur) ); 304 305 return SCIP_OKAY; 306 } 307 308 /** creates a primal solution, initialized to the current pseudo solution 309 * 310 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 311 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 312 * 313 * @pre This method can be called if SCIP is in one of the following stages: 314 * - \ref SCIP_STAGE_SOLVING 315 */ 316 SCIP_RETCODE SCIPcreatePseudoSol( 317 SCIP* scip, /**< SCIP data structure */ 318 SCIP_SOL** sol, /**< pointer to store the solution */ 319 SCIP_HEUR* heur /**< heuristic that found the solution (or NULL if it's from the tree) */ 320 ) 321 { 322 SCIP_CALL( SCIPcheckStage(scip, "SCIPcreatePseudoSol", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 323 324 SCIP_CALL( SCIPsolCreatePseudoSol(sol, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->primal, 325 scip->tree, scip->lp, heur) ); 326 327 return SCIP_OKAY; 328 } 329 330 /** creates a primal solution, initialized to the current LP or pseudo solution, depending on whether the LP was solved 331 * at the current node 332 * 333 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 334 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 335 * 336 * @pre This method can be called if SCIP is in one of the following stages: 337 * - \ref SCIP_STAGE_SOLVING 338 */ 339 SCIP_RETCODE SCIPcreateCurrentSol( 340 SCIP* scip, /**< SCIP data structure */ 341 SCIP_SOL** sol, /**< pointer to store the solution */ 342 SCIP_HEUR* heur /**< heuristic that found the solution (or NULL if it's from the tree) */ 343 ) 344 { 345 SCIP_CALL( SCIPcheckStage(scip, "SCIPcreateCurrentSol", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 346 347 SCIP_CALL( SCIPsolCreateCurrentSol(sol, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->primal, 348 scip->tree, scip->lp, heur) ); 349 350 return SCIP_OKAY; 351 } 352 353 /** creates a partial primal solution, initialized to unknown values 354 * 355 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 356 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 357 * 358 * @pre This method can be called if SCIP is in one of the following stages: 359 * - \ref SCIP_STAGE_PROBLEM 360 */ 361 SCIP_RETCODE SCIPcreatePartialSol( 362 SCIP* scip, /**< SCIP data structure */ 363 SCIP_SOL** sol, /**< pointer to store the solution */ 364 SCIP_HEUR* heur /**< heuristic that found the solution (or NULL if it's from the tree) */ 365 ) 366 { 367 SCIP_CALL( SCIPcheckStage(scip, "SCIPcreatePartialSol", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) ); 368 369 SCIP_CALL( SCIPsolCreatePartial(sol, scip->mem->probmem, scip->set, scip->stat, scip->origprimal, heur) ); 370 371 return SCIP_OKAY; 372 } 373 374 /** creates a primal solution, initialized to unknown values 375 * 376 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 377 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 378 * 379 * @pre This method can be called if SCIP is in one of the following stages: 380 * - \ref SCIP_STAGE_TRANSFORMING 381 * - \ref SCIP_STAGE_TRANSFORMED 382 * - \ref SCIP_STAGE_INITPRESOLVE 383 * - \ref SCIP_STAGE_PRESOLVING 384 * - \ref SCIP_STAGE_EXITPRESOLVE 385 * - \ref SCIP_STAGE_PRESOLVED 386 * - \ref SCIP_STAGE_INITSOLVE 387 * - \ref SCIP_STAGE_SOLVING 388 */ 389 SCIP_RETCODE SCIPcreateUnknownSol( 390 SCIP* scip, /**< SCIP data structure */ 391 SCIP_SOL** sol, /**< pointer to store the solution */ 392 SCIP_HEUR* heur /**< heuristic that found the solution (or NULL if it's from the tree) */ 393 ) 394 { 395 SCIP_CALL( SCIPcheckStage(scip, "SCIPcreateUnknownSol", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 396 397 SCIP_CALL( SCIPsolCreateUnknown(sol, scip->mem->probmem, scip->set, scip->stat, scip->primal, scip->tree, heur) ); 398 399 return SCIP_OKAY; 400 } 401 402 /** creates a primal solution living in the original problem space, initialized to zero; 403 * a solution in original space allows to set original variables to values that would be invalid in the 404 * transformed problem due to preprocessing fixings or aggregations 405 * 406 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 407 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 408 * 409 * @pre This method can be called if SCIP is in one of the following stages: 410 * - \ref SCIP_STAGE_PROBLEM 411 * - \ref SCIP_STAGE_TRANSFORMING 412 * - \ref SCIP_STAGE_TRANSFORMED 413 * - \ref SCIP_STAGE_INITPRESOLVE 414 * - \ref SCIP_STAGE_PRESOLVING 415 * - \ref SCIP_STAGE_EXITPRESOLVE 416 * - \ref SCIP_STAGE_PRESOLVED 417 * - \ref SCIP_STAGE_INITSOLVE 418 * - \ref SCIP_STAGE_SOLVING 419 * - \ref SCIP_STAGE_SOLVED 420 */ 421 SCIP_RETCODE SCIPcreateOrigSol( 422 SCIP* scip, /**< SCIP data structure */ 423 SCIP_SOL** sol, /**< pointer to store the solution */ 424 SCIP_HEUR* heur /**< heuristic that found the solution (or NULL if it's from the tree) */ 425 ) 426 { 427 SCIP_CALL( SCIPcheckStage(scip, "SCIPcreateOrigSol", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 428 429 switch( scip->set->stage ) 430 { 431 case SCIP_STAGE_PROBLEM: 432 SCIP_CALL( SCIPsolCreateOriginal(sol, scip->mem->probmem, scip->set, scip->stat, scip->origprob, scip->origprimal, NULL, heur) ); 433 return SCIP_OKAY; 434 435 case SCIP_STAGE_TRANSFORMING: 436 case SCIP_STAGE_TRANSFORMED: 437 case SCIP_STAGE_INITPRESOLVE: 438 case SCIP_STAGE_PRESOLVING: 439 case SCIP_STAGE_EXITPRESOLVE: 440 case SCIP_STAGE_PRESOLVED: 441 case SCIP_STAGE_INITSOLVE: 442 case SCIP_STAGE_SOLVING: 443 case SCIP_STAGE_SOLVED: 444 SCIP_CALL( SCIPsolCreateOriginal(sol, scip->mem->probmem, scip->set, scip->stat, scip->origprob, scip->primal, scip->tree, heur) ); 445 return SCIP_OKAY; 446 447 case SCIP_STAGE_EXITSOLVE: 448 case SCIP_STAGE_FREETRANS: 449 default: 450 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage); 451 return SCIP_INVALIDCALL; 452 } /*lint !e788*/ 453 } 454 455 /** creates a copy of a primal solution; note that a copy of a linked solution is also linked and needs to be unlinked 456 * if it should stay unaffected from changes in the LP or pseudo solution 457 * 458 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 459 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 460 * 461 * @pre This method can be called if SCIP is in one of the following stages: 462 * - \ref SCIP_STAGE_PROBLEM 463 * - \ref SCIP_STAGE_FREETRANS 464 * - \ref SCIP_STAGE_TRANSFORMING 465 * - \ref SCIP_STAGE_TRANSFORMED 466 * - \ref SCIP_STAGE_INITPRESOLVE 467 * - \ref SCIP_STAGE_PRESOLVING 468 * - \ref SCIP_STAGE_EXITPRESOLVE 469 * - \ref SCIP_STAGE_PRESOLVED 470 * - \ref SCIP_STAGE_INITSOLVE 471 * - \ref SCIP_STAGE_SOLVING 472 * - \ref SCIP_STAGE_SOLVED 473 */ 474 SCIP_RETCODE SCIPcreateSolCopy( 475 SCIP* scip, /**< SCIP data structure */ 476 SCIP_SOL** sol, /**< pointer to store the solution */ 477 SCIP_SOL* sourcesol /**< primal CIP solution to copy */ 478 ) 479 { 480 SCIP_CALL( SCIPcheckStage(scip, "SCIPcreateSolCopy", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 481 482 /* check if we want to copy the current solution, which is the same as creating a current solution */ 483 if( sourcesol == NULL ) 484 { 485 SCIP_CALL( SCIPcreateCurrentSol(scip, sol, NULL) ); 486 } 487 else 488 { 489 SCIP_CALL( SCIPsolCopy(sol, scip->mem->probmem, scip->set, scip->stat, scip->primal, sourcesol) ); 490 } 491 492 return SCIP_OKAY; 493 } 494 495 /** creates a copy of a solution in the original primal solution space 496 * 497 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 498 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 499 * 500 * @pre This method can be called if SCIP is in one of the following stages: 501 * - \ref SCIP_STAGE_PROBLEM 502 * - \ref SCIP_STAGE_TRANSFORMING 503 * - \ref SCIP_STAGE_TRANSFORMED 504 * - \ref SCIP_STAGE_INITPRESOLVE 505 * - \ref SCIP_STAGE_PRESOLVING 506 * - \ref SCIP_STAGE_EXITPRESOLVE 507 * - \ref SCIP_STAGE_PRESOLVED 508 * - \ref SCIP_STAGE_INITSOLVE 509 * - \ref SCIP_STAGE_SOLVING 510 * - \ref SCIP_STAGE_SOLVED 511 * - \ref SCIP_STAGE_EXITSOLVE 512 * - \ref SCIP_STAGE_FREETRANS 513 */ 514 SCIP_RETCODE SCIPcreateSolCopyOrig( 515 SCIP* scip, /**< SCIP data structure */ 516 SCIP_SOL** sol, /**< pointer to store the solution */ 517 SCIP_SOL* sourcesol /**< primal CIP solution to copy */ 518 ) 519 { 520 SCIP_CALL( SCIPcheckStage(scip, "SCIPcreateSolCopyOrig", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) ); 521 522 /* check if we want to copy the current solution, which is the same as creating a current solution */ 523 if( sourcesol == NULL ) 524 { 525 SCIP_CALL( SCIPcreateCurrentSol(scip, sol, NULL) ); 526 } 527 else 528 { 529 switch( scip->set->stage ) 530 { 531 case SCIP_STAGE_PROBLEM: 532 case SCIP_STAGE_FREETRANS: 533 case SCIP_STAGE_SOLVED: 534 case SCIP_STAGE_TRANSFORMING: 535 case SCIP_STAGE_TRANSFORMED: 536 case SCIP_STAGE_INITPRESOLVE: 537 case SCIP_STAGE_PRESOLVING: 538 case SCIP_STAGE_EXITPRESOLVE: 539 case SCIP_STAGE_PRESOLVED: 540 case SCIP_STAGE_INITSOLVE: 541 case SCIP_STAGE_SOLVING: 542 SCIP_CALL( SCIPsolCopy(sol, scip->mem->probmem, scip->set, scip->stat, scip->origprimal, sourcesol) ); 543 break; 544 default: 545 assert(FALSE); /*lint !e506*/ 546 } /*lint !e788*/ 547 } 548 549 return SCIP_OKAY; 550 } 551 552 /** helper method that sets up and solves the sub-SCIP for removing infinite values from solutions */ 553 static 554 SCIP_RETCODE setupAndSolveFiniteSolSubscip( 555 SCIP* scip, /**< SCIP data structure */ 556 SCIP* subscip, /**< SCIP data structure of sub-SCIP*/ 557 SCIP_VAR** origvars, /**< original problem variables of main SCIP */ 558 int norigvars, /**< number of original problem variables of main SCIP */ 559 SCIP_Real* solvals, /**< array with solution values of variables; infinite ones are replaced */ 560 SCIP_Bool* success /**< pointer to store if removing infinite values was successful */ 561 ) 562 { 563 SCIP_HASHMAP* varmap; 564 SCIP_VAR* varcopy; 565 SCIP_Real fixval; 566 SCIP_Bool valid; 567 SCIP_SOL* bestsol; 568 int v; 569 570 assert(scip != NULL); 571 assert(subscip != NULL); 572 assert(origvars != NULL); 573 assert(solvals != NULL); 574 assert(success != NULL); 575 576 /* copy the original problem to the sub-SCIP */ 577 SCIP_CALL( SCIPhashmapCreate(&varmap, SCIPblkmem(scip), norigvars) ); 578 SCIP_CALL( SCIPcopyOrig(scip, subscip, varmap, NULL, "removeinffixings", TRUE, FALSE, TRUE, &valid) ); 579 580 SCIP_CALL( SCIPsetIntParam(subscip, "display/verblevel", (int)SCIP_VERBLEVEL_NONE) ); 581 582 /* in the sub-SCIP, we try to minimize the absolute values of all variables with infinite values in the solution 583 * and fix all other variables to the value they have in the solution 584 */ 585 for( v = 0; v < norigvars; ++v ) 586 { 587 varcopy = (SCIP_VAR*) SCIPhashmapGetImage(varmap, (void*)origvars[v]); 588 assert(varcopy != NULL); 589 590 fixval = solvals[v]; 591 592 if( SCIPisInfinity(scip, fixval) || SCIPisInfinity(scip, -fixval) ) 593 { 594 /* If a variable with a finite finite lower bound was set to +infinity, we just change its objective to 1.0 595 * to minimize its value; if a variable with a finite finite upper bound was set to -infinity, we just 596 * change its objective to -1.0 to maximize its value; if a variable is free, we split the variable into 597 * positive and negative part by creating two new non-negative variables and one constraint linking those 598 * variables. 599 */ 600 if( SCIPisInfinity(scip, fixval) && !SCIPisInfinity(scip, -SCIPvarGetLbLocal(varcopy)) ) 601 { 602 SCIP_CALL( SCIPchgVarObj(subscip, varcopy, 1.0) ); 603 } 604 else if( SCIPisInfinity(scip, -fixval) && !SCIPisInfinity(scip, SCIPvarGetUbLocal(varcopy)) ) 605 { 606 SCIP_CALL( SCIPchgVarObj(subscip, varcopy, -1.0) ); 607 } 608 else 609 { 610 char name[SCIP_MAXSTRLEN]; 611 SCIP_VAR* posvar; 612 SCIP_VAR* negvar; 613 SCIP_CONS* linkcons; 614 615 (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "%s_%s", SCIPvarGetName(varcopy), "run"); 616 SCIP_CALL( SCIPcreateVar(subscip, &posvar, name, 0.0, SCIPinfinity(scip), 1.0, 617 SCIP_VARTYPE_CONTINUOUS, TRUE, FALSE, NULL, NULL, NULL, NULL, NULL) ); 618 SCIP_CALL( SCIPaddVar(subscip, posvar) ); 619 620 (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "%s_%s", SCIPvarGetName(varcopy), "neg"); 621 SCIP_CALL( SCIPcreateVar(subscip, &negvar, name, 0.0, SCIPinfinity(scip), 1.0, 622 SCIP_VARTYPE_CONTINUOUS, TRUE, FALSE, NULL, NULL, NULL, NULL, NULL) ); 623 SCIP_CALL( SCIPaddVar(subscip, negvar) ); 624 625 (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "%s_%s", SCIPvarGetName(varcopy), "linkcons"); 626 SCIP_CALL( SCIPcreateConsBasicLinear(subscip, &linkcons, name, 0, NULL, NULL, 0.0, 0.0 ) ); 627 SCIP_CALL( SCIPaddCoefLinear(subscip, linkcons, varcopy, 1.0) ); 628 SCIP_CALL( SCIPaddCoefLinear(subscip, linkcons, posvar, -1.0) ); 629 SCIP_CALL( SCIPaddCoefLinear(subscip, linkcons, negvar, 1.0) ); 630 SCIP_CALL( SCIPaddCons(subscip, linkcons) ); 631 632 SCIP_CALL( SCIPreleaseCons(subscip, &linkcons) ); 633 SCIP_CALL( SCIPreleaseVar(subscip, &posvar) ); 634 SCIP_CALL( SCIPreleaseVar(subscip, &negvar) ); 635 636 SCIP_CALL( SCIPchgVarObj(subscip, varcopy, 0.0) ); 637 } 638 } 639 else 640 { 641 SCIP_Bool infeasible; 642 SCIP_Bool fixed; 643 644 if( SCIPisFeasLT(scip, solvals[v], SCIPvarGetLbLocal(varcopy)) || SCIPisFeasGT(scip, solvals[v], SCIPvarGetUbLocal(varcopy)) ) 645 { 646 SCIP_CALL( SCIPchgVarType(subscip, varcopy, SCIP_VARTYPE_CONTINUOUS, &infeasible) ); 647 assert(!infeasible); 648 } 649 650 /* fix variable to its value in the solution */ 651 SCIP_CALL( SCIPfixVar(subscip, varcopy, fixval, &infeasible, &fixed) ); 652 assert(!infeasible); 653 } 654 } 655 656 SCIP_CALL( SCIPsolve(subscip) ); 657 658 bestsol = SCIPgetBestSol(subscip); 659 660 if( bestsol != NULL ) 661 { 662 /* change the stored solution values for variables fixed to infinite values */ 663 for( v = 0; v < norigvars; ++v ) 664 { 665 varcopy = (SCIP_VAR*) SCIPhashmapGetImage(varmap, (void*)origvars[v]); 666 assert(varcopy != NULL); 667 668 if( (SCIPisInfinity(scip, solvals[v]) || SCIPisInfinity(scip, -solvals[v])) ) 669 { 670 solvals[v] = SCIPgetSolVal(subscip, bestsol, varcopy); 671 } 672 } 673 } 674 else 675 { 676 *success = FALSE; 677 } 678 679 SCIPhashmapFree(&varmap); 680 681 return SCIP_OKAY; 682 } 683 684 685 /** creates a copy of a primal solution, thereby replacing infinite fixings of variables by finite values; 686 * the copy is always defined in the original variable space; 687 * success indicates whether the objective value of the solution was changed by removing infinite values 688 * 689 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 690 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 691 * 692 * @pre This method can be called if SCIP is in one of the following stages: 693 * - \ref SCIP_STAGE_PROBLEM 694 * - \ref SCIP_STAGE_TRANSFORMING 695 * - \ref SCIP_STAGE_TRANSFORMED 696 * - \ref SCIP_STAGE_INITPRESOLVE 697 * - \ref SCIP_STAGE_PRESOLVING 698 * - \ref SCIP_STAGE_EXITPRESOLVE 699 * - \ref SCIP_STAGE_PRESOLVED 700 * - \ref SCIP_STAGE_INITSOLVE 701 * - \ref SCIP_STAGE_SOLVING 702 * - \ref SCIP_STAGE_SOLVED 703 * - \ref SCIP_STAGE_EXITSOLVE 704 */ 705 SCIP_RETCODE SCIPcreateFiniteSolCopy( 706 SCIP* scip, /**< SCIP data structure */ 707 SCIP_SOL** sol, /**< pointer to store the solution */ 708 SCIP_SOL* sourcesol, /**< primal CIP solution to copy */ 709 SCIP_Bool* success /**< does the finite solution have the same objective value? */ 710 ) 711 { 712 SCIP_VAR** fixedvars; 713 SCIP_VAR** origvars; 714 SCIP_Real* solvals; 715 SCIP_VAR* var; 716 int nfixedvars; 717 int norigvars; 718 int v; 719 720 SCIP_CALL( SCIPcheckStage(scip, "SCIPcreateFiniteSolCopy", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) ); 721 722 assert(scip != NULL); 723 assert(sol != NULL); 724 assert(sourcesol != NULL); 725 assert(success != NULL); 726 727 *success = TRUE; 728 *sol = NULL; 729 730 fixedvars = SCIPgetFixedVars(scip); 731 nfixedvars = SCIPgetNFixedVars(scip); 732 assert(fixedvars != NULL || nfixedvars == 0); 733 734 /* get original variables and their values in the optimal solution */ 735 SCIP_CALL( SCIPgetOrigVarsData(scip, &origvars, &norigvars, NULL, NULL, NULL, NULL) ); 736 SCIP_CALL( SCIPallocBufferArray(scip, &solvals, norigvars) ); 737 SCIP_CALL( SCIPgetSolVals(scip, sourcesol, norigvars, origvars, solvals) ); 738 739 /* check whether there are variables fixed to an infinite value */ 740 for( v = 0; v < nfixedvars; ++v ) 741 { 742 var = fixedvars[v]; /*lint !e613*/ 743 744 /* skip (multi-)aggregated variables */ 745 if( SCIPvarGetStatus(var) != SCIP_VARSTATUS_FIXED ) 746 continue; 747 748 assert(SCIPisEQ(scip, SCIPvarGetLbGlobal(var), SCIPvarGetUbGlobal(var))); 749 750 if( (SCIPisInfinity(scip, SCIPvarGetLbGlobal(var)) || SCIPisInfinity(scip, -SCIPvarGetLbGlobal(var))) ) 751 { 752 SCIPdebugMsg(scip, "var <%s> is fixed to infinite value %g\n", SCIPvarGetName(var), SCIPvarGetLbGlobal(var)); 753 break; 754 } 755 } 756 757 /* there were variables fixed to infinite values */ 758 if( v < nfixedvars ) 759 { 760 SCIP* subscip; 761 SCIP_RETCODE retcode; 762 763 /* if one of the variables was fixed to infinity in the original problem, we stop here */ 764 for( v = 0; v < norigvars; ++v ) 765 { 766 var = origvars[v]; 767 768 if( SCIPisInfinity(scip, SCIPvarGetLbOriginal(var)) || SCIPisInfinity(scip, -SCIPvarGetUbOriginal(var)) ) 769 { 770 assert(SCIPisEQ(scip, SCIPvarGetLbOriginal(var), SCIPvarGetUbOriginal(var))); 771 772 SCIPdebugMsg(scip, "--> var <%s> is fixed to infinite value %g in the original problem, stop making solution finite\n", 773 SCIPvarGetName(var), SCIPvarGetLbOriginal(var)); 774 775 *success = FALSE; 776 777 goto TERMINATE; 778 } 779 } 780 781 /* create sub-SCIP */ 782 SCIP_CALL( SCIPcreate(&subscip) ); 783 784 retcode = setupAndSolveFiniteSolSubscip(scip, subscip, origvars, norigvars, solvals, success); 785 786 /* free sub-SCIP */ 787 SCIP_CALL( SCIPfree(&subscip) ); 788 789 SCIP_CALL( retcode ); 790 } 791 792 /* create original solution and set the solution values */ 793 if( *success ) 794 { 795 SCIP_CALL( SCIPcreateOrigSol(scip, sol, NULL) ); 796 for( v = 0; v < norigvars; ++v ) 797 { 798 SCIP_CALL( SCIPsetSolVal(scip, *sol, origvars[v], solvals[v]) ); 799 } 800 } 801 802 #ifdef SCIP_DEBUG 803 SCIPdebugMsg(scip, "created finites solution copy:\n"); 804 SCIP_CALL( SCIPprintSol(scip, *sol, NULL, FALSE) ); 805 #endif 806 807 /* the solution of the sub-SCIP should have the same objective value */ 808 if( *success && !SCIPisEQ(scip, SCIPgetSolOrigObj(scip, *sol), SCIPgetSolOrigObj(scip, sourcesol)) ) 809 { 810 /* @todo how should we avoid numerical trobles here for large objective values? */ 811 if( (SCIPgetSolOrigObj(scip, *sol) / SCIPepsilon(scip)) < 1e+15 || 812 REALABS(SCIPgetSolOrigObj(scip, *sol) - SCIPgetSolOrigObj(scip, sourcesol)) > 1e-12 * SCIPgetSolOrigObj(scip, *sol) ) 813 *success = FALSE; 814 } 815 816 TERMINATE: 817 SCIPfreeBufferArray(scip, &solvals); 818 819 return SCIP_OKAY; 820 } 821 822 /** frees primal CIP solution 823 * 824 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 825 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 826 * 827 * @pre This method can be called if SCIP is in one of the following stages: 828 * - \ref SCIP_STAGE_PROBLEM 829 * - \ref SCIP_STAGE_TRANSFORMING 830 * - \ref SCIP_STAGE_TRANSFORMED 831 * - \ref SCIP_STAGE_INITPRESOLVE 832 * - \ref SCIP_STAGE_PRESOLVING 833 * - \ref SCIP_STAGE_EXITPRESOLVE 834 * - \ref SCIP_STAGE_PRESOLVED 835 * - \ref SCIP_STAGE_INITSOLVE 836 * - \ref SCIP_STAGE_SOLVING 837 * - \ref SCIP_STAGE_SOLVED 838 * - \ref SCIP_STAGE_EXITSOLVE 839 * - \ref SCIP_STAGE_FREETRANS 840 */ 841 SCIP_RETCODE SCIPfreeSol( 842 SCIP* scip, /**< SCIP data structure */ 843 SCIP_SOL** sol /**< pointer to the solution */ 844 ) 845 { 846 SCIP_CALL( SCIPcheckStage(scip, "SCIPfreeSol", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) ); 847 848 switch( scip->set->stage ) 849 { 850 case SCIP_STAGE_PROBLEM: 851 SCIP_CALL( SCIPsolFree(sol, scip->mem->probmem, scip->origprimal) ); 852 break; 853 case SCIP_STAGE_FREETRANS: 854 case SCIP_STAGE_TRANSFORMED: 855 case SCIP_STAGE_INITPRESOLVE: 856 case SCIP_STAGE_PRESOLVING: 857 case SCIP_STAGE_EXITPRESOLVE: 858 case SCIP_STAGE_PRESOLVED: 859 case SCIP_STAGE_SOLVING: 860 case SCIP_STAGE_TRANSFORMING: 861 case SCIP_STAGE_INITSOLVE: 862 case SCIP_STAGE_SOLVED: 863 case SCIP_STAGE_EXITSOLVE: 864 SCIP_CALL( SCIPsolFree(sol, scip->mem->probmem, scip->primal) ); 865 break; 866 default: 867 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage); 868 return SCIP_INVALIDCALL; 869 } /*lint !e788*/ 870 871 return SCIP_OKAY; 872 } 873 874 /** links a primal solution to the current LP solution 875 * 876 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 877 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 878 * 879 * @pre This method can be called if SCIP is in one of the following stages: 880 * - \ref SCIP_STAGE_SOLVING 881 */ 882 SCIP_RETCODE SCIPlinkLPSol( 883 SCIP* scip, /**< SCIP data structure */ 884 SCIP_SOL* sol /**< primal solution */ 885 ) 886 { 887 SCIP_CALL( SCIPcheckStage(scip, "SCIPlinkLPSol", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 888 889 if( !SCIPlpIsSolved(scip->lp) ) 890 { 891 SCIPerrorMessage("LP solution does not exist\n"); 892 return SCIP_INVALIDCALL; 893 } 894 895 SCIP_CALL( SCIPsolLinkLPSol(sol, scip->set, scip->stat, scip->transprob, scip->tree, scip->lp) ); 896 897 return SCIP_OKAY; 898 } 899 900 /** links a primal solution to the current NLP solution 901 * 902 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 903 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 904 * 905 * @pre This method can be called if SCIP is in one of the following stages: 906 * - \ref SCIP_STAGE_SOLVING 907 */ 908 SCIP_RETCODE SCIPlinkNLPSol( 909 SCIP* scip, /**< SCIP data structure */ 910 SCIP_SOL* sol /**< primal solution */ 911 ) 912 { 913 SCIP_CALL( SCIPcheckStage(scip, "SCIPlinkNLPSol", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 914 915 if( scip->nlp == NULL ) 916 { 917 SCIPerrorMessage("NLP does not exist\n"); 918 return SCIP_INVALIDCALL; 919 } 920 921 if( SCIPnlpGetSolstat(scip->nlp) > SCIP_NLPSOLSTAT_FEASIBLE ) 922 { 923 SCIPerrorMessage("NLP solution does not exist\n"); 924 return SCIP_INVALIDCALL; 925 } 926 927 SCIP_CALL( SCIPsolLinkNLPSol(sol, scip->stat, scip->tree, scip->nlp) ); 928 929 return SCIP_OKAY; 930 } 931 932 /** links a primal solution to the current relaxation solution 933 * 934 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 935 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 936 * 937 * @pre This method can be called if SCIP is in one of the following stages: 938 * - \ref SCIP_STAGE_SOLVING 939 */ 940 SCIP_RETCODE SCIPlinkRelaxSol( 941 SCIP* scip, /**< SCIP data structure */ 942 SCIP_SOL* sol /**< primal solution */ 943 ) 944 { 945 SCIP_CALL( SCIPcheckStage(scip, "SCIPlinkRelaxSol", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 946 947 if( !SCIPrelaxationIsSolValid(scip->relaxation) ) 948 { 949 SCIPerrorMessage("relaxation solution is not valid\n"); 950 return SCIP_INVALIDCALL; 951 } 952 953 SCIP_CALL( SCIPsolLinkRelaxSol(sol, scip->set, scip->stat, scip->tree, scip->relaxation) ); 954 955 return SCIP_OKAY; 956 } 957 958 /** links a primal solution to the current pseudo solution 959 * 960 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 961 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 962 * 963 * @pre This method can be called if SCIP is in one of the following stages: 964 * - \ref SCIP_STAGE_PRESOLVING 965 * - \ref SCIP_STAGE_SOLVING 966 */ 967 SCIP_RETCODE SCIPlinkPseudoSol( 968 SCIP* scip, /**< SCIP data structure */ 969 SCIP_SOL* sol /**< primal solution */ 970 ) 971 { 972 SCIP_CALL( SCIPcheckStage(scip, "SCIPlinkPseudoSol", FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 973 974 SCIP_CALL( SCIPsolLinkPseudoSol(sol, scip->set, scip->stat, scip->transprob, scip->tree, scip->lp) ); 975 976 return SCIP_OKAY; 977 } 978 979 /** links a primal solution to the current LP or pseudo solution 980 * 981 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 982 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 983 * 984 * @pre This method can be called if SCIP is in one of the following stages: 985 * - \ref SCIP_STAGE_SOLVING 986 */ 987 SCIP_RETCODE SCIPlinkCurrentSol( 988 SCIP* scip, /**< SCIP data structure */ 989 SCIP_SOL* sol /**< primal solution */ 990 ) 991 { 992 SCIP_CALL( SCIPcheckStage(scip, "SCIPlinkCurrentSol", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 993 994 SCIP_CALL( SCIPsolLinkCurrentSol(sol, scip->set, scip->stat, scip->transprob, scip->tree, scip->lp) ); 995 996 return SCIP_OKAY; 997 } 998 999 /** clears a primal solution 1000 * 1001 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 1002 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 1003 * 1004 * @pre This method can be called if SCIP is in one of the following stages: 1005 * - \ref SCIP_STAGE_PROBLEM 1006 * - \ref SCIP_STAGE_TRANSFORMING 1007 * - \ref SCIP_STAGE_TRANSFORMED 1008 * - \ref SCIP_STAGE_INITPRESOLVE 1009 * - \ref SCIP_STAGE_PRESOLVING 1010 * - \ref SCIP_STAGE_EXITPRESOLVE 1011 * - \ref SCIP_STAGE_PRESOLVED 1012 * - \ref SCIP_STAGE_INITSOLVE 1013 * - \ref SCIP_STAGE_SOLVING 1014 * - \ref SCIP_STAGE_SOLVED 1015 * - \ref SCIP_STAGE_EXITSOLVE 1016 * - \ref SCIP_STAGE_FREETRANS 1017 */ 1018 SCIP_RETCODE SCIPclearSol( 1019 SCIP* scip, /**< SCIP data structure */ 1020 SCIP_SOL* sol /**< primal solution */ 1021 ) 1022 { 1023 SCIP_CALL( SCIPcheckStage(scip, "SCIPclearSol", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) ); 1024 1025 SCIP_CALL( SCIPsolClear(sol, scip->stat, scip->tree) ); 1026 1027 return SCIP_OKAY; 1028 } 1029 1030 /** stores solution values of variables in solution's own array 1031 * 1032 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 1033 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 1034 * 1035 * @pre This method can be called if SCIP is in one of the following stages: 1036 * - \ref SCIP_STAGE_TRANSFORMING 1037 * - \ref SCIP_STAGE_TRANSFORMED 1038 * - \ref SCIP_STAGE_PRESOLVING 1039 * - \ref SCIP_STAGE_PRESOLVED 1040 * - \ref SCIP_STAGE_INITSOLVE 1041 * - \ref SCIP_STAGE_SOLVING 1042 * - \ref SCIP_STAGE_SOLVED 1043 * - \ref SCIP_STAGE_EXITSOLVE 1044 * - \ref SCIP_STAGE_FREETRANS 1045 */ 1046 SCIP_RETCODE SCIPunlinkSol( 1047 SCIP* scip, /**< SCIP data structure */ 1048 SCIP_SOL* sol /**< primal solution */ 1049 ) 1050 { 1051 SCIP_CALL( SCIPcheckStage(scip, "SCIPunlinkSol", FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) ); 1052 1053 SCIP_CALL( SCIPsolUnlink(sol, scip->set, scip->transprob) ); 1054 1055 return SCIP_OKAY; 1056 } 1057 1058 /** sets value of variable in primal CIP solution 1059 * 1060 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 1061 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 1062 * 1063 * @pre This method can be called if SCIP is in one of the following stages: 1064 * - \ref SCIP_STAGE_PROBLEM 1065 * - \ref SCIP_STAGE_TRANSFORMING 1066 * - \ref SCIP_STAGE_TRANSFORMED 1067 * - \ref SCIP_STAGE_INITPRESOLVE 1068 * - \ref SCIP_STAGE_PRESOLVING 1069 * - \ref SCIP_STAGE_EXITPRESOLVE 1070 * - \ref SCIP_STAGE_PRESOLVED 1071 * - \ref SCIP_STAGE_INITSOLVE 1072 * - \ref SCIP_STAGE_SOLVING 1073 * - \ref SCIP_STAGE_SOLVED 1074 * - \ref SCIP_STAGE_EXITSOLVE 1075 * - \ref SCIP_STAGE_FREETRANS 1076 */ 1077 SCIP_RETCODE SCIPsetSolVal( 1078 SCIP* scip, /**< SCIP data structure */ 1079 SCIP_SOL* sol, /**< primal solution */ 1080 SCIP_VAR* var, /**< variable to add to solution */ 1081 SCIP_Real val /**< solution value of variable */ 1082 ) 1083 { 1084 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetSolVal", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) ); 1085 1086 assert( var->scip == scip ); 1087 1088 if( SCIPsolIsOriginal(sol) && SCIPvarIsTransformed(var) ) 1089 { 1090 SCIPerrorMessage("cannot set value of transformed variable <%s> in original space solution\n", 1091 SCIPvarGetName(var)); 1092 return SCIP_INVALIDCALL; 1093 } 1094 1095 SCIP_CALL( SCIPsolSetVal(sol, scip->set, scip->stat, scip->tree, var, val) ); 1096 1097 return SCIP_OKAY; 1098 } 1099 1100 /** sets values of multiple variables in primal CIP solution 1101 * 1102 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 1103 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 1104 * 1105 * @pre This method can be called if SCIP is in one of the following stages: 1106 * - \ref SCIP_STAGE_PROBLEM 1107 * - \ref SCIP_STAGE_TRANSFORMING 1108 * - \ref SCIP_STAGE_TRANSFORMED 1109 * - \ref SCIP_STAGE_INITPRESOLVE 1110 * - \ref SCIP_STAGE_PRESOLVING 1111 * - \ref SCIP_STAGE_EXITPRESOLVE 1112 * - \ref SCIP_STAGE_PRESOLVED 1113 * - \ref SCIP_STAGE_INITSOLVE 1114 * - \ref SCIP_STAGE_SOLVING 1115 * - \ref SCIP_STAGE_SOLVED 1116 * - \ref SCIP_STAGE_EXITSOLVE 1117 * - \ref SCIP_STAGE_FREETRANS 1118 */ 1119 SCIP_RETCODE SCIPsetSolVals( 1120 SCIP* scip, /**< SCIP data structure */ 1121 SCIP_SOL* sol, /**< primal solution */ 1122 int nvars, /**< number of variables to set solution value for */ 1123 SCIP_VAR** vars, /**< array with variables to add to solution */ 1124 SCIP_Real* vals /**< array with solution values of variables */ 1125 ) 1126 { 1127 int v; 1128 1129 assert(nvars == 0 || vars != NULL); 1130 assert(nvars == 0 || vals != NULL); 1131 1132 SCIP_CALL( SCIPcheckStage(scip, "SCIPsetSolVals", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) ); 1133 1134 if( SCIPsolIsOriginal(sol) ) 1135 { 1136 for( v = 0; v < nvars; ++v ) 1137 { 1138 if( SCIPvarIsTransformed(vars[v]) ) 1139 { 1140 SCIPerrorMessage("cannot set value of transformed variable <%s> in original space solution\n", 1141 SCIPvarGetName(vars[v])); 1142 return SCIP_INVALIDCALL; 1143 } 1144 } 1145 } 1146 1147 for( v = 0; v < nvars; ++v ) 1148 { 1149 SCIP_CALL( SCIPsolSetVal(sol, scip->set, scip->stat, scip->tree, vars[v], vals[v]) ); 1150 } 1151 1152 return SCIP_OKAY; 1153 } 1154 1155 /** increases value of variable in primal CIP solution 1156 * 1157 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 1158 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 1159 * 1160 * @pre This method can be called if SCIP is in one of the following stages: 1161 * - \ref SCIP_STAGE_PROBLEM 1162 * - \ref SCIP_STAGE_TRANSFORMING 1163 * - \ref SCIP_STAGE_TRANSFORMED 1164 * - \ref SCIP_STAGE_INITPRESOLVE 1165 * - \ref SCIP_STAGE_PRESOLVING 1166 * - \ref SCIP_STAGE_EXITPRESOLVE 1167 * - \ref SCIP_STAGE_PRESOLVED 1168 * - \ref SCIP_STAGE_INITSOLVE 1169 * - \ref SCIP_STAGE_SOLVING 1170 * - \ref SCIP_STAGE_SOLVED 1171 * - \ref SCIP_STAGE_EXITSOLVE 1172 * - \ref SCIP_STAGE_FREETRANS 1173 */ 1174 SCIP_RETCODE SCIPincSolVal( 1175 SCIP* scip, /**< SCIP data structure */ 1176 SCIP_SOL* sol, /**< primal solution */ 1177 SCIP_VAR* var, /**< variable to increase solution value for */ 1178 SCIP_Real incval /**< increment for solution value of variable */ 1179 ) 1180 { 1181 SCIP_CALL( SCIPcheckStage(scip, "SCIPincSolVal", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) ); 1182 1183 assert( var->scip == scip ); 1184 1185 if( SCIPsolIsOriginal(sol) && SCIPvarIsTransformed(var) ) 1186 { 1187 SCIPerrorMessage("cannot increase value of transformed variable <%s> in original space solution\n", 1188 SCIPvarGetName(var)); 1189 return SCIP_INVALIDCALL; 1190 } 1191 1192 SCIP_CALL( SCIPsolIncVal(sol, scip->set, scip->stat, scip->tree, var, incval) ); 1193 1194 return SCIP_OKAY; 1195 } 1196 1197 /** returns value of variable in primal CIP solution, or in current LP/pseudo solution 1198 * 1199 * @return value of variable in primal CIP solution, or in current LP/pseudo solution 1200 * 1201 * @pre In case the solution pointer @p sol is @b NULL, that means it is asked for the LP or pseudo solution, this method 1202 * can only be called if @p scip is in the solving stage \ref SCIP_STAGE_SOLVING. In any other case, this method 1203 * can be called if @p scip is in one of the following stages: 1204 * - \ref SCIP_STAGE_PROBLEM 1205 * - \ref SCIP_STAGE_TRANSFORMING 1206 * - \ref SCIP_STAGE_TRANSFORMED 1207 * - \ref SCIP_STAGE_INITPRESOLVE 1208 * - \ref SCIP_STAGE_PRESOLVING 1209 * - \ref SCIP_STAGE_EXITPRESOLVE 1210 * - \ref SCIP_STAGE_PRESOLVED 1211 * - \ref SCIP_STAGE_INITSOLVE 1212 * - \ref SCIP_STAGE_SOLVING 1213 * - \ref SCIP_STAGE_SOLVED 1214 * - \ref SCIP_STAGE_EXITSOLVE 1215 * - \ref SCIP_STAGE_FREETRANS 1216 */ 1217 SCIP_Real SCIPgetSolVal( 1218 SCIP* scip, /**< SCIP data structure */ 1219 SCIP_SOL* sol, /**< primal solution, or NULL for current LP/pseudo solution */ 1220 SCIP_VAR* var /**< variable to get value for */ 1221 ) 1222 { 1223 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetSolVal", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) ); 1224 1225 assert( var->scip == scip ); 1226 1227 if( sol != NULL ) 1228 return SCIPsolGetVal(sol, scip->set, scip->stat, var); 1229 1230 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetSolVal(sol==NULL)", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 1231 1232 return SCIPvarGetSol(var, SCIPtreeHasCurrentNodeLP(scip->tree)); 1233 } 1234 1235 /** gets values of multiple variables in primal CIP solution 1236 * 1237 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 1238 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 1239 * 1240 * @pre This method can be called if SCIP is in one of the following stages: 1241 * - \ref SCIP_STAGE_PROBLEM 1242 * - \ref SCIP_STAGE_TRANSFORMING 1243 * - \ref SCIP_STAGE_TRANSFORMED 1244 * - \ref SCIP_STAGE_INITPRESOLVE 1245 * - \ref SCIP_STAGE_PRESOLVING 1246 * - \ref SCIP_STAGE_EXITPRESOLVE 1247 * - \ref SCIP_STAGE_PRESOLVED 1248 * - \ref SCIP_STAGE_INITSOLVE 1249 * - \ref SCIP_STAGE_SOLVING 1250 * - \ref SCIP_STAGE_SOLVED 1251 * - \ref SCIP_STAGE_EXITSOLVE 1252 * - \ref SCIP_STAGE_FREETRANS 1253 */ 1254 SCIP_RETCODE SCIPgetSolVals( 1255 SCIP* scip, /**< SCIP data structure */ 1256 SCIP_SOL* sol, /**< primal solution, or NULL for current LP/pseudo solution */ 1257 int nvars, /**< number of variables to get solution value for */ 1258 SCIP_VAR** vars, /**< array with variables to get value for */ 1259 SCIP_Real* vals /**< array to store solution values of variables */ 1260 ) 1261 { 1262 assert(nvars == 0 || vars != NULL); 1263 assert(nvars == 0 || vals != NULL); 1264 1265 SCIP_CALL( SCIPcheckStage(scip, "SCIPgetSolVals", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) ); 1266 1267 if( sol != NULL ) 1268 { 1269 int v; 1270 1271 for( v = 0; v < nvars; ++v ) 1272 vals[v] = SCIPsolGetVal(sol, scip->set, scip->stat, vars[v]); 1273 } 1274 else 1275 { 1276 SCIP_CALL( SCIPgetVarSols(scip, nvars, vars, vals) ); 1277 } 1278 1279 return SCIP_OKAY; 1280 } 1281 1282 /** returns objective value of primal CIP solution w.r.t. original problem, or current LP/pseudo objective value 1283 * 1284 * @return objective value of primal CIP solution w.r.t. original problem, or current LP/pseudo objective value 1285 * 1286 * @pre This method can be called if SCIP is in one of the following stages: 1287 * - \ref SCIP_STAGE_PROBLEM 1288 * - \ref SCIP_STAGE_TRANSFORMING 1289 * - \ref SCIP_STAGE_TRANSFORMED 1290 * - \ref SCIP_STAGE_INITPRESOLVE 1291 * - \ref SCIP_STAGE_PRESOLVING 1292 * - \ref SCIP_STAGE_EXITPRESOLVE 1293 * - \ref SCIP_STAGE_PRESOLVED 1294 * - \ref SCIP_STAGE_INITSOLVE 1295 * - \ref SCIP_STAGE_SOLVING 1296 * - \ref SCIP_STAGE_SOLVED 1297 * - \ref SCIP_STAGE_EXITSOLVE 1298 * - \ref SCIP_STAGE_FREETRANS 1299 */ 1300 SCIP_Real SCIPgetSolOrigObj( 1301 SCIP* scip, /**< SCIP data structure */ 1302 SCIP_SOL* sol /**< primal solution, or NULL for current LP/pseudo objective value */ 1303 ) 1304 { 1305 /* for original solutions, an original objective value is already available in SCIP_STAGE_PROBLEM 1306 * for all other solutions, we should be at least in SCIP_STAGE_TRANSFORMING 1307 */ 1308 if( sol != NULL && SCIPsolIsOriginal(sol) ) 1309 { 1310 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetSolOrigObj", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) ); 1311 1312 return SCIPsolGetOrigObj(sol); 1313 } 1314 1315 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetSolOrigObj", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) ); 1316 1317 if( sol != NULL ) 1318 return SCIPprobExternObjval(scip->transprob, scip->origprob, scip->set, SCIPsolGetObj(sol, scip->set, scip->transprob, scip->origprob)); 1319 else 1320 { 1321 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetSolOrigObj(sol==NULL)", \ 1322 FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 1323 if( SCIPtreeHasCurrentNodeLP(scip->tree) ) 1324 return SCIPprobExternObjval(scip->transprob, scip->origprob, scip->set, SCIPlpGetObjval(scip->lp, scip->set, scip->transprob)); 1325 else 1326 return SCIPprobExternObjval(scip->transprob, scip->origprob, scip->set, SCIPlpGetPseudoObjval(scip->lp, scip->set, scip->transprob)); 1327 } 1328 } 1329 1330 /** returns transformed objective value of primal CIP solution, or transformed current LP/pseudo objective value 1331 * 1332 * @return transformed objective value of primal CIP solution, or transformed current LP/pseudo objective value 1333 * 1334 * @pre This method can be called if SCIP is in one of the following stages: 1335 * - \ref SCIP_STAGE_TRANSFORMING 1336 * - \ref SCIP_STAGE_TRANSFORMED 1337 * - \ref SCIP_STAGE_INITPRESOLVE 1338 * - \ref SCIP_STAGE_PRESOLVING 1339 * - \ref SCIP_STAGE_EXITPRESOLVE 1340 * - \ref SCIP_STAGE_PRESOLVED 1341 * - \ref SCIP_STAGE_INITSOLVE 1342 * - \ref SCIP_STAGE_SOLVING 1343 * - \ref SCIP_STAGE_SOLVED 1344 * - \ref SCIP_STAGE_EXITSOLVE 1345 * - \ref SCIP_STAGE_FREETRANS 1346 */ 1347 SCIP_Real SCIPgetSolTransObj( 1348 SCIP* scip, /**< SCIP data structure */ 1349 SCIP_SOL* sol /**< primal solution, or NULL for current LP/pseudo objective value */ 1350 ) 1351 { 1352 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetSolTransObj", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) ); 1353 1354 if( sol != NULL ) 1355 return SCIPsolGetObj(sol, scip->set, scip->transprob, scip->origprob); 1356 else 1357 { 1358 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetSolTransObj(sol==NULL)", \ 1359 FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 1360 if( SCIPtreeHasCurrentNodeLP(scip->tree) ) 1361 return SCIPlpGetObjval(scip->lp, scip->set, scip->transprob); 1362 else 1363 return SCIPlpGetPseudoObjval(scip->lp, scip->set, scip->transprob); 1364 } 1365 } 1366 1367 /** recomputes the objective value of an original solution, e.g., when transferring solutions 1368 * from the solution pool (objective coefficients might have changed in the meantime) 1369 * 1370 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 1371 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 1372 * 1373 * @pre This method can be called if SCIP is in one of the following stages: 1374 * - \ref SCIP_STAGE_PRESOLVING 1375 * - \ref SCIP_STAGE_SOLVING 1376 * 1377 */ 1378 SCIP_RETCODE SCIPrecomputeSolObj( 1379 SCIP* scip, 1380 SCIP_SOL* sol 1381 ) 1382 { 1383 assert(scip != NULL); 1384 1385 SCIP_CALL( SCIPcheckStage(scip, "SCIPrecomputeSolObj", FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 1386 1387 SCIPsolRecomputeObj(sol, scip->set, scip->stat, scip->origprob); 1388 1389 return SCIP_OKAY; 1390 } 1391 1392 /** maps original space objective value into transformed objective value 1393 * 1394 * @return transformed objective value 1395 * 1396 * @pre This method can be called if SCIP is in one of the following stages: 1397 * - \ref SCIP_STAGE_TRANSFORMING 1398 * - \ref SCIP_STAGE_TRANSFORMED 1399 * - \ref SCIP_STAGE_INITPRESOLVE 1400 * - \ref SCIP_STAGE_PRESOLVING 1401 * - \ref SCIP_STAGE_EXITPRESOLVE 1402 * - \ref SCIP_STAGE_PRESOLVED 1403 * - \ref SCIP_STAGE_INITSOLVE 1404 * - \ref SCIP_STAGE_SOLVING 1405 * - \ref SCIP_STAGE_SOLVED 1406 */ 1407 SCIP_Real SCIPtransformObj( 1408 SCIP* scip, /**< SCIP data structure */ 1409 SCIP_Real obj /**< original space objective value to transform */ 1410 ) 1411 { 1412 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPtransformObj", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 1413 1414 return SCIPprobInternObjval(scip->transprob, scip->origprob, scip->set, obj); 1415 } 1416 1417 /** maps transformed objective value into original space 1418 * 1419 * @return objective value into original space 1420 * 1421 * @pre This method can be called if SCIP is in one of the following stages: 1422 * - \ref SCIP_STAGE_TRANSFORMING 1423 * - \ref SCIP_STAGE_TRANSFORMED 1424 * - \ref SCIP_STAGE_INITPRESOLVE 1425 * - \ref SCIP_STAGE_PRESOLVING 1426 * - \ref SCIP_STAGE_EXITPRESOLVE 1427 * - \ref SCIP_STAGE_PRESOLVED 1428 * - \ref SCIP_STAGE_INITSOLVE 1429 * - \ref SCIP_STAGE_SOLVING 1430 * - \ref SCIP_STAGE_SOLVED 1431 */ 1432 SCIP_Real SCIPretransformObj( 1433 SCIP* scip, /**< SCIP data structure */ 1434 SCIP_Real obj /**< transformed objective value to retransform in original space */ 1435 ) 1436 { 1437 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPretransformObj", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 1438 1439 return SCIPprobExternObjval(scip->transprob, scip->origprob, scip->set, obj); 1440 } 1441 1442 /** gets clock time, when this solution was found 1443 * 1444 * @return clock time, when this solution was found 1445 * 1446 * @pre This method can be called if SCIP is in one of the following stages: 1447 * - \ref SCIP_STAGE_TRANSFORMING 1448 * - \ref SCIP_STAGE_TRANSFORMED 1449 * - \ref SCIP_STAGE_INITPRESOLVE 1450 * - \ref SCIP_STAGE_PRESOLVING 1451 * - \ref SCIP_STAGE_EXITPRESOLVE 1452 * - \ref SCIP_STAGE_PRESOLVED 1453 * - \ref SCIP_STAGE_INITSOLVE 1454 * - \ref SCIP_STAGE_SOLVING 1455 * - \ref SCIP_STAGE_SOLVED 1456 * - \ref SCIP_STAGE_EXITSOLVE 1457 * - \ref SCIP_STAGE_FREETRANS 1458 */ 1459 SCIP_Real SCIPgetSolTime( 1460 SCIP* scip, /**< SCIP data structure */ 1461 SCIP_SOL* sol /**< primal solution */ 1462 ) 1463 { 1464 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetSolTime", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) ); 1465 1466 return SCIPsolGetTime(sol); 1467 } 1468 1469 /** gets branch and bound run number, where this solution was found 1470 * 1471 * @return branch and bound run number, where this solution was found 1472 * 1473 * @pre This method can be called if SCIP is in one of the following stages: 1474 * - \ref SCIP_STAGE_TRANSFORMING 1475 * - \ref SCIP_STAGE_TRANSFORMED 1476 * - \ref SCIP_STAGE_INITPRESOLVE 1477 * - \ref SCIP_STAGE_PRESOLVING 1478 * - \ref SCIP_STAGE_EXITPRESOLVE 1479 * - \ref SCIP_STAGE_PRESOLVED 1480 * - \ref SCIP_STAGE_INITSOLVE 1481 * - \ref SCIP_STAGE_SOLVING 1482 * - \ref SCIP_STAGE_SOLVED 1483 * - \ref SCIP_STAGE_EXITSOLVE 1484 * - \ref SCIP_STAGE_FREETRANS 1485 */ 1486 int SCIPgetSolRunnum( 1487 SCIP* scip, /**< SCIP data structure */ 1488 SCIP_SOL* sol /**< primal solution */ 1489 ) 1490 { 1491 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetSolRunnum", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) ); 1492 1493 return SCIPsolGetRunnum(sol); 1494 } 1495 1496 /** gets node number of the specific branch and bound run, where this solution was found 1497 * 1498 * @return node number of the specific branch and bound run, where this solution was found 1499 * 1500 * @pre This method can be called if SCIP is in one of the following stages: 1501 * - \ref SCIP_STAGE_TRANSFORMING 1502 * - \ref SCIP_STAGE_TRANSFORMED 1503 * - \ref SCIP_STAGE_INITPRESOLVE 1504 * - \ref SCIP_STAGE_PRESOLVING 1505 * - \ref SCIP_STAGE_EXITPRESOLVE 1506 * - \ref SCIP_STAGE_PRESOLVED 1507 * - \ref SCIP_STAGE_INITSOLVE 1508 * - \ref SCIP_STAGE_SOLVING 1509 * - \ref SCIP_STAGE_SOLVED 1510 * - \ref SCIP_STAGE_EXITSOLVE 1511 * - \ref SCIP_STAGE_FREETRANS 1512 */ 1513 SCIP_Longint SCIPgetSolNodenum( 1514 SCIP* scip, /**< SCIP data structure */ 1515 SCIP_SOL* sol /**< primal solution */ 1516 ) 1517 { 1518 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetSolNodenum", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) ); 1519 1520 return SCIPsolGetNodenum(sol); 1521 } 1522 1523 /** gets heuristic, that found this solution (or NULL if it's from the tree) 1524 * 1525 * @return heuristic, that found this solution (or NULL if it's from the tree) 1526 * 1527 * @pre This method can be called if SCIP is in one of the following stages: 1528 * - \ref SCIP_STAGE_TRANSFORMING 1529 * - \ref SCIP_STAGE_TRANSFORMED 1530 * - \ref SCIP_STAGE_INITPRESOLVE 1531 * - \ref SCIP_STAGE_PRESOLVING 1532 * - \ref SCIP_STAGE_EXITPRESOLVE 1533 * - \ref SCIP_STAGE_PRESOLVED 1534 * - \ref SCIP_STAGE_INITSOLVE 1535 * - \ref SCIP_STAGE_SOLVING 1536 * - \ref SCIP_STAGE_SOLVED 1537 * - \ref SCIP_STAGE_EXITSOLVE 1538 * - \ref SCIP_STAGE_FREETRANS 1539 */ 1540 SCIP_HEUR* SCIPgetSolHeur( 1541 SCIP* scip, /**< SCIP data structure */ 1542 SCIP_SOL* sol /**< primal solution */ 1543 ) 1544 { 1545 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetSolHeur", FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) ); 1546 1547 return SCIPsolGetHeur(sol); 1548 } 1549 1550 /** returns whether two given solutions are exactly equal 1551 * 1552 * @return returns whether two given solutions are exactly equal 1553 * 1554 * @pre This method can be called if SCIP is in one of the following stages: 1555 * - \ref SCIP_STAGE_PROBLEM 1556 * - \ref SCIP_STAGE_TRANSFORMING 1557 * - \ref SCIP_STAGE_TRANSFORMED 1558 * - \ref SCIP_STAGE_INITPRESOLVE 1559 * - \ref SCIP_STAGE_PRESOLVING 1560 * - \ref SCIP_STAGE_EXITPRESOLVE 1561 * - \ref SCIP_STAGE_PRESOLVED 1562 * - \ref SCIP_STAGE_INITSOLVE 1563 * - \ref SCIP_STAGE_SOLVING 1564 * - \ref SCIP_STAGE_SOLVED 1565 * - \ref SCIP_STAGE_EXITSOLVE 1566 * - \ref SCIP_STAGE_FREETRANS 1567 */ 1568 SCIP_Bool SCIPareSolsEqual( 1569 SCIP* scip, /**< SCIP data structure */ 1570 SCIP_SOL* sol1, /**< first primal CIP solution */ 1571 SCIP_SOL* sol2 /**< second primal CIP solution */ 1572 ) 1573 { 1574 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPareSolsEqual", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) ); 1575 1576 return SCIPsolsAreEqual(sol1, sol2, scip->set, scip->stat, scip->origprob, scip->transprob); 1577 } 1578 1579 /** adjusts solution values of implicit integer variables in handed solution. Solution objective value is not 1580 * deteriorated by this method. 1581 * 1582 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 1583 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 1584 * 1585 * @pre This method can be called if SCIP is in one of the following stages: 1586 * - \ref SCIP_STAGE_SOLVING 1587 */ 1588 SCIP_RETCODE SCIPadjustImplicitSolVals( 1589 SCIP* scip, /**< SCIP data structure */ 1590 SCIP_SOL* sol, /**< primal CIP solution */ 1591 SCIP_Bool uselprows /**< should LP row information be considered for none-objective variables */ 1592 ) 1593 { 1594 assert(scip != NULL); 1595 SCIP_CALL( SCIPcheckStage(scip, "SCIPadjustImplicitSolVals", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 1596 1597 assert(sol != NULL); 1598 SCIP_CALL( SCIPsolAdjustImplicitSolVals(sol, scip->set, scip->stat, scip->transprob, scip->tree, uselprows) ); 1599 1600 return SCIP_OKAY; 1601 } 1602 1603 /** outputs non-zero variables of solution in original problem space to the given file stream 1604 * 1605 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 1606 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 1607 * 1608 * @pre In case the solution pointer @p sol is NULL (asking for the current LP/pseudo solution), this method can be 1609 * called if @p scip is in one of the following stages: 1610 * - \ref SCIP_STAGE_PRESOLVING 1611 * - \ref SCIP_STAGE_EXITPRESOLVE 1612 * - \ref SCIP_STAGE_PRESOLVED 1613 * - \ref SCIP_STAGE_INITSOLVE 1614 * - \ref SCIP_STAGE_SOLVING 1615 * - \ref SCIP_STAGE_SOLVED 1616 * - \ref SCIP_STAGE_EXITSOLVE 1617 * 1618 * @pre In case the solution pointer @p sol is @b not NULL, this method can be called if @p scip is in one of the 1619 * following stages: 1620 * - \ref SCIP_STAGE_PROBLEM 1621 * - \ref SCIP_STAGE_TRANSFORMED 1622 * - \ref SCIP_STAGE_INITPRESOLVE 1623 * - \ref SCIP_STAGE_PRESOLVING 1624 * - \ref SCIP_STAGE_EXITPRESOLVE 1625 * - \ref SCIP_STAGE_PRESOLVED 1626 * - \ref SCIP_STAGE_INITSOLVE 1627 * - \ref SCIP_STAGE_SOLVING 1628 * - \ref SCIP_STAGE_SOLVED 1629 * - \ref SCIP_STAGE_EXITSOLVE 1630 */ 1631 SCIP_RETCODE SCIPprintSol( 1632 SCIP* scip, /**< SCIP data structure */ 1633 SCIP_SOL* sol, /**< primal solution, or NULL for current LP/pseudo solution */ 1634 FILE* file, /**< output file (or NULL for standard output) */ 1635 SCIP_Bool printzeros /**< should variables set to zero be printed? */ 1636 ) 1637 { 1638 SCIP_Real objvalue; 1639 SCIP_Bool currentsol; 1640 SCIP_Bool oldquiet = FALSE; 1641 1642 assert(SCIPisTransformed(scip) || sol != NULL); 1643 1644 SCIP_CALL( SCIPcheckStage(scip, "SCIPprintSol", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) ); 1645 1646 currentsol = (sol == NULL); 1647 if( currentsol ) 1648 { 1649 SCIP_CALL( SCIPcheckStage(scip, "SCIPprintSol(sol==NULL)", \ 1650 FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) ); 1651 1652 /* create a temporary solution that is linked to the current solution */ 1653 SCIP_CALL( SCIPsolCreateCurrentSol(&sol, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->primal, 1654 scip->tree, scip->lp, NULL) ); 1655 } 1656 1657 if( file != NULL && scip->messagehdlr != NULL ) 1658 { 1659 oldquiet = SCIPmessagehdlrIsQuiet(scip->messagehdlr); 1660 SCIPmessagehdlrSetQuiet(scip->messagehdlr, FALSE); 1661 } 1662 1663 SCIPmessageFPrintInfo(scip->messagehdlr, file, "objective value: "); 1664 1665 if( SCIPsolIsPartial(sol) ) 1666 { 1667 SCIPmessageFPrintInfo(scip->messagehdlr, file, "unknown\n"); 1668 } 1669 else 1670 { 1671 if( SCIPsolIsOriginal(sol) ) 1672 objvalue = SCIPsolGetOrigObj(sol); 1673 else 1674 objvalue = SCIPprobExternObjval(scip->transprob, scip->origprob, scip->set, SCIPsolGetObj(sol, scip->set, scip->transprob, scip->origprob)); 1675 1676 SCIPprintReal(scip, file, objvalue, 20, 15); 1677 SCIPmessageFPrintInfo(scip->messagehdlr, file, "\n"); 1678 } 1679 1680 SCIP_CALL( SCIPsolPrint(sol, scip->set, scip->messagehdlr, scip->stat, scip->origprob, scip->transprob, file, FALSE, 1681 printzeros) ); 1682 1683 if( file != NULL && scip->messagehdlr != NULL ) 1684 { 1685 SCIPmessagehdlrSetQuiet(scip->messagehdlr, oldquiet); 1686 } 1687 1688 if( currentsol ) 1689 { 1690 /* free temporary solution */ 1691 SCIP_CALL( SCIPsolFree(&sol, scip->mem->probmem, scip->primal) ); 1692 } 1693 1694 return SCIP_OKAY; 1695 } 1696 1697 /** outputs non-zero variables of solution in transformed problem space to file stream 1698 * 1699 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 1700 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 1701 * 1702 * @pre This method can be called if SCIP is in one of the following stages: 1703 * - \ref SCIP_STAGE_TRANSFORMED 1704 * - \ref SCIP_STAGE_INITPRESOLVE 1705 * - \ref SCIP_STAGE_PRESOLVING 1706 * - \ref SCIP_STAGE_EXITPRESOLVE 1707 * - \ref SCIP_STAGE_PRESOLVED 1708 * - \ref SCIP_STAGE_INITSOLVE 1709 * - \ref SCIP_STAGE_SOLVING 1710 * - \ref SCIP_STAGE_SOLVED 1711 * - \ref SCIP_STAGE_EXITSOLVE 1712 */ 1713 SCIP_RETCODE SCIPprintTransSol( 1714 SCIP* scip, /**< SCIP data structure */ 1715 SCIP_SOL* sol, /**< primal solution, or NULL for current LP/pseudo solution */ 1716 FILE* file, /**< output file (or NULL for standard output) */ 1717 SCIP_Bool printzeros /**< should variables set to zero be printed? */ 1718 ) 1719 { 1720 SCIP_Bool currentsol; 1721 1722 SCIP_CALL( SCIPcheckStage(scip, "SCIPprintTransSol", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) ); 1723 1724 currentsol = (sol == NULL); 1725 if( currentsol ) 1726 { 1727 /* create a temporary solution that is linked to the current solution */ 1728 SCIP_CALL( SCIPsolCreateCurrentSol(&sol, scip->mem->probmem, scip->set, scip->stat, scip->transprob, scip->primal, 1729 scip->tree, scip->lp, NULL) ); 1730 } 1731 1732 if( SCIPsolIsOriginal(sol) ) 1733 { 1734 SCIPerrorMessage("cannot print original space solution as transformed solution\n"); 1735 return SCIP_INVALIDCALL; 1736 } 1737 1738 SCIPmessageFPrintInfo(scip->messagehdlr, file, "objective value: "); 1739 SCIPprintReal(scip, file, SCIPsolGetObj(sol, scip->set, scip->transprob, scip->origprob), 20, 9); 1740 SCIPmessageFPrintInfo(scip->messagehdlr, file, "\n"); 1741 1742 SCIP_CALL( SCIPsolPrint(sol, scip->set, scip->messagehdlr, scip->stat, scip->transprob, NULL, file, FALSE, printzeros) ); 1743 1744 if( currentsol ) 1745 { 1746 /* free temporary solution */ 1747 SCIP_CALL( SCIPsolFree(&sol, scip->mem->probmem, scip->primal) ); 1748 } 1749 1750 return SCIP_OKAY; 1751 } 1752 1753 /** outputs discrete variables of solution in original problem space to the given file stream 1754 * 1755 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 1756 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 1757 * 1758 * @pre This method can be called if @p scip is in one of the following stages: 1759 * - \ref SCIP_STAGE_PROBLEM 1760 * - \ref SCIP_STAGE_TRANSFORMED 1761 * - \ref SCIP_STAGE_INITPRESOLVE 1762 * - \ref SCIP_STAGE_PRESOLVING 1763 * - \ref SCIP_STAGE_EXITPRESOLVE 1764 * - \ref SCIP_STAGE_PRESOLVED 1765 * - \ref SCIP_STAGE_INITSOLVE 1766 * - \ref SCIP_STAGE_SOLVING 1767 * - \ref SCIP_STAGE_SOLVED 1768 * - \ref SCIP_STAGE_EXITSOLVE 1769 */ 1770 SCIP_RETCODE SCIPprintMIPStart( 1771 SCIP* scip, /**< SCIP data structure */ 1772 SCIP_SOL* sol, /**< primal solution */ 1773 FILE* file /**< output file (or NULL for standard output) */ 1774 ) 1775 { 1776 SCIP_Real objvalue; 1777 SCIP_Bool oldquiet = FALSE; 1778 1779 assert(sol != NULL); 1780 assert(!SCIPsolIsPartial(sol)); 1781 1782 SCIP_CALL( SCIPcheckStage(scip, "SCIPprintMIPStart", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) ); 1783 1784 if( file != NULL && scip->messagehdlr != NULL ) 1785 { 1786 oldquiet = SCIPmessagehdlrIsQuiet(scip->messagehdlr); 1787 SCIPmessagehdlrSetQuiet(scip->messagehdlr, FALSE); 1788 } 1789 1790 SCIPmessageFPrintInfo(scip->messagehdlr, file, "objective value: "); 1791 1792 if( SCIPsolIsOriginal(sol) ) 1793 objvalue = SCIPsolGetOrigObj(sol); 1794 else 1795 objvalue = SCIPprobExternObjval(scip->transprob, scip->origprob, scip->set, SCIPsolGetObj(sol, scip->set, scip->transprob, scip->origprob)); 1796 1797 SCIPprintReal(scip, file, objvalue, 20, 15); 1798 SCIPmessageFPrintInfo(scip->messagehdlr, file, "\n"); 1799 1800 SCIP_CALL( SCIPsolPrint(sol, scip->set, scip->messagehdlr, scip->stat, scip->origprob, scip->transprob, file, TRUE, 1801 TRUE) ); 1802 1803 if( file != NULL && scip->messagehdlr != NULL ) 1804 { 1805 SCIPmessagehdlrSetQuiet(scip->messagehdlr, oldquiet); 1806 } 1807 1808 return SCIP_OKAY; 1809 } 1810 1811 /** returns dual solution value of a constraint */ 1812 SCIP_RETCODE SCIPgetDualSolVal( 1813 SCIP* scip, /**< SCIP data structure */ 1814 SCIP_CONS* cons, /**< constraint for which the dual solution should be returned */ 1815 SCIP_Real* dualsolval, /**< pointer to store the dual solution value */ 1816 SCIP_Bool* boundconstraint /**< pointer to store whether the constraint is a bound constraint (or NULL) */ 1817 ) 1818 { 1819 SCIP_CONS* transcons; 1820 int nvars; 1821 SCIP_Bool success; 1822 1823 assert(scip != NULL); 1824 assert(cons != NULL); 1825 assert(dualsolval != NULL); 1826 1827 assert(SCIPconsGetHdlr(cons) != NULL); 1828 assert(strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), "linear" ) == 0); 1829 1830 SCIP_CALL( SCIPconsGetNVars(cons, scip->set, &nvars, &success) ); 1831 assert(success); /* is always successful, since we only have linear constraints */ 1832 1833 if( boundconstraint != NULL ) 1834 *boundconstraint = (nvars == 1); 1835 1836 if( SCIPconsIsTransformed(cons) ) 1837 transcons = cons; 1838 else 1839 transcons = SCIPconsGetTransformed(cons); 1840 1841 /* it can happen that a transformed constraints gets deleted due to redundancy. by complementary slackness the 1842 * corresponding dual solution value would be zero. however, if the constraint contains exactly one variable we need 1843 * to check the reduced costs of the variable. 1844 */ 1845 if( nvars == 0 || (nvars > 1 && transcons == NULL) ) 1846 (*dualsolval) = 0.0; 1847 else 1848 { 1849 if( nvars > 1 ) 1850 (*dualsolval) = SCIPgetDualsolLinear(scip, transcons); 1851 else 1852 { 1853 /* the constraint is a bound constraint */ 1854 SCIP_VAR** vars; 1855 SCIP_Real* vals; 1856 SCIP_Real activity; 1857 1858 vars = SCIPgetVarsLinear(scip, cons); 1859 vals = SCIPgetValsLinear(scip, cons); 1860 1861 activity = SCIPvarGetLPSol(vars[0]) * vals[0]; 1862 1863 /* return the reduced cost of the variable if the constraint would be tight */ 1864 if( SCIPsetIsEQ(scip->set, activity, SCIPgetRhsLinear(scip, cons)) 1865 || SCIPsetIsEQ(scip->set, activity, SCIPgetLhsLinear(scip, cons)) ) 1866 (*dualsolval) = SCIPgetVarRedcost(scip, vars[0]); 1867 else 1868 (*dualsolval) = 0.0; 1869 } 1870 } 1871 assert(*dualsolval != SCIP_INVALID); /*lint !e777*/ 1872 1873 /* dual values are coming from the LP solver that is always solving a minimization problem */ 1874 if( SCIPgetObjsense(scip) == SCIP_OBJSENSE_MAXIMIZE ) 1875 (*dualsolval) *= -1.0; 1876 1877 return SCIP_OKAY; 1878 } 1879 1880 /** outputs dual solution from LP solver to file stream */ 1881 static 1882 SCIP_RETCODE printDualSol( 1883 SCIP* scip, /**< SCIP data structure */ 1884 FILE* file, /**< output file (or NULL for standard output) */ 1885 SCIP_Bool printzeros /**< should variables set to zero be printed? */ 1886 ) 1887 { 1888 SCIP_Bool boundconstraint; 1889 int c; 1890 1891 assert(scip->lp != NULL); 1892 assert(scip->lp->solved); 1893 assert(scip->lp->dualfeasible); 1894 1895 /* print dual solution values of all constraints */ 1896 for( c = 0; c < scip->origprob->nconss; ++c ) 1897 { 1898 SCIP_CONS* cons; 1899 SCIP_Real solval; 1900 1901 cons = scip->origprob->conss[c]; 1902 assert(cons != NULL); 1903 1904 SCIP_CALL( SCIPgetDualSolVal(scip, cons, &solval, &boundconstraint) ); 1905 1906 if( printzeros || !SCIPisZero(scip, solval) ) 1907 { 1908 SCIP_MESSAGEHDLR* messagehdlr = scip->messagehdlr; 1909 1910 SCIPmessageFPrintInfo(messagehdlr, file, "%-32s", SCIPconsGetName(cons)); 1911 1912 if( SCIPisInfinity(scip, solval) ) 1913 SCIPmessageFPrintInfo(messagehdlr, file, " +infinity\n"); 1914 else if( SCIPisInfinity(scip, -solval) ) 1915 SCIPmessageFPrintInfo(messagehdlr, file, " -infinity\n"); 1916 else 1917 { 1918 if( boundconstraint ) 1919 SCIPmessageFPrintInfo(messagehdlr, file, " %20.15g*\n", solval); 1920 else 1921 SCIPmessageFPrintInfo(messagehdlr, file, " %20.15g\n", solval); 1922 } 1923 } 1924 } 1925 1926 return SCIP_OKAY; 1927 } 1928 1929 /** check whether the dual solution is available 1930 * 1931 * @note This is used when calling \ref SCIPprintDualSol() 1932 * 1933 * @return is dual solution available? 1934 * 1935 * @pre This method can be called if SCIP is in one of the following stages: 1936 * - \ref SCIP_STAGE_SOLVED 1937 */ 1938 SCIP_Bool SCIPisDualSolAvailable( 1939 SCIP* scip, /**< SCIP data structure */ 1940 SCIP_Bool printreason /**< print warning message if dualsol is not available? */ 1941 ) 1942 { 1943 int c; 1944 1945 assert(scip != NULL); 1946 1947 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPisDualSolAvailable", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE) ); 1948 1949 if( SCIPgetStage(scip) != SCIP_STAGE_SOLVED ) 1950 { 1951 if( printreason ) 1952 SCIPmessageFPrintInfo(scip->messagehdlr, NULL, "No dual solution available.\n"); 1953 return FALSE; 1954 } 1955 1956 assert(scip->stat != NULL); 1957 assert(scip->transprob != NULL); 1958 1959 /* dual solution only useful when no presolving was performed */ 1960 if( scip->stat->performpresol ) 1961 { 1962 if( printreason ) 1963 SCIPwarningMessage(scip, "No dual information available when presolving was performed.\n"); 1964 return FALSE; 1965 } 1966 1967 /* dual solution is created by LP solver and therefore only available for pure LPs */ 1968 if( scip->transprob->nvars != scip->transprob->ncontvars ) 1969 { 1970 if( printreason ) 1971 SCIPwarningMessage(scip, "Dual information only available for pure LPs (only continuous variables).\n"); 1972 return FALSE; 1973 } 1974 1975 /* dual solution is created by LP solver and therefore only available for linear constraints */ 1976 for( c = scip->transprob->nconss - 1; c >= 0; --c ) 1977 { 1978 SCIP_CONSHDLR* conshdlr; 1979 1980 conshdlr = SCIPconsGetHdlr(scip->transprob->conss[c]); 1981 assert(conshdlr != NULL); 1982 1983 if( strcmp(SCIPconshdlrGetName(conshdlr), "linear" ) != 0 ) 1984 { 1985 if( printreason ) 1986 SCIPwarningMessage(scip, "Dual information only available for pure LPs (only linear constraints).\n"); 1987 return FALSE; 1988 } 1989 } 1990 1991 return TRUE; 1992 } 1993 1994 /** outputs dual solution from LP solver to file stream 1995 * 1996 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 1997 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 1998 * 1999 * @pre This method can be called in all stages but only prints dual information when called in \ref SCIP_STAGE_SOLVED 2000 */ 2001 SCIP_RETCODE SCIPprintDualSol( 2002 SCIP* scip, /**< SCIP data structure */ 2003 FILE* file, /**< output file (or NULL for standard output) */ 2004 SCIP_Bool printzeros /**< should variables set to zero be printed? */ 2005 ) 2006 { 2007 if( SCIPisDualSolAvailable(scip, TRUE) ) 2008 { 2009 /* print dual solution */ 2010 SCIP_CALL( printDualSol(scip, file, printzeros) ); 2011 } 2012 2013 return SCIP_OKAY; 2014 } 2015 2016 2017 /** outputs non-zero variables of solution representing a ray in original problem space to file stream 2018 * 2019 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 2020 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 2021 * 2022 * @pre This method can be called if SCIP is in one of the following stages: 2023 * - \ref SCIP_STAGE_PROBLEM 2024 * - \ref SCIP_STAGE_TRANSFORMED 2025 * - \ref SCIP_STAGE_INITPRESOLVE 2026 * - \ref SCIP_STAGE_PRESOLVING 2027 * - \ref SCIP_STAGE_EXITPRESOLVE 2028 * - \ref SCIP_STAGE_PRESOLVED 2029 * - \ref SCIP_STAGE_INITSOLVE 2030 * - \ref SCIP_STAGE_SOLVING 2031 * - \ref SCIP_STAGE_SOLVED 2032 * - \ref SCIP_STAGE_EXITSOLVE 2033 */ 2034 SCIP_RETCODE SCIPprintRay( 2035 SCIP* scip, /**< SCIP data structure */ 2036 SCIP_SOL* sol, /**< primal solution representing ray */ 2037 FILE* file, /**< output file (or NULL for standard output) */ 2038 SCIP_Bool printzeros /**< should variables set to zero be printed? */ 2039 ) 2040 { 2041 assert(scip != NULL); 2042 assert(sol != NULL); 2043 2044 SCIP_CALL( SCIPcheckStage(scip, "SCIPprintRay", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) ); 2045 2046 SCIP_CALL( SCIPsolPrintRay(sol, scip->set, scip->messagehdlr, scip->stat, scip->origprob, scip->transprob, file, printzeros) ); 2047 2048 return SCIP_OKAY; 2049 } 2050 2051 /** gets number of feasible primal solutions stored in the solution storage in case the problem is transformed; 2052 * in case the problem stage is SCIP_STAGE_PROBLEM, the number of solution in the original solution candidate 2053 * storage is returned 2054 * 2055 * @return number of feasible primal solutions stored in the solution storage in case the problem is transformed; or 2056 * number of solution in the original solution candidate storage if the problem stage is SCIP_STAGE_PROBLEM 2057 * 2058 * @pre This method can be called if SCIP is in one of the following stages: 2059 * - \ref SCIP_STAGE_PROBLEM 2060 * - \ref SCIP_STAGE_TRANSFORMED 2061 * - \ref SCIP_STAGE_INITPRESOLVE 2062 * - \ref SCIP_STAGE_PRESOLVING 2063 * - \ref SCIP_STAGE_EXITPRESOLVE 2064 * - \ref SCIP_STAGE_PRESOLVED 2065 * - \ref SCIP_STAGE_INITSOLVE 2066 * - \ref SCIP_STAGE_SOLVING 2067 * - \ref SCIP_STAGE_SOLVED 2068 * - \ref SCIP_STAGE_EXITSOLVE 2069 */ 2070 int SCIPgetNSols( 2071 SCIP* scip /**< SCIP data structure */ 2072 ) 2073 { 2074 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNSols", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) ); 2075 2076 switch( scip->set->stage ) 2077 { 2078 case SCIP_STAGE_PROBLEM: 2079 return scip->origprimal->nsols; 2080 2081 case SCIP_STAGE_TRANSFORMED: 2082 case SCIP_STAGE_INITPRESOLVE: 2083 case SCIP_STAGE_PRESOLVING: 2084 case SCIP_STAGE_EXITPRESOLVE: 2085 case SCIP_STAGE_PRESOLVED: 2086 case SCIP_STAGE_INITSOLVE: 2087 case SCIP_STAGE_SOLVING: 2088 case SCIP_STAGE_SOLVED: 2089 case SCIP_STAGE_EXITSOLVE: 2090 return scip->primal->nsols; 2091 2092 case SCIP_STAGE_INIT: 2093 case SCIP_STAGE_TRANSFORMING: 2094 case SCIP_STAGE_FREETRANS: 2095 default: 2096 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage); 2097 SCIPABORT(); 2098 return -1; /*lint !e527*/ 2099 } /*lint !e788*/ 2100 } 2101 2102 /** gets array of feasible primal solutions stored in the solution storage in case the problem is transformed; in case 2103 * if the problem stage is in SCIP_STAGE_PROBLEM, it returns the number array of solution candidate stored 2104 * 2105 * @return array of feasible primal solutions 2106 * 2107 * @pre This method can be called if SCIP is in one of the following stages: 2108 * - \ref SCIP_STAGE_PROBLEM 2109 * - \ref SCIP_STAGE_TRANSFORMED 2110 * - \ref SCIP_STAGE_INITPRESOLVE 2111 * - \ref SCIP_STAGE_PRESOLVING 2112 * - \ref SCIP_STAGE_EXITPRESOLVE 2113 * - \ref SCIP_STAGE_PRESOLVED 2114 * - \ref SCIP_STAGE_INITSOLVE 2115 * - \ref SCIP_STAGE_SOLVING 2116 * - \ref SCIP_STAGE_SOLVED 2117 * - \ref SCIP_STAGE_EXITSOLVE 2118 */ 2119 SCIP_SOL** SCIPgetSols( 2120 SCIP* scip /**< SCIP data structure */ 2121 ) 2122 { 2123 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetSols", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) ); 2124 2125 switch( scip->set->stage ) 2126 { 2127 case SCIP_STAGE_PROBLEM: 2128 return scip->origprimal->sols; 2129 2130 case SCIP_STAGE_TRANSFORMED: 2131 case SCIP_STAGE_INITPRESOLVE: 2132 case SCIP_STAGE_PRESOLVING: 2133 case SCIP_STAGE_EXITPRESOLVE: 2134 case SCIP_STAGE_PRESOLVED: 2135 case SCIP_STAGE_INITSOLVE: 2136 case SCIP_STAGE_SOLVING: 2137 case SCIP_STAGE_SOLVED: 2138 case SCIP_STAGE_EXITSOLVE: 2139 return scip->primal->sols; 2140 2141 case SCIP_STAGE_INIT: 2142 case SCIP_STAGE_TRANSFORMING: 2143 case SCIP_STAGE_FREETRANS: 2144 case SCIP_STAGE_FREE: 2145 default: 2146 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage); 2147 return NULL; 2148 } /*lint !e788*/ 2149 } 2150 2151 /** gets best feasible primal solution found so far if the problem is transformed; in case the problem is in 2152 * SCIP_STAGE_PROBLEM it returns the best solution candidate, or NULL if no solution has been found or the candidate 2153 * store is empty; 2154 * 2155 * @return best feasible primal solution so far 2156 * 2157 * @pre This method can be called if SCIP is in one of the following stages: 2158 * - \ref SCIP_STAGE_PROBLEM 2159 * - \ref SCIP_STAGE_TRANSFORMED 2160 * - \ref SCIP_STAGE_INITPRESOLVE 2161 * - \ref SCIP_STAGE_PRESOLVING 2162 * - \ref SCIP_STAGE_EXITPRESOLVE 2163 * - \ref SCIP_STAGE_PRESOLVED 2164 * - \ref SCIP_STAGE_INITSOLVE 2165 * - \ref SCIP_STAGE_SOLVING 2166 * - \ref SCIP_STAGE_SOLVED 2167 * - \ref SCIP_STAGE_EXITSOLVE 2168 */ 2169 SCIP_SOL* SCIPgetBestSol( 2170 SCIP* scip /**< SCIP data structure */ 2171 ) 2172 { 2173 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetBestSol", TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) ); 2174 switch( scip->set->stage ) 2175 { 2176 case SCIP_STAGE_INIT: 2177 return NULL; 2178 case SCIP_STAGE_PROBLEM: 2179 assert(scip->origprimal != NULL); 2180 if( scip->origprimal->nsols > 0 ) 2181 { 2182 assert(scip->origprimal->sols != NULL); 2183 assert(scip->origprimal->sols[0] != NULL); 2184 return scip->origprimal->sols[0]; 2185 } 2186 break; 2187 2188 case SCIP_STAGE_TRANSFORMED: 2189 case SCIP_STAGE_INITPRESOLVE: 2190 case SCIP_STAGE_PRESOLVING: 2191 case SCIP_STAGE_EXITPRESOLVE: 2192 case SCIP_STAGE_PRESOLVED: 2193 case SCIP_STAGE_INITSOLVE: 2194 case SCIP_STAGE_SOLVING: 2195 case SCIP_STAGE_SOLVED: 2196 case SCIP_STAGE_EXITSOLVE: 2197 assert(scip->primal != NULL); 2198 if( scip->primal->nsols > 0 ) 2199 { 2200 assert(scip->primal->sols != NULL); 2201 assert(scip->primal->sols[0] != NULL); 2202 return scip->primal->sols[0]; 2203 } 2204 break; 2205 2206 case SCIP_STAGE_TRANSFORMING: 2207 case SCIP_STAGE_FREETRANS: 2208 case SCIP_STAGE_FREE: 2209 default: 2210 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage); 2211 return NULL; 2212 } 2213 2214 return NULL; 2215 } 2216 2217 /** outputs best feasible primal solution found so far to file stream 2218 * 2219 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 2220 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 2221 * 2222 * @pre This method can be called if SCIP is in one of the following stages: 2223 * - \ref SCIP_STAGE_INIT 2224 * - \ref SCIP_STAGE_PROBLEM 2225 * - \ref SCIP_STAGE_TRANSFORMED 2226 * - \ref SCIP_STAGE_INITPRESOLVE 2227 * - \ref SCIP_STAGE_PRESOLVING 2228 * - \ref SCIP_STAGE_EXITPRESOLVE 2229 * - \ref SCIP_STAGE_PRESOLVED 2230 * - \ref SCIP_STAGE_INITSOLVE 2231 * - \ref SCIP_STAGE_SOLVING 2232 * - \ref SCIP_STAGE_SOLVED 2233 * - \ref SCIP_STAGE_EXITSOLVE 2234 */ 2235 SCIP_RETCODE SCIPprintBestSol( 2236 SCIP* scip, /**< SCIP data structure */ 2237 FILE* file, /**< output file (or NULL for standard output) */ 2238 SCIP_Bool printzeros /**< should variables set to zero be printed? */ 2239 ) 2240 { 2241 SCIP_SOL* sol; 2242 2243 SCIP_CALL( SCIPcheckStage(scip, "SCIPprintBestSol", TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) ); 2244 2245 sol = SCIPgetBestSol(scip); 2246 2247 if( sol == NULL ) 2248 SCIPmessageFPrintInfo(scip->messagehdlr, file, "no solution available\n"); 2249 else 2250 { 2251 SCIP_CALL( SCIPprintSol(scip, sol, file, printzeros) ); 2252 } 2253 2254 return SCIP_OKAY; 2255 } 2256 2257 /** outputs best feasible primal solution found so far in transformed variables to file stream 2258 * 2259 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 2260 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 2261 * 2262 * @pre This method can be called if SCIP is in one of the following stages: 2263 * - \ref SCIP_STAGE_INIT 2264 * - \ref SCIP_STAGE_PROBLEM 2265 * - \ref SCIP_STAGE_TRANSFORMED 2266 * - \ref SCIP_STAGE_INITPRESOLVE 2267 * - \ref SCIP_STAGE_PRESOLVING 2268 * - \ref SCIP_STAGE_EXITPRESOLVE 2269 * - \ref SCIP_STAGE_PRESOLVED 2270 * - \ref SCIP_STAGE_INITSOLVE 2271 * - \ref SCIP_STAGE_SOLVING 2272 * - \ref SCIP_STAGE_SOLVED 2273 * - \ref SCIP_STAGE_EXITSOLVE 2274 */ 2275 SCIP_RETCODE SCIPprintBestTransSol( 2276 SCIP* scip, /**< SCIP data structure */ 2277 FILE* file, /**< output file (or NULL for standard output) */ 2278 SCIP_Bool printzeros /**< should variables set to zero be printed? */ 2279 ) 2280 { 2281 SCIP_SOL* sol; 2282 2283 SCIP_CALL( SCIPcheckStage(scip, "SCIPprintBestTransSol", TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) ); 2284 2285 sol = SCIPgetBestSol(scip); 2286 2287 if( sol != NULL && SCIPsolIsOriginal(sol) ) 2288 { 2289 SCIPerrorMessage("best solution is defined in original space - cannot print it as transformed solution\n"); 2290 return SCIP_INVALIDCALL; 2291 } 2292 2293 if( sol == NULL ) 2294 SCIPmessageFPrintInfo(scip->messagehdlr, file, "no solution available\n"); 2295 else 2296 { 2297 SCIP_CALL( SCIPprintTransSol(scip, sol, file, printzeros) ); 2298 } 2299 2300 return SCIP_OKAY; 2301 } 2302 2303 /** try to round given solution 2304 * 2305 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 2306 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 2307 * 2308 * @pre This method can be called if SCIP is in one of the following stages: 2309 * - \ref SCIP_STAGE_SOLVING 2310 */ 2311 SCIP_RETCODE SCIProundSol( 2312 SCIP* scip, /**< SCIP data structure */ 2313 SCIP_SOL* sol, /**< primal solution */ 2314 SCIP_Bool* success /**< pointer to store whether rounding was successful */ 2315 ) 2316 { 2317 SCIP_CALL( SCIPcheckStage(scip, "SCIProundSol", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 2318 2319 if( SCIPsolIsOriginal(sol) ) 2320 { 2321 SCIPerrorMessage("cannot round original space solution\n"); 2322 return SCIP_INVALIDCALL; 2323 } 2324 2325 SCIP_CALL( SCIPsolRound(sol, scip->set, scip->stat, scip->transprob, scip->tree, success) ); 2326 2327 return SCIP_OKAY; 2328 } 2329 2330 /** retransforms solution to original problem space 2331 * 2332 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 2333 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 2334 * 2335 * @pre This method can be called if SCIP is in one of the following stages: 2336 * - \ref SCIP_STAGE_TRANSFORMED 2337 * - \ref SCIP_STAGE_INITPRESOLVE 2338 * - \ref SCIP_STAGE_PRESOLVING 2339 * - \ref SCIP_STAGE_EXITPRESOLVE 2340 * - \ref SCIP_STAGE_PRESOLVED 2341 * - \ref SCIP_STAGE_INITSOLVE 2342 * - \ref SCIP_STAGE_SOLVING 2343 * - \ref SCIP_STAGE_SOLVED 2344 * - \ref SCIP_STAGE_EXITSOLVE 2345 * - \ref SCIP_STAGE_FREETRANS 2346 */ 2347 SCIP_RETCODE SCIPretransformSol( 2348 SCIP* scip, /**< SCIP data structure */ 2349 SCIP_SOL* sol /**< primal CIP solution */ 2350 ) 2351 { 2352 SCIP_CALL( SCIPcheckStage(scip, "SCIPretransformSol", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE) ); 2353 2354 switch ( SCIPsolGetOrigin(sol) ) 2355 { 2356 case SCIP_SOLORIGIN_ORIGINAL: 2357 /* nothing to do */ 2358 return SCIP_OKAY; 2359 2360 case SCIP_SOLORIGIN_LPSOL: 2361 case SCIP_SOLORIGIN_NLPSOL: 2362 case SCIP_SOLORIGIN_RELAXSOL: 2363 case SCIP_SOLORIGIN_PSEUDOSOL: 2364 2365 /* first unlink solution */ 2366 SCIP_CALL( SCIPunlinkSol(scip, sol) ); 2367 2368 /*lint -fallthrough*/ 2369 case SCIP_SOLORIGIN_ZERO: 2370 { 2371 SCIP_Bool hasinfval; 2372 2373 SCIP_CALL( SCIPsolRetransform(sol, scip->set, scip->stat, scip->origprob, scip->transprob, &hasinfval) ); 2374 break; 2375 } 2376 case SCIP_SOLORIGIN_PARTIAL: 2377 case SCIP_SOLORIGIN_UNKNOWN: 2378 SCIPerrorMessage("unknown solution origin.\n"); 2379 return SCIP_INVALIDCALL; 2380 2381 default: 2382 /* note that this is in an internal SCIP error since all solution origins are covert in the switch above */ 2383 SCIPerrorMessage("invalid solution origin <%d>\n", SCIPsolGetOrigin(sol)); 2384 return SCIP_ERROR; 2385 } 2386 2387 return SCIP_OKAY; 2388 } 2389 2390 /** reads a given solution file 2391 * 2392 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 2393 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 2394 * 2395 * @pre This method can be called if SCIP is in one of the following stages: 2396 * - \ref SCIP_STAGE_PROBLEM 2397 * - \ref SCIP_STAGE_TRANSFORMED 2398 * - \ref SCIP_STAGE_INITPRESOLVE 2399 * - \ref SCIP_STAGE_PRESOLVING 2400 * - \ref SCIP_STAGE_EXITPRESOLVE 2401 * - \ref SCIP_STAGE_PRESOLVED 2402 * - \ref SCIP_STAGE_INITSOLVE 2403 * - \ref SCIP_STAGE_SOLVING 2404 */ 2405 SCIP_RETCODE SCIPreadSol( 2406 SCIP* scip, /**< SCIP data structure */ 2407 const char* filename /**< name of the input file */ 2408 ) 2409 { 2410 SCIP_CALL( SCIPcheckStage(scip, "SCIPreadSol", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 2411 2412 /* we pass the reading of the solution file on to reader_sol via the following call */ 2413 SCIP_CALL( SCIPreadProb(scip, filename, "sol") ); 2414 2415 return SCIP_OKAY; 2416 } 2417 2418 /** reads a given solution file and store the solution values in the given solution pointer */ 2419 static 2420 SCIP_RETCODE readSolFile( 2421 SCIP* scip, /**< SCIP data structure */ 2422 const char* filename, /**< name of the input file */ 2423 SCIP_SOL* sol, /**< solution pointer */ 2424 SCIP_Bool* partial, /**< pointer to store if the solution is partial (or NULL, if not needed) */ 2425 SCIP_Bool* error /**< pointer store if an error occured */ 2426 ) 2427 { 2428 SCIP_FILE* file; 2429 SCIP_Bool unknownvariablemessage; 2430 SCIP_Bool localpartial; 2431 int lineno; 2432 2433 assert(scip != NULL); 2434 assert(sol != NULL); 2435 assert(error != NULL); 2436 2437 /* open input file */ 2438 file = SCIPfopen(filename, "r"); 2439 if( file == NULL ) 2440 { 2441 SCIPerrorMessage("cannot open file <%s> for reading\n", filename); 2442 SCIPprintSysError(filename); 2443 return SCIP_NOFILE; 2444 } 2445 2446 *error = FALSE; 2447 localpartial = SCIPsolIsPartial(sol); 2448 2449 unknownvariablemessage = FALSE; 2450 lineno = 0; 2451 2452 /* read the file */ 2453 while( !SCIPfeof(file) && !(*error) ) 2454 { 2455 char buffer[SCIP_MAXSTRLEN]; 2456 char varname[SCIP_MAXSTRLEN]; 2457 char valuestring[SCIP_MAXSTRLEN]; 2458 char objstring[SCIP_MAXSTRLEN]; 2459 char format[SCIP_MAXSTRLEN]; 2460 SCIP_VAR* var; 2461 SCIP_Real value; 2462 int nread; 2463 2464 /* get next line */ 2465 if( SCIPfgets(buffer, (int) sizeof(buffer), file) == NULL ) 2466 break; 2467 lineno++; 2468 2469 /* there are some lines which may preceed the solution information */ 2470 if( strncasecmp(buffer, "solution status:", 16) == 0 || strncasecmp(buffer, "objective value:", 16) == 0 || 2471 strncasecmp(buffer, "Log started", 11) == 0 || strncasecmp(buffer, "Variable Name", 13) == 0 || 2472 strncasecmp(buffer, "All other variables", 19) == 0 || strspn(buffer, " \n\r\t\f") == strlen(buffer) || 2473 strncasecmp(buffer, "NAME", 4) == 0 || strncasecmp(buffer, "ENDATA", 6) == 0 || /* allow parsing of SOL-format on the MIPLIB 2003 pages */ 2474 strncasecmp(buffer, "=obj=", 5) == 0 ) /* avoid "unknown variable" warning when reading MIPLIB SOL files */ 2475 continue; 2476 2477 /* parse the line */ 2478 (void) SCIPsnprintf(format, SCIP_MAXSTRLEN, "%%%ds %%%ds %%%ds\n", SCIP_MAXSTRLEN, SCIP_MAXSTRLEN, SCIP_MAXSTRLEN); 2479 nread = sscanf(buffer, format, varname, valuestring, objstring); 2480 if( nread < 2 ) 2481 { 2482 SCIPerrorMessage("Invalid input line %d in solution file <%s>: <%s>.\n", lineno, filename, buffer); 2483 *error = TRUE; 2484 break; 2485 } 2486 2487 /* find the variable */ 2488 var = SCIPfindVar(scip, varname); 2489 if( var == NULL ) 2490 { 2491 if( !unknownvariablemessage ) 2492 { 2493 SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, "unknown variable <%s> in line %d of solution file <%s>\n", 2494 varname, lineno, filename); 2495 SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, " (further unknown variables are ignored)\n"); 2496 unknownvariablemessage = TRUE; 2497 } 2498 continue; 2499 } 2500 2501 /* cast the value */ 2502 if( strncasecmp(valuestring, "inv", 3) == 0 ) 2503 continue; 2504 else if( strncasecmp(valuestring, "+inf", 4) == 0 || strncasecmp(valuestring, "inf", 3) == 0 ) 2505 value = SCIPinfinity(scip); 2506 else if( strncasecmp(valuestring, "-inf", 4) == 0 ) 2507 value = -SCIPinfinity(scip); 2508 else if( strncasecmp(valuestring, "unknown", 7) == 0 ) 2509 { 2510 value = SCIP_UNKNOWN; 2511 localpartial = TRUE; 2512 } 2513 else 2514 { 2515 /* coverity[secure_coding] */ 2516 nread = sscanf(valuestring, "%lf", &value); 2517 if( nread != 1 ) 2518 { 2519 SCIPerrorMessage("Invalid solution value <%s> for variable <%s> in line %d of solution file <%s>.\n", 2520 valuestring, varname, lineno, filename); 2521 *error = TRUE; 2522 break; 2523 } 2524 } 2525 2526 /* set the solution value of the variable, if not multiaggregated */ 2527 if( SCIPisTransformed(scip) && SCIPvarGetStatus(SCIPvarGetProbvar(var)) == SCIP_VARSTATUS_MULTAGGR ) 2528 { 2529 SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, "ignored solution value for multiaggregated variable <%s>\n", SCIPvarGetName(var)); 2530 } 2531 else 2532 { 2533 SCIP_RETCODE retcode; 2534 2535 retcode = SCIPsetSolVal(scip, sol, var, value); 2536 2537 if( retcode == SCIP_INVALIDDATA ) 2538 { 2539 if( SCIPvarGetStatus(SCIPvarGetProbvar(var)) == SCIP_VARSTATUS_FIXED ) 2540 { 2541 SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, "ignored conflicting solution value for fixed variable <%s>\n", 2542 SCIPvarGetName(var)); 2543 } 2544 else 2545 { 2546 SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, "ignored solution value for multiaggregated variable <%s>\n", 2547 SCIPvarGetName(var)); 2548 } 2549 } 2550 else 2551 { 2552 SCIP_CALL_FINALLY( retcode, SCIPfclose(file) ); 2553 } 2554 } 2555 } 2556 2557 /* close input file */ 2558 SCIPfclose(file); 2559 2560 if( localpartial && !SCIPsolIsPartial(sol) ) 2561 { 2562 if( SCIPgetStage(scip) == SCIP_STAGE_PROBLEM ) 2563 { 2564 SCIP_CALL( SCIPsolMarkPartial(sol, scip->set, scip->stat, scip->origprob->vars, scip->origprob->nvars) ); 2565 } 2566 else 2567 *error = TRUE; 2568 } 2569 2570 if( partial != NULL ) 2571 *partial = localpartial; 2572 2573 return SCIP_OKAY; 2574 } 2575 2576 /** reads a given xml solution file and store the solution values in the given solution pointer */ 2577 static 2578 SCIP_RETCODE readXmlSolFile( 2579 SCIP* scip, /**< SCIP data structure */ 2580 const char* filename, /**< name of the input file */ 2581 SCIP_SOL* sol, /**< solution pointer */ 2582 SCIP_Bool* partial, /**< pointer to store if the solution is partial (or NULL if not needed) */ 2583 SCIP_Bool* error /**< pointer store if an error occured */ 2584 ) 2585 { 2586 SCIP_Bool unknownvariablemessage; 2587 SCIP_Bool localpartial; 2588 XML_NODE* start; 2589 const XML_NODE* varsnode; 2590 const XML_NODE* varnode; 2591 const char* tag; 2592 2593 assert(scip != NULL); 2594 assert(sol != NULL); 2595 assert(error != NULL); 2596 2597 /* read xml file */ 2598 start = xmlProcess(filename); 2599 2600 if( start == NULL ) 2601 { 2602 SCIPerrorMessage("Some error occured during parsing the XML solution file.\n"); 2603 return SCIP_READERROR; 2604 } 2605 2606 *error = FALSE; 2607 localpartial = SCIPsolIsPartial(sol); 2608 2609 /* find variable sections */ 2610 tag = "variables"; 2611 varsnode = xmlFindNodeMaxdepth(start, tag, 0, 3); 2612 if( varsnode == NULL ) 2613 { 2614 /* free xml data */ 2615 xmlFreeNode(start); 2616 2617 SCIPerrorMessage("Variable section not found.\n"); 2618 return SCIP_READERROR; 2619 } 2620 2621 /* loop through all variables */ 2622 unknownvariablemessage = FALSE; 2623 for( varnode = xmlFirstChild(varsnode); varnode != NULL; varnode = xmlNextSibl(varnode) ) 2624 { 2625 SCIP_VAR* var; 2626 const char* varname; 2627 const char* valuestring; 2628 SCIP_Real value; 2629 int nread; 2630 2631 /* find variable name */ 2632 varname = xmlGetAttrval(varnode, "name"); 2633 if( varname == NULL ) 2634 { 2635 SCIPerrorMessage("Attribute \"name\" of variable not found.\n"); 2636 *error = TRUE; 2637 break; 2638 } 2639 2640 /* find the variable */ 2641 var = SCIPfindVar(scip, varname); 2642 if( var == NULL ) 2643 { 2644 if( !unknownvariablemessage ) 2645 { 2646 SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, "unknown variable <%s> of solution file <%s>\n", 2647 varname, filename); 2648 SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, " (further unknown variables are ignored)\n"); 2649 unknownvariablemessage = TRUE; 2650 } 2651 continue; 2652 } 2653 2654 /* find value of variable */ 2655 valuestring = xmlGetAttrval(varnode, "value"); 2656 if( valuestring == NULL ) 2657 { 2658 SCIPerrorMessage("Attribute \"value\" of variable not found.\n"); 2659 *error = TRUE; 2660 break; 2661 } 2662 2663 /* cast the value */ 2664 if( strncasecmp(valuestring, "inv", 3) == 0 ) 2665 continue; 2666 else if( strncasecmp(valuestring, "+inf", 4) == 0 || strncasecmp(valuestring, "inf", 3) == 0 ) 2667 value = SCIPinfinity(scip); 2668 else if( strncasecmp(valuestring, "-inf", 4) == 0 ) 2669 value = -SCIPinfinity(scip); 2670 else if( strncasecmp(valuestring, "unknown", 7) == 0 ) 2671 { 2672 value = SCIP_UNKNOWN; 2673 localpartial = TRUE; 2674 } 2675 else 2676 { 2677 /* coverity[secure_coding] */ 2678 nread = sscanf(valuestring, "%lf", &value); 2679 if( nread != 1 ) 2680 { 2681 SCIPwarningMessage(scip, "invalid solution value <%s> for variable <%s> in XML solution file <%s>\n", valuestring, varname, filename); 2682 *error = TRUE; 2683 break; 2684 } 2685 } 2686 2687 /* set the solution value of the variable, if not multiaggregated */ 2688 if( SCIPisTransformed(scip) && SCIPvarGetStatus(SCIPvarGetProbvar(var)) == SCIP_VARSTATUS_MULTAGGR ) 2689 { 2690 SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, "ignored solution value for multiaggregated variable <%s>\n", SCIPvarGetName(var)); 2691 } 2692 else 2693 { 2694 SCIP_RETCODE retcode; 2695 retcode = SCIPsetSolVal(scip, sol, var, value); 2696 2697 if( retcode == SCIP_INVALIDDATA ) 2698 { 2699 if( SCIPvarGetStatus(SCIPvarGetProbvar(var)) == SCIP_VARSTATUS_FIXED ) 2700 { 2701 SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, "ignored conflicting solution value for fixed variable <%s>\n", 2702 SCIPvarGetName(var)); 2703 } 2704 else 2705 { 2706 SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, "ignored solution value for multiaggregated variable <%s>\n", 2707 SCIPvarGetName(var)); 2708 } 2709 } 2710 else 2711 { 2712 SCIP_CALL( retcode ); 2713 } 2714 } 2715 } 2716 2717 /* free xml data */ 2718 xmlFreeNode(start); 2719 2720 if( localpartial && !SCIPsolIsPartial(sol) ) 2721 { 2722 if( SCIPgetStage(scip) == SCIP_STAGE_PROBLEM ) 2723 { 2724 SCIP_CALL( SCIPsolMarkPartial(sol, scip->set, scip->stat, scip->origprob->vars, scip->origprob->nvars) ); 2725 } 2726 else 2727 *error = TRUE; 2728 } 2729 2730 if( partial != NULL ) 2731 *partial = localpartial; 2732 2733 return SCIP_OKAY; 2734 } 2735 2736 /** reads a given solution file and store the solution values in the given solution pointer 2737 * 2738 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 2739 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 2740 * 2741 * @pre This method can be called if SCIP is in one of the following stages: 2742 * - \ref SCIP_STAGE_PROBLEM 2743 * - \ref SCIP_STAGE_TRANSFORMED 2744 * - \ref SCIP_STAGE_INITPRESOLVE 2745 * - \ref SCIP_STAGE_PRESOLVING 2746 * - \ref SCIP_STAGE_EXITPRESOLVE 2747 * - \ref SCIP_STAGE_PRESOLVED 2748 * - \ref SCIP_STAGE_INITSOLVE 2749 * - \ref SCIP_STAGE_SOLVING 2750 */ 2751 SCIP_RETCODE SCIPreadSolFile( 2752 SCIP* scip, /**< SCIP data structure */ 2753 const char* filename, /**< name of the input file */ 2754 SCIP_SOL* sol, /**< solution pointer */ 2755 SCIP_Bool xml, /**< true, iff the given solution in written in XML */ 2756 SCIP_Bool* partial, /**< pointer to store if the solution is partial */ 2757 SCIP_Bool* error /**< pointer store if an error occured */ 2758 ) 2759 { 2760 SCIP_CALL( SCIPcheckStage(scip, "SCIPreadSolFile", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 2761 2762 if( xml ) 2763 { 2764 SCIP_CALL( readXmlSolFile(scip, filename, sol, partial, error) ); 2765 } 2766 else 2767 { 2768 SCIP_CALL( readSolFile(scip, filename, sol, partial, error) ); 2769 } 2770 2771 return SCIP_OKAY; 2772 } 2773 2774 /** adds feasible primal solution to solution storage by copying it 2775 * 2776 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 2777 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 2778 * 2779 * @pre This method can be called if SCIP is in one of the following stages: 2780 * - \ref SCIP_STAGE_PROBLEM 2781 * - \ref SCIP_STAGE_TRANSFORMED 2782 * - \ref SCIP_STAGE_INITPRESOLVE 2783 * - \ref SCIP_STAGE_PRESOLVING 2784 * - \ref SCIP_STAGE_EXITPRESOLVE 2785 * - \ref SCIP_STAGE_PRESOLVED 2786 * - \ref SCIP_STAGE_SOLVING 2787 * - \ref SCIP_STAGE_FREETRANS 2788 * 2789 * @note Do not call during propagation, use heur_trysol instead. 2790 */ 2791 SCIP_RETCODE SCIPaddSol( 2792 SCIP* scip, /**< SCIP data structure */ 2793 SCIP_SOL* sol, /**< primal CIP solution */ 2794 SCIP_Bool* stored /**< stores whether given solution was good enough to keep */ 2795 ) 2796 { 2797 SCIP_CALL( SCIPcheckStage(scip, "SCIPaddSol", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE) ); 2798 2799 switch( scip->set->stage ) 2800 { 2801 case SCIP_STAGE_PROBLEM: 2802 case SCIP_STAGE_FREETRANS: 2803 assert(SCIPsolIsOriginal(sol)); 2804 SCIP_CALL( SCIPprimalAddOrigSol(scip->origprimal, scip->mem->probmem, scip->set, scip->stat, scip->origprob, sol, stored) ); 2805 return SCIP_OKAY; 2806 2807 case SCIP_STAGE_TRANSFORMED: 2808 case SCIP_STAGE_INITPRESOLVE: 2809 case SCIP_STAGE_PRESOLVING: 2810 case SCIP_STAGE_EXITPRESOLVE: 2811 case SCIP_STAGE_PRESOLVED: 2812 case SCIP_STAGE_SOLVING: 2813 { 2814 SCIP_SOL* bestsol = SCIPgetBestSol(scip); 2815 2816 SCIP_CALL( SCIPprimalAddSol(scip->primal, scip->mem->probmem, scip->set, scip->messagehdlr, scip->stat, 2817 scip->origprob, scip->transprob, scip->tree, scip->reopt, scip->lp, scip->eventqueue, scip->eventfilter, sol, 2818 stored) ); 2819 2820 /* @todo use solution index rather than pointer */ 2821 if( *stored && (bestsol != SCIPgetBestSol(scip)) ) 2822 { 2823 SCIPstoreSolutionGap(scip); 2824 } 2825 2826 return SCIP_OKAY; 2827 } 2828 case SCIP_STAGE_TRANSFORMING: 2829 case SCIP_STAGE_INITSOLVE: 2830 case SCIP_STAGE_SOLVED: 2831 case SCIP_STAGE_EXITSOLVE: 2832 default: 2833 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage); 2834 return SCIP_INVALIDCALL; 2835 } /*lint !e788*/ 2836 } 2837 2838 /** adds primal solution to solution storage, frees the solution afterwards 2839 * 2840 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 2841 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 2842 * 2843 * @pre This method can be called if SCIP is in one of the following stages: 2844 * - \ref SCIP_STAGE_PROBLEM 2845 * - \ref SCIP_STAGE_TRANSFORMED 2846 * - \ref SCIP_STAGE_INITPRESOLVE 2847 * - \ref SCIP_STAGE_PRESOLVING 2848 * - \ref SCIP_STAGE_EXITPRESOLVE 2849 * - \ref SCIP_STAGE_PRESOLVED 2850 * - \ref SCIP_STAGE_SOLVING 2851 * - \ref SCIP_STAGE_FREETRANS 2852 * 2853 * @note Do not call during propagation, use heur_trysol instead. 2854 */ 2855 SCIP_RETCODE SCIPaddSolFree( 2856 SCIP* scip, /**< SCIP data structure */ 2857 SCIP_SOL** sol, /**< pointer to primal CIP solution; is cleared in function call */ 2858 SCIP_Bool* stored /**< stores whether given solution was good enough to keep */ 2859 ) 2860 { 2861 SCIP_CALL( SCIPcheckStage(scip, "SCIPaddSolFree", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE) ); 2862 2863 switch( scip->set->stage ) 2864 { 2865 case SCIP_STAGE_PROBLEM: 2866 case SCIP_STAGE_FREETRANS: 2867 assert(SCIPsolIsOriginal(*sol)); 2868 SCIP_CALL( SCIPprimalAddOrigSolFree(scip->origprimal, scip->mem->probmem, scip->set, scip->stat, scip->origprob, sol, stored) ); 2869 return SCIP_OKAY; 2870 2871 case SCIP_STAGE_TRANSFORMED: 2872 case SCIP_STAGE_INITPRESOLVE: 2873 case SCIP_STAGE_PRESOLVING: 2874 case SCIP_STAGE_EXITPRESOLVE: 2875 case SCIP_STAGE_PRESOLVED: 2876 case SCIP_STAGE_SOLVING: 2877 { 2878 SCIP_SOL* bestsol = SCIPgetBestSol(scip); 2879 2880 SCIP_CALL( SCIPprimalAddSolFree(scip->primal, scip->mem->probmem, scip->set, scip->messagehdlr, scip->stat, 2881 scip->origprob, scip->transprob, scip->tree, scip->reopt, scip->lp, scip->eventqueue, scip->eventfilter, 2882 sol, stored) ); 2883 2884 if( *stored ) 2885 { 2886 if( bestsol != SCIPgetBestSol(scip) ) 2887 { 2888 assert(SCIPgetBestSol(scip) != NULL); 2889 SCIPstoreSolutionGap(scip); 2890 } 2891 } 2892 2893 return SCIP_OKAY; 2894 } 2895 case SCIP_STAGE_TRANSFORMING: 2896 case SCIP_STAGE_INITSOLVE: 2897 case SCIP_STAGE_SOLVED: 2898 case SCIP_STAGE_EXITSOLVE: 2899 default: 2900 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage); 2901 return SCIP_INVALIDCALL; 2902 } /*lint !e788*/ 2903 } 2904 2905 /** adds current LP/pseudo solution to solution storage 2906 * 2907 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 2908 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 2909 * 2910 * @pre This method can be called if SCIP is in one of the following stages: 2911 * - \ref SCIP_STAGE_PRESOLVED 2912 * - \ref SCIP_STAGE_SOLVING 2913 */ 2914 SCIP_RETCODE SCIPaddCurrentSol( 2915 SCIP* scip, /**< SCIP data structure */ 2916 SCIP_HEUR* heur, /**< heuristic that found the solution */ 2917 SCIP_Bool* stored /**< stores whether given solution was good enough to keep */ 2918 ) 2919 { 2920 SCIP_SOL* bestsol; 2921 2922 SCIP_CALL( SCIPcheckStage(scip, "SCIPaddCurrentSol", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 2923 2924 bestsol = SCIPgetBestSol(scip); 2925 2926 SCIP_CALL( SCIPprimalAddCurrentSol(scip->primal, scip->mem->probmem, scip->set, scip->messagehdlr, scip->stat, 2927 scip->origprob, scip->transprob, scip->tree, scip->reopt, scip->lp, scip->eventqueue, scip->eventfilter, heur, 2928 stored) ); 2929 2930 if( *stored ) 2931 { 2932 if( bestsol != SCIPgetBestSol(scip) ) 2933 SCIPstoreSolutionGap(scip); 2934 } 2935 2936 return SCIP_OKAY; 2937 } 2938 2939 /** checks solution for feasibility; if possible, adds it to storage by copying 2940 * 2941 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 2942 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 2943 * 2944 * @pre This method can be called if SCIP is in one of the following stages: 2945 * - \ref SCIP_STAGE_TRANSFORMED 2946 * - \ref SCIP_STAGE_INITPRESOLVE 2947 * - \ref SCIP_STAGE_PRESOLVING 2948 * - \ref SCIP_STAGE_EXITPRESOLVE 2949 * - \ref SCIP_STAGE_PRESOLVED 2950 * - \ref SCIP_STAGE_SOLVING 2951 * 2952 * @note Do not call during propagation, use heur_trysol instead. 2953 */ 2954 SCIP_RETCODE SCIPtrySol( 2955 SCIP* scip, /**< SCIP data structure */ 2956 SCIP_SOL* sol, /**< primal CIP solution */ 2957 SCIP_Bool printreason, /**< Should all reasons of violation be printed? */ 2958 SCIP_Bool completely, /**< Should all violations be checked if printreason is true? */ 2959 SCIP_Bool checkbounds, /**< Should the bounds of the variables be checked? */ 2960 SCIP_Bool checkintegrality, /**< Has integrality to be checked? */ 2961 SCIP_Bool checklprows, /**< Do constraints represented by rows in the current LP have to be checked? */ 2962 SCIP_Bool* stored /**< stores whether given solution was feasible and good enough to keep */ 2963 ) 2964 { 2965 SCIP_SOL* bestsol; 2966 2967 assert(sol != NULL); 2968 assert(stored != NULL); 2969 2970 SCIP_CALL( SCIPcheckStage(scip, "SCIPtrySol", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 2971 2972 bestsol = SCIPgetBestSol(scip); 2973 2974 if( !printreason ) 2975 completely = FALSE; 2976 2977 /* we cannot check partial solutions */ 2978 if( SCIPsolIsPartial(sol) ) 2979 { 2980 SCIPerrorMessage("Cannot check feasibility of partial solutions.\n"); 2981 return SCIP_INVALIDDATA; 2982 } 2983 2984 if( SCIPsolIsOriginal(sol) ) 2985 { 2986 SCIP_Bool feasible; 2987 2988 /* SCIPprimalTrySol() can only be called on transformed solutions; therefore check solutions in original problem 2989 * including modifiable constraints */ 2990 SCIP_CALL( SCIPsolCheckOrig(sol, scip->set, scip->messagehdlr, scip->mem->probmem, scip->stat, scip->origprob, scip->origprimal, 2991 printreason, completely, checkbounds, checkintegrality, checklprows, TRUE, &feasible) ); 2992 if( feasible ) 2993 { 2994 SCIP_CALL( SCIPprimalAddSol(scip->primal, scip->mem->probmem, scip->set, scip->messagehdlr, scip->stat, 2995 scip->origprob, scip->transprob, scip->tree, scip->reopt, scip->lp, scip->eventqueue, scip->eventfilter, 2996 sol, stored) ); 2997 2998 if( *stored ) 2999 { 3000 if( bestsol != SCIPgetBestSol(scip) ) 3001 SCIPstoreSolutionGap(scip); 3002 } 3003 } 3004 else 3005 *stored = FALSE; 3006 } 3007 else 3008 { 3009 SCIP_CALL( SCIPprimalTrySol(scip->primal, scip->mem->probmem, scip->set, scip->messagehdlr, scip->stat, scip->origprob, 3010 scip->transprob, scip->tree, scip->reopt, scip->lp, scip->eventqueue, scip->eventfilter, sol, printreason, 3011 completely, checkbounds, checkintegrality, checklprows, stored) ); 3012 3013 if( *stored ) 3014 { 3015 if( bestsol != SCIPgetBestSol(scip) ) 3016 { 3017 #ifdef SCIP_DEBUG_ABORTATORIGINFEAS 3018 SCIP_Bool feasible; 3019 SCIP_CALL( SCIPsolCheckOrig(sol, scip->set, scip->messagehdlr, scip->mem->probmem, scip->stat, scip->origprob, scip->origprimal, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, &feasible) ); 3020 3021 if( ! feasible ) 3022 { 3023 SCIPerrorMessage("Accepted solution not feasible for original problem\n"); 3024 SCIPABORT(); 3025 } 3026 #endif 3027 SCIPstoreSolutionGap(scip); 3028 } 3029 } 3030 } 3031 3032 return SCIP_OKAY; 3033 } 3034 3035 /** checks primal solution; if feasible, adds it to storage; solution is freed afterwards 3036 * 3037 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 3038 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 3039 * 3040 * @pre This method can be called if SCIP is in one of the following stages: 3041 * - \ref SCIP_STAGE_TRANSFORMED 3042 * - \ref SCIP_STAGE_INITPRESOLVE 3043 * - \ref SCIP_STAGE_PRESOLVING 3044 * - \ref SCIP_STAGE_EXITPRESOLVE 3045 * - \ref SCIP_STAGE_PRESOLVED 3046 * - \ref SCIP_STAGE_SOLVING 3047 * 3048 * @note Do not call during propagation, use heur_trysol instead. 3049 */ 3050 SCIP_RETCODE SCIPtrySolFree( 3051 SCIP* scip, /**< SCIP data structure */ 3052 SCIP_SOL** sol, /**< pointer to primal CIP solution; is cleared in function call */ 3053 SCIP_Bool printreason, /**< Should all reasons of violations be printed */ 3054 SCIP_Bool completely, /**< Should all violations be checked if printreason is true? */ 3055 SCIP_Bool checkbounds, /**< Should the bounds of the variables be checked? */ 3056 SCIP_Bool checkintegrality, /**< Has integrality to be checked? */ 3057 SCIP_Bool checklprows, /**< Do constraints represented by rows in the current LP have to be checked? */ 3058 SCIP_Bool* stored /**< stores whether solution was feasible and good enough to keep */ 3059 ) 3060 { 3061 SCIP_SOL* bestsol; 3062 3063 assert(stored != NULL); 3064 assert(sol != NULL); 3065 3066 SCIP_CALL( SCIPcheckStage(scip, "SCIPtrySolFree", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 3067 3068 bestsol = SCIPgetBestSol(scip); 3069 3070 if( !printreason ) 3071 completely = FALSE; 3072 3073 /* we cannot check partial solutions */ 3074 if( SCIPsolIsPartial(*sol) ) 3075 { 3076 SCIPerrorMessage("Cannot check feasibility of partial solutions.\n"); 3077 return SCIP_INVALIDDATA; 3078 } 3079 3080 if( SCIPsolIsOriginal(*sol) ) 3081 { 3082 SCIP_Bool feasible; 3083 3084 /* SCIPprimalTrySol() can only be called on transformed solutions; therefore check solutions in original problem 3085 * including modifiable constraints 3086 */ 3087 SCIP_CALL( SCIPsolCheckOrig(*sol, scip->set, scip->messagehdlr, scip->mem->probmem, scip->stat, scip->origprob, scip->origprimal, 3088 printreason, completely, checkbounds, checkintegrality, checklprows, TRUE, &feasible) ); 3089 3090 if( feasible ) 3091 { 3092 SCIP_CALL( SCIPprimalAddSolFree(scip->primal, scip->mem->probmem, scip->set, scip->messagehdlr, scip->stat, 3093 scip->origprob, scip->transprob, scip->tree, scip->reopt, scip->lp, scip->eventqueue, scip->eventfilter, 3094 sol, stored) ); 3095 3096 if( *stored ) 3097 { 3098 if( bestsol != SCIPgetBestSol(scip) ) 3099 SCIPstoreSolutionGap(scip); 3100 } 3101 } 3102 else 3103 { 3104 SCIP_CALL( SCIPsolFree(sol, scip->mem->probmem, scip->primal) ); 3105 *stored = FALSE; 3106 } 3107 } 3108 else 3109 { 3110 SCIP_CALL( SCIPprimalTrySolFree(scip->primal, scip->mem->probmem, scip->set, scip->messagehdlr, scip->stat, 3111 scip->origprob, scip->transprob, scip->tree, scip->reopt, scip->lp, scip->eventqueue, scip->eventfilter, 3112 sol, printreason, completely, checkbounds, checkintegrality, checklprows, stored) ); 3113 3114 if( *stored ) 3115 { 3116 if( bestsol != SCIPgetBestSol(scip) ) 3117 { 3118 #ifdef SCIP_DEBUG_ABORTATORIGINFEAS 3119 SCIP_Bool feasible; 3120 SCIP_CALL( SCIPsolCheckOrig(SCIPgetBestSol(scip), scip->set, scip->messagehdlr, scip->mem->probmem, scip->stat, scip->origprob, scip->origprimal, 3121 TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, &feasible) ); 3122 3123 if( ! feasible ) 3124 { 3125 SCIPerrorMessage("Accepted incumbent not feasible for original problem\n"); 3126 SCIPABORT(); 3127 } 3128 #endif 3129 SCIPstoreSolutionGap(scip); 3130 } 3131 } 3132 } 3133 3134 return SCIP_OKAY; 3135 } 3136 3137 /** checks current LP/pseudo solution for feasibility; if possible, adds it to storage 3138 * 3139 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 3140 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 3141 * 3142 * @pre This method can be called if SCIP is in one of the following stages: 3143 * - \ref SCIP_STAGE_PRESOLVED 3144 * - \ref SCIP_STAGE_SOLVING 3145 */ 3146 SCIP_RETCODE SCIPtryCurrentSol( 3147 SCIP* scip, /**< SCIP data structure */ 3148 SCIP_HEUR* heur, /**< heuristic that found the solution */ 3149 SCIP_Bool printreason, /**< Should all reasons of violations be printed? */ 3150 SCIP_Bool completely, /**< Should all violations be checked if printreason is true? */ 3151 SCIP_Bool checkintegrality, /**< Has integrality to be checked? */ 3152 SCIP_Bool checklprows, /**< Do constraints represented by rows in the current LP have to be checked? */ 3153 SCIP_Bool* stored /**< stores whether given solution was feasible and good enough to keep */ 3154 ) 3155 { 3156 SCIP_SOL* bestsol; 3157 3158 SCIP_CALL( SCIPcheckStage(scip, "SCIPtryCurrentSol", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE) ); 3159 3160 bestsol = SCIPgetBestSol(scip); 3161 3162 if( !printreason ) 3163 completely = FALSE; 3164 3165 SCIP_CALL( SCIPprimalTryCurrentSol(scip->primal, scip->mem->probmem, scip->set, scip->messagehdlr, scip->stat, 3166 scip->origprob, scip->transprob, scip->tree, scip->reopt, scip->lp, scip->eventqueue, scip->eventfilter, heur, 3167 printreason, completely, checkintegrality, checklprows, stored) ); 3168 3169 if( *stored ) 3170 { 3171 if( bestsol != SCIPgetBestSol(scip) ) 3172 { 3173 #ifdef SCIP_DEBUG_ABORTATORIGINFEAS 3174 SCIP_Bool feasible; 3175 SCIP_CALL( SCIPsolCheckOrig(SCIPgetBestSol(scip), scip->set, scip->messagehdlr, scip->mem->probmem, scip->stat, scip->origprob, scip->origprimal, 3176 TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, &feasible) ); 3177 3178 if( ! feasible ) 3179 { 3180 SCIPerrorMessage("Accepted incumbent not feasible for original problem\n"); 3181 SCIPABORT(); 3182 } 3183 #endif 3184 SCIPstoreSolutionGap(scip); 3185 } 3186 } 3187 3188 return SCIP_OKAY; 3189 } 3190 3191 /** returns all partial solutions 3192 * 3193 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 3194 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 3195 * 3196 * @pre This method can be called if SCIP is in one of the following stages: 3197 * - \ref SCIP_STAGE_PROBLEM 3198 * - \ref SCIP_STAGE_PRESOLVING 3199 * - \ref SCIP_STAGE_SOLVING 3200 * - \ref SCIP_STAGE_SOLVED 3201 */ 3202 SCIP_SOL** SCIPgetPartialSols( 3203 SCIP* scip /**< SCIP data structure */ 3204 ) 3205 { 3206 assert(scip != NULL); 3207 3208 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetPartialSols", FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 3209 3210 return scip->origprimal->partialsols; 3211 } 3212 3213 /** returns number of partial solutions 3214 * 3215 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 3216 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 3217 * 3218 * @pre This method can be called if SCIP is in one of the following stages: 3219 * - \ref SCIP_STAGE_PROBLEM 3220 * - \ref SCIP_STAGE_PRESOLVING 3221 * - \ref SCIP_STAGE_SOLVING 3222 * - \ref SCIP_STAGE_SOLVED 3223 */ 3224 int SCIPgetNPartialSols( 3225 SCIP* scip /**< SCIP data structure */ 3226 ) 3227 { 3228 assert(scip != NULL); 3229 3230 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetNPartialSols", FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 3231 3232 return scip->origprimal->npartialsols; 3233 } 3234 3235 /** checks solution for feasibility without adding it to the solution store 3236 * 3237 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 3238 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 3239 * 3240 * @pre This method can be called if SCIP is in one of the following stages: 3241 * - \ref SCIP_STAGE_PROBLEM 3242 * - \ref SCIP_STAGE_TRANSFORMED 3243 * - \ref SCIP_STAGE_INITPRESOLVE 3244 * - \ref SCIP_STAGE_PRESOLVING 3245 * - \ref SCIP_STAGE_EXITPRESOLVE 3246 * - \ref SCIP_STAGE_PRESOLVED 3247 * - \ref SCIP_STAGE_INITSOLVE 3248 * - \ref SCIP_STAGE_SOLVING 3249 * - \ref SCIP_STAGE_SOLVED 3250 */ 3251 SCIP_RETCODE SCIPcheckSol( 3252 SCIP* scip, /**< SCIP data structure */ 3253 SCIP_SOL* sol, /**< primal CIP solution */ 3254 SCIP_Bool printreason, /**< Should all reasons of violations be printed? */ 3255 SCIP_Bool completely, /**< Should all violations be checked if printreason is true? */ 3256 SCIP_Bool checkbounds, /**< Should the bounds of the variables be checked? */ 3257 SCIP_Bool checkintegrality, /**< Has integrality to be checked? */ 3258 SCIP_Bool checklprows, /**< Do constraints represented by rows in the current LP have to be checked? */ 3259 SCIP_Bool* feasible /**< stores whether given solution is feasible */ 3260 ) 3261 { 3262 SCIP_CALL( SCIPcheckStage(scip, "SCIPcheckSol", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 3263 3264 /* return immediately if the solution is of type partial */ 3265 if( SCIPsolIsPartial(sol) ) 3266 { 3267 SCIPerrorMessage("Cannot check feasibility of partial solutions."); 3268 return SCIP_INVALIDDATA; 3269 } 3270 3271 /* if we want to solve exactly, the constraint handlers cannot rely on the LP's feasibility */ 3272 checklprows = checklprows || scip->set->misc_exactsolve; 3273 3274 if( !printreason ) 3275 completely = FALSE; 3276 3277 if( SCIPsolIsOriginal(sol) ) 3278 { 3279 /* SCIPsolCheck() can only be called on transformed solutions */ 3280 SCIP_CALL( SCIPsolCheckOrig(sol, scip->set, scip->messagehdlr, scip->mem->probmem, scip->stat, scip->origprob, scip->origprimal, 3281 printreason, completely, checkbounds, checkintegrality, checklprows, FALSE, feasible) ); 3282 } 3283 else 3284 { 3285 SCIP_CALL( SCIPsolCheck(sol, scip->set, scip->messagehdlr, scip->mem->probmem, scip->stat, scip->transprob, 3286 printreason, completely, checkbounds, checkintegrality, checklprows, feasible) ); 3287 } 3288 3289 return SCIP_OKAY; 3290 } 3291 3292 /** checks solution for feasibility in original problem without adding it to the solution store; 3293 * this method is used to double check a solution in order to validate the presolving process 3294 * 3295 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 3296 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 3297 * 3298 * @pre This method can be called if SCIP is in one of the following stages: 3299 * - \ref SCIP_STAGE_PROBLEM 3300 * - \ref SCIP_STAGE_TRANSFORMED 3301 * - \ref SCIP_STAGE_INITPRESOLVE 3302 * - \ref SCIP_STAGE_PRESOLVING 3303 * - \ref SCIP_STAGE_EXITPRESOLVE 3304 * - \ref SCIP_STAGE_PRESOLVED 3305 * - \ref SCIP_STAGE_INITSOLVE 3306 * - \ref SCIP_STAGE_SOLVING 3307 * - \ref SCIP_STAGE_SOLVED 3308 */ 3309 SCIP_RETCODE SCIPcheckSolOrig( 3310 SCIP* scip, /**< SCIP data structure */ 3311 SCIP_SOL* sol, /**< primal CIP solution */ 3312 SCIP_Bool* feasible, /**< stores whether given solution is feasible */ 3313 SCIP_Bool printreason, /**< should the reason for the violation be printed? */ 3314 SCIP_Bool completely /**< Should all violations be checked if printreason is true? */ 3315 ) 3316 { 3317 assert(scip != NULL); 3318 assert(sol != NULL); 3319 assert(feasible != NULL); 3320 3321 SCIP_CALL( SCIPcheckStage(scip, "SCIPcheckSolOrig", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 3322 3323 /* return immediately if the solution is of type partial */ 3324 if( SCIPsolIsPartial(sol) ) 3325 { 3326 SCIPerrorMessage("Cannot check feasibility of partial solutions."); 3327 return SCIP_INVALIDDATA; 3328 } 3329 3330 if( !printreason ) 3331 completely = FALSE; 3332 3333 /* check solution in original problem; that includes bounds, integrality, and non modifiable constraints */ 3334 SCIP_CALL( SCIPsolCheckOrig(sol, scip->set, scip->messagehdlr, scip->mem->probmem, scip->stat, scip->origprob, scip->origprimal, 3335 printreason, completely, TRUE, TRUE, TRUE, FALSE, feasible) ); 3336 3337 return SCIP_OKAY; 3338 } 3339 3340 /** return whether a primal ray is stored that proves unboundedness of the LP relaxation 3341 * 3342 * @return return whether a primal ray is stored that proves unboundedness of the LP relaxation 3343 * 3344 * @pre This method can be called if SCIP is in one of the following stages: 3345 * - \ref SCIP_STAGE_SOLVING 3346 * - \ref SCIP_STAGE_SOLVED 3347 */ 3348 SCIP_Bool SCIPhasPrimalRay( 3349 SCIP* scip /**< SCIP data structure */ 3350 ) 3351 { 3352 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPhasPrimalRay", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 3353 3354 return scip->primal->primalray != NULL; 3355 } 3356 3357 /** gets value of given variable in primal ray causing unboundedness of the LP relaxation; 3358 * should only be called if such a ray is stored (check with SCIPhasPrimalRay()) 3359 * 3360 * @return value of given variable in primal ray causing unboundedness of the LP relaxation 3361 * 3362 * @pre This method can be called if SCIP is in one of the following stages: 3363 * - \ref SCIP_STAGE_SOLVING 3364 * - \ref SCIP_STAGE_SOLVED 3365 */ 3366 SCIP_Real SCIPgetPrimalRayVal( 3367 SCIP* scip, /**< SCIP data structure */ 3368 SCIP_VAR* var /**< variable to get value for */ 3369 ) 3370 { 3371 SCIP_CALL_ABORT( SCIPcheckStage(scip, "SCIPgetPrimalRayVal", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 3372 3373 assert(var != NULL); 3374 assert(scip->primal->primalray != NULL); 3375 assert(var->scip == scip); 3376 3377 return SCIPsolGetRayVal(scip->primal->primalray, scip->set, scip->stat, var); 3378 } 3379 3380 /** updates the primal ray thats proves unboundedness 3381 * 3382 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref 3383 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes. 3384 * 3385 * @pre This method can be called if @p scip is in one of the following stages: 3386 * - \ref SCIP_STAGE_PRESOLVING 3387 * - \ref SCIP_STAGE_PRESOLVED 3388 * - \ref SCIP_STAGE_SOLVING 3389 * - \ref SCIP_STAGE_SOLVED 3390 * 3391 * See \ref SCIP_Stage "SCIP_STAGE" for a complete list of all possible solving stages. 3392 */ 3393 SCIP_RETCODE SCIPupdatePrimalRay( 3394 SCIP* scip, /**< SCIP data structure */ 3395 SCIP_SOL* primalray /**< the new primal ray */ 3396 ) 3397 { 3398 assert(scip != NULL); 3399 assert(primalray != NULL); 3400 3401 SCIP_CALL( SCIPcheckStage(scip, "SCIPupdatePrimalRay", FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) ); 3402 3403 SCIP_CALL( SCIPprimalUpdateRay(scip->primal, scip->set, scip->stat, primalray, scip->mem->probmem) ); 3404 3405 return SCIP_OKAY; 3406 } 3407