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