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 debug.c 26 * @ingroup OTHER_CFILES 27 * @brief methods for debugging 28 * @author Tobias Achterberg 29 */ 30 31 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/ 32 33 #include <stdio.h> 34 #include <string.h> 35 #include <assert.h> 36 #if defined(_WIN32) || defined(_WIN64) 37 #else 38 #include <strings.h> /*lint --e{766}*/ 39 #endif 40 41 #include "scip/def.h" 42 #include "blockmemshell/memory.h" 43 #include "scip/set.h" 44 #include "scip/lp.h" 45 #include "scip/var.h" 46 #include "scip/prob.h" 47 #include "scip/tree.h" 48 #include "scip/scip.h" 49 #include "scip/debug.h" 50 #include "scip/pub_message.h" 51 #include "scip/pub_misc.h" 52 #include "scip/struct_scip.h" 53 54 #ifdef WITH_DEBUG_SOLUTION 55 56 #define SCIP_HASHSIZE_DEBUG 500 /**< minimum size of hash map for storing whether a solution is valid for the node */ 57 58 struct SCIP_DebugSolData 59 { 60 char** solnames; /**< variable names in the solution */ 61 SCIP_Real* solvals; /**< solution value array (only nonzero entries) */ 62 int nsolvals; /**< number of entries in the debug solution */ 63 int solsize; /**< size of the array entries */ 64 SCIP_SOL* debugsol; /**< a debug solution */ 65 SCIP_STAGE debugsolstage; /**< solving stage of debug solution */ 66 SCIP_HASHMAP* solinnode; /**< maps nodes to bools, storing whether the solution is valid for the node */ 67 SCIP_Bool falseptr; /**< pointer to value FALSE used for hashmap */ 68 SCIP_Bool trueptr; /**< pointer to value TRUE used for hashmap */ 69 SCIP_Bool solisachieved; /**< means if current best solution is better than the given debug solution */ 70 SCIP_Real debugsolval; /**< objective value for debug solution */ 71 SCIP_Bool debugsoldisabled; /**< flag indicating if debugging of solution was disabled or not */ 72 SCIP_Bool warningprinted; /**< flag indicating if a warning was already printed */ 73 }; 74 75 76 /** creates debug solution data */ 77 SCIP_RETCODE SCIPdebugSolDataCreate( 78 SCIP_DEBUGSOLDATA** debugsoldata /**< pointer to debug solution data */ 79 ) 80 { 81 assert(debugsoldata != NULL); 82 83 SCIP_ALLOC( BMSallocMemory(debugsoldata) ); 84 85 (*debugsoldata)->solnames = NULL; 86 (*debugsoldata)->solvals = NULL; 87 (*debugsoldata)->nsolvals = 0; 88 (*debugsoldata)->solsize = 0; 89 (*debugsoldata)->debugsol = NULL; 90 (*debugsoldata)->debugsolstage = SCIP_STAGE_INIT; 91 (*debugsoldata)->solinnode = NULL; 92 (*debugsoldata)->falseptr = FALSE; 93 (*debugsoldata)->trueptr = TRUE; 94 (*debugsoldata)->solisachieved = FALSE; 95 (*debugsoldata)->debugsolval = 0.0; 96 (*debugsoldata)->debugsoldisabled = TRUE; 97 (*debugsoldata)->warningprinted = FALSE; 98 99 return SCIP_OKAY; 100 } 101 102 #ifdef SCIP_MORE_DEBUG 103 /** comparison method for sorting variables w.r.t. to their name */ 104 static 105 SCIP_DECL_SORTPTRCOMP(sortVarsAfterNames) 106 { 107 return strcmp(SCIPvarGetName((SCIP_VAR*)elem1), SCIPvarGetName((SCIP_VAR*)elem2)); 108 } 109 #endif 110 111 /* checks whether the parameter is specified */ 112 static 113 SCIP_Bool debugSolutionAvailable( 114 SCIP_SET* set /**< global SCIP settings */ 115 ) 116 { 117 SCIP_DEBUGSOLDATA* debugsoldata; 118 119 assert(set != NULL); 120 121 debugsoldata = SCIPsetGetDebugSolData(set); 122 123 /* check whether a debug solution is specified */ 124 if( strcmp(set->misc_debugsol, "-") == 0 ) 125 { 126 if( !debugsoldata->warningprinted ) 127 { 128 SCIPmessagePrintWarning(SCIPgetMessagehdlr(set->scip), "SCIP is compiled with 'DEBUGSOL=true' but no debug solution is given:\n "); 129 SCIPmessagePrintWarning(SCIPgetMessagehdlr(set->scip), "*** Please set the parameter 'misc/debugsol' and reload the problem again to use the debugging-mechanism ***\n\n"); 130 debugsoldata->warningprinted = TRUE; 131 } 132 return FALSE; 133 } 134 else 135 { 136 debugsoldata->warningprinted = FALSE; 137 return TRUE; 138 } 139 } 140 141 /** reads solution from given file into given arrays */ 142 static 143 SCIP_RETCODE readSolfile( 144 SCIP_SET* set, /**< global SCIP settings */ 145 const char* solfilename, /**< solution filename to read */ 146 SCIP_SOL** debugsolptr, 147 SCIP_Real* debugsolvalptr, 148 SCIP_STAGE* debugsolstageptr, 149 char*** names, /**< pointer to store the array of variable names */ 150 SCIP_Real** vals, /**< pointer to store the array of solution values */ 151 int* nvals, /**< pointer to store the number of non-zero elements */ 152 int* valssize /**< pointer to store the length of the variable names and solution values arrays */ 153 ) 154 { 155 SCIP_VAR** vars; 156 SCIP_Real* solvalues; 157 SCIP_FILE* file; 158 SCIP_SOL* debugsol; 159 SCIP_Real debugsolval; 160 int nonvalues; 161 int nfound; 162 int i; 163 SCIP_Bool unknownvariablemessage; 164 165 assert(set != NULL); 166 assert(solfilename != NULL); 167 assert(names != NULL); 168 assert(*names == NULL); 169 assert(vals != NULL); 170 assert(*vals == NULL); 171 assert(nvals != NULL); 172 assert(valssize != NULL); 173 174 printf("***** debug: reading solution file <%s>\n", solfilename); 175 176 /* open solution file */ 177 file = SCIPfopen(solfilename, "r"); 178 if( file == NULL ) 179 { 180 SCIPerrorMessage("cannot open solution file <%s> specified in scip/debug.h\n", solfilename); 181 SCIPprintSysError(solfilename); 182 return SCIP_NOFILE; 183 } 184 185 /* read data */ 186 nonvalues = 0; 187 *valssize = 0; 188 unknownvariablemessage = FALSE; 189 190 while( !SCIPfeof(file) ) 191 { 192 char buf[SCIP_MAXSTRLEN]; 193 char name[SCIP_MAXSTRLEN]; 194 char objstring[SCIP_MAXSTRLEN]; 195 char valuestring[SCIP_MAXSTRLEN]; 196 SCIP_VAR* var; 197 SCIP_Real val; 198 int nread; 199 200 if( SCIPfgets(buf, SCIP_MAXSTRLEN, file) == NULL ) 201 { 202 if( SCIPfeof(file) ) 203 break; 204 else 205 return SCIP_READERROR; 206 } 207 208 /* there are some lines which may preceed the solution information */ 209 if( strncasecmp(buf, "solution status:", 16) == 0 || strncasecmp(buf, "objective value:", 16) == 0 || 210 strncasecmp(buf, "Log started", 11) == 0 || strncasecmp(buf, "Variable Name", 13) == 0 || 211 strncasecmp(buf, "All other variables", 19) == 0 || strspn(buf, " \n\r\t\f") == strlen(buf) || 212 strncasecmp(buf, "NAME", 4) == 0 || strncasecmp(buf, "ENDATA", 6) == 0 || /* allow parsing of SOL-format on the MIPLIB 2003 pages */ 213 strncasecmp(buf, "=obj=", 5) == 0 ) /* avoid "unknown variable" warning when reading MIPLIB SOL files */ 214 { 215 ++nonvalues; 216 continue; 217 } 218 219 /* cppcheck-suppress invalidscanf */ 220 nread = sscanf(buf, "%s %s %s\n", name, valuestring, objstring); 221 if( nread < 2 ) 222 { 223 printf("invalid input line %d in solution file <%s>: <%s>\n", *nvals + nonvalues, solfilename, name); 224 SCIPfclose(file); 225 return SCIP_READERROR; 226 } 227 228 /* find the variable */ 229 var = SCIPfindVar(set->scip, name); 230 if( var == NULL ) 231 { 232 if( !unknownvariablemessage ) 233 { 234 SCIPverbMessage(set->scip, SCIP_VERBLEVEL_NORMAL, NULL, "unknown variable <%s> in line %d of solution file <%s>\n", 235 name, *nvals + nonvalues, solfilename); 236 SCIPverbMessage(set->scip, SCIP_VERBLEVEL_NORMAL, NULL, " (further unknown variables are ignored)\n"); 237 unknownvariablemessage = TRUE; 238 } 239 continue; 240 } 241 242 /* cast the value, check first for inv(alid) or inf(inite) ones that need special treatment */ 243 if( strncasecmp(valuestring, "inv", 3) == 0 ) 244 continue; 245 else if( strncasecmp(valuestring, "+inf", 4) == 0 || strncasecmp(valuestring, "inf", 3) == 0 ) 246 val = SCIPsetInfinity(set); 247 else if( strncasecmp(valuestring, "-inf", 4) == 0 ) 248 val = -SCIPsetInfinity(set); 249 else 250 { 251 /* cppcheck-suppress invalidscanf */ 252 nread = sscanf(valuestring, "%lf", &val); 253 if( nread != 1 ) 254 { 255 SCIPerrorMessage("Invalid solution value <%s> for variable <%s> in line %d of solution file <%s>.\n", 256 valuestring, name, *nvals + nonvalues, solfilename); 257 SCIPfclose(file); 258 return SCIP_READERROR; 259 } 260 } 261 262 /* allocate memory */ 263 if( *nvals >= *valssize ) 264 { 265 *valssize = MAX(2 * *valssize, (*nvals)+1); 266 SCIP_ALLOC( BMSreallocMemoryArray(names, *valssize) ); 267 SCIP_ALLOC( BMSreallocMemoryArray(vals, *valssize) ); 268 } 269 assert(*nvals < *valssize); 270 271 /* store solution value in sorted list */ 272 for( i = *nvals; i > 0 && strcmp(name, (*names)[i-1]) < 0; --i ) 273 { 274 (*names)[i] = (*names)[i-1]; 275 (*vals)[i] = (*vals)[i-1]; 276 } 277 SCIP_ALLOC( BMSduplicateMemoryArray(&(*names)[i], name, strlen(name)+1) ); 278 SCIPdebugMsg(set->scip, "found variable <%s>: value <%g>\n", (*names)[i], val); 279 (*vals)[i] = val; 280 (*nvals)++; 281 } 282 283 /* get memory for SCIP solution */ 284 SCIP_ALLOC( BMSallocMemoryArray(&vars, *valssize) ); 285 SCIP_ALLOC( BMSallocMemoryArray(&solvalues, *valssize) ); 286 287 debugsolval = 0.0; 288 nfound = 0; 289 290 /* get solution value */ 291 for( i = 0; i < *nvals; ++i) 292 { 293 SCIP_VAR* var; 294 var = SCIPfindVar(set->scip, (*names)[i]); 295 if( var != NULL ) 296 { 297 vars[nfound] = var; 298 solvalues[nfound] = (*vals)[i]; 299 ++nfound; 300 debugsolval += (*vals)[i] * SCIPvarGetObj(var); 301 } 302 } 303 SCIPdebugMsg(set->scip, "Debug Solution value is %g.\n", debugsolval); 304 305 #ifdef SCIP_MORE_DEBUG 306 SCIPsortPtrReal((void**)vars, solvalues, sortVarsAfterNames, nfound); 307 308 for( i = 0; i < nfound - 1; ++i) 309 { 310 assert(strcmp(SCIPvarGetName(vars[i]), SCIPvarGetName(vars[i + 1])) != 0); 311 } 312 #endif 313 314 if( debugsolptr != NULL ) 315 { 316 /* create SCIP solution */ 317 SCIP_CALL( SCIPcreateOrigSol(set->scip, &debugsol, NULL) ); 318 *debugsolstageptr = SCIPgetStage(set->scip); 319 320 /* set SCIP solution values */ 321 SCIP_CALL( SCIPsetSolVals(set->scip, debugsol, nfound, vars, solvalues ) ); 322 } 323 324 BMSfreeMemoryArray(&vars); 325 BMSfreeMemoryArray(&solvalues); 326 327 if( debugsolptr != NULL ) 328 *debugsolptr = debugsol; 329 330 if( debugsolvalptr != NULL ) 331 *debugsolvalptr = debugsolval; 332 333 /* close file */ 334 SCIPfclose(file); 335 336 printf("***** debug: read %d non-zero entries (%d variables found)\n", *nvals, nfound); 337 338 return SCIP_OKAY; 339 } 340 341 /** reads feasible solution to check from file */ 342 static 343 SCIP_RETCODE readSolution( 344 SCIP_SET* set /**< global SCIP settings */ 345 ) 346 { 347 SCIP_DEBUGSOLDATA* debugsoldata; 348 349 assert(set != NULL); 350 351 debugsoldata = SCIPsetGetDebugSolData(set); 352 353 /* check whether a debug solution is available */ 354 if( !debugSolutionAvailable(set) ) 355 return SCIP_OKAY; 356 357 if( debugsoldata == NULL || debugsoldata->nsolvals > 0 ) 358 return SCIP_OKAY; 359 360 SCIP_CALL( readSolfile(set, set->misc_debugsol, &debugsoldata->debugsol, &debugsoldata->debugsolval, 361 &debugsoldata->debugsolstage, &(debugsoldata->solnames), &(debugsoldata->solvals), &(debugsoldata->nsolvals), 362 &(debugsoldata->solsize)) ); 363 364 return SCIP_OKAY; 365 } 366 367 /** gets value of given variable in debugging solution */ 368 static 369 SCIP_RETCODE getSolutionValue( 370 SCIP_SET* set, /**< global SCIP settings */ 371 SCIP_VAR* var, /**< variable to get solution value for */ 372 SCIP_Real* val /**< pointer to store solution value */ 373 ) 374 { 375 SCIP_VAR* solvar; 376 SCIP_DEBUGSOLDATA* debugsoldata; 377 SCIP_Real scalar; 378 SCIP_Real constant; 379 const char* name; 380 int left; 381 int right; 382 int middle; 383 int cmp; 384 385 assert(set != NULL); 386 assert(var != NULL); 387 assert(val != NULL); 388 389 /* check whether a debug solution is available */ 390 if( !debugSolutionAvailable(set) ) 391 return SCIP_OKAY; 392 393 debugsoldata = SCIPsetGetDebugSolData(set); 394 assert(debugsoldata != NULL); 395 396 /* allow retrieving solution values only if referring to the SCIP instance that is debugged */ 397 if( !SCIPdebugSolIsEnabled(set->scip) ) 398 { 399 *val = SCIP_UNKNOWN; 400 return SCIP_OKAY; 401 } 402 403 SCIP_CALL( readSolution(set) ); 404 SCIPsetDebugMsg(set, "Now handling variable <%s>, which has status %d, is of type %d, and was deleted: %d, negated: %d, transformed: %d\n", 405 SCIPvarGetName(var), SCIPvarGetStatus(var), SCIPvarGetType(var), SCIPvarIsDeleted(var), SCIPvarIsNegated(var),SCIPvarIsTransformedOrigvar(var)); 406 407 /* ignore deleted variables */ 408 if( SCIPvarIsDeleted(var) ) 409 { 410 SCIPsetDebugMsg(set, "**** unknown solution value for deleted variable <%s>\n", SCIPvarGetName(var)); 411 *val = SCIP_UNKNOWN; 412 return SCIP_OKAY; 413 } 414 415 /* retransform variable onto original variable space */ 416 solvar = var; 417 scalar = 1.0; 418 constant = 0.0; 419 if( SCIPvarIsNegated(solvar) ) 420 { 421 scalar = -1.0; 422 constant = SCIPvarGetNegationConstant(solvar); 423 solvar = SCIPvarGetNegationVar(solvar); 424 } 425 426 if( SCIPvarIsTransformed(solvar) ) 427 { 428 SCIP_CALL( SCIPvarGetOrigvarSum(&solvar, &scalar, &constant) ); 429 if( solvar == NULL ) 430 { 431 /* if no original counterpart, then maybe someone added a value for the transformed variable, so search for var (or its negation) */ 432 SCIPsetDebugMsg(set, "variable <%s> has no original counterpart\n", SCIPvarGetName(var)); 433 solvar = var; 434 scalar = 1.0; 435 constant = 0.0; 436 if( SCIPvarIsNegated(solvar) ) 437 { 438 scalar = -1.0; 439 constant = SCIPvarGetNegationConstant(solvar); 440 solvar = SCIPvarGetNegationVar(solvar); 441 } 442 } 443 } 444 445 /* perform a binary search for the variable */ 446 name = SCIPvarGetName(solvar); 447 left = 0; 448 right = debugsoldata->nsolvals-1; 449 while( left <= right ) 450 { 451 middle = (left+right)/2; 452 cmp = strcmp(name, debugsoldata->solnames[middle]); 453 if( cmp < 0 ) 454 right = middle-1; 455 else if( cmp > 0 ) 456 left = middle+1; 457 else 458 { 459 *val = scalar * debugsoldata->solvals[middle] + constant; 460 461 if( SCIPsetIsFeasLT(set, *val, SCIPvarGetLbGlobal(var)) || SCIPsetIsFeasGT(set, *val, SCIPvarGetUbGlobal(var)) ) 462 { 463 SCIPmessagePrintWarning(SCIPgetMessagehdlr(set->scip), "invalid solution value %.15g for variable <%s>[%.15g,%.15g]\n", 464 *val, SCIPvarGetName(var), SCIPvarGetLbGlobal(var), SCIPvarGetUbGlobal(var)); 465 } 466 467 return SCIP_OKAY; 468 } 469 } 470 *val = constant; 471 472 if( SCIPsetIsFeasLT(set, *val, SCIPvarGetLbGlobal(var)) || SCIPsetIsFeasGT(set, *val, SCIPvarGetUbGlobal(var)) ) 473 { 474 SCIPmessagePrintWarning(SCIPgetMessagehdlr(set->scip), "invalid solution value %.15g for variable <%s>[%.15g,%.15g]\n", 475 *val, SCIPvarGetName(var), SCIPvarGetLbGlobal(var), SCIPvarGetUbGlobal(var)); 476 } 477 478 return SCIP_OKAY; 479 } 480 481 /** gets pointer to the debug solution */ 482 SCIP_RETCODE SCIPdebugGetSol( 483 SCIP* scip, /**< SCIP data structure */ 484 SCIP_SOL** sol /**< buffer to store pointer to the debug solution */ 485 ) 486 { 487 SCIP_DEBUGSOLDATA* debugsoldata; 488 489 debugsoldata = SCIPsetGetDebugSolData(scip->set); 490 assert(scip != NULL); 491 assert(sol != NULL); 492 493 *sol = NULL; 494 495 /* check whether a debug solution is available */ 496 if( !debugSolutionAvailable(scip->set) ) 497 return SCIP_OKAY; 498 499 SCIP_CALL( readSolution(scip->set) ); 500 501 if( debugsoldata->debugsol == NULL ) 502 return SCIP_ERROR; 503 504 *sol = debugsoldata->debugsol; 505 506 return SCIP_OKAY; 507 } 508 509 /** gets value for a variable in the debug solution 510 * 511 * if no value is stored for the variable, gives 0.0 512 */ 513 SCIP_RETCODE SCIPdebugGetSolVal( 514 SCIP* scip, /**< SCIP data structure */ 515 SCIP_VAR* var, /**< variable for which to get the value */ 516 SCIP_Real* val /**< buffer to store solution value */ 517 ) 518 { 519 SCIP_CALL( getSolutionValue(scip->set, var, val) ); 520 521 return SCIP_OKAY; 522 } 523 524 /** returns whether the debug solution is worse than the best known solution or if the debug solution was found */ 525 static 526 SCIP_Bool debugSolIsAchieved( 527 SCIP_SET* set /**< global SCIP settings */ 528 ) 529 { 530 SCIP_SOL* bestsol; 531 SCIP* scip; 532 SCIP_DEBUGSOLDATA* debugsoldata; 533 534 /* check whether a debug solution is available */ 535 if( !debugSolutionAvailable(set) ) 536 return SCIP_OKAY; 537 538 assert(set != NULL); 539 debugsoldata = SCIPsetGetDebugSolData(set); 540 541 assert(debugsoldata != NULL); 542 543 if( debugsoldata->solisachieved ) 544 return TRUE; 545 546 assert(set != NULL); 547 548 scip = set->scip; 549 assert(scip != NULL); 550 551 bestsol = SCIPgetBestSol(scip); 552 553 if( bestsol != NULL ) 554 { 555 SCIP_Real solvalue; 556 557 /* don't check solution while in problem creation stage */ 558 if( SCIPsetGetStage(set) == SCIP_STAGE_PROBLEM ) 559 return TRUE; 560 561 solvalue = SCIPgetSolOrigObj(scip, bestsol); 562 563 /* make sure a debug solution has been read, so we do not compare against the initial debugsolval == 0 */ 564 SCIP_CALL( readSolution(set) ); 565 566 if( (SCIPgetObjsense(scip) == SCIP_OBJSENSE_MINIMIZE && SCIPsetIsLE(set, solvalue, debugsoldata->debugsolval)) 567 || (SCIPgetObjsense(scip) == SCIP_OBJSENSE_MAXIMIZE && SCIPsetIsGE(set, solvalue, debugsoldata->debugsolval)) ) 568 debugsoldata->solisachieved = TRUE; 569 } 570 571 return debugsoldata->solisachieved; 572 } 573 574 /** returns whether the solution is contained in node's subproblem */ 575 static 576 SCIP_RETCODE isSolutionInNode( 577 BMS_BLKMEM* blkmem, /**< block memory */ 578 SCIP_SET* set, /**< global SCIP settings */ 579 SCIP_NODE* node, /**< local node where this bound change was applied */ 580 SCIP_Bool* solcontained /**< pointer to store whether the solution is contained in node's subproblem */ 581 ) 582 { 583 SCIP_Bool* boolptr; 584 SCIP_DEBUGSOLDATA* debugsoldata; 585 586 assert(set != NULL); 587 assert(blkmem != NULL); 588 assert(node != NULL); 589 assert(solcontained != NULL); 590 591 /* check whether a debug solution is available */ 592 if( !debugSolutionAvailable(set) ) 593 return SCIP_OKAY; 594 595 debugsoldata = SCIPsetGetDebugSolData(set); 596 assert(debugsoldata != NULL); 597 598 if( debugsoldata ->debugsoldisabled ) 599 { 600 *solcontained = FALSE; 601 return SCIP_OKAY; 602 } 603 604 /* generate the hashmap */ 605 if( debugsoldata->solinnode == NULL ) 606 { 607 SCIP_CALL( SCIPhashmapCreate(&debugsoldata->solinnode, blkmem, SCIP_HASHSIZE_DEBUG) ); 608 } 609 610 /* check, whether we know already whether the solution is contained in the given node */ 611 boolptr = (SCIP_Bool*)SCIPhashmapGetImage(debugsoldata->solinnode, (void*)node); 612 if( boolptr != NULL ) 613 { 614 if( boolptr != &debugsoldata->falseptr && boolptr != &debugsoldata->trueptr ) 615 { 616 SCIPerrorMessage("wrong value in node hashmap\n"); 617 SCIPABORT(); 618 return SCIP_ERROR; 619 } 620 *solcontained = *boolptr; 621 return SCIP_OKAY; 622 } 623 624 /* if the solution is not contained in the parent of the node, it cannot be contained in the current node */ 625 *solcontained = TRUE; 626 if( node->parent != NULL ) 627 { 628 SCIP_CALL( isSolutionInNode(blkmem, set, node->parent, solcontained) ); 629 } 630 631 if( *solcontained ) 632 { 633 /* check whether the bound changes at the current node remove the debugging solution from the subproblem */ 634 if( node->domchg != NULL ) 635 { 636 SCIP_DOMCHGBOUND* domchgbound; 637 SCIP_BOUNDCHG* boundchgs; 638 int i; 639 640 domchgbound = &node->domchg->domchgbound; 641 boundchgs = domchgbound->boundchgs; 642 for( i = 0; i < (int)domchgbound->nboundchgs && *solcontained; ++i ) 643 { 644 SCIP_Real varsol; 645 646 /* get solution value of variable */ 647 SCIP_CALL( getSolutionValue(set, boundchgs[i].var, &varsol) ); 648 649 if( varsol != SCIP_UNKNOWN ) /*lint !e777*/ 650 { 651 /* compare the bound change with the solution value */ 652 if( SCIPboundchgGetBoundtype(&boundchgs[i]) == SCIP_BOUNDTYPE_LOWER ) 653 *solcontained = SCIPsetIsFeasGE(set, varsol, boundchgs[i].newbound); 654 else 655 *solcontained = SCIPsetIsFeasLE(set, varsol, boundchgs[i].newbound); 656 657 if( !(*solcontained) && SCIPboundchgGetBoundchgtype(&boundchgs[i]) != SCIP_BOUNDCHGTYPE_BRANCHING ) 658 { 659 SCIPerrorMessage("debugging solution was cut off in local node %p at depth %d by inference <%s>[%.15g] %s %.15g\n", 660 (void*) node, SCIPnodeGetDepth(node), SCIPvarGetName(boundchgs[i].var), varsol, 661 SCIPboundchgGetBoundtype(&boundchgs[i]) == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=", boundchgs[i].newbound); 662 SCIPABORT(); 663 } 664 } 665 else if( SCIPboundchgGetBoundchgtype(&boundchgs[i]) == SCIP_BOUNDCHGTYPE_BRANCHING ) 666 { 667 /* we branched on a variable were we don't know the solution: no debugging can be applied in this subtree */ 668 *solcontained = FALSE; 669 } 670 } 671 } 672 if( *solcontained && SCIPnodeGetNAddedConss(node) > 0 ) 673 { 674 int i; 675 int naddedcons = 0; 676 SCIP_CONS** addedcons; 677 678 SCIPsetAllocBufferArray(set, &addedcons, SCIPnodeGetNAddedConss(node)); 679 680 SCIPnodeGetAddedConss(node, addedcons, &naddedcons, SCIPnodeGetNAddedConss(node)); 681 682 for( i = 0; i < naddedcons && *solcontained; ++i ) 683 { 684 SCIP_RESULT result = SCIP_FEASIBLE; 685 SCIP_CALL( SCIPcheckCons(set->scip, addedcons[i], debugsoldata->debugsol , TRUE, TRUE, FALSE, &result) ); 686 687 if( result != SCIP_FEASIBLE ) 688 *solcontained = FALSE; 689 } 690 691 SCIPsetFreeBufferArray(set, &addedcons); 692 } 693 } 694 695 /* remember the status of the current node */ 696 SCIP_CALL( SCIPhashmapSetImage(debugsoldata->solinnode, (void*)node, *solcontained ? (void*)(&debugsoldata->trueptr) : (void*)(&debugsoldata->falseptr)) ); 697 698 return SCIP_OKAY; 699 } 700 701 /** frees the debug solution */ 702 SCIP_RETCODE SCIPdebugFreeSol( 703 SCIP_SET* set 704 ) 705 { 706 SCIP_DEBUGSOLDATA* debugsoldata; 707 708 debugsoldata = SCIPsetGetDebugSolData(set); 709 assert(debugsoldata != NULL); 710 711 if( debugsoldata->debugsol != NULL && ((SCIPgetStage(set->scip) > SCIP_STAGE_PROBLEM && debugsoldata->debugsolstage > SCIP_STAGE_PROBLEM) 712 || (SCIPgetStage(set->scip) <= SCIP_STAGE_PROBLEM && debugsoldata->debugsolstage <= SCIP_STAGE_PROBLEM)) ) 713 { 714 SCIP_CALL( SCIPfreeSol(set->scip, &debugsoldata->debugsol) ); 715 } 716 717 return SCIP_OKAY; 718 } 719 720 /** resets the data structure after restart */ 721 SCIP_RETCODE SCIPdebugReset( 722 SCIP_SET* set 723 ) 724 { 725 SCIP_DEBUGSOLDATA* debugsoldata; 726 727 assert(set != NULL); 728 729 debugsoldata = SCIPsetGetDebugSolData(set); 730 assert(debugsoldata != NULL); 731 732 if( debugsoldata->solinnode != NULL ) 733 { 734 SCIP_CALL( SCIPhashmapRemoveAll(debugsoldata->solinnode) ); 735 } 736 737 return SCIP_OKAY; 738 } 739 740 /** frees debugging data for the particular instance */ 741 SCIP_RETCODE SCIPdebugFreeDebugData( 742 SCIP_SET* set /**< global SCIP settings */ 743 ) 744 { 745 int s; 746 747 SCIP_DEBUGSOLDATA* debugsoldata; 748 assert(set != NULL); 749 750 debugsoldata = SCIPsetGetDebugSolData(set); 751 assert(debugsoldata != NULL); 752 753 for( s = debugsoldata->nsolvals - 1; s >= 0; --s ) 754 BMSfreeMemoryArrayNull(&(debugsoldata->solnames[s])); 755 756 BMSfreeMemoryArrayNull(&debugsoldata->solnames); 757 BMSfreeMemoryArrayNull(&debugsoldata->solvals); 758 759 debugsoldata->nsolvals = 0; 760 debugsoldata->debugsolval= 0.0; 761 debugsoldata->solisachieved = FALSE; 762 763 if( debugsoldata->solinnode != NULL) 764 SCIPhashmapFree(&debugsoldata->solinnode); 765 766 /* free the debug solution */ 767 SCIP_CALL( SCIPdebugFreeSol(set) ); 768 769 return SCIP_OKAY; 770 } 771 772 /** frees all debugging data */ 773 SCIP_RETCODE SCIPdebugFree( 774 SCIP_SET* set /**< global SCIP settings */ 775 ) 776 { 777 SCIP_DEBUGSOLDATA* debugsoldata; 778 779 assert(set != NULL); 780 781 debugsoldata = SCIPsetGetDebugSolData(set); 782 assert(debugsoldata != NULL); 783 784 SCIP_CALL( SCIPdebugFreeDebugData(set) ); 785 BMSfreeMemoryNull(&debugsoldata); 786 787 set->debugsoldata = NULL; 788 789 return SCIP_OKAY; 790 } 791 792 /** checks for validity of the debugging solution in given constraints */ 793 SCIP_RETCODE SCIPdebugCheckConss( 794 SCIP* scip, /**< SCIP data structure */ 795 SCIP_CONS** conss, /**< constraints to check for validity */ 796 int nconss /**< number of given constraints */ 797 ) 798 { 799 SCIP_RESULT result; 800 int c; 801 802 SCIP_DEBUGSOLDATA* debugsoldata; 803 assert(scip->set != NULL); 804 805 /* check if we are in the original problem and not in a sub MIP */ 806 if( !SCIPdebugSolIsEnabled(scip) ) 807 return SCIP_OKAY; 808 809 /* check whether a debug solution is available */ 810 if( !debugSolutionAvailable(scip->set) ) 811 return SCIP_OKAY; 812 813 debugsoldata = SCIPsetGetDebugSolData(scip->set); 814 815 assert(conss != NULL || nconss == 0); 816 assert(debugsoldata->debugsol != NULL); 817 818 /* check if the incumbent solution is at least as good as the debug solution, so we can stop to check the debug 819 * solution 820 */ 821 if( debugSolIsAchieved(scip->set) ) 822 return SCIP_OKAY; 823 824 result = SCIP_FEASIBLE; 825 826 /* checking each given constraint against the debugging solution */ 827 for( c = nconss - 1; c >= 0; --c ) 828 { 829 assert(conss[c] != NULL); 830 831 if( !SCIPconsIsActive(conss[c]) ) 832 continue; 833 834 assert(SCIPconsGetActiveDepth(conss[c]) <= SCIPgetDepth(scip)); 835 836 /* if the cons is only locally valid, check whether the debugging solution is contained in the local subproblem */ 837 if( SCIPconsIsLocal(conss[c]) ) 838 { 839 SCIP_Bool solcontained; 840 841 SCIP_CALL( isSolutionInNode(SCIPblkmem(scip), scip->set, SCIPgetCurrentNode(scip), &solcontained) ); 842 if( !solcontained ) 843 return SCIP_OKAY; 844 } 845 846 SCIP_CALL( SCIPcheckCons(scip, conss[c], debugsoldata->debugsol, TRUE, TRUE, TRUE, &result) ); 847 848 SCIPdebugMsg(scip, " -> checking of constraint %s returned result <%d>\n", SCIPconsGetName(conss[c]), result); 849 850 if( result != SCIP_FEASIBLE ) 851 { 852 SCIPerrorMessage("constraint %s violates the debugging solution\n", SCIPconsGetName(conss[c])); 853 SCIPABORT(); 854 } 855 } 856 857 return SCIP_OKAY; 858 } 859 860 /** checks whether given row is valid for the debugging solution */ 861 SCIP_RETCODE SCIPdebugCheckRow( 862 SCIP_SET* set, /**< global SCIP settings */ 863 SCIP_ROW* row /**< row to check for validity */ 864 ) 865 { 866 SCIP_COL** cols; 867 SCIP_Real* vals; 868 SCIP_Real lhs; 869 SCIP_Real rhs; 870 int nnonz; 871 int i; 872 SCIP_Real minactivity; 873 SCIP_Real maxactivity; 874 SCIP_Real solval; 875 876 assert(set != NULL); 877 assert(row != NULL); 878 879 /* when debugging was disabled the solution is not defined to be not valid in the current subtree */ 880 if( !SCIPdebugSolIsEnabled(set->scip) ) 881 return SCIP_OKAY; 882 883 /* check whether a debug solution is available */ 884 if( !debugSolutionAvailable(set) ) 885 return SCIP_OKAY; 886 887 /* check if the incumbent solution is at least as good as the debug solution, so we can stop to check the debug solution */ 888 if( debugSolIsAchieved(set) ) 889 return SCIP_OKAY; 890 891 /* if the row is only locally valid, check whether the debugging solution is contained in the local subproblem */ 892 if( SCIProwIsLocal(row) ) 893 { 894 SCIP_Bool solcontained; 895 896 SCIP_CALL( isSolutionInNode(SCIPblkmem(set->scip), set, SCIPgetCurrentNode(set->scip), &solcontained) ); 897 if( !solcontained ) 898 return SCIP_OKAY; 899 } 900 901 cols = SCIProwGetCols(row); 902 vals = SCIProwGetVals(row); 903 nnonz = SCIProwGetNNonz(row); 904 lhs = SCIProwGetLhs(row); 905 rhs = SCIProwGetRhs(row); 906 907 /* calculate row's activity on debugging solution */ 908 minactivity = SCIProwGetConstant(row); 909 maxactivity = minactivity; 910 for( i = 0; i < nnonz; ++i ) 911 { 912 SCIP_VAR* var; 913 914 /* get solution value of variable in debugging solution */ 915 var = SCIPcolGetVar(cols[i]); 916 SCIP_CALL( getSolutionValue(set, var, &solval) ); 917 918 if( solval != SCIP_UNKNOWN ) /*lint !e777*/ 919 { 920 minactivity += vals[i] * solval; 921 maxactivity += vals[i] * solval; 922 } 923 else if( vals[i] > 0.0 ) 924 { 925 minactivity += vals[i] * SCIPvarGetLbGlobal(var); 926 maxactivity += vals[i] * SCIPvarGetUbGlobal(var); 927 } 928 else if( vals[i] < 0.0 ) 929 { 930 minactivity += vals[i] * SCIPvarGetUbGlobal(var); 931 maxactivity += vals[i] * SCIPvarGetLbGlobal(var); 932 } 933 } 934 SCIPsetDebugMsg(set, "debugging solution on row <%s>: %g <= [%g,%g] <= %g\n", 935 SCIProwGetName(row), lhs, minactivity, maxactivity, rhs); 936 937 /* check row for violation, using absolute LP feasibility tolerance (as LP solver should do) */ 938 if( maxactivity + SCIPgetLPFeastol(set->scip) < lhs || minactivity - SCIPgetLPFeastol(set->scip) > rhs ) 939 { 940 printf("***** debug: row <%s> violates debugging solution (lhs=%.15g, rhs=%.15g, activity=[%.15g,%.15g], local=%u, lpfeastol=%g)\n", 941 SCIProwGetName(row), lhs, rhs, minactivity, maxactivity, SCIProwIsLocal(row), SCIPgetLPFeastol(set->scip)); 942 SCIProwPrint(row, SCIPgetMessagehdlr(set->scip), NULL); 943 944 /* output row with solution values */ 945 printf("\n\n"); 946 printf("***** debug: violated row <%s>:\n", SCIProwGetName(row)); 947 printf(" %.15g <= %.15g", lhs, SCIProwGetConstant(row)); 948 for( i = 0; i < nnonz; ++i ) 949 { 950 /* get solution value of variable in debugging solution */ 951 SCIP_CALL( getSolutionValue(set, SCIPcolGetVar(cols[i]), &solval) ); 952 printf(" %+.15g<%s>[%.15g]", vals[i], SCIPvarGetName(SCIPcolGetVar(cols[i])), solval); 953 } 954 printf(" <= %.15g\n", rhs); 955 956 SCIPABORT(); 957 } 958 959 return SCIP_OKAY; 960 } 961 962 /** checks whether given global lower bound is valid for the debugging solution */ 963 SCIP_RETCODE SCIPdebugCheckLbGlobal( 964 SCIP* scip, /**< SCIP data structure */ 965 SCIP_VAR* var, /**< problem variable */ 966 SCIP_Real lb /**< lower bound */ 967 ) 968 { 969 SCIP_Real varsol; 970 971 assert(scip != NULL); 972 assert(var != NULL); 973 974 /* check if we are in the original problem and not in a sub MIP */ 975 if( !SCIPdebugSolIsEnabled(scip) ) 976 return SCIP_OKAY; 977 978 /* check whether a debug solution is available */ 979 if( !debugSolutionAvailable(scip->set) ) 980 return SCIP_OKAY; 981 982 if( SCIPgetStage(scip) == SCIP_STAGE_PROBLEM ) 983 return SCIP_OKAY; 984 985 /* skip unused relaxation-only variables 986 * Relaxation-only variables are not part of any constraints or the original problem and thus there is no need to check their solution value. 987 * However, for relaxation-only variables that are still in use for the current solve round and for which a debug solution value has been set, 988 * checking against the debug solution value is helpful. If they not in use anymore, they will be captured only by the transformed problem 989 * and they may get fixed to some arbitrary value, e.g., in dual fixing. 990 * Thus, we skip checking bound changes on unused relaxation-only variables. 991 */ 992 if( SCIPvarIsRelaxationOnly(var) && SCIPvarGetNUses(var) == 1 ) 993 return SCIP_OKAY; 994 995 /* check if the incumbent solution is at least as good as the debug solution, so we can stop to check the debug solution */ 996 if( debugSolIsAchieved(scip->set) ) 997 return SCIP_OKAY; 998 999 /* get solution value of variable */ 1000 SCIP_CALL( getSolutionValue(scip->set, var, &varsol) ); 1001 SCIPdebugMsg(scip, "debugging solution on lower bound of <%s>[%g] >= %g\n", SCIPvarGetName(var), varsol, lb); 1002 1003 /* check validity of debugging solution */ 1004 if( varsol != SCIP_UNKNOWN && SCIPisFeasLT(scip, varsol, lb) ) /*lint !e777*/ 1005 { 1006 SCIPerrorMessage("invalid global lower bound: <%s>[%.15g] >= %.15g\n", SCIPvarGetName(var), varsol, lb); 1007 SCIPABORT(); 1008 } 1009 1010 return SCIP_OKAY; 1011 } 1012 1013 /** checks whether given global upper bound is valid for the debugging solution */ 1014 SCIP_RETCODE SCIPdebugCheckUbGlobal( 1015 SCIP* scip, /**< SCIP data structure */ 1016 SCIP_VAR* var, /**< problem variable */ 1017 SCIP_Real ub /**< upper bound */ 1018 ) 1019 { 1020 SCIP_Real varsol; 1021 1022 assert(scip != NULL); 1023 assert(var != NULL); 1024 1025 /* when debugging was disabled the solution is not defined to be not valid in the current subtree */ 1026 if( !SCIPdebugSolIsEnabled(scip) ) 1027 return SCIP_OKAY; 1028 1029 /* check whether a debug solution is available */ 1030 if( !debugSolutionAvailable(scip->set) ) 1031 return SCIP_OKAY; 1032 1033 if( SCIPgetStage(scip) == SCIP_STAGE_PROBLEM ) 1034 return SCIP_OKAY; 1035 1036 /* skip unused relaxation-only variables, see also comment in SCIPdebugCheckLbGlobal() */ 1037 if( SCIPvarIsRelaxationOnly(var) && SCIPvarGetNUses(var) == 1 ) 1038 return SCIP_OKAY; 1039 1040 /* check if the incumbent solution is at least as good as the debug solution, so we can stop to check the debug solution */ 1041 if( debugSolIsAchieved(scip->set) ) 1042 return SCIP_OKAY; 1043 1044 /* get solution value of variable */ 1045 SCIP_CALL( getSolutionValue(scip->set, var, &varsol) ); 1046 SCIPdebugMsg(scip, "debugging solution on upper bound of <%s>[%g] <= %g\n", SCIPvarGetName(var), varsol, ub); 1047 1048 /* check validity of debugging solution */ 1049 if( varsol != SCIP_UNKNOWN && SCIPisFeasGT(scip, varsol, ub) ) /*lint !e777*/ 1050 { 1051 SCIPerrorMessage("invalid global upper bound: <%s>[%.15g] <= %.15g\n", SCIPvarGetName(var), varsol, ub); 1052 SCIPABORT(); 1053 } 1054 1055 return SCIP_OKAY; 1056 } 1057 1058 /** checks whether given local bound implication is valid for the debugging solution */ 1059 SCIP_RETCODE SCIPdebugCheckInference( 1060 BMS_BLKMEM* blkmem, /**< block memory */ 1061 SCIP_SET* set, /**< global SCIP settings */ 1062 SCIP_NODE* node, /**< local node where this bound change was applied */ 1063 SCIP_VAR* var, /**< problem variable */ 1064 SCIP_Real newbound, /**< new value for bound */ 1065 SCIP_BOUNDTYPE boundtype /**< type of bound: lower or upper bound */ 1066 ) 1067 { 1068 SCIP_Real varsol; 1069 SCIP_Bool solcontained; 1070 1071 assert(set != NULL); 1072 assert(blkmem != NULL); 1073 assert(node != NULL); 1074 assert(var != NULL); 1075 1076 /* in case we are in probing or diving we have to avoid checking the solution */ 1077 if( SCIPlpDiving(set->scip->lp) || SCIPtreeProbing(set->scip->tree) ) 1078 return SCIP_OKAY; 1079 1080 /* when debugging was disabled the solution is not defined to be not valid in the current subtree */ 1081 if( !SCIPdebugSolIsEnabled(set->scip) ) 1082 return SCIP_OKAY; 1083 1084 /* check whether a debug solution is available */ 1085 if( !debugSolutionAvailable(set) ) 1086 return SCIP_OKAY; 1087 1088 /* check if the incumbent solution is at least as good as the debug solution, so we can stop to check the debug solution */ 1089 if( debugSolIsAchieved(set) ) 1090 return SCIP_OKAY; 1091 1092 /* check whether the debugging solution is contained in the local subproblem */ 1093 SCIP_CALL( isSolutionInNode(blkmem, set, node, &solcontained) ); 1094 if( !solcontained ) 1095 return SCIP_OKAY; 1096 1097 /* get solution value of variable */ 1098 SCIP_CALL( getSolutionValue(set, var, &varsol) ); 1099 1100 /* check validity of debugging solution */ 1101 if( varsol != SCIP_UNKNOWN ) /*lint !e777*/ 1102 { 1103 if( boundtype == SCIP_BOUNDTYPE_LOWER && SCIPsetIsFeasLT(set, varsol, newbound) ) 1104 { 1105 SCIPerrorMessage("invalid local lower bound implication: <%s>[%.15g] >= %.15g\n", SCIPvarGetName(var), varsol, newbound); 1106 SCIPABORT(); 1107 } 1108 if( boundtype == SCIP_BOUNDTYPE_UPPER && SCIPsetIsFeasGT(set, varsol, newbound) ) 1109 { 1110 SCIPerrorMessage("invalid local upper bound implication: <%s>[%.15g] <= %.15g\n", SCIPvarGetName(var), varsol, newbound); 1111 SCIPABORT(); 1112 } 1113 } 1114 1115 return SCIP_OKAY; 1116 } 1117 1118 /** informs solution debugger, that the given node will be freed */ 1119 SCIP_RETCODE SCIPdebugRemoveNode( 1120 BMS_BLKMEM* blkmem, /**< block memory */ 1121 SCIP_SET* set, /**< global SCIP settings */ 1122 SCIP_NODE* node /**< node that will be freed */ 1123 ) 1124 { 1125 SCIP_DEBUGSOLDATA* debugsoldata; 1126 1127 assert(set != NULL); 1128 assert(blkmem != NULL); 1129 assert(node != NULL); 1130 1131 debugsoldata = SCIPsetGetDebugSolData(set); 1132 assert(debugsoldata != NULL); 1133 1134 /* when debugging was disabled the solution is not defined to be not valid in the current subtree */ 1135 if( !SCIPdebugSolIsEnabled(set->scip) ) 1136 return SCIP_OKAY; 1137 1138 /* check whether a debug solution is available */ 1139 if( !debugSolutionAvailable(set) ) 1140 return SCIP_OKAY; 1141 1142 /* check if the incumbent solution is at least as good as the debug solution, so we can stop to check the debug solution */ 1143 if( debugSolIsAchieved(set) ) 1144 return SCIP_OKAY; 1145 1146 /* check if a solution will be cutoff in tree */ 1147 if( SCIPgetStage(set->scip) != SCIP_STAGE_EXITSOLVE && SCIPgetStage(set->scip) != SCIP_STAGE_EXITPRESOLVE 1148 && SCIPnodeGetType(node) != SCIP_NODETYPE_PROBINGNODE && !SCIPisInRestart(set->scip) ) 1149 { 1150 SCIP_Bool solisinnode; 1151 1152 solisinnode = FALSE; 1153 1154 SCIP_CALL( isSolutionInNode(blkmem, set, node, &solisinnode) ); 1155 /* wrong node will be cutoff */ 1156 if( solisinnode ) 1157 { 1158 SCIPerrorMessage("debugging solution was cut off in local node #%" SCIP_LONGINT_FORMAT " (%p) at depth %d\n", 1159 node->number, (void*) node, SCIPnodeGetDepth(node)); 1160 SCIPABORT(); 1161 } 1162 } 1163 1164 /* remove node from the hash map */ 1165 if( debugsoldata->solinnode != NULL ) 1166 { 1167 SCIP_CALL( SCIPhashmapRemove(debugsoldata->solinnode, (void*)node) ); 1168 } 1169 1170 return SCIP_OKAY; 1171 } 1172 1173 /** checks whether global lower bound does not exceed debuging solution value */ 1174 SCIP_RETCODE SCIPdebugCheckGlobalLowerbound( 1175 BMS_BLKMEM* blkmem, /**< block memory */ 1176 SCIP_SET* set /**< global SCIP settings */ 1177 ) 1178 { 1179 SCIP_DEBUGSOLDATA* debugsoldata; 1180 SCIP_Real treelowerbound; 1181 1182 assert(set != NULL); 1183 assert(blkmem != NULL); 1184 1185 /* when debugging was disabled the solution is not defined to be not valid in the current subtree */ 1186 if( !SCIPdebugSolIsEnabled(set->scip) ) 1187 return SCIP_OKAY; 1188 1189 /* check whether a debug solution is available */ 1190 if( !debugSolutionAvailable(set) ) 1191 return SCIP_OKAY; 1192 1193 if( SCIPgetStage(set->scip) <= SCIP_STAGE_INITSOLVE || SCIPgetStage(set->scip) >= SCIP_STAGE_EXITSOLVE ) 1194 return SCIP_OKAY; 1195 1196 if( SCIPgetStatus(set->scip) == SCIP_STATUS_INFORUNBD || SCIPgetStatus(set->scip) == SCIP_STATUS_UNBOUNDED ) 1197 return SCIP_OKAY; 1198 1199 /* if there are no leaves then SCIPtreeGetLowerbound() will return infintiy */ 1200 if( SCIPgetNLeaves(set->scip) <= 0 ) 1201 return SCIP_OKAY; 1202 1203 debugsoldata = SCIPsetGetDebugSolData(set); 1204 assert(debugsoldata != NULL); 1205 1206 /* make sure a debug solution has been read */ 1207 if( debugsoldata->debugsol == NULL ) 1208 { 1209 SCIP_CALL( readSolution(set) ); 1210 } 1211 1212 /* get global lower bound of tree (do not use SCIPgetLowerbound() since this adjusts the value using the primal bound) */ 1213 treelowerbound = SCIPtreeGetLowerbound(set->scip->tree, set); 1214 treelowerbound = SCIPprobExternObjval(set->scip->transprob, set->scip->origprob, set, treelowerbound); 1215 1216 if( SCIPgetObjsense(set->scip) == SCIP_OBJSENSE_MINIMIZE && SCIPsetIsGT(set, treelowerbound, SCIPsolGetOrigObj(debugsoldata->debugsol)) ) 1217 { 1218 SCIPerrorMessage("global lower bound %g is larger than the value of the debugging solution %g.\n", treelowerbound, SCIPsolGetOrigObj(debugsoldata->debugsol)); 1219 SCIPABORT(); 1220 } 1221 else if( SCIPgetObjsense(set->scip) == SCIP_OBJSENSE_MAXIMIZE && SCIPsetIsLT(set, treelowerbound, SCIPsolGetOrigObj(debugsoldata->debugsol)) ) 1222 { 1223 SCIPerrorMessage("global upper bound %g is smaller than the value of the debugging solution %g.\n", treelowerbound, SCIPsolGetOrigObj(debugsoldata->debugsol)); 1224 SCIPABORT(); 1225 } 1226 1227 return SCIP_OKAY; 1228 } 1229 1230 /** checks whether local lower bound does not exceed debuging solution value */ 1231 SCIP_RETCODE SCIPdebugCheckLocalLowerbound( 1232 BMS_BLKMEM* blkmem, /**< block memory */ 1233 SCIP_SET* set, /**< global SCIP settings */ 1234 SCIP_NODE* node /**< node that will be freed */ 1235 ) 1236 { 1237 SCIP_DEBUGSOLDATA* debugsoldata; 1238 SCIP_Bool solisinnode; 1239 1240 assert(set != NULL); 1241 assert(blkmem != NULL); 1242 1243 /* exit if we do not have a node to check */ 1244 if( node == NULL ) 1245 return SCIP_OKAY; 1246 1247 /* when debugging was disabled the solution is not defined to be not valid in the current subtree */ 1248 if( !SCIPdebugSolIsEnabled(set->scip) ) 1249 return SCIP_OKAY; 1250 1251 /* check whether a debug solution is available */ 1252 if( !debugSolutionAvailable(set) ) 1253 return SCIP_OKAY; 1254 1255 if( SCIPgetStage(set->scip) <= SCIP_STAGE_INITSOLVE ) 1256 return SCIP_OKAY; 1257 1258 if( SCIPgetStatus(set->scip) == SCIP_STATUS_INFORUNBD || SCIPgetStatus(set->scip) == SCIP_STATUS_UNBOUNDED ) 1259 return SCIP_OKAY; 1260 1261 debugsoldata = SCIPsetGetDebugSolData(set); 1262 assert(debugsoldata != NULL); 1263 1264 /* make sure a debug solution has been read */ 1265 if( debugsoldata->debugsol == NULL ) 1266 { 1267 SCIP_CALL( readSolution(set) ); 1268 } 1269 1270 /* check local lower bound */ 1271 SCIP_CALL( isSolutionInNode(blkmem, set, node, &solisinnode) ); 1272 1273 /* if we are in a node that contains the given debug solution, the lower bound should not exceed the solution's objective */ 1274 if( solisinnode ) 1275 { 1276 SCIP_Real localbound; 1277 1278 localbound = SCIPnodeGetLowerbound(node); 1279 localbound = SCIPprobExternObjval(set->scip->transprob, set->scip->origprob, set, localbound); 1280 1281 if( SCIPgetObjsense(set->scip) == SCIP_OBJSENSE_MINIMIZE && SCIPsetIsGT(set, localbound, SCIPsolGetOrigObj(debugsoldata->debugsol)) ) 1282 { 1283 SCIPerrorMessage("local lower bound %g of node #%" SCIP_LONGINT_FORMAT " at depth %d is larger than the value of the debugging solution %g contained in this node.\n", 1284 localbound, node->number, SCIPnodeGetDepth(node), SCIPsolGetOrigObj(debugsoldata->debugsol)); 1285 SCIPABORT(); 1286 } 1287 else if( SCIPgetObjsense(set->scip) == SCIP_OBJSENSE_MAXIMIZE && SCIPsetIsLT(set, localbound, SCIPsolGetOrigObj(debugsoldata->debugsol)) ) 1288 { 1289 SCIPerrorMessage("local upper bound %g of node #%" SCIP_LONGINT_FORMAT " at depth %d is smaller than the value of the debugging solution %g contained in this node.\n", 1290 localbound, node->number, SCIPnodeGetDepth(node), SCIPsolGetOrigObj(debugsoldata->debugsol)); 1291 SCIPABORT(); 1292 } 1293 } 1294 1295 return SCIP_OKAY; 1296 } 1297 1298 /** checks whether given variable bound is valid for the debugging solution */ 1299 SCIP_RETCODE SCIPdebugCheckVbound( 1300 SCIP_SET* set, /**< global SCIP settings */ 1301 SCIP_VAR* var, /**< problem variable x in x <= b*z + d or x >= b*z + d */ 1302 SCIP_BOUNDTYPE vbtype, /**< type of variable bound (LOWER or UPPER) */ 1303 SCIP_VAR* vbvar, /**< variable z in x <= b*z + d or x >= b*z + d */ 1304 SCIP_Real vbcoef, /**< coefficient b in x <= b*z + d or x >= b*z + d */ 1305 SCIP_Real vbconstant /**< constant d in x <= b*z + d or x >= b*z + d */ 1306 ) 1307 { 1308 SCIP_Real varsol; 1309 SCIP_Real vbvarsol; 1310 SCIP_Real vb; 1311 1312 assert(set != NULL); 1313 assert(var != NULL); 1314 1315 /* when debugging was disabled the solution is not defined to be not valid in the current subtree */ 1316 if( !SCIPdebugSolIsEnabled(set->scip) ) 1317 return SCIP_OKAY; 1318 1319 /* check whether a debug solution is available */ 1320 if( !debugSolutionAvailable(set) ) 1321 return SCIP_OKAY; 1322 1323 /* check if the incumbent solution is at least as good as the debug solution, so we can stop to check the debug solution */ 1324 if( debugSolIsAchieved(set) ) 1325 return SCIP_OKAY; 1326 1327 /* get solution value of variables */ 1328 SCIP_CALL( getSolutionValue(set, var, &varsol) ); 1329 SCIP_CALL( getSolutionValue(set, vbvar, &vbvarsol) ); 1330 1331 /* check validity of debugging solution */ 1332 if( varsol != SCIP_UNKNOWN && vbvarsol != SCIP_UNKNOWN ) /*lint !e777*/ 1333 { 1334 vb = vbcoef * vbvarsol + vbconstant; 1335 if( (vbtype == SCIP_BOUNDTYPE_LOWER && SCIPsetIsFeasLT(set, varsol, vb)) 1336 || (vbtype == SCIP_BOUNDTYPE_UPPER && SCIPsetIsFeasGT(set, varsol, vb)) ) 1337 { 1338 SCIPerrorMessage("invalid variable bound: <%s>[%.15g] %s %.15g<%s>[%.15g] %+.15g\n", 1339 SCIPvarGetName(var), varsol, vbtype == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=", vbcoef, 1340 SCIPvarGetName(vbvar), vbvarsol, vbconstant); 1341 SCIPABORT(); 1342 } 1343 } 1344 1345 return SCIP_OKAY; 1346 } 1347 1348 /** checks whether given implication is valid for the debugging solution */ 1349 SCIP_RETCODE SCIPdebugCheckImplic( 1350 SCIP_SET* set, /**< global SCIP settings */ 1351 SCIP_VAR* var, /**< problem variable */ 1352 SCIP_Bool varfixing, /**< FALSE if y should be added in implications for x == 0, TRUE for x == 1 */ 1353 SCIP_VAR* implvar, /**< variable y in implication y <= b or y >= b */ 1354 SCIP_BOUNDTYPE impltype, /**< type of implication y <= b (SCIP_BOUNDTYPE_UPPER) or y >= b (SCIP_BOUNDTYPE_LOWER) */ 1355 SCIP_Real implbound /**< bound b in implication y <= b or y >= b */ 1356 ) 1357 { 1358 SCIP_Real solval; 1359 1360 assert(set != NULL); 1361 assert(var != NULL); 1362 assert(SCIPvarGetType(var) == SCIP_VARTYPE_BINARY); 1363 1364 /* when debugging was disabled the solution is not defined to be not valid in the current subtree */ 1365 if( !SCIPdebugSolIsEnabled(set->scip) ) 1366 return SCIP_OKAY; 1367 1368 /* check whether a debug solution is available */ 1369 if( !debugSolutionAvailable(set) ) 1370 return SCIP_OKAY; 1371 1372 /* check if the incumbent solution is at least as good as the debug solution, so we can stop to check the debug solution */ 1373 if( debugSolIsAchieved(set) ) 1374 return SCIP_OKAY; 1375 1376 /* get solution value of variable */ 1377 SCIP_CALL( getSolutionValue(set, var, &solval) ); 1378 if( solval == SCIP_UNKNOWN ) /*lint !e777*/ 1379 return SCIP_OKAY; 1380 assert(SCIPsetIsFeasZero(set, solval) || SCIPsetIsFeasEQ(set, solval, 1.0)); 1381 1382 /* check, whether the implication applies for the debugging solution */ 1383 if( (solval > 0.5) != varfixing ) 1384 return SCIP_OKAY; 1385 1386 /* get solution value of implied variable */ 1387 SCIP_CALL( getSolutionValue(set, implvar, &solval) ); 1388 if( solval == SCIP_UNKNOWN ) /*lint !e777*/ 1389 return SCIP_OKAY; 1390 1391 if( impltype == SCIP_BOUNDTYPE_LOWER ) 1392 { 1393 if( SCIPsetIsFeasLT(set, solval, implbound) ) 1394 { 1395 SCIPerrorMessage("invalid implication <%s> == %d -> <%s> >= %.15g (variable has value %.15g in solution)\n", 1396 SCIPvarGetName(var), varfixing, SCIPvarGetName(implvar), implbound, solval); 1397 SCIPABORT(); 1398 } 1399 } 1400 else 1401 { 1402 if( SCIPsetIsFeasGT(set, solval, implbound) ) 1403 { 1404 SCIPerrorMessage("invalid implication <%s> == %d -> <%s> <= %.15g (variable has value %.15g in solution)\n", 1405 SCIPvarGetName(var), varfixing, SCIPvarGetName(implvar), implbound, solval); 1406 SCIPABORT(); 1407 } 1408 } 1409 1410 return SCIP_OKAY; 1411 } 1412 1413 /** checks whether given (multi)-aggregation is valid for the debugging solution */ 1414 SCIP_RETCODE SCIPdebugCheckAggregation( 1415 SCIP_SET* set, /**< global SCIP settings */ 1416 SCIP_VAR* var, /**< problem variable */ 1417 SCIP_VAR** aggrvars, /**< variables y_i in aggregation x = a_1*y_1 + ... + a_n*y_n + c */ 1418 SCIP_Real* scalars, /**< multipliers a_i in aggregation x = a_1*y_1 + ... + a_n*y_n + c */ 1419 SCIP_Real constant, /**< constant shift c in aggregation x = a_1*y_1 + ... + a_n*y_n + c */ 1420 int naggrvars /**< number n of variables in aggregation x = a_1*y_1 + ... + a_n*y_n + c */ 1421 ) 1422 { 1423 SCIP_Real solval; 1424 SCIP_Real val; 1425 int i; 1426 1427 assert(set != NULL); 1428 assert(var != NULL); 1429 assert(aggrvars != NULL); 1430 assert(scalars != NULL); 1431 assert(naggrvars >= 0); 1432 1433 /* when debugging was disabled the solution is not defined to be not valid in the current subtree */ 1434 if( !SCIPdebugSolIsEnabled(set->scip) ) 1435 return SCIP_OKAY; 1436 1437 /* check whether a debug solution is available */ 1438 if( !debugSolutionAvailable(set) ) 1439 return SCIP_OKAY; 1440 1441 /* check if the incumbent solution is at least as good as the debug solution, so we can stop to check the debug solution */ 1442 if( debugSolIsAchieved(set) ) 1443 return SCIP_OKAY; 1444 1445 /* get solution value of x variable */ 1446 SCIP_CALL( getSolutionValue(set, var, &solval) ); 1447 1448 if( solval == SCIP_UNKNOWN ) /*lint !e777*/ 1449 return SCIP_OKAY; 1450 1451 val = constant; 1452 1453 for( i = 0; i < naggrvars; i++ ) 1454 { 1455 SCIP_Real aggrsolval; 1456 1457 /* get solution value of y variable */ 1458 SCIP_CALL( getSolutionValue(set, aggrvars[i], &aggrsolval) ); 1459 1460 if( aggrsolval == SCIP_UNKNOWN ) /*lint !e777*/ 1461 return SCIP_OKAY; 1462 1463 val += scalars[i] * aggrsolval; 1464 } 1465 1466 /* print debug message if the aggregation violates the debugging solution */ 1467 if( !SCIPsetIsRelEQ(set, solval, val) ) 1468 { 1469 if( naggrvars == 1 ) 1470 { 1471 SCIP_Real aggrsolval; 1472 1473 /* get solution value of y variable */ 1474 SCIP_CALL( getSolutionValue(set, aggrvars[0], &aggrsolval) ); 1475 1476 SCIPerrorMessage("aggregation <%s>[%g] = %g<%s>[%g] + %g violates debugging solution (expected %g)\n", 1477 SCIPvarGetName(var), solval, scalars[0], SCIPvarGetName(aggrvars[0]), aggrsolval, constant, val); 1478 } 1479 else 1480 { 1481 SCIPerrorMessage("multi-aggregation <%s>[%g] = ... %d vars ... + %g violates debugging solution (expected %g)\n", 1482 SCIPvarGetName(var), solval, naggrvars, constant, val); 1483 } 1484 SCIPABORT(); 1485 } 1486 1487 return SCIP_OKAY; 1488 } 1489 1490 /** check whether given clique is valid for the debugging solution */ 1491 SCIP_RETCODE SCIPdebugCheckClique( 1492 SCIP_SET* set, /**< global SCIP settings */ 1493 SCIP_VAR** vars, /**< binary variables in the clique: at most one can be set to the given value */ 1494 SCIP_Bool* values, /**< values of the variables in the clique; NULL to use TRUE for all vars */ 1495 int nvars /**< number of variables in the clique */ 1496 ) 1497 { 1498 SCIP_Real solval; 1499 int pos1; 1500 int pos2; 1501 int v; 1502 1503 assert(set != NULL); 1504 assert(vars != NULL); 1505 1506 /* when debugging was disabled the solution is not defined to be not valid in the current subtree */ 1507 if( !SCIPdebugSolIsEnabled(set->scip) ) 1508 return SCIP_OKAY; 1509 1510 /* check whether a debug solution is available */ 1511 if( !debugSolutionAvailable(set) ) 1512 return SCIP_OKAY; 1513 1514 /* check if the incumbent solution is at least as good as the debug solution, so we can stop to check the debug solution */ 1515 if( debugSolIsAchieved(set) ) 1516 return SCIP_OKAY; 1517 1518 pos1 = -1; 1519 pos2 = -1; 1520 1521 for( v = 0; v < nvars; ++v ) 1522 { 1523 assert(vars[v] != NULL); 1524 assert(SCIPvarIsBinary(vars[v])); 1525 1526 /* get solution value of variable */ 1527 SCIP_CALL( getSolutionValue(set, vars[v], &solval) ); 1528 1529 if( solval == SCIP_UNKNOWN ) /*lint !e777*/ 1530 continue; 1531 1532 assert(SCIPsetIsFeasZero(set, solval) || SCIPsetIsFeasEQ(set, solval, 1.0)); 1533 1534 /* negated solution value if negated variable is in clique */ 1535 if( values != NULL && values[v] == 0 ) 1536 solval = 1.0 - solval; 1537 1538 if( SCIPsetIsFeasEQ(set, solval, 1.0) ) 1539 { 1540 if( pos1 == -1 ) 1541 pos1 = v; 1542 else 1543 { 1544 assert(pos2 == -1); 1545 pos2 = v; 1546 break; 1547 } 1548 } 1549 } 1550 1551 /* print debug message if the clique violates the debugging solution */ 1552 if( pos2 != -1 ) 1553 { 1554 assert(pos1 != -1); 1555 SCIPerrorMessage("clique violates debugging solution, (at least) variable <%s%s> and variable <%s%s> are both one in the debugging solution\n", 1556 (values == NULL || values[pos1]) ? "" : "~", SCIPvarGetName(vars[pos1]), (values == NULL || values[pos2]) ? "" : "~", SCIPvarGetName(vars[pos2])); 1557 SCIPABORT(); 1558 } 1559 1560 return SCIP_OKAY; 1561 } 1562 1563 /** check, whether at least one literals is TRUE in the debugging solution */ 1564 static 1565 SCIP_Bool debugCheckBdchginfos( 1566 SCIP_SET* set, /**< global SCIP settings */ 1567 SCIP_BDCHGINFO** bdchginfos, /**< bound change informations of the conflict set */ 1568 SCIP_Real* relaxedbds, /**< array with relaxed bounds which are efficient to create a valid conflict, or NULL */ 1569 int nbdchginfos /**< number of bound changes in the conflict set */ 1570 ) 1571 { 1572 SCIP_Real solval; 1573 int i; 1574 1575 /* check whether a debug solution is available */ 1576 if( !debugSolutionAvailable(set) ) 1577 return SCIP_OKAY; 1578 1579 assert(SCIPdebugSolIsEnabled(set->scip)); 1580 1581 solval = 0.0; 1582 /* check, whether at least one literals is TRUE in the debugging solution */ 1583 for( i = 0; i < nbdchginfos; ++i ) 1584 { 1585 SCIP_BDCHGINFO* bdchginfo; 1586 SCIP_VAR* var; 1587 SCIP_Real newbound; 1588 1589 bdchginfo = bdchginfos[i]; 1590 assert(bdchginfo != NULL); 1591 1592 var = SCIPbdchginfoGetVar(bdchginfo); 1593 assert(var != NULL); 1594 1595 if( relaxedbds != NULL ) 1596 newbound = relaxedbds[i]; 1597 else 1598 newbound = SCIPbdchginfoGetNewbound(bdchginfo); 1599 1600 SCIP_CALL( getSolutionValue(set, var, &solval) ); 1601 1602 if( solval == SCIP_UNKNOWN ) /*lint !e777*/ 1603 return TRUE; 1604 1605 if( SCIPbdchginfoGetBoundtype(bdchginfo) == SCIP_BOUNDTYPE_LOWER ) 1606 { 1607 assert(SCIPsetIsLE(set, newbound, SCIPbdchginfoGetNewbound(bdchginfo))); 1608 1609 if( SCIPvarGetType(var) == SCIP_VARTYPE_CONTINUOUS ) 1610 { 1611 if( SCIPsetIsLE(set, solval, newbound) ) 1612 return TRUE; 1613 } 1614 else 1615 { 1616 if( SCIPsetIsLT(set, solval, newbound) ) 1617 return TRUE; 1618 } 1619 } 1620 else 1621 { 1622 assert(SCIPsetIsGE(set, newbound, SCIPbdchginfoGetNewbound(bdchginfo))); 1623 1624 if( SCIPvarGetType(var) == SCIP_VARTYPE_CONTINUOUS ) 1625 { 1626 if( SCIPsetIsGE(set, solval, newbound) ) 1627 return TRUE; 1628 } 1629 else 1630 { 1631 if( SCIPsetIsGT(set, solval, newbound) ) 1632 return TRUE; 1633 } 1634 } 1635 } 1636 1637 return FALSE; 1638 } 1639 1640 /** print bound change information */ 1641 static 1642 SCIP_RETCODE printBdchginfo( 1643 SCIP_SET* set, /**< global SCIP settings */ 1644 SCIP_BDCHGINFO * bdchginfo, /**< bound change information */ 1645 SCIP_Real relaxedbd /**< array with relaxed bounds which are efficient to create a valid conflict, or NULL */ 1646 ) 1647 { 1648 SCIP_Real solval; 1649 1650 /* check whether a debug solution is available */ 1651 if( !debugSolutionAvailable(set) ) 1652 return SCIP_OKAY; 1653 1654 /* get solution value within the debug solution */ 1655 SCIP_CALL( getSolutionValue(set, SCIPbdchginfoGetVar(bdchginfo), &solval) ); 1656 1657 printf(" <%s>[%.15g] %s %g(%g)", SCIPvarGetName(SCIPbdchginfoGetVar(bdchginfo)), solval, 1658 SCIPbdchginfoGetBoundtype(bdchginfo) == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=", 1659 SCIPbdchginfoGetNewbound(bdchginfo), relaxedbd); 1660 1661 return SCIP_OKAY; 1662 } 1663 1664 1665 /** print bound change information */ 1666 static 1667 SCIP_RETCODE printBdchginfos( 1668 SCIP_SET* set, /**< global SCIP settings */ 1669 SCIP_BDCHGINFO** bdchginfos, /**< bound change information array */ 1670 SCIP_Real* relaxedbds, /**< array with relaxed bounds which are efficient to create a valid conflict, or NULL */ 1671 int nbdchginfos /**< number of bound changes in the conflict set */ 1672 ) 1673 { 1674 int i; 1675 1676 /* check whether a debug solution is available */ 1677 if( !debugSolutionAvailable(set) ) 1678 return SCIP_OKAY; 1679 1680 for( i = 0; i < nbdchginfos; ++i ) 1681 { 1682 SCIP_BDCHGINFO* bdchginfo; 1683 1684 bdchginfo = bdchginfos[i]; 1685 assert(bdchginfo != NULL); 1686 1687 printBdchginfo(set, bdchginfo, relaxedbds != NULL ? relaxedbds[i] : SCIPbdchginfoGetNewbound(bdchginfo)); 1688 } 1689 1690 return SCIP_OKAY; 1691 } 1692 1693 /** checks whether given conflict is valid for the debugging solution */ 1694 SCIP_RETCODE SCIPdebugCheckConflict( 1695 BMS_BLKMEM* blkmem, /**< block memory */ 1696 SCIP_SET* set, /**< global SCIP settings */ 1697 SCIP_NODE* node, /**< node where the conflict clause is added */ 1698 SCIP_BDCHGINFO** bdchginfos, /**< bound change informations of the conflict set */ 1699 SCIP_Real* relaxedbds, /**< array with relaxed bounds which are efficient to create a valid conflict */ 1700 int nbdchginfos /**< number of bound changes in the conflict set */ 1701 ) 1702 { 1703 SCIP_Bool solcontained; 1704 1705 assert(set != NULL); 1706 assert(blkmem != NULL); 1707 assert(node != NULL); 1708 assert(nbdchginfos == 0 || bdchginfos != NULL); 1709 1710 /* when debugging was disabled the solution is not defined to be not valid in the current subtree */ 1711 if( !SCIPdebugSolIsEnabled(set->scip) ) 1712 return SCIP_OKAY; 1713 1714 /* check whether a debug solution is available */ 1715 if( !debugSolutionAvailable(set) ) 1716 return SCIP_OKAY; 1717 1718 /* check if the incumbent solution is at least as good as the debug solution, so we can stop to check the debug solution */ 1719 if( debugSolIsAchieved(set) ) 1720 return SCIP_OKAY; 1721 1722 /* check whether the debugging solution is contained in the local subproblem */ 1723 SCIP_CALL( isSolutionInNode(blkmem, set, node, &solcontained) ); 1724 if( !solcontained ) 1725 return SCIP_OKAY; 1726 1727 /* check, whether at least one literals is TRUE in the debugging solution */ 1728 if( debugCheckBdchginfos(set, bdchginfos, relaxedbds, nbdchginfos) ) 1729 return SCIP_OKAY; 1730 1731 SCIPerrorMessage("invalid conflict set:"); 1732 1733 /* print bound changes which are already part of the conflict set */ 1734 SCIP_CALL( printBdchginfos(set, bdchginfos, relaxedbds, nbdchginfos) ); 1735 1736 printf("\n"); 1737 SCIPABORT(); 1738 1739 return SCIP_OKAY; /*lint !e527*/ 1740 } 1741 1742 /** checks whether given conflict graph frontier is valid for the debugging solution */ 1743 SCIP_RETCODE SCIPdebugCheckConflictFrontier( 1744 BMS_BLKMEM* blkmem, /**< block memory */ 1745 SCIP_SET* set, /**< global SCIP settings */ 1746 SCIP_NODE* node, /**< node where the conflict clause is added */ 1747 SCIP_BDCHGINFO* bdchginfo, /**< bound change info which got resolved, or NULL */ 1748 SCIP_BDCHGINFO** bdchginfos, /**< bound change informations of the conflict set */ 1749 SCIP_Real* relaxedbds, /**< array with relaxed bounds which are efficient to create a valid conflict */ 1750 int nbdchginfos, /**< number of bound changes in the conflict set */ 1751 SCIP_PQUEUE* bdchgqueue, /**< unprocessed conflict bound changes */ 1752 SCIP_PQUEUE* forcedbdchgqueue /**< unprocessed conflict bound changes that must be resolved */ 1753 ) 1754 { 1755 SCIP_BDCHGINFO** bdchgqueued; 1756 SCIP_BDCHGINFO** forcedbdchgqueued; 1757 SCIP_Bool solcontained; 1758 int nbdchgqueued; 1759 int nforcedbdchgqueued; 1760 1761 assert(set != NULL); 1762 assert(blkmem != NULL); 1763 assert(node != NULL); 1764 assert(nbdchginfos == 0 || bdchginfos != NULL); 1765 1766 /* when debugging was disabled the solution is not defined to be not valid in the current subtree */ 1767 if( !SCIPdebugSolIsEnabled(set->scip) ) 1768 return SCIP_OKAY; 1769 1770 /* check whether a debug solution is available */ 1771 if( !debugSolutionAvailable(set) ) 1772 return SCIP_OKAY; 1773 1774 /* check if the incumbent solution is at least as good as the debug solution, so we can stop to check the debug solution */ 1775 if( debugSolIsAchieved(set) ) 1776 return SCIP_OKAY; 1777 1778 /* check whether the debugging solution is contained in the local subproblem */ 1779 SCIP_CALL( isSolutionInNode(blkmem, set, node, &solcontained) ); 1780 if( !solcontained ) 1781 return SCIP_OKAY; 1782 1783 /* check, whether one literals is TRUE in the debugging solution */ 1784 if( debugCheckBdchginfos(set, bdchginfos, relaxedbds, nbdchginfos) ) 1785 return SCIP_OKAY; 1786 1787 /* get the elements of the bound change queue */ 1788 bdchgqueued = (SCIP_BDCHGINFO**)SCIPpqueueElems(bdchgqueue); 1789 nbdchgqueued = SCIPpqueueNElems(bdchgqueue); 1790 1791 /* check, whether one literals is TRUE in the debugging solution */ 1792 if( debugCheckBdchginfos(set, bdchgqueued, NULL, nbdchgqueued) ) 1793 return SCIP_OKAY; 1794 1795 /* get the elements of the bound change queue */ 1796 forcedbdchgqueued = (SCIP_BDCHGINFO**)SCIPpqueueElems(forcedbdchgqueue); 1797 nforcedbdchgqueued = SCIPpqueueNElems(forcedbdchgqueue); 1798 1799 /* check, whether one literals is TRUE in the debugging solution */ 1800 if( debugCheckBdchginfos(set, forcedbdchgqueued, NULL, nforcedbdchgqueued) ) 1801 return SCIP_OKAY; 1802 1803 SCIPerrorMessage("invalid conflict frontier"); 1804 1805 if( bdchginfo != NULL ) 1806 { 1807 printf(" (after resolving bound change "); 1808 printBdchginfo(set, bdchginfo, SCIPbdchginfoGetNewbound(bdchginfo)); 1809 printf(")"); 1810 } 1811 printf(":"); 1812 1813 /* print bound changes which are already part of the conflict set */ 1814 SCIP_CALL( printBdchginfos(set, bdchginfos, relaxedbds, nbdchginfos) ); 1815 1816 /* print bound changes which are queued */ 1817 SCIP_CALL( printBdchginfos(set, bdchgqueued, NULL, nbdchgqueued) ); 1818 1819 /* print bound changes which are queued in the force queue */ 1820 SCIP_CALL( printBdchginfos(set, forcedbdchgqueued, NULL, nforcedbdchgqueued) ); 1821 1822 printf("\n"); 1823 SCIPABORT(); 1824 1825 return SCIP_OKAY; /*lint !e527*/ 1826 } 1827 1828 /** check whether the debugging solution is valid in the current node */ 1829 SCIP_RETCODE SCIPdebugSolIsValidInSubtree( 1830 SCIP* scip, /**< SCIP data structure */ 1831 SCIP_Bool* isvalidinsubtree /**< pointer to store whether the solution is valid in the current 1832 * subtree */ 1833 ) 1834 { 1835 SCIP_Bool solcontained; 1836 1837 *isvalidinsubtree = FALSE; 1838 1839 assert(scip->set != NULL); 1840 1841 /* when debugging was disabled the solution is not defined to be not valid in the current subtree */ 1842 if( !SCIPdebugSolIsEnabled(scip) ) 1843 return SCIP_OKAY; 1844 1845 /* check whether a debug solution is available */ 1846 if( !debugSolutionAvailable(scip->set) ) 1847 return SCIP_OKAY; 1848 1849 /* check if the incumbent solution is at least as good as the debug solution, so we can stop to check the debug solution */ 1850 if( debugSolIsAchieved(scip->set) ) 1851 return SCIP_OKAY; 1852 1853 /* check whether the debugging solution is contained in the local subproblem */ 1854 SCIP_CALL( isSolutionInNode(SCIPblkmem(scip), scip->set, SCIPgetCurrentNode(scip), &solcontained) ); 1855 1856 if( solcontained ) 1857 *isvalidinsubtree = TRUE; 1858 1859 return SCIP_OKAY; 1860 } 1861 1862 /** checks whether SCIP data structure is the main SCIP (the one for which debugging is enabled) */ 1863 SCIP_Bool SCIPdebugIsMainscip( 1864 SCIP* scip /**< SCIP data structure */ 1865 ) 1866 { 1867 assert(scip != NULL); 1868 1869 return SCIPdebugSolIsEnabled(scip); 1870 } 1871 1872 /** enabling solution debugging mechanism */ 1873 void SCIPdebugSolEnable( 1874 SCIP* scip /**< SCIP data structure */ 1875 ) 1876 { 1877 SCIP_DEBUGSOLDATA* debugsoldata; 1878 assert(scip != NULL); 1879 assert(scip->set != NULL); 1880 1881 debugsoldata = SCIPsetGetDebugSolData(scip->set); 1882 assert(debugsoldata != NULL); 1883 1884 debugsoldata->debugsoldisabled = FALSE; 1885 } 1886 1887 /** disabling solution debugging mechanism */ 1888 void SCIPdebugSolDisable( 1889 SCIP* scip /**< SCIP data structure */ 1890 ) 1891 { 1892 SCIP_DEBUGSOLDATA* debugsoldata; 1893 assert(scip != NULL); 1894 assert(scip->set != NULL); 1895 1896 debugsoldata = SCIPsetGetDebugSolData(scip->set); 1897 assert(debugsoldata != NULL); 1898 1899 debugsoldata->debugsoldisabled = TRUE; 1900 } 1901 1902 /** check if solution debugging mechanism is enabled */ 1903 SCIP_Bool SCIPdebugSolIsEnabled( 1904 SCIP* scip /**< SCIP data structure */ 1905 ) 1906 { 1907 SCIP_DEBUGSOLDATA* debugsoldata; 1908 assert(scip != NULL); 1909 assert(scip->set != NULL); 1910 1911 debugsoldata = SCIPsetGetDebugSolData(scip->set); 1912 assert(debugsoldata != NULL); 1913 1914 return (!debugsoldata->debugsoldisabled); 1915 } 1916 1917 /** check if SCIP is compiled with WITH_DEBUG_SOLUTION */ 1918 SCIP_Bool SCIPwithDebugSol(void) 1919 { 1920 #ifdef WITH_DEBUG_SOLUTION 1921 return TRUE; 1922 #else 1923 return FALSE; 1924 #endif 1925 } 1926 1927 1928 /** propagator to force finding the debugging solution */ 1929 static 1930 SCIP_DECL_PROPEXEC(propExecDebug) 1931 { /*lint --e{715}*/ 1932 SCIP_VAR** vars; 1933 int nvars; 1934 int i; 1935 1936 assert(scip != NULL); 1937 assert(result != NULL); 1938 1939 *result = SCIP_DIDNOTFIND; 1940 1941 /* check if we are in the original problem and not in a sub MIP */ 1942 if( !SCIPdebugIsMainscip(scip) ) 1943 return SCIP_OKAY; 1944 1945 if( SCIPgetStage(scip) != SCIP_STAGE_SOLVING ) 1946 return SCIP_OKAY; 1947 1948 /* check whether a debug solution is available */ 1949 if( !debugSolutionAvailable(scip->set) ) 1950 return SCIP_OKAY; 1951 1952 /* check if the incumbent solution is at least as good as the debug solution, so we can stop to check the debug solution */ 1953 if( debugSolIsAchieved(scip->set) ) 1954 return SCIP_OKAY; 1955 1956 #if 1 1957 /* solve at least one LP */ 1958 if( SCIPgetNLPIterations(scip) == 0 ) 1959 return SCIP_OKAY; 1960 #endif 1961 1962 vars = SCIPgetOrigVars(scip); 1963 nvars = SCIPgetNOrigVars(scip); 1964 for( i = 0; i < nvars; ++i ) 1965 { 1966 SCIP_Real solval; 1967 SCIP_Real lb; 1968 SCIP_Real ub; 1969 SCIP_Bool infeasible; 1970 SCIP_Bool fixed; 1971 1972 SCIP_CALL( getSolutionValue(scip->set, vars[i], &solval) ); 1973 if( solval == SCIP_UNKNOWN ) /*lint !e777*/ 1974 { 1975 SCIPerrorMessage("original variable without debugging solution value\n"); 1976 SCIPABORT(); 1977 } 1978 1979 lb = SCIPvarGetLbGlobal(vars[i]); 1980 ub = SCIPvarGetUbGlobal(vars[i]); 1981 if( SCIPisLT(scip, solval, lb) || SCIPisGT(scip, solval, ub) ) 1982 { 1983 SCIPerrorMessage("solution value %.15g of <%s> outside bounds loc=[%.15g,%.15g], glb=[%.15g,%.15g]\n", 1984 solval, SCIPvarGetName(vars[i]), lb, ub, SCIPvarGetLbGlobal(vars[i]), SCIPvarGetUbGlobal(vars[i])); 1985 SCIPABORT(); 1986 } 1987 1988 SCIP_CALL( SCIPfixVar(scip, vars[i], solval, &infeasible, &fixed) ); 1989 if( infeasible ) 1990 *result = SCIP_CUTOFF; 1991 else if( fixed ) 1992 *result = SCIP_REDUCEDDOM; 1993 } 1994 1995 return SCIP_OKAY; 1996 } 1997 1998 /** creates the debugging propagator and includes it in SCIP */ 1999 SCIP_RETCODE SCIPdebugIncludeProp( 2000 SCIP* scip /**< SCIP data structure */ 2001 ) 2002 { 2003 assert(scip != NULL); 2004 2005 /* include propagator */ 2006 SCIP_CALL( SCIPincludeProp(scip, "debug", "debugging propagator", 99999999, -1, FALSE, 2007 SCIP_PROPTIMING_ALWAYS, 99999999, 0, SCIP_PRESOLTIMING_FAST, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 2008 NULL, propExecDebug, NULL, NULL) ); 2009 2010 return SCIP_OKAY; 2011 } 2012 2013 /** adds a solution value for a new variable in the transformed problem that has no original counterpart 2014 * a value can only be set if no value has been set for this variable before 2015 */ 2016 SCIP_RETCODE SCIPdebugAddSolVal( 2017 SCIP* scip, /**< SCIP data structure */ 2018 SCIP_VAR* var, /**< variable for which to add a value */ 2019 SCIP_Real val /**< solution value for variable */ 2020 ) 2021 { 2022 SCIP_DEBUGSOLDATA* debugsoldata; 2023 SCIP_Real testval; 2024 const char* varname; 2025 int i; 2026 2027 assert(scip != NULL); 2028 assert(var != NULL); 2029 assert(scip->set != NULL); 2030 2031 debugsoldata = SCIPsetGetDebugSolData(scip->set); 2032 assert(debugsoldata != NULL); 2033 2034 /* assert that we are in the SCIP instance that we are debugging and not some different (subSCIP, 2035 * auxiliary CIP, ...) 2036 */ 2037 if( !SCIPdebugSolIsEnabled(scip) ) 2038 return SCIP_OKAY; 2039 2040 /* check whether a debug solution is available */ 2041 if( !debugSolutionAvailable(scip->set) ) 2042 return SCIP_OKAY; 2043 2044 if( debugsoldata->debugsol == NULL ) 2045 { 2046 /* make sure a debug solution has been read, so we do not compare against the initial debugsolval == 0 */ 2047 SCIP_CALL( readSolution(scip->set) ); 2048 } 2049 2050 /* allocate memory */ 2051 if( debugsoldata->nsolvals >= debugsoldata->solsize ) 2052 { 2053 debugsoldata->solsize = MAX(2*debugsoldata->solsize, debugsoldata->nsolvals+1); 2054 SCIP_ALLOC( BMSreallocMemoryArray(&debugsoldata->solnames, debugsoldata->solsize) ); 2055 SCIP_ALLOC( BMSreallocMemoryArray(&debugsoldata->solvals, debugsoldata->solsize) ); 2056 } 2057 assert(debugsoldata->nsolvals < debugsoldata->solsize); 2058 2059 /* store solution value in sorted list */ 2060 varname = SCIPvarGetName(var); 2061 for( i = debugsoldata->nsolvals; i > 0 && strcmp(varname, debugsoldata->solnames[i-1]) < 0; --i ) 2062 { 2063 debugsoldata->solnames[i] = debugsoldata->solnames[i-1]; 2064 debugsoldata->solvals[i] = debugsoldata->solvals[i-1]; 2065 } 2066 if( i > 0 && strcmp(varname, debugsoldata->solnames[i-1]) == 0 ) 2067 { 2068 if( REALABS(debugsoldata->solvals[i-1] - val) > 1e-9 ) 2069 { 2070 SCIPerrorMessage("already have stored different debugging solution value (%g) for variable <%s>, cannot store %g\n", debugsoldata->solvals[i-1], varname, val); 2071 return SCIP_ERROR; 2072 } 2073 else 2074 { 2075 SCIPdebugMsg(scip, "already have stored debugging solution value %g for variable <%s>, do not store same value again\n", val, varname); 2076 for( ; i < debugsoldata->nsolvals; ++i ) 2077 { 2078 debugsoldata->solnames[i] = debugsoldata->solnames[i+1]; 2079 debugsoldata->solvals[i] = debugsoldata->solvals[i+1]; 2080 } 2081 return SCIP_OKAY; 2082 } 2083 } 2084 2085 /* insert new solution value */ 2086 SCIP_ALLOC( BMSduplicateMemoryArray(&(debugsoldata->solnames[i]), varname, strlen(varname)+1) ); 2087 SCIPdebugMsg(scip, "add variable <%s>: value <%g>\n", debugsoldata->solnames[i], val); 2088 debugsoldata->solvals[i] = val; 2089 debugsoldata->nsolvals++; 2090 2091 /* update objective function value of debug solution */ 2092 debugsoldata->debugsolval += debugsoldata->solvals[i] * SCIPvarGetObj(var); 2093 SCIPdebugMsg(scip, "Debug Solution value is now %g.\n", debugsoldata->debugsolval); 2094 2095 if( SCIPvarGetStatus(var) == SCIP_VARSTATUS_ORIGINAL ) 2096 { 2097 /* add values to SCIP debug solution */ 2098 SCIP_CALL( SCIPsetSolVal(scip, debugsoldata->debugsol, var, debugsoldata->solvals[i] ) ); 2099 } 2100 2101 /* get solution value once to produce warning if solution was cut off */ 2102 SCIPdebugGetSolVal(scip, var, &testval); 2103 2104 return SCIP_OKAY; 2105 } 2106 2107 #else 2108 2109 /** this is a dummy method to make the SunOS gcc linker happy */ 2110 extern void SCIPdummyDebugMethodForSun(void); 2111 void SCIPdummyDebugMethodForSun(void) 2112 { 2113 return; 2114 } 2115 2116 #endif 2117 2118 2119 /* 2120 * debug method for LP interface, to check if the LP interface works correct 2121 */ 2122 #ifdef SCIP_DEBUG_LP_INTERFACE 2123 2124 /* check whether coef is the r-th row of the inverse basis matrix B^-1; this is 2125 * the case if( coef * B ) is the r-th unit vector */ 2126 SCIP_RETCODE SCIPdebugCheckBInvRow( 2127 SCIP* scip, /**< SCIP data structure */ 2128 int r, /**< row number */ 2129 SCIP_Real* coef /**< r-th row of the inverse basis matrix */ 2130 ) 2131 { 2132 SCIP_Real vecval; 2133 SCIP_Real matrixval; 2134 int* basisind; 2135 int nrows; 2136 int idx; 2137 int i; 2138 int k; 2139 2140 assert(scip != NULL); 2141 2142 nrows = SCIPgetNLPRows(scip); 2143 2144 /* get basic indices for the basic matrix B */ 2145 SCIP_CALL( SCIPallocBufferArray(scip, &basisind, nrows) ); 2146 SCIP_CALL( SCIPgetLPBasisInd(scip, basisind) ); 2147 2148 /* loop over the columns of B */ 2149 for( k = 0; k < nrows; ++k ) 2150 { 2151 vecval = 0.0; 2152 2153 /* indices of basic columns and rows: 2154 * - index i >= 0 corresponds to column i, 2155 * - index i < 0 to row -i-1 2156 */ 2157 idx = basisind[k]; 2158 2159 /* check if we have a slack variable; this is the case if idx < 0 */ 2160 if( idx >= 0 ) 2161 { 2162 /* loop over the rows to compute the corresponding value in the unit vector */ 2163 for( i = 0; i < nrows; ++i ) 2164 { 2165 SCIP_CALL( SCIPlpiGetCoef(scip->lp->lpi, i, idx, &matrixval) ); 2166 vecval += coef[i] * matrixval; 2167 } 2168 } 2169 else 2170 { 2171 assert( idx < 0 ); 2172 2173 /* retransform idx 2174 * - index i >= 0 corresponds to column i, 2175 * - index i < 0 to row -i-1 2176 */ 2177 idx = -idx - 1; 2178 assert( idx >= 0 && idx < nrows ); 2179 2180 /* since idx < 0 we are in the case of a slack variable, i.e., the corresponding column 2181 is the idx-unit vector; note that some LP solver return a -idx-unit vector */ 2182 /* vecval = REALABS(coef[idx]);*/ 2183 vecval = coef[idx]; 2184 } 2185 2186 /* check if vecval fits to the r-th unit vector */ 2187 if( k == r && !SCIPisFeasEQ(scip, vecval, 1.0) ) 2188 { 2189 /* we expected a 1.0 and found something different */ 2190 SCIPmessagePrintWarning(SCIPgetMessagehdlr(scip), "checked SCIPgetLPBInvRow() found value <%g> expected 1.0\n", vecval); 2191 } 2192 else if( k != r && !SCIPisFeasZero(scip, vecval) ) 2193 { 2194 /* we expected a 0.0 and found something different */ 2195 SCIPmessagePrintWarning(SCIPgetMessagehdlr(scip), "checked SCIPgetLPBInvRow() found value <%g> expected 0.0\n", vecval); 2196 } 2197 } 2198 2199 SCIPfreeBufferArray(scip, &basisind); 2200 2201 return SCIP_OKAY; 2202 } 2203 2204 #endif 2205 2206 /** checks, if SCIP is in one of the feasible stages */ 2207 #ifndef NDEBUG 2208 SCIP_RETCODE SCIPcheckStage( 2209 SCIP* scip, /**< SCIP data structure */ 2210 const char* method, /**< method that was called */ 2211 SCIP_Bool init, /**< may method be called in the INIT stage? */ 2212 SCIP_Bool problem, /**< may method be called in the PROBLEM stage? */ 2213 SCIP_Bool transforming, /**< may method be called in the TRANSFORMING stage? */ 2214 SCIP_Bool transformed, /**< may method be called in the TRANSFORMED stage? */ 2215 SCIP_Bool initpresolve, /**< may method be called in the INITPRESOLVE stage? */ 2216 SCIP_Bool presolving, /**< may method be called in the PRESOLVING stage? */ 2217 SCIP_Bool exitpresolve, /**< may method be called in the EXITPRESOLE stage? */ 2218 SCIP_Bool presolved, /**< may method be called in the PRESOLVED stage? */ 2219 SCIP_Bool initsolve, /**< may method be called in the INITSOLVE stage? */ 2220 SCIP_Bool solving, /**< may method be called in the SOLVING stage? */ 2221 SCIP_Bool solved, /**< may method be called in the SOLVED stage? */ 2222 SCIP_Bool exitsolve, /**< may method be called in the EXITSOLVE stage? */ 2223 SCIP_Bool freetrans, /**< may method be called in the FREETRANS stage? */ 2224 SCIP_Bool freescip /**< may method be called in the FREE stage? */ 2225 ) 2226 { 2227 assert(scip != NULL); 2228 assert(method != NULL); 2229 2230 /*SCIPdebugMsg(scip, "called method <%s> at stage %d ------------------------------------------------\n", 2231 method, scip->set->stage);*/ 2232 2233 assert(scip->mem != NULL); 2234 assert(scip->set != NULL); 2235 assert(scip->interrupt != NULL); 2236 assert(scip->dialoghdlr != NULL); 2237 assert(scip->totaltime != NULL); 2238 2239 switch( scip->set->stage ) 2240 { 2241 case SCIP_STAGE_INIT: 2242 assert(scip->stat == NULL); 2243 assert(scip->origprob == NULL); 2244 assert(scip->eventfilter == NULL); 2245 assert(scip->eventqueue == NULL); 2246 assert(scip->branchcand == NULL); 2247 assert(scip->lp == NULL); 2248 assert(scip->nlp == NULL); 2249 assert(scip->primal == NULL); 2250 assert(scip->tree == NULL); 2251 assert(scip->conflict == NULL); 2252 assert(scip->transprob == NULL); 2253 assert(scip->pricestore == NULL); 2254 assert(scip->sepastore == NULL); 2255 assert(scip->cutpool == NULL); 2256 assert(scip->delayedcutpool == NULL); 2257 2258 if( !init ) 2259 { 2260 SCIPerrorMessage("cannot call method <%s> in initialization stage\n", method); 2261 return SCIP_INVALIDCALL; 2262 } 2263 return SCIP_OKAY; 2264 2265 case SCIP_STAGE_PROBLEM: 2266 assert(scip->stat != NULL); 2267 assert(scip->origprob != NULL); 2268 assert(scip->eventfilter == NULL); 2269 assert(scip->eventqueue == NULL); 2270 assert(scip->branchcand == NULL); 2271 assert(scip->lp == NULL); 2272 assert(scip->nlp == NULL); 2273 assert(scip->primal == NULL); 2274 assert(scip->tree == NULL); 2275 assert(scip->conflict == NULL); 2276 assert(scip->transprob == NULL); 2277 assert(scip->pricestore == NULL); 2278 assert(scip->sepastore == NULL); 2279 assert(scip->cutpool == NULL); 2280 assert(scip->delayedcutpool == NULL); 2281 2282 if( !problem ) 2283 { 2284 SCIPerrorMessage("cannot call method <%s> in problem creation stage\n", method); 2285 return SCIP_INVALIDCALL; 2286 } 2287 return SCIP_OKAY; 2288 2289 case SCIP_STAGE_TRANSFORMING: 2290 assert(scip->stat != NULL); 2291 assert(scip->origprob != NULL); 2292 assert(scip->eventfilter != NULL); 2293 assert(scip->eventqueue != NULL); 2294 assert(scip->branchcand != NULL); 2295 assert(scip->lp != NULL); 2296 assert(scip->primal != NULL); 2297 assert(scip->tree != NULL); 2298 assert(scip->conflict != NULL); 2299 assert(scip->transprob != NULL); 2300 assert(scip->pricestore == NULL); 2301 assert(scip->sepastore == NULL); 2302 assert(scip->cutpool == NULL); 2303 assert(scip->delayedcutpool == NULL); 2304 2305 if( !transforming ) 2306 { 2307 SCIPerrorMessage("cannot call method <%s> in problem transformation stage\n", method); 2308 return SCIP_INVALIDCALL; 2309 } 2310 return SCIP_OKAY; 2311 2312 case SCIP_STAGE_TRANSFORMED: 2313 assert(scip->stat != NULL); 2314 assert(scip->origprob != NULL); 2315 assert(scip->eventfilter != NULL); 2316 assert(scip->eventqueue != NULL); 2317 assert(scip->branchcand != NULL); 2318 assert(scip->lp != NULL); 2319 assert(scip->primal != NULL); 2320 assert(scip->tree != NULL); 2321 assert(scip->conflict != NULL); 2322 assert(scip->transprob != NULL); 2323 assert(scip->pricestore == NULL); 2324 assert(scip->sepastore == NULL); 2325 assert(scip->cutpool == NULL); 2326 assert(scip->delayedcutpool == NULL); 2327 2328 if( !transformed ) 2329 { 2330 SCIPerrorMessage("cannot call method <%s> in problem transformed stage\n", method); 2331 return SCIP_INVALIDCALL; 2332 } 2333 return SCIP_OKAY; 2334 2335 case SCIP_STAGE_INITPRESOLVE: 2336 assert(scip->stat != NULL); 2337 assert(scip->origprob != NULL); 2338 assert(scip->eventfilter != NULL); 2339 assert(scip->eventqueue != NULL); 2340 assert(scip->branchcand != NULL); 2341 assert(scip->lp != NULL); 2342 assert(scip->primal != NULL); 2343 assert(scip->tree != NULL); 2344 assert(scip->conflict != NULL); 2345 assert(scip->transprob != NULL); 2346 assert(scip->pricestore == NULL); 2347 assert(scip->sepastore == NULL); 2348 assert(scip->cutpool == NULL); 2349 assert(scip->delayedcutpool == NULL); 2350 2351 if( !initpresolve ) 2352 { 2353 SCIPerrorMessage("cannot call method <%s> in init presolving stage\n", method); 2354 return SCIP_INVALIDCALL; 2355 } 2356 return SCIP_OKAY; 2357 2358 case SCIP_STAGE_PRESOLVING: 2359 assert(scip->stat != NULL); 2360 assert(scip->origprob != NULL); 2361 assert(scip->eventfilter != NULL); 2362 assert(scip->eventqueue != NULL); 2363 assert(scip->branchcand != NULL); 2364 assert(scip->lp != NULL); 2365 assert(scip->primal != NULL); 2366 assert(scip->tree != NULL); 2367 assert(scip->conflict != NULL); 2368 assert(scip->transprob != NULL); 2369 assert(scip->pricestore == NULL); 2370 assert(scip->sepastore == NULL); 2371 assert(scip->cutpool == NULL); 2372 assert(scip->delayedcutpool == NULL); 2373 2374 if( !presolving ) 2375 { 2376 SCIPerrorMessage("cannot call method <%s> in presolving stage\n", method); 2377 return SCIP_INVALIDCALL; 2378 } 2379 return SCIP_OKAY; 2380 2381 case SCIP_STAGE_EXITPRESOLVE: 2382 assert(scip->stat != NULL); 2383 assert(scip->origprob != NULL); 2384 assert(scip->eventfilter != NULL); 2385 assert(scip->eventqueue != NULL); 2386 assert(scip->branchcand != NULL); 2387 assert(scip->lp != NULL); 2388 assert(scip->primal != NULL); 2389 assert(scip->tree != NULL); 2390 assert(scip->conflict != NULL); 2391 assert(scip->transprob != NULL); 2392 assert(scip->pricestore == NULL); 2393 assert(scip->sepastore == NULL); 2394 assert(scip->cutpool == NULL); 2395 assert(scip->delayedcutpool == NULL); 2396 2397 if( !exitpresolve ) 2398 { 2399 SCIPerrorMessage("cannot call method <%s> in exit presolving stage\n", method); 2400 return SCIP_INVALIDCALL; 2401 } 2402 return SCIP_OKAY; 2403 2404 case SCIP_STAGE_PRESOLVED: 2405 assert(scip->stat != NULL); 2406 assert(scip->origprob != NULL); 2407 assert(scip->eventfilter != NULL); 2408 assert(scip->eventqueue != NULL); 2409 assert(scip->branchcand != NULL); 2410 assert(scip->lp != NULL); 2411 assert(scip->primal != NULL); 2412 assert(scip->tree != NULL); 2413 assert(scip->conflict != NULL); 2414 assert(scip->transprob != NULL); 2415 assert(scip->pricestore == NULL); 2416 assert(scip->sepastore == NULL); 2417 assert(scip->cutpool == NULL); 2418 assert(scip->delayedcutpool == NULL); 2419 2420 if( !presolved ) 2421 { 2422 SCIPerrorMessage("cannot call method <%s> in problem presolved stage\n", method); 2423 return SCIP_INVALIDCALL; 2424 } 2425 return SCIP_OKAY; 2426 2427 case SCIP_STAGE_INITSOLVE: 2428 assert(scip->stat != NULL); 2429 assert(scip->origprob != NULL); 2430 assert(scip->eventfilter != NULL); 2431 assert(scip->eventqueue != NULL); 2432 assert(scip->branchcand != NULL); 2433 assert(scip->lp != NULL); 2434 assert(scip->primal != NULL); 2435 assert(scip->tree != NULL); 2436 assert(scip->transprob != NULL); 2437 2438 if( !initsolve ) 2439 { 2440 SCIPerrorMessage("cannot call method <%s> in init solve stage\n", method); 2441 return SCIP_INVALIDCALL; 2442 } 2443 return SCIP_OKAY; 2444 2445 case SCIP_STAGE_SOLVING: 2446 assert(scip->stat != NULL); 2447 assert(scip->origprob != NULL); 2448 assert(scip->eventfilter != NULL); 2449 assert(scip->eventqueue != NULL); 2450 assert(scip->branchcand != NULL); 2451 assert(scip->lp != NULL); 2452 assert(scip->primal != NULL); 2453 assert(scip->tree != NULL); 2454 assert(scip->conflict != NULL); 2455 assert(scip->transprob != NULL); 2456 assert(scip->pricestore != NULL); 2457 assert(scip->sepastore != NULL); 2458 assert(scip->cutpool != NULL); 2459 assert(scip->delayedcutpool != NULL); 2460 2461 if( !solving ) 2462 { 2463 SCIPerrorMessage("cannot call method <%s> in solving stage\n", method); 2464 return SCIP_INVALIDCALL; 2465 } 2466 return SCIP_OKAY; 2467 2468 case SCIP_STAGE_SOLVED: 2469 assert(scip->stat != NULL); 2470 assert(scip->origprob != NULL); 2471 assert(scip->eventfilter != NULL); 2472 assert(scip->eventqueue != NULL); 2473 assert(scip->branchcand != NULL); 2474 assert(scip->lp != NULL); 2475 assert(scip->primal != NULL); 2476 assert(scip->tree != NULL); 2477 assert(scip->conflict != NULL); 2478 assert(scip->transprob != NULL); 2479 assert(scip->pricestore != NULL); 2480 assert(scip->sepastore != NULL); 2481 assert(scip->cutpool != NULL); 2482 assert(scip->delayedcutpool != NULL); 2483 2484 if( !solved ) 2485 { 2486 SCIPerrorMessage("cannot call method <%s> in problem solved stage\n", method); 2487 return SCIP_INVALIDCALL; 2488 } 2489 return SCIP_OKAY; 2490 2491 case SCIP_STAGE_EXITSOLVE: 2492 assert(scip->stat != NULL); 2493 assert(scip->origprob != NULL); 2494 assert(scip->eventfilter != NULL); 2495 assert(scip->eventqueue != NULL); 2496 assert(scip->branchcand != NULL); 2497 assert(scip->lp != NULL); 2498 assert(scip->primal != NULL); 2499 assert(scip->tree != NULL); 2500 assert(scip->transprob != NULL); 2501 2502 if( !exitsolve ) 2503 { 2504 SCIPerrorMessage("cannot call method <%s> in solve deinitialization stage\n", method); 2505 return SCIP_INVALIDCALL; 2506 } 2507 return SCIP_OKAY; 2508 2509 case SCIP_STAGE_FREETRANS: 2510 assert(scip->stat != NULL); 2511 assert(scip->origprob != NULL); 2512 assert(scip->pricestore == NULL); 2513 assert(scip->sepastore == NULL); 2514 assert(scip->cutpool == NULL); 2515 assert(scip->delayedcutpool == NULL); 2516 2517 if( !freetrans ) 2518 { 2519 SCIPerrorMessage("cannot call method <%s> in free transformed problem stage\n", method); 2520 return SCIP_INVALIDCALL; 2521 } 2522 return SCIP_OKAY; 2523 2524 case SCIP_STAGE_FREE: 2525 if( !freescip ) 2526 { 2527 SCIPerrorMessage("cannot call method <%s> in free stage\n", method); 2528 return SCIP_INVALIDCALL; 2529 } 2530 return SCIP_OKAY; 2531 2532 default: 2533 /* note that this is in an internal SCIP error since all SCIP stages are covert in the switch above */ 2534 SCIPerrorMessage("invalid SCIP stage <%d>\n", scip->set->stage); 2535 return SCIP_ERROR; 2536 } 2537 } 2538 #endif 2539