Scippy

SCIP

Solving Constraint Integer Programs

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