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-2017 Konrad-Zuse-Zentrum */
7 /* fuer Informationstechnik Berlin */
8 /* */
9 /* SCIP is distributed under the terms of the ZIB Academic License. */
10 /* */
11 /* You should have received a copy of the ZIB Academic License */
12 /* along with SCIP; see the file COPYING. If not email to scip@zib.de. */
13 /* */
14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15 
16 /**@file debug.c
17  * @brief methods for debugging
18  * @author Tobias Achterberg
19  */
20 
21 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
22 
23 #include <stdio.h>
24 #include <string.h>
25 #include <assert.h>
26 #if defined(_WIN32) || defined(_WIN64)
27 #else
28 #include <strings.h> /*lint --e{766}*/
29 #endif
30 
31 #include "scip/def.h"
32 #include "blockmemshell/memory.h"
33 #include "scip/set.h"
34 #include "scip/lp.h"
35 #include "scip/var.h"
36 #include "scip/prob.h"
37 #include "scip/tree.h"
38 #include "scip/scip.h"
39 #include "scip/debug.h"
40 #include "scip/pub_message.h"
41 #include "scip/pub_misc.h"
42 #include "scip/struct_scip.h"
43 
44 #ifdef SCIP_DEBUG_SOLUTION
45 
46 #define SCIP_HASHSIZE_DEBUG 500 /**< minimum size of hash map for storing whether a solution is valid for the node */
47 
48 struct SCIP_DebugSolData
49 {
50  char** solnames; /**< variable names in the solution */
51  SCIP_Real* solvals; /**< solution value array (only nonzero entries) */
52  int nsolvals; /**< number of entries in the debug solution */
53  int solsize; /**< size of the array entries */
54  SCIP_SOL* debugsol; /**< a debug solution */
55  SCIP_STAGE debugsolstage; /**< solving stage of debug solution */
56  SCIP_HASHMAP* solinnode; /**< maps nodes to bools, storing whether the solution is valid for the node */
57  SCIP_Bool falseptr; /**< pointer to value FALSE used for hashmap */
58  SCIP_Bool trueptr; /**< pointer to value TRUE used for hashmap */
59  SCIP_Bool solisachieved; /**< means if current best solution is better than the given debug solution */
60  SCIP_Real debugsolval; /**< objective value for debug solution */
61  SCIP_Bool debugsoldisabled; /**< flag indicating if debugging of solution was disabled or not */
62 };
63 
64 
65 /** creates debug solution data */
67  SCIP_DEBUGSOLDATA** debugsoldata /**< pointer to debug solution data */
68  )
69 {
70  assert(debugsoldata != NULL);
71 
72  SCIP_ALLOC( BMSallocMemory(debugsoldata) );
73 
74  (*debugsoldata)->solnames = NULL;
75  (*debugsoldata)->solvals = NULL;
76  (*debugsoldata)->nsolvals = 0;
77  (*debugsoldata)->solsize = 0;
78  (*debugsoldata)->debugsol = NULL;
79  (*debugsoldata)->debugsolstage = SCIP_STAGE_INIT;
80  (*debugsoldata)->solinnode = NULL;
81  (*debugsoldata)->falseptr = FALSE;
82  (*debugsoldata)->trueptr = TRUE;
83  (*debugsoldata)->solisachieved = FALSE;
84  (*debugsoldata)->debugsolval = 0.0;
85  (*debugsoldata)->debugsoldisabled = TRUE;
86 
87  return SCIP_OKAY;
88 }
89 
90 #ifdef SCIP_MORE_DEBUG
91 /** comparison method for sorting variables w.r.t. to their name */
92 static
93 SCIP_DECL_SORTPTRCOMP(sortVarsAfterNames)
94 {
95  return strcmp(SCIPvarGetName((SCIP_VAR*)elem1), SCIPvarGetName((SCIP_VAR*)elem2));
96 }
97 #endif
98 
99 
100 /** reads solution from given file into given arrays */
101 static
102 SCIP_RETCODE readSolfile(
103  SCIP_SET* set, /**< global SCIP settings */
104  const char* solfilename, /**< solution filename to read */
105  SCIP_SOL** debugsolptr,
106  SCIP_Real* debugsolvalptr,
107  SCIP_STAGE* debugsolstageptr,
108  char*** names, /**< pointer to store the array of variable names */
109  SCIP_Real** vals, /**< pointer to store the array of solution values */
110  int* nvals, /**< pointer to store the number of non-zero elements */
111  int* valssize /**< pointer to store the length of the variable names and solution values arrays */
112  )
113 {
114  SCIP_VAR** vars;
115  SCIP_Real* solvalues;
116  SCIP_FILE* file;
117  SCIP_SOL* debugsol;
118  SCIP_Real debugsolval;
119  int nonvalues;
120  int nfound;
121  int i;
122  SCIP_Bool unknownvariablemessage;
123 
124  assert(set != NULL);
125  assert(solfilename != NULL);
126  assert(names != NULL);
127  assert(*names == NULL);
128  assert(vals != NULL);
129  assert(*vals == NULL);
130  assert(nvals != NULL);
131  assert(valssize != NULL);
132 
133  printf("***** debug: reading solution file <%s>\n", solfilename);
134 
135  /* open solution file */
136  file = SCIPfopen(solfilename, "r");
137  if( file == NULL )
138  {
139  SCIPerrorMessage("cannot open solution file <%s> specified in scip/debug.h\n", solfilename);
140  SCIPprintSysError(solfilename);
141  return SCIP_NOFILE;
142  }
143 
144  /* read data */
145  nonvalues = 0;
146  *valssize = 0;
147  unknownvariablemessage = FALSE;
148 
149  while( !SCIPfeof(file) )
150  {
151  char buf[SCIP_MAXSTRLEN];
152  char name[SCIP_MAXSTRLEN];
153  char objstring[SCIP_MAXSTRLEN];
154  char valuestring[SCIP_MAXSTRLEN];
155  SCIP_VAR* var;
156  SCIP_Real val;
157  int nread;
158 
159  if( SCIPfgets(buf, SCIP_MAXSTRLEN, file) == NULL )
160  {
161  if( SCIPfeof(file) )
162  break;
163  else
164  return SCIP_READERROR;
165  }
166 
167  /* there are some lines which may preceed the solution information */
168  if( strncasecmp(buf, "solution status:", 16) == 0 || strncasecmp(buf, "objective value:", 16) == 0 ||
169  strncasecmp(buf, "Log started", 11) == 0 || strncasecmp(buf, "Variable Name", 13) == 0 ||
170  strncasecmp(buf, "All other variables", 19) == 0 || strncasecmp(buf, "\n", 1) == 0 ||
171  strncasecmp(buf, "NAME", 4) == 0 || strncasecmp(buf, "ENDATA", 6) == 0 ) /* allow parsing of SOL-format on the MIPLIB 2003 pages */
172  {
173  ++nonvalues;
174  continue;
175  }
176 
177  nread = sscanf(buf, "%s %s %s\n", name, valuestring, objstring);
178  if( nread < 2 )
179  {
180  printf("invalid input line %d in solution file <%s>: <%s>\n", *nvals + nonvalues, SCIP_DEBUG_SOLUTION, name);
181  SCIPfclose(file);
182  return SCIP_READERROR;
183  }
184 
185  /* find the variable */
186  var = SCIPfindVar(set->scip, name);
187  if( var == NULL )
188  {
189  if( !unknownvariablemessage )
190  {
191  SCIPverbMessage(set->scip, SCIP_VERBLEVEL_NORMAL, NULL, "unknown variable <%s> in line %d of solution file <%s>\n",
192  name, *nvals + nonvalues, SCIP_DEBUG_SOLUTION);
193  SCIPverbMessage(set->scip, SCIP_VERBLEVEL_NORMAL, NULL, " (further unknown variables are ignored)\n");
194  unknownvariablemessage = TRUE;
195  }
196  continue;
197  }
198 
199  /* cast the value, check first for inv(alid) or inf(inite) ones that need special treatment */
200  if( strncasecmp(valuestring, "inv", 3) == 0 )
201  continue;
202  else if( strncasecmp(valuestring, "+inf", 4) == 0 || strncasecmp(valuestring, "inf", 3) == 0 )
203  val = SCIPsetInfinity(set);
204  else if( strncasecmp(valuestring, "-inf", 4) == 0 )
205  val = -SCIPsetInfinity(set);
206  else
207  {
208  nread = sscanf(valuestring, "%lf", &val);
209  if( nread != 1 )
210  {
211  SCIPerrorMessage("Invalid solution value <%s> for variable <%s> in line %d of solution file <%s>.\n",
212  valuestring, name, *nvals + nonvalues, SCIP_DEBUG_SOLUTION);
213  SCIPfclose(file);
214  return SCIP_READERROR;
215  }
216  }
217 
218  /* allocate memory */
219  if( *nvals >= *valssize )
220  {
221  *valssize = MAX(2 * *valssize, (*nvals)+1);
222  SCIP_ALLOC( BMSreallocMemoryArray(names, *valssize) );
223  SCIP_ALLOC( BMSreallocMemoryArray(vals, *valssize) );
224  }
225  assert(*nvals < *valssize);
226 
227  /* store solution value in sorted list */
228  for( i = *nvals; i > 0 && strcmp(name, (*names)[i-1]) < 0; --i )
229  {
230  (*names)[i] = (*names)[i-1];
231  (*vals)[i] = (*vals)[i-1];
232  }
233  SCIP_ALLOC( BMSduplicateMemoryArray(&(*names)[i], name, strlen(name)+1) );
234  SCIPdebugMsg(set->scip, "found variable <%s>: value <%g>\n", (*names)[i], val);
235  (*vals)[i] = val;
236  (*nvals)++;
237  }
238 
239  /* get memory for SCIP solution */
240  SCIP_ALLOC( BMSallocMemoryArray(&vars, *valssize) );
241  SCIP_ALLOC( BMSallocMemoryArray(&solvalues, *valssize) );
242 
243  debugsolval = 0.0;
244  nfound = 0;
245 
246  /* get solution value */
247  for( i = 0; i < *nvals; ++i)
248  {
249  SCIP_VAR* var;
250  var = SCIPfindVar(set->scip, (*names)[i]);
251  if( var != NULL )
252  {
253  vars[nfound] = var;
254  solvalues[nfound] = (*vals)[i];
255  ++nfound;
256  debugsolval += (*vals)[i] * SCIPvarGetObj(var);
257  }
258  }
259  SCIPdebugMsg(set->scip, "Debug Solution value is %g.\n", debugsolval);
260 
261 #ifdef SCIP_MORE_DEBUG
262  SCIPsortPtrReal((void**)vars, solvalues, sortVarsAfterNames, nfound);
263 
264  for( i = 0; i < nfound - 1; ++i)
265  {
266  assert(strcmp(SCIPvarGetName(vars[i]), SCIPvarGetName(vars[i + 1])) != 0);
267  }
268 #endif
269 
270  if( debugsolptr != NULL )
271  {
272  /* create SCIP solution */
273  SCIP_CALL( SCIPcreateOrigSol(set->scip, &debugsol, NULL) );
274  *debugsolstageptr = SCIPgetStage(set->scip);
275 
276  /* set SCIP solution values */
277  SCIP_CALL( SCIPsetSolVals(set->scip, debugsol, nfound, vars, solvalues ) );
278  }
279 
280  BMSfreeMemoryArray(&vars);
281  BMSfreeMemoryArray(&solvalues);
282 
283  if( debugsolptr != NULL )
284  *debugsolptr = debugsol;
285 
286  if( debugsolvalptr != NULL )
287  *debugsolvalptr = debugsolval;
288 
289  /* close file */
290  SCIPfclose(file);
291 
292  printf("***** debug: read %d non-zero entries (%d variables found)\n", *nvals, nfound);
293 
294  return SCIP_OKAY;
295 }
296 
297 /** reads feasible solution to check from file */
298 static
299 SCIP_RETCODE readSolution(
300  SCIP_SET* set /**< global SCIP settings */
301  )
302 {
303  SCIP_DEBUGSOLDATA* debugsoldata;
304 
305  assert(set != NULL);
306 
307  debugsoldata = SCIPsetGetDebugSolData(set);
308 
309  if( debugsoldata == NULL || debugsoldata->nsolvals > 0 )
310  return SCIP_OKAY;
311 
312  SCIP_CALL( readSolfile(set, SCIP_DEBUG_SOLUTION, &debugsoldata->debugsol, &debugsoldata->debugsolval,
313  &debugsoldata->debugsolstage, &(debugsoldata->solnames), &(debugsoldata->solvals), &(debugsoldata->nsolvals),
314  &(debugsoldata->solsize)) );
315 
316  return SCIP_OKAY;
317 }
318 
319 /** gets value of given variable in debugging solution */
320 static
321 SCIP_RETCODE getSolutionValue(
322  SCIP_SET* set, /**< global SCIP settings */
323  SCIP_VAR* var, /**< variable to get solution value for */
324  SCIP_Real* val /**< pointer to store solution value */
325  )
326 {
327  SCIP_VAR* solvar;
328  SCIP_DEBUGSOLDATA* debugsoldata;
329  SCIP_Real scalar;
330  SCIP_Real constant;
331  const char* name;
332  int left;
333  int right;
334  int middle;
335  int cmp;
336 
337  assert(set != NULL);
338  assert(var != NULL);
339  assert(val != NULL);
340 
341  debugsoldata = SCIPsetGetDebugSolData(set);
342  assert(debugsoldata != NULL);
343 
344  /* allow retrieving solution values only if referring to the SCIP instance that is debugged */
345  if( debugsoldata->debugsoldisabled )
346  {
347  *val = SCIP_UNKNOWN;
348  return SCIP_OKAY;
349  }
350 
351  SCIP_CALL( readSolution(set) );
352  SCIPsetDebugMsg(set, "Now handling variable <%s>, which has status %d, is of type %d, and was deleted: %d, negated: %d, transformed: %d\n",
354 
355  /* ignore deleted variables */
356  if( SCIPvarIsDeleted(var) )
357  {
358  SCIPsetDebugMsg(set, "**** unknown solution value for deleted variable <%s>\n", SCIPvarGetName(var));
359  *val = SCIP_UNKNOWN;
360  return SCIP_OKAY;
361  }
362 
363  /* retransform variable onto original variable space */
364  solvar = var;
365  scalar = 1.0;
366  constant = 0.0;
367  if( SCIPvarIsNegated(solvar) )
368  {
369  scalar = -1.0;
370  constant = SCIPvarGetNegationConstant(solvar);
371  solvar = SCIPvarGetNegationVar(solvar);
372  }
373 
374  if( SCIPvarIsTransformed(solvar) )
375  {
376  SCIP_CALL( SCIPvarGetOrigvarSum(&solvar, &scalar, &constant) );
377  if( solvar == NULL )
378  {
379  /* if no original counterpart, then maybe someone added a value for the transformed variable, so search for var (or its negation) */
380  SCIPsetDebugMsg(set, "variable <%s> has no original counterpart\n", SCIPvarGetName(var));
381  solvar = var;
382  scalar = 1.0;
383  constant = 0.0;
384  if( SCIPvarIsNegated(solvar) )
385  {
386  scalar = -1.0;
387  constant = SCIPvarGetNegationConstant(solvar);
388  solvar = SCIPvarGetNegationVar(solvar);
389  }
390  }
391  }
392 
393  /* perform a binary search for the variable */
394  name = SCIPvarGetName(solvar);
395  left = 0;
396  right = debugsoldata->nsolvals-1;
397  while( left <= right )
398  {
399  middle = (left+right)/2;
400  cmp = strcmp(name, debugsoldata->solnames[middle]);
401  if( cmp < 0 )
402  right = middle-1;
403  else if( cmp > 0 )
404  left = middle+1;
405  else
406  {
407  *val = scalar * debugsoldata->solvals[middle] + constant;
408 
409  if( SCIPsetIsFeasLT(set, *val, SCIPvarGetLbGlobal(var)) || SCIPsetIsFeasGT(set, *val, SCIPvarGetUbGlobal(var)) )
410  {
411  SCIPmessagePrintWarning(SCIPgetMessagehdlr(set->scip), "invalid solution value %.15g for variable <%s>[%.15g,%.15g]\n",
412  *val, SCIPvarGetName(var), SCIPvarGetLbGlobal(var), SCIPvarGetUbGlobal(var));
413  }
414 
415  return SCIP_OKAY;
416  }
417  }
418  *val = constant;
419 
420  if( SCIPsetIsFeasLT(set, *val, SCIPvarGetLbGlobal(var)) || SCIPsetIsFeasGT(set, *val, SCIPvarGetUbGlobal(var)) )
421  {
422  SCIPmessagePrintWarning(SCIPgetMessagehdlr(set->scip), "invalid solution value %.15g for variable <%s>[%.15g,%.15g]\n",
423  *val, SCIPvarGetName(var), SCIPvarGetLbGlobal(var), SCIPvarGetUbGlobal(var));
424  }
425 
426  return SCIP_OKAY;
427 }
428 
429 /** gets pointer to the debug solution */
430 SCIP_RETCODE SCIPdebugGetSol(
431  SCIP* scip, /**< SCIP data structure */
432  SCIP_SOL** sol /**< buffer to store pointer to the debug solution */
433  )
434 {
435  SCIP_DEBUGSOLDATA* debugsoldata;
436 
437  debugsoldata = SCIPsetGetDebugSolData(scip->set);
438  assert(scip != NULL);
439  assert(sol != NULL);
440 
441  SCIP_CALL( readSolution(scip->set) );
442 
443 
444  if( debugsoldata->debugsol == NULL )
445  {
446  *sol = NULL;
447  return SCIP_ERROR;
448  }
449 
450  *sol = debugsoldata->debugsol;
451 
452  return SCIP_OKAY;
453 }
454 
455 /** gets value for a variable in the debug solution
456  *
457  * if no value is stored for the variable, gives 0.0
458  */
460  SCIP* scip, /**< SCIP data structure */
461  SCIP_VAR* var, /**< variable for which to get the value */
462  SCIP_Real* val /**< buffer to store solution value */
463  )
464 {
465  SCIP_CALL( getSolutionValue(scip->set, var, val) );
466 
467  return SCIP_OKAY;
468 }
469 
470 /** returns whether the debug solution is worse than the best known solution or if the debug solution was found */
471 static
472 SCIP_Bool debugSolIsAchieved(
473  SCIP_SET* set /**< global SCIP settings */
474  )
475 {
476  SCIP_SOL* bestsol;
477  SCIP* scip;
478  SCIP_DEBUGSOLDATA* debugsoldata;
479 
480  assert(set != NULL);
481  debugsoldata = SCIPsetGetDebugSolData(set);
482 
483  assert(debugsoldata != NULL);
484 
485  if( debugsoldata->solisachieved )
486  return TRUE;
487 
488  assert(set != NULL);
489 
490  scip = set->scip;
491  assert(scip != NULL);
492 
493  bestsol = SCIPgetBestSol(scip);
494 
495  if( bestsol != NULL )
496  {
497  SCIP_Real solvalue;
498 
499  /* don't check solution while in problem creation stage */
500  if( SCIPsetGetStage(set) == SCIP_STAGE_PROBLEM )
501  return TRUE;
502 
503  /* we can't get the original objective function value during probing mode when the objective has changed */
504  if( SCIPisObjChangedProbing(scip) )
505  return TRUE;
506 
507  solvalue = SCIPgetSolOrigObj(scip, bestsol);
508 
509  /* make sure a debug solution has been read, so we do not compare against the initial debugsolval == 0 */
510  SCIP_CALL( readSolution(set) );
511 
512  if( (SCIPgetObjsense(scip) == SCIP_OBJSENSE_MINIMIZE && SCIPsetIsLE(set, solvalue, debugsoldata->debugsolval))
513  || (SCIPgetObjsense(scip) == SCIP_OBJSENSE_MAXIMIZE && SCIPsetIsGE(set, solvalue, debugsoldata->debugsolval)) )
514  debugsoldata->solisachieved = TRUE;
515  }
516 
517  return debugsoldata->solisachieved;
518 }
519 
520 /** returns whether the solution is contained in node's subproblem */
521 static
522 SCIP_RETCODE isSolutionInNode(
523  BMS_BLKMEM* blkmem, /**< block memory */
524  SCIP_SET* set, /**< global SCIP settings */
525  SCIP_NODE* node, /**< local node where this bound change was applied */
526  SCIP_Bool* solcontained /**< pointer to store whether the solution is contained in node's subproblem */
527  )
528 {
529  SCIP_Bool* boolptr;
530  SCIP_DEBUGSOLDATA* debugsoldata;
531 
532  assert(set != NULL);
533  assert(blkmem != NULL);
534  assert(node != NULL);
535  assert(solcontained != NULL);
536 
537 
538  debugsoldata = SCIPsetGetDebugSolData(set);
539  assert(debugsoldata != NULL);
540 
541  if( debugsoldata ->debugsoldisabled )
542  {
543  *solcontained = FALSE;
544  return SCIP_OKAY;
545  }
546 
547  /* generate the hashmap */
548  if( debugsoldata->solinnode == NULL )
549  {
550  SCIP_CALL( SCIPhashmapCreate(&debugsoldata->solinnode, blkmem, SCIP_HASHSIZE_DEBUG) );
551  }
552 
553  /* check, whether we know already whether the solution is contained in the given node */
554  boolptr = (SCIP_Bool*)SCIPhashmapGetImage(debugsoldata->solinnode, (void*)node);
555  if( boolptr != NULL )
556  {
557  if( boolptr != &debugsoldata->falseptr && boolptr != &debugsoldata->trueptr )
558  {
559  SCIPerrorMessage("wrong value in node hashmap\n");
560  SCIPABORT();
561  return SCIP_ERROR;
562  }
563  *solcontained = *boolptr;
564  return SCIP_OKAY;
565  }
566 
567  /* if the solution is not contained in the parent of the node, it cannot be contained in the current node */
568  *solcontained = TRUE;
569  if( node->parent != NULL )
570  {
571  SCIP_CALL( isSolutionInNode(blkmem, set, node->parent, solcontained) );
572  }
573 
574  if( *solcontained )
575  {
576  /* check whether the bound changes at the current node remove the debugging solution from the subproblem */
577  if( node->domchg != NULL )
578  {
579  SCIP_DOMCHGBOUND* domchgbound;
580  SCIP_BOUNDCHG* boundchgs;
581  int i;
582 
583  domchgbound = &node->domchg->domchgbound;
584  boundchgs = domchgbound->boundchgs;
585  for( i = 0; i < (int)domchgbound->nboundchgs && *solcontained; ++i )
586  {
587  SCIP_Real varsol;
588 
589  /* get solution value of variable */
590  SCIP_CALL( getSolutionValue(set, boundchgs[i].var, &varsol) );
591 
592  if( varsol != SCIP_UNKNOWN ) /*lint !e777*/
593  {
594  /* compare the bound change with the solution value */
595  if( SCIPboundchgGetBoundtype(&boundchgs[i]) == SCIP_BOUNDTYPE_LOWER )
596  *solcontained = SCIPsetIsFeasGE(set, varsol, boundchgs[i].newbound);
597  else
598  *solcontained = SCIPsetIsFeasLE(set, varsol, boundchgs[i].newbound);
599 
600  if( !(*solcontained) && SCIPboundchgGetBoundchgtype(&boundchgs[i]) != SCIP_BOUNDCHGTYPE_BRANCHING )
601  {
602  SCIPerrorMessage("debugging solution was cut off in local node %p at depth %d by inference <%s>[%.15g] %s %.15g\n",
603  node, SCIPnodeGetDepth(node), SCIPvarGetName(boundchgs[i].var), varsol,
604  SCIPboundchgGetBoundtype(&boundchgs[i]) == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=", boundchgs[i].newbound);
605  SCIPABORT();
606  }
607  }
608  else if( SCIPboundchgGetBoundchgtype(&boundchgs[i]) == SCIP_BOUNDCHGTYPE_BRANCHING )
609  {
610  /* we branched on a variable were we don't know the solution: no debugging can be applied in this subtree */
611  *solcontained = FALSE;
612  }
613  }
614  }
615  }
616 
617  /* remember the status of the current node */
618  SCIP_CALL( SCIPhashmapSetImage(debugsoldata->solinnode, (void*)node, *solcontained ? (void*)(&debugsoldata->trueptr) : (void*)(&debugsoldata->falseptr)) );
619 
620  return SCIP_OKAY;
621 }
622 
623 /** frees the debug solution */
625  SCIP_SET* set
626  )
627 {
628  SCIP_DEBUGSOLDATA* debugsoldata;
629 
630  debugsoldata = SCIPsetGetDebugSolData(set);
631  assert(debugsoldata != NULL);
632 
633  if( debugsoldata->debugsol != NULL && ((SCIPgetStage(set->scip) > SCIP_STAGE_PROBLEM && debugsoldata->debugsolstage > SCIP_STAGE_PROBLEM)
634  || (SCIPgetStage(set->scip) <= SCIP_STAGE_PROBLEM && debugsoldata->debugsolstage <= SCIP_STAGE_PROBLEM)) )
635  {
636  SCIP_CALL( SCIPfreeSol(set->scip, &debugsoldata->debugsol) );
637  }
638 
639  return SCIP_OKAY;
640 }
641 
642 /** resets the data structure after restart */
644  SCIP_SET* set
645  )
646 {
647  SCIP_DEBUGSOLDATA* debugsoldata;
648 
649  assert(set != NULL);
650 
651  debugsoldata = SCIPsetGetDebugSolData(set);
652  assert(debugsoldata != NULL);
653 
654  if( debugsoldata->solinnode != NULL )
655  {
656  SCIP_CALL( SCIPhashmapRemoveAll(debugsoldata->solinnode) );
657  }
658 
659  return SCIP_OKAY;
660 }
661 
662 /** frees all debugging solution data */
664  SCIP_SET* set /**< global SCIP settings */
665  )
666 {
667  int s;
668 
669  SCIP_DEBUGSOLDATA* debugsoldata;
670  assert(set != NULL);
671 
672  debugsoldata = SCIPsetGetDebugSolData(set);
673  assert(debugsoldata != NULL);
674 
675  for( s = debugsoldata->nsolvals - 1; s >= 0; --s )
676  BMSfreeMemoryArrayNull(&(debugsoldata->solnames[s]));
677 
678  BMSfreeMemoryArrayNull(&debugsoldata->solnames);
679  BMSfreeMemoryArrayNull(&debugsoldata->solvals);
680 
681  debugsoldata->nsolvals = 0;
682  debugsoldata->debugsolval= 0.0;
683  debugsoldata->solisachieved = FALSE;
684 
685  if( debugsoldata->solinnode != NULL)
686  SCIPhashmapFree(&debugsoldata->solinnode);
687 
688  /* free the debug solution */
689  SCIP_CALL( SCIPdebugFreeSol(set) );
690 
691  BMSfreeMemoryNull(&debugsoldata);
692 
693  set->debugsoldata = NULL;
694 
695  return SCIP_OKAY;
696 }
697 
698 /** checks for validity of the debugging solution in given constraints */
700  SCIP* scip, /**< SCIP data structure */
701  SCIP_CONS** conss, /**< constraints to check for validity */
702  int nconss /**< number of given constraints */
703  )
704 {
705  SCIP_RESULT result;
706  int c;
707 
708  SCIP_DEBUGSOLDATA* debugsoldata;
709  assert(scip->set != NULL);
710 
711  /* check if we are in the original problem and not in a sub MIP */
712  if( ! SCIPdebugSolIsEnabled(scip) )
713  return SCIP_OKAY;
714 
715  debugsoldata = SCIPsetGetDebugSolData(scip->set);
716 
717  assert(conss != NULL || nconss == 0);
718  assert(debugsoldata->debugsol != NULL);
719 
720  /* check if the incumbent solution is at least as good as the debug solution, so we can stop to check the debug
721  * solution
722  */
723  if( debugSolIsAchieved(scip->set) )
724  return SCIP_OKAY;
725 
726  result = SCIP_FEASIBLE;
727 
728  /* checking each given constraint against the debugging solution */
729  for( c = nconss - 1; c >= 0; --c )
730  {
731  assert(conss[c] != NULL);
732 
733  if( !SCIPconsIsActive(conss[c]) )
734  continue;
735 
736  assert(SCIPconsGetActiveDepth(conss[c]) <= SCIPgetDepth(scip));
737 
738  /* if the cons is only locally valid, check whether the debugging solution is contained in the local subproblem */
739  if( SCIPconsIsLocal(conss[c]) )
740  {
741  SCIP_Bool solcontained;
742 
743  SCIP_CALL( isSolutionInNode(SCIPblkmem(scip), scip->set, SCIPgetCurrentNode(scip), &solcontained) );
744  if( !solcontained )
745  return SCIP_OKAY;
746  }
747 
748  SCIP_CALL( SCIPcheckCons(scip, conss[c], debugsoldata->debugsol, TRUE, TRUE, TRUE, &result) );
749 
750  SCIPdebugMsg(scip, " -> checking of constraint %s returned result <%d>\n", SCIPconsGetName(conss[c]), result);
751 
752  if( result != SCIP_FEASIBLE )
753  {
754  SCIPerrorMessage("constraint %s violates the debugging solution\n", SCIPconsGetName(conss[c]));
755  SCIPABORT();
756  }
757  }
758 
759  return SCIP_OKAY;
760 }
761 
762 /** checks whether given row is valid for the debugging solution */
764  SCIP_SET* set, /**< global SCIP settings */
765  SCIP_ROW* row /**< row to check for validity */
766  )
767 {
768  SCIP_COL** cols;
769  SCIP_DEBUGSOLDATA* debugsoldata;
770  SCIP_Real* vals;
771  SCIP_Real lhs;
772  SCIP_Real rhs;
773  int nnonz;
774  int i;
775  SCIP_Real minactivity;
776  SCIP_Real maxactivity;
777  SCIP_Real solval;
778 
779  assert(set != NULL);
780  assert(row != NULL);
781 
782  debugsoldata = SCIPsetGetDebugSolData(set);
783  assert(debugsoldata != NULL);
784 
785  /* when debugging was disabled the solution is not defined to be not valid in the current subtree */
786  if( debugsoldata->debugsoldisabled )
787  return SCIP_OKAY;
788 
789  /* check if the incumbent solution is at least as good as the debug solution, so we can stop to check the debug solution */
790  if( debugSolIsAchieved(set) )
791  return SCIP_OKAY;
792 
793  /* if the row is only locally valid, check whether the debugging solution is contained in the local subproblem */
794  if( SCIProwIsLocal(row) )
795  {
796  SCIP_Bool solcontained;
797 
798  SCIP_CALL( isSolutionInNode(SCIPblkmem(set->scip), set, SCIPgetCurrentNode(set->scip), &solcontained) );
799  if( !solcontained )
800  return SCIP_OKAY;
801  }
802 
803  cols = SCIProwGetCols(row);
804  vals = SCIProwGetVals(row);
805  nnonz = SCIProwGetNNonz(row);
806  lhs = SCIProwGetLhs(row);
807  rhs = SCIProwGetRhs(row);
808 
809  /* calculate row's activity on debugging solution */
810  minactivity = SCIProwGetConstant(row);
811  maxactivity = minactivity;
812  for( i = 0; i < nnonz; ++i )
813  {
814  SCIP_VAR* var;
815 
816  /* get solution value of variable in debugging solution */
817  var = SCIPcolGetVar(cols[i]);
818  SCIP_CALL( getSolutionValue(set, var, &solval) );
819 
820  if( solval != SCIP_UNKNOWN ) /*lint !e777*/
821  {
822  minactivity += vals[i] * solval;
823  maxactivity += vals[i] * solval;
824  }
825  else if( vals[i] > 0.0 )
826  {
827  minactivity += vals[i] * SCIPvarGetLbGlobal(var);
828  maxactivity += vals[i] * SCIPvarGetUbGlobal(var);
829  }
830  else if( vals[i] < 0.0 )
831  {
832  minactivity += vals[i] * SCIPvarGetUbGlobal(var);
833  maxactivity += vals[i] * SCIPvarGetLbGlobal(var);
834  }
835  }
836  SCIPsetDebugMsg(set, "debugging solution on row <%s>: %g <= [%g,%g] <= %g\n",
837  SCIProwGetName(row), lhs, minactivity, maxactivity, rhs);
838 
839  /* check row for violation */
840  if( SCIPsetIsFeasLT(set, maxactivity, lhs) || SCIPsetIsFeasGT(set, minactivity, rhs) )
841  {
842  printf("***** debug: row <%s> violates debugging solution (lhs=%.15g, rhs=%.15g, activity=[%.15g,%.15g], local=%d)\n",
843  SCIProwGetName(row), lhs, rhs, minactivity, maxactivity, SCIProwIsLocal(row));
844  SCIProwPrint(row, SCIPgetMessagehdlr(set->scip), NULL);
845 
846  /* output row with solution values */
847  printf("\n\n");
848  printf("***** debug: violated row <%s>:\n", SCIProwGetName(row));
849  printf(" %.15g <= %.15g", lhs, SCIProwGetConstant(row));
850  for( i = 0; i < nnonz; ++i )
851  {
852  /* get solution value of variable in debugging solution */
853  SCIP_CALL( getSolutionValue(set, SCIPcolGetVar(cols[i]), &solval) );
854  printf(" %+.15g<%s>[%.15g]", vals[i], SCIPvarGetName(SCIPcolGetVar(cols[i])), solval);
855  }
856  printf(" <= %.15g\n", rhs);
857 
858  SCIPABORT();
859  }
860 
861  return SCIP_OKAY;
862 }
863 
864 /** checks whether given global lower bound is valid for the debugging solution */
866  SCIP* scip, /**< SCIP data structure */
867  SCIP_VAR* var, /**< problem variable */
868  SCIP_Real lb /**< lower bound */
869  )
870 {
871  SCIP_Real varsol;
872 
873  assert(scip != NULL);
874  assert(var != NULL);
875 
876  /* check if we are in the original problem and not in a sub MIP */
877  if( !SCIPdebugSolIsEnabled(scip) )
878  return SCIP_OKAY;
879 
880  /* check if the incumbent solution is at least as good as the debug solution, so we can stop to check the debug solution */
881  if( debugSolIsAchieved(scip->set) )
882  return SCIP_OKAY;
883 
884  /* get solution value of variable */
885  SCIP_CALL( getSolutionValue(scip->set, var, &varsol) );
886  SCIPdebugMsg(scip, "debugging solution on lower bound of <%s>[%g] >= %g\n", SCIPvarGetName(var), varsol, lb);
887 
888  /* check validity of debugging solution */
889  if( varsol != SCIP_UNKNOWN && SCIPisFeasLT(scip, varsol, lb) ) /*lint !e777*/
890  {
891  SCIPerrorMessage("invalid global lower bound: <%s>[%.15g] >= %.15g\n", SCIPvarGetName(var), varsol, lb);
892  SCIPABORT();
893  }
894 
895  return SCIP_OKAY;
896 }
897 
898 /** checks whether given global upper bound is valid for the debugging solution */
900  SCIP* scip, /**< SCIP data structure */
901  SCIP_VAR* var, /**< problem variable */
902  SCIP_Real ub /**< upper bound */
903  )
904 {
905  SCIP_Real varsol;
906  SCIP_DEBUGSOLDATA* debugsoldata;
907 
908  assert(scip != NULL);
909  assert(var != NULL);
910 
911  debugsoldata = SCIPsetGetDebugSolData(scip->set);
912 
913  /* when debugging was disabled the solution is not defined to be not valid in the current subtree */
914  if( debugsoldata->debugsoldisabled )
915  return SCIP_OKAY;
916 
917  /* check if the incumbent solution is at least as good as the debug solution, so we can stop to check the debug solution */
918  if( debugSolIsAchieved(scip->set) )
919  return SCIP_OKAY;
920 
921  /* get solution value of variable */
922  SCIP_CALL( getSolutionValue(scip->set, var, &varsol) );
923  SCIPdebugMsg(scip, "debugging solution on upper bound of <%s>[%g] <= %g\n", SCIPvarGetName(var), varsol, ub);
924 
925  /* check validity of debugging solution */
926  if( varsol != SCIP_UNKNOWN && SCIPisFeasGT(scip, varsol, ub) ) /*lint !e777*/
927  {
928  SCIPerrorMessage("invalid global upper bound: <%s>[%.15g] <= %.15g\n", SCIPvarGetName(var), varsol, ub);
929  SCIPABORT();
930  }
931 
932  return SCIP_OKAY;
933 }
934 
935 /** checks whether given local bound implication is valid for the debugging solution */
937  BMS_BLKMEM* blkmem, /**< block memory */
938  SCIP_SET* set, /**< global SCIP settings */
939  SCIP_NODE* node, /**< local node where this bound change was applied */
940  SCIP_VAR* var, /**< problem variable */
941  SCIP_Real newbound, /**< new value for bound */
942  SCIP_BOUNDTYPE boundtype /**< type of bound: lower or upper bound */
943  )
944 {
945  SCIP_Real varsol;
946  SCIP_Bool solcontained;
947  SCIP_DEBUGSOLDATA* debugsoldata;
948 
949  assert(set != NULL);
950  assert(blkmem != NULL);
951  assert(node != NULL);
952  assert(var != NULL);
953 
954  /* in case we are in probing or diving we have to avoid checking the solution */
955  if( SCIPlpDiving(set->scip->lp) || SCIPtreeProbing(set->scip->tree) )
956  return SCIP_OKAY;
957 
958  debugsoldata = SCIPsetGetDebugSolData(set);
959  assert(debugsoldata != NULL);
960 
961  /* when debugging was disabled the solution is not defined to be not valid in the current subtree */
962  if( debugsoldata->debugsoldisabled )
963  return SCIP_OKAY;
964 
965  /* check if the incumbent solution is at least as good as the debug solution, so we can stop to check the debug solution */
966  if( debugSolIsAchieved(set) )
967  return SCIP_OKAY;
968 
969  /* check whether the debugging solution is contained in the local subproblem */
970  SCIP_CALL( isSolutionInNode(blkmem, set, node, &solcontained) );
971  if( !solcontained )
972  return SCIP_OKAY;
973 
974  /* get solution value of variable */
975  SCIP_CALL( getSolutionValue(set, var, &varsol) );
976 
977  /* check validity of debugging solution */
978  if( varsol != SCIP_UNKNOWN ) /*lint !e777*/
979  {
980  if( boundtype == SCIP_BOUNDTYPE_LOWER && SCIPsetIsFeasLT(set, varsol, newbound) )
981  {
982  SCIPerrorMessage("invalid local lower bound implication: <%s>[%.15g] >= %.15g\n", SCIPvarGetName(var), varsol, newbound);
983  SCIPABORT();
984  }
985  if( boundtype == SCIP_BOUNDTYPE_UPPER && SCIPsetIsFeasGT(set, varsol, newbound) )
986  {
987  SCIPerrorMessage("invalid local upper bound implication: <%s>[%.15g] <= %.15g\n", SCIPvarGetName(var), varsol, newbound);
988  SCIPABORT();
989  }
990  }
991 
992  return SCIP_OKAY;
993 }
994 
995 /** informs solution debugger, that the given node will be freed */
997  BMS_BLKMEM* blkmem, /**< block memory */
998  SCIP_SET* set, /**< global SCIP settings */
999  SCIP_NODE* node /**< node that will be freed */
1000  )
1001 {
1002  SCIP_DEBUGSOLDATA* debugsoldata;
1003 
1004  assert(set != NULL);
1005  assert(blkmem != NULL);
1006  assert(node != NULL);
1007 
1008  debugsoldata = SCIPsetGetDebugSolData(set);
1009  assert(debugsoldata != NULL);
1010 
1011  /* when debugging was disabled the solution is not defined to be not valid in the current subtree */
1012  if( debugsoldata->debugsoldisabled )
1013  return SCIP_OKAY;
1014 
1015  /* check if the incumbent solution is at least as good as the debug solution, so we can stop to check the debug solution */
1016  if( debugSolIsAchieved(set) )
1017  return SCIP_OKAY;
1018 
1019  /* check if a solution will be cutoff in tree */
1021  {
1022  SCIP_Bool solisinnode;
1023 
1024  solisinnode = FALSE;
1025 
1026  SCIP_CALL( isSolutionInNode(blkmem, set, node, &solisinnode) );
1027  /* wrong node will be cutoff */
1028  if( solisinnode )
1029  {
1030  SCIPerrorMessage("debugging solution was cut off in local node #%" SCIP_LONGINT_FORMAT " (%p) at depth %d\n",
1031  node->number, node, SCIPnodeGetDepth(node));
1032  SCIPABORT();
1033  }
1034  }
1035 
1036  /* remove node from the hash map */
1037  if( debugsoldata->solinnode != NULL )
1038  {
1039  SCIP_CALL( SCIPhashmapRemove(debugsoldata->solinnode, (void*)node) );
1040  }
1041 
1042  return SCIP_OKAY;
1043 }
1044 
1045 /** checks whether given variable bound is valid for the debugging solution */
1047  SCIP_SET* set, /**< global SCIP settings */
1048  SCIP_VAR* var, /**< problem variable x in x <= b*z + d or x >= b*z + d */
1049  SCIP_BOUNDTYPE vbtype, /**< type of variable bound (LOWER or UPPER) */
1050  SCIP_VAR* vbvar, /**< variable z in x <= b*z + d or x >= b*z + d */
1051  SCIP_Real vbcoef, /**< coefficient b in x <= b*z + d or x >= b*z + d */
1052  SCIP_Real vbconstant /**< constant d in x <= b*z + d or x >= b*z + d */
1053  )
1054 {
1055  SCIP_DEBUGSOLDATA* debugsoldata;
1056  SCIP_Real varsol;
1057  SCIP_Real vbvarsol;
1058  SCIP_Real vb;
1059 
1060  assert(set != NULL);
1061  assert(var != NULL);
1062 
1063  debugsoldata = SCIPsetGetDebugSolData(set);
1064  assert(debugsoldata != NULL);
1065 
1066  /* when debugging was disabled the solution is not defined to be not valid in the current subtree */
1067  if( debugsoldata->debugsoldisabled )
1068  return SCIP_OKAY;
1069 
1070  /* check if the incumbent solution is at least as good as the debug solution, so we can stop to check the debug solution */
1071  if( debugSolIsAchieved(set) )
1072  return SCIP_OKAY;
1073 
1074  /* get solution value of variables */
1075  SCIP_CALL( getSolutionValue(set, var, &varsol) );
1076  SCIP_CALL( getSolutionValue(set, vbvar, &vbvarsol) );
1077 
1078  /* check validity of debugging solution */
1079  if( varsol != SCIP_UNKNOWN && vbvarsol != SCIP_UNKNOWN ) /*lint !e777*/
1080  {
1081  vb = vbcoef * vbvarsol + vbconstant;
1082  if( (vbtype == SCIP_BOUNDTYPE_LOWER && SCIPsetIsFeasLT(set, varsol, vb))
1083  || (vbtype == SCIP_BOUNDTYPE_UPPER && SCIPsetIsFeasGT(set, varsol, vb)) )
1084  {
1085  SCIPerrorMessage("invalid variable bound: <%s>[%.15g] %s %.15g<%s>[%.15g] %+.15g\n",
1086  SCIPvarGetName(var), varsol, vbtype == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=", vbcoef,
1087  SCIPvarGetName(vbvar), vbvarsol, vbconstant);
1088  SCIPABORT();
1089  }
1090  }
1091 
1092  return SCIP_OKAY;
1093 }
1094 
1095 /** checks whether given implication is valid for the debugging solution */
1097  SCIP_SET* set, /**< global SCIP settings */
1098  SCIP_VAR* var, /**< problem variable */
1099  SCIP_Bool varfixing, /**< FALSE if y should be added in implications for x == 0, TRUE for x == 1 */
1100  SCIP_VAR* implvar, /**< variable y in implication y <= b or y >= b */
1101  SCIP_BOUNDTYPE impltype, /**< type of implication y <= b (SCIP_BOUNDTYPE_UPPER) or y >= b (SCIP_BOUNDTYPE_LOWER) */
1102  SCIP_Real implbound /**< bound b in implication y <= b or y >= b */
1103  )
1104 {
1105  SCIP_DEBUGSOLDATA* debugsoldata;
1106  SCIP_Real solval;
1107 
1108  assert(set != NULL);
1109  assert(var != NULL);
1110  assert(SCIPvarGetType(var) == SCIP_VARTYPE_BINARY);
1111 
1112  debugsoldata = SCIPsetGetDebugSolData(set);
1113  assert(debugsoldata != NULL);
1114 
1115  /* when debugging was disabled the solution is not defined to be not valid in the current subtree */
1116  if( debugsoldata->debugsoldisabled )
1117  return SCIP_OKAY;
1118 
1119  /* check if the incumbent solution is at least as good as the debug solution, so we can stop to check the debug solution */
1120  if( debugSolIsAchieved(set) )
1121  return SCIP_OKAY;
1122 
1123  /* get solution value of variable */
1124  SCIP_CALL( getSolutionValue(set, var, &solval) );
1125  if( solval == SCIP_UNKNOWN ) /*lint !e777*/
1126  return SCIP_OKAY;
1127  assert(SCIPsetIsFeasZero(set, solval) || SCIPsetIsFeasEQ(set, solval, 1.0));
1128 
1129  /* check, whether the implication applies for the debugging solution */
1130  if( (solval > 0.5) != varfixing )
1131  return SCIP_OKAY;
1132 
1133  /* get solution value of implied variable */
1134  SCIP_CALL( getSolutionValue(set, implvar, &solval) );
1135  if( solval == SCIP_UNKNOWN ) /*lint !e777*/
1136  return SCIP_OKAY;
1137 
1138  if( impltype == SCIP_BOUNDTYPE_LOWER )
1139  {
1140  if( SCIPsetIsFeasLT(set, solval, implbound) )
1141  {
1142  SCIPerrorMessage("invalid implication <%s> == %d -> <%s> >= %.15g (variable has value %.15g in solution)\n",
1143  SCIPvarGetName(var), varfixing, SCIPvarGetName(implvar), implbound, solval);
1144  SCIPABORT();
1145  }
1146  }
1147  else
1148  {
1149  if( SCIPsetIsFeasGT(set, solval, implbound) )
1150  {
1151  SCIPerrorMessage("invalid implication <%s> == %d -> <%s> <= %.15g (variable has value %.15g in solution)\n",
1152  SCIPvarGetName(var), varfixing, SCIPvarGetName(implvar), implbound, solval);
1153  SCIPABORT();
1154  }
1155  }
1156 
1157  return SCIP_OKAY;
1158 }
1159 
1160 /** check whether given clique is valid for the debugging solution */
1162  SCIP_SET* set, /**< global SCIP settings */
1163  SCIP_VAR** vars, /**< binary variables in the clique: at most one can be set to the given value */
1164  SCIP_Bool* values, /**< values of the variables in the clique; NULL to use TRUE for all vars */
1165  int nvars /**< number of variables in the clique */
1166  )
1167 {
1168  SCIP_DEBUGSOLDATA* debugsoldata;
1169  SCIP_Real solval;
1170  int pos1;
1171  int pos2;
1172  int v;
1173 
1174  assert(set != NULL);
1175  assert(vars != NULL);
1176 
1177  debugsoldata = SCIPsetGetDebugSolData(set);
1178  assert(debugsoldata != NULL);
1179 
1180  /* when debugging was disabled the solution is not defined to be not valid in the current subtree */
1181  if( debugsoldata->debugsoldisabled )
1182  return SCIP_OKAY;
1183 
1184  /* check if the incumbent solution is at least as good as the debug solution, so we can stop to check the debug solution */
1185  if( debugSolIsAchieved(set) )
1186  return SCIP_OKAY;
1187 
1188  pos1 = -1;
1189  pos2 = -1;
1190 
1191  for( v = 0; v < nvars; ++v )
1192  {
1193  assert(vars[v] != NULL);
1194  assert(SCIPvarIsBinary(vars[v]));
1195 
1196  /* get solution value of variable */
1197  SCIP_CALL( getSolutionValue(set, vars[v], &solval) );
1198 
1199  if( solval == SCIP_UNKNOWN ) /*lint !e777*/
1200  continue;
1201 
1202  assert(SCIPsetIsFeasZero(set, solval) || SCIPsetIsFeasEQ(set, solval, 1.0));
1203 
1204  /* negated solution value if negated variable is in clique */
1205  if( values != NULL && values[v] == 0 )
1206  solval = 1.0 - solval;
1207 
1208  if( SCIPsetIsFeasEQ(set, solval, 1.0) )
1209  {
1210  if( pos1 == -1 )
1211  pos1 = v;
1212  else
1213  {
1214  assert(pos2 == -1);
1215  pos2 = v;
1216  break;
1217  }
1218  }
1219  }
1220 
1221  /* print debug message if the clique violates the debugging solution */
1222  if( pos2 != -1 )
1223  {
1224  assert(pos1 != -1);
1225  SCIPerrorMessage("clique violates debugging solution, (at least) variable <%s%s> and variable <%s%s> are both one in the debugging solution\n",
1226  (values == NULL || values[pos1]) ? "" : "~", SCIPvarGetName(vars[pos1]), (values == NULL || values[pos2]) ? "" : "~", SCIPvarGetName(vars[pos2]));
1227  SCIPABORT();
1228  }
1229 
1230  return SCIP_OKAY;
1231 }
1232 
1233 /** check, whether at least one literals is TRUE in the debugging solution */
1234 static
1235 SCIP_Bool debugCheckBdchginfos(
1236  SCIP_SET* set, /**< global SCIP settings */
1237  SCIP_BDCHGINFO** bdchginfos, /**< bound change informations of the conflict set */
1238  SCIP_Real* relaxedbds, /**< array with relaxed bounds which are efficient to create a valid conflict, or NULL */
1239  int nbdchginfos /**< number of bound changes in the conflict set */
1240  )
1241 {
1242  SCIP_Real solval;
1243  int i;
1244 
1245 
1246  assert(SCIPdebugSolIsEnabled(set->scip));
1247 
1248  solval = 0.0;
1249  /* check, whether at least one literals is TRUE in the debugging solution */
1250  for( i = 0; i < nbdchginfos; ++i )
1251  {
1252  SCIP_BDCHGINFO* bdchginfo;
1253  SCIP_VAR* var;
1254  SCIP_Real newbound;
1255 
1256  bdchginfo = bdchginfos[i];
1257  assert(bdchginfo != NULL);
1258 
1259  var = SCIPbdchginfoGetVar(bdchginfo);
1260  assert(var != NULL);
1261 
1262  if( relaxedbds != NULL )
1263  newbound = relaxedbds[i];
1264  else
1265  newbound = SCIPbdchginfoGetNewbound(bdchginfo);
1266 
1267  SCIP_CALL( getSolutionValue(set, var, &solval) );
1268 
1269  if( solval == SCIP_UNKNOWN ) /*lint !e777*/
1270  return TRUE;
1271 
1273  {
1274  assert(SCIPsetIsLE(set, newbound, SCIPbdchginfoGetNewbound(bdchginfo)));
1275 
1277  {
1278  if( SCIPsetIsLE(set, solval, newbound) )
1279  return TRUE;
1280  }
1281  else
1282  {
1283  if( SCIPsetIsLT(set, solval, newbound) )
1284  return TRUE;
1285  }
1286  }
1287  else
1288  {
1289  assert(SCIPsetIsGE(set, newbound, SCIPbdchginfoGetNewbound(bdchginfo)));
1290 
1292  {
1293  if( SCIPsetIsGE(set, solval, newbound) )
1294  return TRUE;
1295  }
1296  else
1297  {
1298  if( SCIPsetIsGT(set, solval, newbound) )
1299  return TRUE;
1300  }
1301  }
1302  }
1303 
1304  return FALSE;
1305 }
1306 
1307 /** print bound change information */
1308 static
1309 SCIP_RETCODE printBdchginfo(
1310  SCIP_SET* set, /**< global SCIP settings */
1311  SCIP_BDCHGINFO * bdchginfo, /**< bound change information */
1312  SCIP_Real relaxedbd /**< array with relaxed bounds which are efficient to create a valid conflict, or NULL */
1313  )
1314 {
1315  SCIP_Real solval;
1316 
1317  /* get solution value within the debug solution */
1318  SCIP_CALL( getSolutionValue(set, SCIPbdchginfoGetVar(bdchginfo), &solval) );
1319 
1320  printf(" <%s>[%.15g] %s %g(%g)", SCIPvarGetName(SCIPbdchginfoGetVar(bdchginfo)), solval,
1321  SCIPbdchginfoGetBoundtype(bdchginfo) == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=",
1322  SCIPbdchginfoGetNewbound(bdchginfo), relaxedbd);
1323 
1324  return SCIP_OKAY;
1325 }
1326 
1327 
1328 /** print bound change information */
1329 static
1330 SCIP_RETCODE printBdchginfos(
1331  SCIP_SET* set, /**< global SCIP settings */
1332  SCIP_BDCHGINFO** bdchginfos, /**< bound change information array */
1333  SCIP_Real* relaxedbds, /**< array with relaxed bounds which are efficient to create a valid conflict, or NULL */
1334  int nbdchginfos /**< number of bound changes in the conflict set */
1335  )
1336 {
1337  int i;
1338 
1339  for( i = 0; i < nbdchginfos; ++i )
1340  {
1341  SCIP_BDCHGINFO* bdchginfo;
1342 
1343  bdchginfo = bdchginfos[i];
1344  assert(bdchginfo != NULL);
1345 
1346  printBdchginfo(set, bdchginfo, relaxedbds != NULL ? relaxedbds[i] : SCIPbdchginfoGetNewbound(bdchginfo));
1347  }
1348 
1349  return SCIP_OKAY;
1350 }
1351 
1352 /** checks whether given conflict is valid for the debugging solution */
1354  BMS_BLKMEM* blkmem, /**< block memory */
1355  SCIP_SET* set, /**< global SCIP settings */
1356  SCIP_NODE* node, /**< node where the conflict clause is added */
1357  SCIP_BDCHGINFO** bdchginfos, /**< bound change informations of the conflict set */
1358  SCIP_Real* relaxedbds, /**< array with relaxed bounds which are efficient to create a valid conflict */
1359  int nbdchginfos /**< number of bound changes in the conflict set */
1360  )
1361 {
1362  SCIP_DEBUGSOLDATA* debugsoldata;
1363  SCIP_Bool solcontained;
1364 
1365  assert(set != NULL);
1366  assert(blkmem != NULL);
1367  assert(node != NULL);
1368  assert(nbdchginfos == 0 || bdchginfos != NULL);
1369 
1370  debugsoldata = SCIPsetGetDebugSolData(set);
1371  assert(debugsoldata != NULL);
1372 
1373  /* when debugging was disabled the solution is not defined to be not valid in the current subtree */
1374  if( debugsoldata->debugsoldisabled )
1375  return SCIP_OKAY;
1376 
1377  /* check if the incumbent solution is at least as good as the debug solution, so we can stop to check the debug solution */
1378  if( debugSolIsAchieved(set) )
1379  return SCIP_OKAY;
1380 
1381  /* check whether the debugging solution is contained in the local subproblem */
1382  SCIP_CALL( isSolutionInNode(blkmem, set, node, &solcontained) );
1383  if( !solcontained )
1384  return SCIP_OKAY;
1385 
1386  /* check, whether at least one literals is TRUE in the debugging solution */
1387  if( debugCheckBdchginfos(set, bdchginfos, relaxedbds, nbdchginfos) )
1388  return SCIP_OKAY;
1389 
1390  SCIPerrorMessage("invalid conflict set:");
1391 
1392  /* print bound changes which are already part of the conflict set */
1393  SCIP_CALL( printBdchginfos(set, bdchginfos, relaxedbds, nbdchginfos) );
1394 
1395  printf("\n");
1396  SCIPABORT();
1397 
1398  return SCIP_OKAY; /*lint !e527*/
1399 }
1400 
1401 /** checks whether given conflict graph frontier is valid for the debugging solution */
1403  BMS_BLKMEM* blkmem, /**< block memory */
1404  SCIP_SET* set, /**< global SCIP settings */
1405  SCIP_NODE* node, /**< node where the conflict clause is added */
1406  SCIP_BDCHGINFO* bdchginfo, /**< bound change info which got resolved, or NULL */
1407  SCIP_BDCHGINFO** bdchginfos, /**< bound change informations of the conflict set */
1408  SCIP_Real* relaxedbds, /**< array with relaxed bounds which are efficient to create a valid conflict */
1409  int nbdchginfos, /**< number of bound changes in the conflict set */
1410  SCIP_PQUEUE* bdchgqueue, /**< unprocessed conflict bound changes */
1411  SCIP_PQUEUE* forcedbdchgqueue /**< unprocessed conflict bound changes that must be resolved */
1412  )
1413 {
1414  SCIP_BDCHGINFO** bdchgqueued;
1415  SCIP_BDCHGINFO** forcedbdchgqueued;
1416  SCIP_DEBUGSOLDATA* debugsoldata;
1417  SCIP_Bool solcontained;
1418  int nbdchgqueued;
1419  int nforcedbdchgqueued;
1420 
1421  assert(set != NULL);
1422  assert(blkmem != NULL);
1423  assert(node != NULL);
1424  assert(nbdchginfos == 0 || bdchginfos != NULL);
1425 
1426  debugsoldata = SCIPsetGetDebugSolData(set);
1427  assert(debugsoldata != NULL);
1428 
1429  /* when debugging was disabled the solution is not defined to be not valid in the current subtree */
1430  if( debugsoldata->debugsoldisabled )
1431  return SCIP_OKAY;
1432 
1433  /* check if the incumbent solution is at least as good as the debug solution, so we can stop to check the debug solution */
1434  if( debugSolIsAchieved(set) )
1435  return SCIP_OKAY;
1436 
1437  /* check whether the debugging solution is contained in the local subproblem */
1438  SCIP_CALL( isSolutionInNode(blkmem, set, node, &solcontained) );
1439  if( !solcontained )
1440  return SCIP_OKAY;
1441 
1442  /* check, whether one literals is TRUE in the debugging solution */
1443  if( debugCheckBdchginfos(set, bdchginfos, relaxedbds, nbdchginfos) )
1444  return SCIP_OKAY;
1445 
1446  /* get the elements of the bound change queue */
1447  bdchgqueued = (SCIP_BDCHGINFO**)SCIPpqueueElems(bdchgqueue);
1448  nbdchgqueued = SCIPpqueueNElems(bdchgqueue);
1449 
1450  /* check, whether one literals is TRUE in the debugging solution */
1451  if( debugCheckBdchginfos(set, bdchgqueued, NULL, nbdchgqueued) )
1452  return SCIP_OKAY;
1453 
1454  /* get the elements of the bound change queue */
1455  forcedbdchgqueued = (SCIP_BDCHGINFO**)SCIPpqueueElems(forcedbdchgqueue);
1456  nforcedbdchgqueued = SCIPpqueueNElems(forcedbdchgqueue);
1457 
1458  /* check, whether one literals is TRUE in the debugging solution */
1459  if( debugCheckBdchginfos(set, forcedbdchgqueued, NULL, nforcedbdchgqueued) )
1460  return SCIP_OKAY;
1461 
1462  SCIPerrorMessage("invalid conflict frontier");
1463 
1464  if( bdchginfo != NULL )
1465  {
1466  printf(" (after resolving bound change ");
1467  printBdchginfo(set, bdchginfo, SCIPbdchginfoGetNewbound(bdchginfo));
1468  printf(")");
1469  }
1470  printf(":");
1471 
1472  /* print bound changes which are already part of the conflict set */
1473  SCIP_CALL( printBdchginfos(set, bdchginfos, relaxedbds, nbdchginfos) );
1474 
1475  /* print bound changes which are queued */
1476  SCIP_CALL( printBdchginfos(set, bdchgqueued, NULL, nbdchgqueued) );
1477 
1478  /* print bound changes which are queued in the force queue */
1479  SCIP_CALL( printBdchginfos(set, forcedbdchgqueued, NULL, nforcedbdchgqueued) );
1480 
1481  printf("\n");
1482  SCIPABORT();
1483 
1484  return SCIP_OKAY; /*lint !e527*/
1485 }
1486 
1487 /** check whether the debugging solution is valid in the current node */
1489  SCIP* scip, /**< SCIP data structure */
1490  SCIP_Bool* isvalidinsubtree /**< pointer to store whether the solution is valid in the current
1491  * subtree */
1492  )
1493 {
1494  SCIP_DEBUGSOLDATA* debugsoldata;
1495  SCIP_Bool solcontained;
1496 
1497  *isvalidinsubtree = FALSE;
1498 
1499  assert(scip->set != NULL);
1500 
1501  debugsoldata = SCIPsetGetDebugSolData(scip->set);
1502  assert(debugsoldata != NULL);
1503 
1504  /* when debugging was disabled the solution is not defined to be not valid in the current subtree */
1505  if( debugsoldata->debugsoldisabled )
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(scip->set) )
1510  return SCIP_OKAY;
1511 
1512  /* check whether the debugging solution is contained in the local subproblem */
1513  SCIP_CALL( isSolutionInNode(SCIPblkmem(scip), scip->set, SCIPgetCurrentNode(scip), &solcontained) );
1514 
1515  if( solcontained )
1516  *isvalidinsubtree = TRUE;
1517 
1518  return SCIP_OKAY;
1519 }
1520 
1521 /** checks whether SCIP data structure is the main SCIP (the one for which debugging is enabled) */
1522 SCIP_Bool SCIPdebugIsMainscip(
1523  SCIP* scip /**< SCIP data structure */
1524  )
1525 {
1526  assert(scip != NULL);
1527 
1528  return SCIPdebugSolIsEnabled(scip);
1529 }
1530 
1531 /** enabling solution debugging mechanism */
1532 void SCIPdebugSolEnable(
1533  SCIP* scip /**< SCIP data structure */
1534  )
1535 {
1536  SCIP_DEBUGSOLDATA* debugsoldata;
1537  assert(scip != NULL);
1538  assert(scip->set != NULL);
1539 
1540  debugsoldata = SCIPsetGetDebugSolData(scip->set);
1541  assert(debugsoldata != NULL);
1542 
1543  debugsoldata->debugsoldisabled = FALSE;
1544 }
1545 
1546 /** disabling solution debugging mechanism */
1547 void SCIPdebugSolDisable(
1548  SCIP* scip /**< SCIP data structure */
1549  )
1550 {
1551  SCIP_DEBUGSOLDATA* debugsoldata;
1552  assert(scip != NULL);
1553  assert(scip->set != NULL);
1554 
1555  debugsoldata = SCIPsetGetDebugSolData(scip->set);
1556  assert(debugsoldata != NULL);
1557 
1558  debugsoldata->debugsoldisabled = TRUE;
1559 }
1560 
1561 /** check if solution debugging mechanism is enabled */
1563  SCIP* scip /**< SCIP data structure */
1564  )
1565 {
1566  SCIP_DEBUGSOLDATA* debugsoldata;
1567  assert(scip != NULL);
1568  assert(scip->set != NULL);
1569 
1570  debugsoldata = SCIPsetGetDebugSolData(scip->set);
1571  assert(debugsoldata != NULL);
1572 
1573  return (!debugsoldata->debugsoldisabled);
1574 }
1575 
1576 /** propagator to force finding the debugging solution */
1577 static
1578 SCIP_DECL_PROPEXEC(propExecDebug)
1579 { /*lint --e{715}*/
1580  SCIP_VAR** vars;
1581  int nvars;
1582  int i;
1583 
1584  assert(scip != NULL);
1585  assert(result != NULL);
1586 
1587  *result = SCIP_DIDNOTFIND;
1588 
1589  /* check if we are in the original problem and not in a sub MIP */
1590  if( !SCIPdebugIsMainscip(scip) )
1591  return SCIP_OKAY;
1592 
1593  if( SCIPgetStage(scip) != SCIP_STAGE_SOLVING )
1594  return SCIP_OKAY;
1595 
1596  /* check if the incumbent solution is at least as good as the debug solution, so we can stop to check the debug solution */
1597  if( debugSolIsAchieved(scip->set) )
1598  return SCIP_OKAY;
1599 
1600 #if 1
1601  /* solve at least one LP */
1602  if( SCIPgetNLPIterations(scip) == 0 )
1603  return SCIP_OKAY;
1604 #endif
1605 
1606  vars = SCIPgetOrigVars(scip);
1607  nvars = SCIPgetNOrigVars(scip);
1608  for( i = 0; i < nvars; ++i )
1609  {
1610  SCIP_Real solval;
1611  SCIP_Real lb;
1612  SCIP_Real ub;
1613  SCIP_Bool infeasible;
1614  SCIP_Bool fixed;
1615 
1616  SCIP_CALL( getSolutionValue(scip->set, vars[i], &solval) );
1617  if( solval == SCIP_UNKNOWN ) /*lint !e777*/
1618  {
1619  SCIPerrorMessage("original variable without debugging solution value\n");
1620  SCIPABORT();
1621  }
1622 
1623  lb = SCIPvarGetLbGlobal(vars[i]);
1624  ub = SCIPvarGetUbGlobal(vars[i]);
1625  if( SCIPisLT(scip, solval, lb) || SCIPisGT(scip, solval, ub) )
1626  {
1627  SCIPerrorMessage("solution value %.15g of <%s> outside bounds loc=[%.15g,%.15g], glb=[%.15g,%.15g]\n",
1628  solval, SCIPvarGetName(vars[i]), lb, ub, SCIPvarGetLbGlobal(vars[i]), SCIPvarGetUbGlobal(vars[i]));
1629  SCIPABORT();
1630  }
1631 
1632  SCIP_CALL( SCIPfixVar(scip, vars[i], solval, &infeasible, &fixed) );
1633  if( infeasible )
1634  *result = SCIP_CUTOFF;
1635  else if( fixed )
1636  *result = SCIP_REDUCEDDOM;
1637  }
1638 
1639  return SCIP_OKAY;
1640 }
1641 
1642 /** creates the debugging propagator and includes it in SCIP */
1644  SCIP* scip /**< SCIP data structure */
1645  )
1646 {
1647  assert(scip != NULL);
1648 
1649  /* include propagator */
1650  SCIP_CALL( SCIPincludeProp(scip, "debug", "debugging propagator", 99999999, -1, FALSE,
1652  NULL, propExecDebug, NULL, NULL) );
1653 
1654  return SCIP_OKAY;
1655 }
1656 
1657 /** adds a solution value for a new variable in the transformed problem that has no original counterpart
1658  * a value can only be set if no value has been set for this variable before
1659  */
1661  SCIP* scip, /**< SCIP data structure */
1662  SCIP_VAR* var, /**< variable for which to add a value */
1663  SCIP_Real val /**< solution value for variable */
1664  )
1665 {
1666  SCIP_DEBUGSOLDATA* debugsoldata;
1667  SCIP_Real testval;
1668  const char* varname;
1669  int i;
1670 
1671  assert(scip != NULL);
1672  assert(var != NULL);
1673  assert(scip->set != NULL);
1674 
1675  debugsoldata = SCIPsetGetDebugSolData(scip->set);
1676  assert(debugsoldata != NULL);
1677 
1678  /* assert that we are in the SCIP instance that we are debugging and not some different (subSCIP, auxiliary CIP, ...) */
1679  if( !SCIPdebugSolIsEnabled(scip) )
1680  return SCIP_OKAY;
1681 
1682  if( debugsoldata->debugsol == NULL )
1683  {
1684  /* make sure a debug solution has been read, so we do not compare against the initial debugsolval == 0 */
1685  SCIP_CALL( readSolution(scip->set) );
1686  }
1687 
1688  /* allocate memory */
1689  if( debugsoldata->nsolvals >= debugsoldata->solsize )
1690  {
1691  debugsoldata->solsize = MAX(2*debugsoldata->solsize, debugsoldata->nsolvals+1);
1692  SCIP_ALLOC( BMSreallocMemoryArray(&debugsoldata->solnames, debugsoldata->solsize) );
1693  SCIP_ALLOC( BMSreallocMemoryArray(&debugsoldata->solvals, debugsoldata->solsize) );
1694  }
1695  assert(debugsoldata->nsolvals < debugsoldata->solsize);
1696 
1697  /* store solution value in sorted list */
1698  varname = SCIPvarGetName(var);
1699  for( i = debugsoldata->nsolvals; i > 0 && strcmp(varname, debugsoldata->solnames[i-1]) < 0; --i )
1700  {
1701  debugsoldata->solnames[i] = debugsoldata->solnames[i-1];
1702  debugsoldata->solvals[i] = debugsoldata->solvals[i-1];
1703  }
1704  if( i > 0 && strcmp(varname, debugsoldata->solnames[i-1]) == 0 )
1705  {
1706  if( REALABS(debugsoldata->solvals[i-1] - val) > 1e-9 )
1707  {
1708  SCIPerrorMessage("already have stored different debugging solution value (%g) for variable <%s>, cannot store %g\n", debugsoldata->solvals[i-1], varname, val);
1709  return SCIP_ERROR;
1710  }
1711  else
1712  {
1713  SCIPdebugMsg(scip, "already have stored debugging solution value %g for variable <%s>, do not store same value again\n", val, varname);
1714  for( ; i < debugsoldata->nsolvals; ++i )
1715  {
1716  debugsoldata->solnames[i] = debugsoldata->solnames[i+1];
1717  debugsoldata->solvals[i] = debugsoldata->solvals[i+1];
1718  }
1719  return SCIP_OKAY;
1720  }
1721  }
1722 
1723  /* insert new solution value */
1724  SCIP_ALLOC( BMSduplicateMemoryArray(&(debugsoldata->solnames[i]), varname, strlen(varname)+1) );
1725  SCIPdebugMsg(scip, "add variable <%s>: value <%g>\n", debugsoldata->solnames[i], val);
1726  debugsoldata->solvals[i] = val;
1727  debugsoldata->nsolvals++;
1728 
1729  /* update objective function value of debug solution */
1730  debugsoldata->debugsolval += debugsoldata->solvals[i] * SCIPvarGetObj(var);
1731  SCIPdebugMsg(scip, "Debug Solution value is now %g.\n", debugsoldata->debugsolval);
1732 
1734  {
1735  /* add values to SCIP debug solution */
1736  SCIP_CALL( SCIPsetSolVal(scip, debugsoldata->debugsol, var, debugsoldata->solvals[i] ) );
1737  }
1738 
1739  /* get solution value once to produce warning if solution was cut off */
1740  SCIPdebugGetSolVal(scip, var, &testval);
1741 
1742  return SCIP_OKAY;
1743 }
1744 
1745 #else
1746 
1747 /** this is a dummy method to make the SunOS gcc linker happy */
1748 extern void SCIPdummyDebugMethodForSun(void);
1750 {
1751  return;
1752 }
1753 
1754 #endif
1755 
1756 
1757 /*
1758  * debug method for LP interface, to check if the LP interface works correct
1759  */
1760 #ifdef SCIP_DEBUG_LP_INTERFACE
1761 
1762 /* check whether coef is the r-th row of the inverse basis matrix B^-1; this is
1763  * the case if( coef * B ) is the r-th unit vector */
1765  SCIP* scip, /**< SCIP data structure */
1766  int r, /**< row number */
1767  SCIP_Real* coef /**< r-th row of the inverse basis matrix */
1768  )
1769 {
1770  SCIP_Real vecval;
1771  SCIP_Real matrixval;
1772  int* basisind;
1773  int nrows;
1774  int idx;
1775  int i;
1776  int k;
1777 
1778  assert(scip != NULL);
1779 
1780  nrows = SCIPgetNLPRows(scip);
1781 
1782  /* get basic indices for the basic matrix B */
1783  SCIP_CALL( SCIPallocBufferArray(scip, &basisind, nrows) );
1784  SCIP_CALL( SCIPgetLPBasisInd(scip, basisind) );
1785 
1786 
1787  /* loop over the columns of B */
1788  for( k = 0; k < nrows; ++k )
1789  {
1790  vecval = 0.0;
1791 
1792  /* indices of basic columns and rows:
1793  * - index i >= 0 corresponds to column i,
1794  * - index i < 0 to row -i-1
1795  */
1796  idx = basisind[k];
1797 
1798  /* check if we have a slack variable; this is the case if idx < 0 */
1799  if( idx >= 0 )
1800  {
1801  /* loop over the rows to compute the corresponding value in the unit vector */
1802  for( i = 0; i < nrows; ++i )
1803  {
1804  SCIP_CALL( SCIPlpiGetCoef(scip->lp->lpi, i, idx, &matrixval) );
1805  vecval += coef[i] * matrixval;
1806  }
1807  }
1808  else
1809  {
1810  assert( idx < 0 );
1811 
1812  /* retransform idx
1813  * - index i >= 0 corresponds to column i,
1814  * - index i < 0 to row -i-1
1815  */
1816  idx = -idx - 1;
1817  assert( idx >= 0 && idx < nrows );
1818 
1819  /* since idx < 0 we are in the case of a slack variable, i.e., the corresponding column
1820  is the idx-unit vector; note that some LP solver return a -idx-unit vector */
1821  /* vecval = REALABS(coef[idx]);*/
1822  vecval = coef[idx];
1823  }
1824 
1825  /* check if vecval fits to the r-th unit vector */
1826  if( k == r && !SCIPisFeasEQ(scip, vecval, 1.0) )
1827  {
1828  /* we expected a 1.0 and found something different */
1829  SCIPmessagePrintWarning(SCIPgetMessagehdlr(scip), "checked SCIPgetLPBInvRow() found value <%g> expected 1.0\n", vecval);
1830  }
1831  else if( k != r && !SCIPisFeasZero(scip, vecval) )
1832  {
1833  /* we expected a 0.0 and found something different */
1834  SCIPmessagePrintWarning(SCIPgetMessagehdlr(scip), "checked SCIPgetLPBInvRow() found value <%g> expected 0.0\n", vecval);
1835  }
1836  }
1837 
1838  SCIPfreeBufferArray(scip, &basisind);
1839 
1840  return SCIP_OKAY;
1841 }
1842 
1843 #endif
enum SCIP_Result SCIP_RESULT
Definition: type_result.h:52
enum SCIP_BoundType SCIP_BOUNDTYPE
Definition: type_lp.h:50
SCIP_Bool SCIPisFeasZero(SCIP *scip, SCIP_Real val)
Definition: scip.c:46385
int SCIPpqueueNElems(SCIP_PQUEUE *pqueue)
Definition: misc.c:1263
SCIP_Bool SCIPsetIsLE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:5575
SCIP_Bool SCIPsetIsFeasZero(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6025
SCIP_Bool SCIPisFeasEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:46320
SCIP_Bool SCIPlpDiving(SCIP_LP *lp)
Definition: lp.c:16899
SCIP_NODE * SCIPgetCurrentNode(SCIP *scip)
Definition: scip.c:40680
SCIP_STAGE SCIPgetStage(SCIP *scip)
Definition: scip.c:814
#define SCIPdebugRemoveNode(blkmem, set, node)
Definition: debug.h:257
#define BMSfreeMemoryArrayNull(ptr)
Definition: memory.h:107
internal methods for branch and bound tree
SCIP_Longint SCIPgetNLPIterations(SCIP *scip)
Definition: scip.c:41609
SCIP_Bool SCIPisFeasLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:46333
#define SCIPdebugFreeDebugData(set)
Definition: debug.h:251
SCIP_Bool SCIPsetIsFeasEQ(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:5915
SCIP_VAR * SCIPbdchginfoGetVar(SCIP_BDCHGINFO *bdchginfo)
Definition: var.c:17791
SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
Definition: var.c:17169
#define SCIP_MAXSTRLEN
Definition: def.h:225
SCIP_BOUNDCHG * boundchgs
Definition: struct_var.h:124
int SCIProwGetNNonz(SCIP_ROW *row)
Definition: lp.c:16312
#define SCIPdebugCheckImplic(set, var, varfixing, implvar, impltype, implbound)
Definition: debug.h:259
int SCIPgetNOrigVars(SCIP *scip)
Definition: scip.c:12120
#define SCIPdebugSolDataCreate(debugsoldata)
Definition: debug.h:248
const char * SCIProwGetName(SCIP_ROW *row)
Definition: lp.c:16450
SCIP_Bool SCIPvarIsBinary(SCIP_VAR *var)
Definition: var.c:16735
SCIP_Real SCIPsetInfinity(SCIP_SET *set)
Definition: set.c:5379
SCIP_BOUNDTYPE SCIPboundchgGetBoundtype(SCIP_BOUNDCHG *boundchg)
Definition: var.c:16482
unsigned int nboundchgs
Definition: struct_var.h:122
#define SCIPdebugCheckClique(set, vars, values, nvars)
Definition: debug.h:260
SCIP_Real SCIProwGetLhs(SCIP_ROW *row)
Definition: lp.c:16391
#define FALSE
Definition: def.h:64
SCIP_RETCODE SCIPhashmapCreate(SCIP_HASHMAP **hashmap, BMS_BLKMEM *blkmem, int mapsize)
Definition: misc.c:2764
#define TRUE
Definition: def.h:63
#define SCIPdebugCheckRow(set, row)
Definition: debug.h:253
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:53
SCIP_Real SCIPvarGetNegationConstant(SCIP_VAR *var)
Definition: var.c:17006
SCIP_VAR ** SCIPgetOrigVars(SCIP *scip)
Definition: scip.c:12093
#define BMSallocMemoryArray(ptr, num)
Definition: memory.h:82
SCIP_MESSAGEHDLR * SCIPgetMessagehdlr(SCIP *scip)
Definition: scip.c:1228
void * SCIPhashmapGetImage(SCIP_HASHMAP *hashmap, void *origin)
Definition: misc.c:2902
int SCIPnodeGetDepth(SCIP_NODE *node)
Definition: tree.c:7182
#define SCIPfreeBufferArray(scip, ptr)
Definition: scip.h:22003
#define SCIP_DECL_PROPEXEC(x)
Definition: type_prop.h:203
#define SCIPdebugCheckVbound(set, var, vbtype, vbvar, vbcoef, vbconstant)
Definition: debug.h:258
SCIP_VAR * SCIPvarGetNegationVar(SCIP_VAR *var)
Definition: var.c:16995
#define SCIPdebugMsg
Definition: scip.h:451
internal methods for LP management
SCIP_Bool SCIPconsIsActive(SCIP_CONS *cons)
Definition: cons.c:7942
SCIP_Longint number
Definition: struct_tree.h:131
SCIP_RETCODE SCIPcreateOrigSol(SCIP *scip, SCIP_SOL **sol, SCIP_HEUR *heur)
Definition: scip.c:37415
#define SCIP_PRESOLTIMING_FAST
Definition: type_timing.h:43
SCIP_Bool SCIPsetIsGE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:5611
#define SCIPdebugCheckConflict(blkmem, set, node, bdchginfos, relaxedbds, nliterals)
Definition: debug.h:261
SCIP_VAR * SCIPfindVar(SCIP *scip, const char *name)
Definition: scip.c:12374
SCIP_FILE * SCIPfopen(const char *path, const char *mode)
Definition: fileio.c:140
struct SCIP_DebugSolData SCIP_DEBUGSOLDATA
Definition: debug.h:47
SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
Definition: var.c:17179
SCIP_Bool SCIPsetIsLT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:5557
SCIP_DOMCHG * domchg
Definition: struct_tree.h:147
SCIP_Bool SCIPtreeProbing(SCIP_TREE *tree)
Definition: tree.c:8014
#define SCIPdebugIncludeProp(scip)
Definition: debug.h:263
#define BMSfreeMemoryArray(ptr)
Definition: memory.h:106
internal methods for storing and manipulating the main problem
#define SCIPerrorMessage
Definition: pub_message.h:45
SCIP_Bool SCIPisLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:45998
#define SCIPdebugCheckInference(blkmem, set, node, var, newbound, boundtype)
Definition: debug.h:256
SCIP_Bool SCIProwIsLocal(SCIP_ROW *row)
Definition: lp.c:16500
SCIP_Bool SCIPvarIsTransformedOrigvar(SCIP_VAR *var)
Definition: var.c:12167
int SCIPfeof(SCIP_FILE *stream)
Definition: fileio.c:214
BMS_BLKMEM * SCIPblkmem(SCIP *scip)
Definition: scip.c:45753
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.c:28346
struct SCIP_File SCIP_FILE
Definition: pub_fileio.h:34
char * SCIPfgets(char *s, int size, SCIP_FILE *stream)
Definition: fileio.c:187
const char * SCIPconsGetName(SCIP_CONS *cons)
Definition: cons.c:7881
const char * SCIPvarGetName(SCIP_VAR *var)
Definition: var.c:16555
void SCIPhashmapFree(SCIP_HASHMAP **hashmap)
Definition: misc.c:2797
void SCIPmessagePrintWarning(SCIP_MESSAGEHDLR *messagehdlr, const char *formatstr,...)
Definition: message.c:417
#define NULL
Definition: lpi_spx1.cpp:137
SCIP_Bool SCIPisObjChangedProbing(SCIP *scip)
Definition: scip.c:35627
#define REALABS(x)
Definition: def.h:169
#define SCIP_PROPTIMING_ALWAYS
Definition: type_timing.h:64
int SCIPgetNLPRows(SCIP *scip)
Definition: scip.c:29351
internal methods for global SCIP settings
#define SCIP_CALL(x)
Definition: def.h:316
SCIP main data structure.
SCIP_Bool SCIPsetIsFeasGE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6003
SCIP_Bool SCIPisFeasGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:46359
SCIP_Real SCIProwGetRhs(SCIP_ROW *row)
Definition: lp.c:16401
void SCIPverbMessage(SCIP *scip, SCIP_VERBLEVEL msgverblevel, FILE *file, const char *formatstr,...)
Definition: scip.c:1353
void SCIPdummyDebugMethodForSun(void)
Definition: debug.c:1749
SCIP_Bool SCIPconsIsLocal(SCIP_CONS *cons)
Definition: cons.c:8120
#define SCIPdebugCheckBInvRow(scip, r, coef)
Definition: debug.h:289
#define SCIPdebugCheckLbGlobal(scip, var, lb)
Definition: debug.h:254
SCIP_LPI * lpi
Definition: struct_lp.h:281
#define SCIPdebugGetSolVal(scip, var, val)
Definition: debug.h:265
void SCIProwPrint(SCIP_ROW *row, SCIP_MESSAGEHDLR *messagehdlr, FILE *file)
Definition: lp.c:5129
SCIP_Bool SCIPsetIsFeasLE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:5959
SCIP_COL ** SCIProwGetCols(SCIP_ROW *row)
Definition: lp.c:16337
#define SCIPdebugCheckUbGlobal(scip, var, ub)
Definition: debug.h:255
#define BMSduplicateMemoryArray(ptr, source, num)
Definition: memory.h:102
#define SCIPdebugCheckConss(scip, conss, nconss)
Definition: debug.h:252
internal methods for problem variables
#define SCIPallocBufferArray(scip, ptr, num)
Definition: scip.h:21991
#define SCIP_UNKNOWN
Definition: def.h:166
SCIP_RETCODE SCIPsetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var, SCIP_Real val)
Definition: scip.c:38042
SCIP_Real * SCIProwGetVals(SCIP_ROW *row)
Definition: lp.c:16347
public data structures and miscellaneous methods
#define SCIP_Bool
Definition: def.h:61
SCIP_BOUNDCHGTYPE SCIPboundchgGetBoundchgtype(SCIP_BOUNDCHG *boundchg)
Definition: var.c:16472
void SCIPprintSysError(const char *message)
Definition: misc.c:9276
SCIP_RETCODE SCIPhashmapRemoveAll(SCIP_HASHMAP *hashmap)
Definition: misc.c:3163
int SCIPgetDepth(SCIP *scip)
Definition: scip.c:42321
#define SCIPdebugSolIsValidInSubtree(scip, isvalidinsubtree)
Definition: debug.h:266
#define MAX(x, y)
Definition: tclique_def.h:75
#define SCIPdebugCheckConflictFrontier(blkmem, set, node, bdchginfo, bdchginfos, relaxedbds, nliterals, bdchgqueue, forcedbdchgqueue)
Definition: debug.h:262
methods for debugging
#define SCIPsetDebugMsg
Definition: set.h:1870
SCIP_RETCODE SCIPfreeSol(SCIP *scip, SCIP_SOL **sol)
Definition: scip.c:37806
SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
Definition: var.c:17017
SCIP_Real SCIPbdchginfoGetNewbound(SCIP_BDCHGINFO *bdchginfo)
Definition: var.c:17781
void ** SCIPpqueueElems(SCIP_PQUEUE *pqueue)
Definition: misc.c:1274
SCIP_RETCODE SCIPfixVar(SCIP *scip, SCIP_VAR *var, SCIP_Real fixedval, SCIP_Bool *infeasible, SCIP_Bool *fixed)
Definition: scip.c:25235
SCIP_RETCODE SCIPgetLPBasisInd(SCIP *scip, int *basisind)
Definition: scip.c:29411
SCIP_Real SCIPgetSolOrigObj(SCIP *scip, SCIP_SOL *sol)
Definition: scip.c:38268
SCIP_RETCODE SCIPvarGetOrigvarSum(SCIP_VAR **var, SCIP_Real *scalar, SCIP_Real *constant)
Definition: var.c:12080
SCIP_Bool SCIPsetIsFeasLT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:5937
SCIP_Real SCIProwGetConstant(SCIP_ROW *row)
Definition: lp.c:16357
#define SCIPdebugReset(set)
Definition: debug.h:250
SCIP_DOMCHGBOUND domchgbound
Definition: struct_var.h:152
SCIP_RETCODE SCIPhashmapRemove(SCIP_HASHMAP *hashmap, void *origin)
Definition: misc.c:3012
SCIP_SOL * SCIPgetBestSol(SCIP *scip)
Definition: scip.c:39158
SCIP_Bool SCIPisGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:46024
SCIP_NODE * parent
Definition: struct_tree.h:145
SCIP_VAR * SCIPcolGetVar(SCIP_COL *col)
Definition: lp.c:16161
#define SCIP_DECL_SORTPTRCOMP(x)
Definition: type_misc.h:151
#define BMSfreeMemoryNull(ptr)
Definition: memory.h:105
SCIP_SET * set
Definition: struct_scip.h:62
public methods for message output
SCIP_Bool SCIPsetIsGT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:5593
SCIP_RETCODE SCIPhashmapSetImage(SCIP_HASHMAP *hashmap, void *origin, void *image)
Definition: misc.c:2942
SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
Definition: var.c:16674
#define SCIPdebugSolDisable(scip)
Definition: debug.h:268
SCIP_NODETYPE SCIPnodeGetType(SCIP_NODE *node)
Definition: tree.c:7162
#define SCIP_Real
Definition: def.h:145
enum SCIP_Stage SCIP_STAGE
Definition: type_set.h:50
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.c:7555
SCIP_DEBUGSOLDATA * SCIPsetGetDebugSolData(SCIP_SET *set)
Definition: set.c:5272
#define BMSallocMemory(ptr)
Definition: memory.h:78
#define BMSreallocMemoryArray(ptr, num)
Definition: memory.h:86
void SCIPsortPtrReal(void **ptrarray, SCIP_Real *realarray, SCIP_DECL_SORTPTRCOMP((*ptrcomp)), int len)
#define SCIPdebugAddSolVal(scip, var, val)
Definition: debug.h:264
SCIP_Bool SCIPsetIsFeasGT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:5981
SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
Definition: var.c:16720
SCIP_OBJSENSE SCIPgetObjsense(SCIP *scip)
Definition: scip.c:10917
SCIP_RETCODE SCIPsetSolVals(SCIP *scip, SCIP_SOL *sol, int nvars, SCIP_VAR **vars, SCIP_Real *vals)
Definition: scip.c:38084
#define SCIPdebugSolIsEnabled(scip)
Definition: debug.h:269
SCIP_STAGE SCIPsetGetStage(SCIP_SET *set)
Definition: set.c:2664
int SCIPconsGetActiveDepth(SCIP_CONS *cons)
Definition: cons.c:7931
SCIP_Bool SCIPvarIsTransformed(SCIP_VAR *var)
Definition: var.c:16697
SCIP_BOUNDTYPE SCIPbdchginfoGetBoundtype(SCIP_BDCHGINFO *bdchginfo)
Definition: var.c:17811
common defines and data types used in all packages of SCIP
SCIP_RETCODE SCIPlpiGetCoef(SCIP_LPI *lpi, int row, int col, SCIP_Real *val)
Definition: lpi_clp.cpp:1619
struct BMS_BlkMem BMS_BLKMEM
Definition: memory.h:396
int SCIPfclose(SCIP_FILE *fp)
Definition: fileio.c:219
SCIP_LP * lp
Definition: struct_scip.h:80
#define SCIP_ALLOC(x)
Definition: def.h:327
#define SCIPdebugSolEnable(scip)
Definition: debug.h:267
#define SCIPABORT()
Definition: def.h:288
SCIP_Bool SCIPvarIsDeleted(SCIP_VAR *var)
Definition: var.c:16776
#define SCIPdebugFreeSol(set)
Definition: debug.h:249
SCIP callable library.
SCIP_Bool SCIPvarIsNegated(SCIP_VAR *var)
Definition: var.c:16710
memory allocation routines