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