Scippy

SCIP

Solving Constraint Integer Programs

visual.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 visual.c
17  * @brief methods for creating output for visualization tools (VBC, BAK)
18  * @author Tobias Achterberg
19  * @author Marc Pfetsch
20  *
21  * Output can be generated for the following visualization tools:
22  *
23  * - VBCTOOL - a graphical interface for Visualization of Branch Cut algorithms @n
24  * See <a href="http://www.informatik.uni-koeln.de/ls_juenger/research/vbctool">VBCTOOL</a>.
25  * - BAK: Branch-and-bound Analysis Kit @n
26  * BAK is available through COIN-OR, see <a href="https://projects.coin-or.org/CoinBazaar/wiki/Projects/BAK">BAK</a>.
27  * A description is <a href="http://www.optimization-online.org/DB_HTML/2007/09/1785.html">available</a> as well.
28  */
29 
30 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
31 
32 #include <stdio.h>
33 #include <assert.h>
34 
35 #include "blockmemshell/memory.h"
36 #include "scip/scip.h"
37 #include "scip/set.h"
38 #include "scip/stat.h"
39 #include "scip/clock.h"
40 #include "scip/var.h"
41 #include "scip/tree.h"
42 #include "scip/visual.h"
43 #include "scip/struct_visual.h"
44 
45 
46 /** returns the branching variable of the node, or NULL */
47 static
49  SCIP_NODE* node, /**< node */
50  SCIP_VAR** var, /**< pointer to store the branching variable */
51  SCIP_BOUNDTYPE* boundtype, /**< pointer to store the branching type: lower or upper bound */
52  SCIP_Real* bound /**< pointer to store the new bound of the branching variable */
53  )
54 {
55  SCIP_DOMCHGBOUND* domchgbound;
56 
57  (*var) = NULL;
58  (*bound) = 0.0;
59  (*boundtype) = SCIP_BOUNDTYPE_LOWER;
60 
61  assert(node != NULL);
62  if( node->domchg == NULL )
63  return;
64 
65  domchgbound = &node->domchg->domchgbound;
66  if( domchgbound->nboundchgs == 0 )
67  return;
68 
69  (*var) = domchgbound->boundchgs[0].var;
70  (*bound) = domchgbound->boundchgs[0].newbound;
71  (*boundtype) = (SCIP_BOUNDTYPE) domchgbound->boundchgs[0].boundtype;
72 }
73 
74 /** creates visualization data structure */
76  SCIP_VISUAL** visual, /**< pointer to store visualization information */
77  SCIP_MESSAGEHDLR* messagehdlr /**< message handler */
78  )
79 {
80  SCIP_ALLOC( BMSallocMemory(visual) );
81 
82  (*visual)->vbcfile = NULL;
83  (*visual)->bakfile = NULL;
84  (*visual)->messagehdlr = messagehdlr;
85  (*visual)->nodenum = NULL;
86  (*visual)->timestep = 0;
87  (*visual)->lastnode = NULL;
88  (*visual)->lastcolor = SCIP_VBCCOLOR_NONE;
89  (*visual)->userealtime = FALSE;
90 
91  return SCIP_OKAY;
92 }
93 
94 /** frees visualization data structure */
96  SCIP_VISUAL** visual /**< pointer to store visualization information */
97  )
98 {
99  assert( visual != NULL );
100  assert( *visual != NULL );
101  assert( (*visual)->vbcfile == NULL );
102  assert( (*visual)->bakfile == NULL );
103  assert( (*visual)->nodenum == NULL );
104 
105  BMSfreeMemory(visual);
106 }
107 
108 /** initializes visualization information and creates a file for visualization output */
110  SCIP_VISUAL* visual, /**< visualization information */
111  BMS_BLKMEM* blkmem, /**< block memory */
112  SCIP_SET* set, /**< global SCIP settings */
113  SCIP_MESSAGEHDLR* messagehdlr /**< message handler */
114  )
115 {
116  assert( visual != NULL );
117  assert( set != NULL );
118  assert( set->visual_vbcfilename != NULL );
119  assert( set->visual_bakfilename != NULL );
120  assert( visual->nodenum == NULL );
121 
122  /* check whether we should initialize VBC output */
123  if ( set->visual_vbcfilename[0] != '-' || set->visual_vbcfilename[1] != '\0' )
124  {
125  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_NORMAL,
126  "storing VBC information in file <%s>\n", set->visual_vbcfilename);
127  visual->vbcfile = fopen(set->visual_vbcfilename, "w");
128  visual->timestep = 0;
129  visual->lastnode = NULL;
130  visual->lastcolor = SCIP_VBCCOLOR_NONE;
131  visual->userealtime = set->visual_realtime;
132 
133  if( visual->vbcfile == NULL )
134  {
135  SCIPerrorMessage("error creating file <%s>\n", set->visual_vbcfilename);
136  SCIPprintSysError(set->visual_vbcfilename);
137  return SCIP_FILECREATEERROR;
138  }
139 
140  SCIPmessageFPrintInfo(visual->messagehdlr, visual->vbcfile, "#TYPE: COMPLETE TREE\n");
141  SCIPmessageFPrintInfo(visual->messagehdlr, visual->vbcfile, "#TIME: SET\n");
142  SCIPmessageFPrintInfo(visual->messagehdlr, visual->vbcfile, "#BOUNDS: SET\n");
143  SCIPmessageFPrintInfo(visual->messagehdlr, visual->vbcfile, "#INFORMATION: STANDARD\n");
144  SCIPmessageFPrintInfo(visual->messagehdlr, visual->vbcfile, "#NODE_NUMBER: NONE\n");
145  }
146 
147  /* check whether we should initialize BAK output */
148  if ( set->visual_bakfilename[0] != '-' || set->visual_bakfilename[1] != '\0' )
149  {
150  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_NORMAL,
151  "storing BAK information in file <%s>\n", set->visual_bakfilename);
152  visual->bakfile = fopen(set->visual_bakfilename, "w");
153  visual->timestep = 0;
154  visual->lastnode = NULL;
155  visual->lastcolor = SCIP_VBCCOLOR_NONE;
156  visual->userealtime = set->visual_realtime;
157 
158  if ( visual->bakfile == NULL )
159  {
160  SCIPerrorMessage("error creating file <%s>\n", set->visual_bakfilename);
161  SCIPprintSysError(set->visual_bakfilename);
162  return SCIP_FILECREATEERROR;
163  }
164  }
165 
166  /* possibly init hashmap for nodes */
167  if ( visual->vbcfile != NULL || visual->bakfile != NULL )
168  {
170  }
171 
172  return SCIP_OKAY;
173 }
174 
175 /** closes the visualization output file */
177  SCIP_VISUAL* visual, /**< visualization information */
178  SCIP_SET* set, /**< global SCIP settings */
179  SCIP_MESSAGEHDLR* messagehdlr /**< message handler */
180  )
181 {
182  assert( visual != NULL );
183  assert( set != NULL );
184 
185  if ( visual->vbcfile != NULL )
186  {
187  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL, "closing VBC information file\n");
188 
189  fclose(visual->vbcfile);
190  visual->vbcfile = NULL;
191  }
192 
193  if ( visual->bakfile != NULL )
194  {
195  SCIPmessagePrintVerbInfo(messagehdlr, set->disp_verblevel, SCIP_VERBLEVEL_FULL, "closing BAK information file\n");
196 
197  fclose(visual->bakfile);
198  visual->bakfile = NULL;
199  }
200 
201  if ( visual->nodenum )
202  SCIPhashmapFree(&visual->nodenum);
203 }
204 
205 /** prints current solution time to visualization output file */
206 static
208  SCIP_VISUAL* visual, /**< visualization information */
209  SCIP_STAT* stat, /**< problem statistics */
210  SCIP_Bool vbc /**< whether we use vbc output (bak otherwise) */
211  )
212 {
213  SCIP_Longint step;
214  int hours;
215  int mins;
216  int secs;
217  int hunds;
218 
219  assert( visual != NULL );
220  assert( stat != NULL );
221 
222  if( visual->userealtime )
223  {
224  double time;
225  time = SCIPclockGetTime(stat->solvingtime);
226  step = (SCIP_Longint)(time * 100.0);
227  }
228  else
229  {
230  step = visual->timestep;
231  visual->timestep++;
232  }
233 
234  if ( vbc )
235  {
236  hours = (int)(step / (60*60*100));
237  step %= 60*60*100;
238  mins = (int)(step / (60*100));
239  step %= 60*100;
240  secs = (int)(step / 100);
241  step %= 100;
242  hunds = (int)step;
243 
244  SCIPmessageFPrintInfo(visual->messagehdlr, visual->vbcfile, "%02d:%02d:%02d.%02d ", hours, mins, secs, hunds);
245  }
246  else
247  {
248  SCIPmessageFPrintInfo(visual->messagehdlr, visual->bakfile, "%f ", (SCIP_Real) step/100.0);
249  }
250 }
251 
252 /** creates a new node entry in the visualization output file */
254  SCIP_VISUAL* visual, /**< visualization information */
255  SCIP_SET* set, /**< global SCIP settings */
256  SCIP_STAT* stat, /**< problem statistics */
257  SCIP_NODE* node /**< new node, that was created */
258  )
259 {
260  SCIP_VAR* branchvar;
261  SCIP_BOUNDTYPE branchtype;
262  SCIP_Real branchbound;
263  SCIP_Real lowerbound;
264  size_t parentnodenum;
265  size_t nodenum;
266 
267  assert( visual != NULL );
268  assert( stat != NULL );
269  assert( node != NULL );
270 
271  /* visualization is disabled on probing nodes */
273  return SCIP_OKAY;
274 
275  /* check whether output should be created */
276  if ( visual->vbcfile == NULL && visual->bakfile == NULL )
277  return SCIP_OKAY;
278 
279  /* insert mapping node -> nodenum into hash map */
280  if( stat->ncreatednodesrun >= (SCIP_Longint)INT_MAX )
281  {
282  SCIPerrorMessage("too many nodes to store in the visualization file\n");
283  return SCIP_INVALIDDATA;
284  }
285 
286  nodenum = (size_t)stat->ncreatednodesrun;
287  assert(nodenum > 0);
288  SCIP_CALL( SCIPhashmapSetImage(visual->nodenum, node, (void*)nodenum) );
289 
290  /* get nodenum of parent node from hash map */
291  parentnodenum = (node->parent != NULL ? (size_t)SCIPhashmapGetImage(visual->nodenum, node->parent) : 0);
292  assert(node->parent == NULL || parentnodenum > 0);
293 
294  /* get branching information */
295  getBranchInfo(node, &branchvar, &branchtype, &branchbound);
296 
297  /* determine lower bound */
298  if ( set->visual_objextern )
299  lowerbound = SCIPretransformObj(set->scip, SCIPnodeGetLowerbound(node));
300  else
301  lowerbound = SCIPnodeGetLowerbound(node);
302 
303  if ( visual->vbcfile != NULL )
304  {
305  printTime(visual, stat, TRUE);
306  SCIPmessageFPrintInfo(visual->messagehdlr, visual->vbcfile, "N %d %d %d\n", (int)parentnodenum, (int)nodenum, SCIP_VBCCOLOR_UNSOLVED);
307  printTime(visual, stat, TRUE);
308  if( branchvar != NULL )
309  {
310  SCIPmessageFPrintInfo(visual->messagehdlr, visual->vbcfile, "I %d \\inode:\\t%d (%p)\\idepth:\\t%d\\nvar:\\t%s [%g,%g] %s %f\\nbound:\\t%f\n",
311  (int)nodenum, (int)nodenum, node, SCIPnodeGetDepth(node),
312  SCIPvarGetName(branchvar), SCIPvarGetLbLocal(branchvar), SCIPvarGetUbLocal(branchvar),
313  branchtype == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=", branchbound, lowerbound);
314  }
315  else
316  {
317  SCIPmessageFPrintInfo(visual->messagehdlr, visual->vbcfile, "I %d \\inode:\\t%d (%p)\\idepth:\\t%d\\nvar:\\t-\\nbound:\\t%f\n",
318  (int)nodenum, (int)nodenum, node, SCIPnodeGetDepth(node), lowerbound);
319  }
320  }
321 
322  /* For BAK, not all available information is available here. Use SCIPvisualUpdateChild() instead */
323 
324  return SCIP_OKAY;
325 }
326 
327 /** updates a node entry in the visualization output file */
329  SCIP_VISUAL* visual, /**< visualization information */
330  SCIP_SET* set, /**< global SCIP settings */
331  SCIP_STAT* stat, /**< problem statistics */
332  SCIP_NODE* node /**< new node, that was created */
333  )
334 {
335  SCIP_VAR* branchvar;
336  SCIP_BOUNDTYPE branchtype;
337  SCIP_Real branchbound;
338  SCIP_Real lowerbound;
339  size_t nodenum;
340 
341  assert( visual != NULL );
342  assert( stat != NULL );
343  assert( node != NULL );
344 
345  /* check whether output should be created */
346  if ( visual->vbcfile == NULL && visual->bakfile == NULL )
347  return SCIP_OKAY;
348 
349  /* visualization is disabled on probing nodes */
351  return SCIP_OKAY;
352 
353  /* get node num from hash map */
354  nodenum = (size_t)SCIPhashmapGetImage(visual->nodenum, node);
355  assert(nodenum > 0);
356 
357  /* get branching information */
358  getBranchInfo(node, &branchvar, &branchtype, &branchbound);
359 
360  /* determine lower bound */
361  if ( set->visual_objextern )
362  lowerbound = SCIPretransformObj(set->scip, SCIPnodeGetLowerbound(node));
363  else
364  lowerbound = SCIPnodeGetLowerbound(node);
365 
366  if ( visual->vbcfile != NULL )
367  {
368  printTime(visual, stat, TRUE);
369  if( branchvar != NULL )
370  {
371  SCIPmessageFPrintInfo(visual->messagehdlr, visual->vbcfile, "I %d \\inode:\\t%d (%p)\\idepth:\\t%d\\nvar:\\t%s [%g,%g] %s %f\\nbound:\\t%f\n",
372  (int)nodenum, (int)nodenum, node, SCIPnodeGetDepth(node),
373  SCIPvarGetName(branchvar), SCIPvarGetLbLocal(branchvar), SCIPvarGetUbLocal(branchvar),
374  branchtype == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=", branchbound, lowerbound);
375  }
376  else
377  {
378  SCIPmessageFPrintInfo(visual->messagehdlr, visual->vbcfile, "I %d \\inode:\\t%d (%p)\\idepth:\\t%d\\nvar:\\t-\\nbound:\\t%f\n",
379  (int)nodenum, (int)nodenum, node, SCIPnodeGetDepth(node), lowerbound);
380  }
381  }
382 
383  if ( visual->bakfile != NULL )
384  {
385  size_t parentnodenum;
386  SCIP_Real* lpcandsfrac;
387  SCIP_Real sum = 0.0;
388  int nlpcands = 0;
389  char t = 'M';
390  const char* nodeinfo;
391  int j;
392 
393  /* determine branching type */
394  if ( branchvar != NULL )
395  t = (branchtype == SCIP_BOUNDTYPE_LOWER ? 'R' : 'L');
396 
397  /* get nodenum of parent node from hash map */
398  parentnodenum = (node->parent != NULL ? (size_t)SCIPhashmapGetImage(visual->nodenum, node->parent) : 0);
399  assert(node->parent == NULL || parentnodenum > 0);
400 
401  /* update info depending on the node type */
402  switch( SCIPnodeGetType(node) )
403  {
404  case SCIP_NODETYPE_CHILD:
405  /* the child is a new candidate */
406  nodeinfo = "candidate";
407  break;
409  /* the focus node is updated to a branch node */
410  nodeinfo = "branched";
411 
412  /* calculate infeasibility information only if the LP was solved to optimality */
413  if( SCIPgetLPSolstat(set->scip) == SCIP_LPSOLSTAT_OPTIMAL )
414  {
415  SCIP_CALL( SCIPgetLPBranchCands(set->scip, NULL, NULL, &lpcandsfrac, &nlpcands, NULL, NULL) );
416  for( j = 0; j < nlpcands; ++j )
417  sum += lpcandsfrac[j];
418  }
419 
420  break;
421  default:
422  SCIPerrorMessage("Error: Unexpected node type <%d> in Update Child Method", SCIPnodeGetType(node));
423  return SCIP_INVALIDDATA;
424  } /*lint !e788*/
425  /* append new status line with updated node information to the bakfile */
426  printTime(visual, stat, FALSE);
427  SCIPmessageFPrintInfo(visual->messagehdlr, visual->bakfile, "%s %d %d %c %f %f %d\n", nodeinfo, (int)nodenum, (int)parentnodenum, t,
428  lowerbound, sum, nlpcands);
429  }
430 
431  return SCIP_OKAY;
432 }
433 
434 /** changes the color of the node to the given color */
435 static
437  SCIP_VISUAL* visual, /**< visualization information */
438  SCIP_STAT* stat, /**< problem statistics */
439  SCIP_NODE* node, /**< node to change color for */
440  SCIP_VBCCOLOR color /**< new color of node, or SCIP_VBCCOLOR_NONE */
441  )
442 {
443  assert( visual != NULL );
444  assert( node != NULL );
445 
446  if( visual->vbcfile != NULL && color != SCIP_VBCCOLOR_NONE && (node != visual->lastnode || color != visual->lastcolor) )
447  {
448  size_t nodenum;
449 
450  nodenum = (size_t)SCIPhashmapGetImage(visual->nodenum, node);
451  assert(nodenum > 0);
452  printTime(visual, stat, TRUE);
453  SCIPmessageFPrintInfo(visual->messagehdlr, visual->vbcfile, "P %d %d\n", (int)nodenum, color);
454  visual->lastnode = node;
455  visual->lastcolor = color;
456  }
457 }
458 
459 /** marks node as solved in visualization output file */
461  SCIP_VISUAL* visual, /**< visualization information */
462  SCIP_SET* set, /**< global SCIP settings */
463  SCIP_STAT* stat, /**< problem statistics */
464  SCIP_NODE* node /**< node, that was solved */
465  )
466 {
467  SCIP_VAR* branchvar;
468  SCIP_BOUNDTYPE branchtype;
469  SCIP_Real branchbound;
470  SCIP_Real lowerbound;
471  size_t nodenum;
472 
473  assert( visual != NULL );
474  assert( stat != NULL );
475  assert( node != NULL );
476 
477  /* check whether output should be created */
478  if ( visual->vbcfile == NULL && visual->bakfile == NULL )
479  return;
480 
481  /* visualization is disabled on probing nodes */
483  return;
484 
485  /* get node num from hash map */
486  nodenum = (size_t)SCIPhashmapGetImage(visual->nodenum, node);
487  assert(nodenum > 0);
488 
489  /* get branching information */
490  getBranchInfo(node, &branchvar, &branchtype, &branchbound);
491 
492  /* determine lower bound */
493  if ( set->visual_objextern )
494  lowerbound = SCIPretransformObj(set->scip, SCIPnodeGetLowerbound(node));
495  else
496  lowerbound = SCIPnodeGetLowerbound(node);
497 
498  if ( visual->vbcfile != NULL )
499  {
500  printTime(visual, stat, TRUE);
501  if( branchvar != NULL )
502  {
503  SCIPmessageFPrintInfo(visual->messagehdlr, visual->vbcfile, "I %d \\inode:\\t%d (%p)\\idepth:\\t%d\\nvar:\\t%s [%g,%g] %s %f\\nbound:\\t%f\\nnr:\\t%" SCIP_LONGINT_FORMAT "\n",
504  (int)nodenum, (int)nodenum, node, SCIPnodeGetDepth(node),
505  SCIPvarGetName(branchvar), SCIPvarGetLbLocal(branchvar), SCIPvarGetUbLocal(branchvar),
506  branchtype == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=", branchbound, lowerbound, stat->nnodes);
507  }
508  else
509  {
510  SCIPmessageFPrintInfo(visual->messagehdlr, visual->vbcfile, "I %d \\inode:\\t%d (%p)\\idepth:\\t%d\\nvar:\\t-\\nbound:\\t%f\\nnr:\\t%" SCIP_LONGINT_FORMAT "\n",
511  (int)nodenum, (int)nodenum, node, SCIPnodeGetDepth(node), lowerbound, stat->nnodes);
512  }
513  vbcSetColor(visual, stat, node, SCIP_VBCCOLOR_SOLVED);
514  }
515 
516  /* do nothing for BAK */
517 }
518 
519 /** changes the color of the node to the color of cutoff nodes */
521  SCIP_VISUAL* visual, /**< visualization information */
522  SCIP_SET* set, /**< global SCIP settings */
523  SCIP_STAT* stat, /**< problem statistics */
524  SCIP_NODE* node, /**< node, that was cut off */
525  SCIP_Bool infeasible /**< whether the node is infeasible (otherwise exceeded the cutoff bound) */
526  )
527 {
528  SCIP_VAR* branchvar;
529  SCIP_BOUNDTYPE branchtype;
530  SCIP_Real branchbound;
531  SCIP_Real lowerbound;
532  size_t nodenum;
533 
534  assert( visual != NULL );
535  assert( stat != NULL );
536  assert( node != NULL );
537 
538  /* check whether output should be created */
539  if ( visual->vbcfile == NULL && visual->bakfile == NULL )
540  return;
541 
542  /* visualization is disabled on probing nodes */
544  return;
545 
546  /* get node num from hash map */
547  nodenum = (size_t)SCIPhashmapGetImage(visual->nodenum, node);
548  assert(nodenum > 0);
549 
550  /* get branching information */
551  getBranchInfo(node, &branchvar, &branchtype, &branchbound);
552 
553  /* determine lower bound */
554  if ( set->visual_objextern )
555  lowerbound = SCIPretransformObj(set->scip, SCIPnodeGetLowerbound(node));
556  else
557  lowerbound = SCIPnodeGetLowerbound(node);
558 
559  if ( visual->vbcfile != NULL )
560  {
561  printTime(visual, stat, TRUE);
562  if( branchvar != NULL )
563  {
564  SCIPmessageFPrintInfo(visual->messagehdlr, visual->vbcfile, "I %d \\inode:\\t%d (%p)\\idepth:\\t%d\\nvar:\\t%s [%g,%g] %s %f\\nbound:\\t%f\\nnr:\\t%" SCIP_LONGINT_FORMAT "\n",
565  (int)nodenum, (int)nodenum, node, SCIPnodeGetDepth(node),
566  SCIPvarGetName(branchvar), SCIPvarGetLbLocal(branchvar), SCIPvarGetUbLocal(branchvar),
567  branchtype == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=", branchbound, lowerbound, stat->nnodes);
568  }
569  else
570  {
571  SCIPmessageFPrintInfo(visual->messagehdlr, visual->vbcfile, "I %d \\inode:\\t%d (%p)\\idepth:\\t%d\\nvar:\\t-\\nbound:\\t%f\\nnr:\\t%" SCIP_LONGINT_FORMAT "\n",
572  (int)nodenum, (int)nodenum, node, SCIPnodeGetDepth(node), lowerbound, stat->nnodes);
573  }
574  vbcSetColor(visual, stat, node, SCIP_VBCCOLOR_CUTOFF);
575  }
576 
577  if ( visual->bakfile != NULL )
578  {
579  size_t parentnodenum;
580  char t = 'M';
581 
582  /* determine branching type */
583  if ( branchvar != NULL )
584  t = (branchtype == SCIP_BOUNDTYPE_LOWER ? 'R' : 'L');
585 
586  /* get nodenum of parent node from hash map */
587  parentnodenum = (node->parent != NULL ? (size_t)SCIPhashmapGetImage(visual->nodenum, node->parent) : 0);
588  assert(node->parent == NULL || parentnodenum > 0);
589 
590  printTime(visual, stat, FALSE);
591  if ( infeasible )
592  SCIPmessageFPrintInfo(visual->messagehdlr, visual->bakfile, "infeasible %d %d %c\n", (int)nodenum, (int)parentnodenum, t);
593  else
594  SCIPmessageFPrintInfo(visual->messagehdlr, visual->bakfile, "fathomed %d %d %c\n", (int)nodenum, (int)parentnodenum, t);
595  }
596 }
597 
598 /** changes the color of the node to the color of nodes where a conflict constraint was found */
600  SCIP_VISUAL* visual, /**< visualization information */
601  SCIP_STAT* stat, /**< problem statistics */
602  SCIP_NODE* node /**< node, where the conflict was found */
603  )
604 {
605  assert(node != NULL);
606 
607  /* visualization is disabled on probing nodes */
609  return;
610 
611  vbcSetColor(visual, stat, node, SCIP_VBCCOLOR_CONFLICT);
612 
613  /* do nothing for BAK */
614 }
615 
616 /** changes the color of the node to the color of nodes that were marked to be repropagated */
618  SCIP_VISUAL* visual, /**< visualization information */
619  SCIP_STAT* stat, /**< problem statistics */
620  SCIP_NODE* node /**< node, that was marked to be repropagated */
621  )
622 {
623  assert(node != NULL);
624 
625  /* visualization is disabled on probing nodes */
627  return;
628 
629  /* if the node number is zero, then SCIP is currently in probing and wants to mark a probing node; however this node
630  * is not part of the search tree */
631  if( SCIPnodeGetNumber(node) > 0 )
632  vbcSetColor(visual, stat, node, SCIP_VBCCOLOR_MARKREPROP);
633 
634  /* do nothing for BAK */
635 }
636 
637 /** changes the color of the node to the color of repropagated nodes */
639  SCIP_VISUAL* visual, /**< visualization information */
640  SCIP_STAT* stat, /**< problem statistics */
641  SCIP_NODE* node /**< node, that was repropagated */
642  )
643 {
644  assert(node != NULL);
645 
646  /* visualization is disabled on probing nodes */
648  return;
649 
650  vbcSetColor(visual, stat, node, SCIP_VBCCOLOR_REPROP);
651 
652  /* do nothing for BAK */
653 }
654 
655 /** changes the color of the node to the color of nodes with a primal solution */
657  SCIP_VISUAL* visual, /**< visualization information */
658  SCIP_SET* set, /**< global SCIP settings */
659  SCIP_STAT* stat, /**< problem statistics */
660  SCIP_NODE* node, /**< node where the solution was found, or NULL */
661  SCIP_Bool bettersol, /**< the solution was better than the previous ones */
662  SCIP_SOL* sol /**< solution that has been found */
663  )
664 {
665  if( node == NULL || !set->visual_dispsols || SCIPnodeGetType(node) == SCIP_NODETYPE_PROBINGNODE )
666  return;
667 
668  if( visual->vbcfile != NULL )
669  {
670  SCIP_Real obj;
671  size_t nodenum;
672 
673  /* get node num from hash map */
674  assert(node != NULL);
675  nodenum = (size_t)SCIPhashmapGetImage(visual->nodenum, node);
676  assert(nodenum > 0);
677 
678  /* get objective of solution */
679  if( set->visual_objextern )
680  obj = SCIPgetSolOrigObj(set->scip, sol);
681  else
682  obj = SCIPgetSolTransObj(set->scip, sol);
683 
684  printTime(visual, stat, TRUE);
685  if( bettersol )
686  {
687  /* note that this output is in addition to the one by SCIPvisualUpperbound() */
688  SCIPmessageFPrintInfo(visual->messagehdlr, visual->vbcfile, "A %d \\nfound better solution: %f\n", (int)nodenum, obj);
689  }
690  else
691  SCIPmessageFPrintInfo(visual->messagehdlr, visual->vbcfile, "A %d \\nfound solution: %f\n", (int)nodenum, obj);
692 
693  vbcSetColor(visual, stat, node, SCIP_VBCCOLOR_SOLUTION);
694  }
695 
696  if( visual->bakfile != NULL && bettersol )
697  {
698  SCIP_Real obj;
699 
700  if( set->visual_objextern )
701  obj = SCIPgetSolOrigObj(set->scip, sol);
702  else
703  obj = SCIPgetSolTransObj(set->scip, sol);
704 
705  if( SCIPsolGetHeur(sol) == NULL )
706  {
707  /* if LP solution was feasible ... */
708  SCIP_VAR* branchvar;
709  SCIP_BOUNDTYPE branchtype;
710  SCIP_Real branchbound;
711  SCIP_NODE *pnode;
712  size_t parentnodenum;
713  size_t nodenum;
714  char t = 'M';
715 
716  /* find first parent that is not a probing node */
717  assert(node != NULL);
718  pnode = node;
719  while( pnode != NULL && SCIPnodeGetType(pnode) == SCIP_NODETYPE_PROBINGNODE )
720  pnode = pnode->parent;
721 
722  if( pnode != NULL )
723  {
724  /* get node num from hash map */
725  nodenum = (size_t)SCIPhashmapGetImage(visual->nodenum, pnode);
726 
727  /* get nodenum of parent node from hash map */
728  parentnodenum = (pnode->parent != NULL ? (size_t)SCIPhashmapGetImage(visual->nodenum, pnode->parent) : 0);
729  assert(pnode->parent == NULL || parentnodenum > 0);
730 
731  /* get branching information */
732  getBranchInfo(pnode, &branchvar, &branchtype, &branchbound);
733 
734  /* determine branching type */
735  if( branchvar != NULL )
736  t = (branchtype == SCIP_BOUNDTYPE_LOWER ? 'R' : 'L');
737 
738  printTime(visual, stat, FALSE);
739  SCIPmessageFPrintInfo(visual->messagehdlr, visual->bakfile, "integer %d %d %c %f\n", (int)nodenum, (int)parentnodenum, t, obj);
740  }
741  }
742  else
743  {
744  printTime(visual, stat, FALSE);
745  SCIPmessageFPrintInfo(visual->messagehdlr, visual->bakfile, "heuristic %f\n", obj);
746  }
747  }
748 }
749 
750 /** outputs a new global lower bound to the visualization output file */
752  SCIP_VISUAL* visual, /**< visualization information */
753  SCIP_SET* set, /**< global SCIP settings */
754  SCIP_STAT* stat, /**< problem statistics */
755  SCIP_Real lowerbound /**< new lower bound */
756  )
757 {
758  assert(visual != NULL);
759 
760  /* check, if VBC output should be created */
761  if( visual->vbcfile == NULL )
762  return;
763 
764  /* determine external lower bound */
765  if( set->visual_objextern )
766  lowerbound = SCIPretransformObj(set->scip, lowerbound);
767 
768  printTime(visual, stat, TRUE);
769  if( SCIPgetObjsense(set->scip) == SCIP_OBJSENSE_MINIMIZE )
770  SCIPmessageFPrintInfo(visual->messagehdlr, visual->vbcfile, "L %f\n", lowerbound);
771  else
772  SCIPmessageFPrintInfo(visual->messagehdlr, visual->vbcfile, "U %f\n", lowerbound);
773 
774  /* do nothing for BAK */
775 }
776 
777 /** outputs a new global upper bound to the visualization output file */
779  SCIP_VISUAL* visual, /**< visualization information */
780  SCIP_SET* set, /**< global SCIP settings */
781  SCIP_STAT* stat, /**< problem statistics */
782  SCIP_Real upperbound /**< new upper bound */
783  )
784 {
785  assert(visual != NULL);
786 
787  /* check, if VBC output should be created */
788  if( visual->vbcfile == NULL )
789  return;
790 
791  /* determine external upper bound */
792  if( set->visual_objextern )
793  upperbound = SCIPretransformObj(set->scip, upperbound);
794 
795  printTime(visual, stat, TRUE);
796  if( SCIPgetObjsense(set->scip) == SCIP_OBJSENSE_MINIMIZE )
797  SCIPmessageFPrintInfo(visual->messagehdlr, visual->vbcfile, "U %f\n", upperbound);
798  else
799  SCIPmessageFPrintInfo(visual->messagehdlr, visual->vbcfile, "L %f\n", upperbound);
800 
801  /* do nothing for BAK */
802 }
SCIP_RETCODE SCIPgetLPBranchCands(SCIP *scip, SCIP_VAR ***lpcands, SCIP_Real **lpcandssol, SCIP_Real **lpcandsfrac, int *nlpcands, int *npriolpcands, int *nfracimplvars)
Definition: scip.c:36301
data structures for output for visualization tools (VBC, BAK)
enum SCIP_BoundType SCIP_BOUNDTYPE
Definition: type_lp.h:50
SCIP_RETCODE SCIPvisualCreate(SCIP_VISUAL **visual, SCIP_MESSAGEHDLR *messagehdlr)
Definition: visual.c:75
enum SCIP_VBCColor SCIP_VBCCOLOR
Definition: type_visual.h:64
void SCIPvisualRepropagatedNode(SCIP_VISUAL *visual, SCIP_STAT *stat, SCIP_NODE *node)
Definition: visual.c:638
internal methods for branch and bound tree
SCIP_Real SCIPnodeGetLowerbound(SCIP_NODE *node)
Definition: tree.c:7192
internal methods for clocks and timing issues
SCIP_BOUNDCHG * boundchgs
Definition: struct_var.h:124
static long bound
SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition: var.c:17225
unsigned int nboundchgs
Definition: struct_var.h:122
void SCIPvisualFree(SCIP_VISUAL **visual)
Definition: visual.c:95
#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
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:53
void SCIPvisualSolvedNode(SCIP_VISUAL *visual, SCIP_SET *set, SCIP_STAT *stat, SCIP_NODE *node)
Definition: visual.c:460
void * SCIPhashmapGetImage(SCIP_HASHMAP *hashmap, void *origin)
Definition: misc.c:2902
int SCIPnodeGetDepth(SCIP_NODE *node)
Definition: tree.c:7182
methods for creating output for visualization tools (VBC, BAK)
static void getBranchInfo(SCIP_NODE *node, SCIP_VAR **var, SCIP_BOUNDTYPE *boundtype, SCIP_Real *bound)
Definition: visual.c:48
#define BMSfreeMemory(ptr)
Definition: memory.h:104
void SCIPvisualExit(SCIP_VISUAL *visual, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr)
Definition: visual.c:176
void SCIPvisualLowerbound(SCIP_VISUAL *visual, SCIP_SET *set, SCIP_STAT *stat, SCIP_Real lowerbound)
Definition: visual.c:751
FILE * vbcfile
Definition: struct_visual.h:42
static void vbcSetColor(SCIP_VISUAL *visual, SCIP_STAT *stat, SCIP_NODE *node, SCIP_VBCCOLOR color)
Definition: visual.c:436
SCIP_Longint SCIPnodeGetNumber(SCIP_NODE *node)
Definition: tree.c:7172
SCIP_DOMCHG * domchg
Definition: struct_tree.h:147
SCIP_RETCODE SCIPvisualNewChild(SCIP_VISUAL *visual, SCIP_SET *set, SCIP_STAT *stat, SCIP_NODE *node)
Definition: visual.c:253
#define SCIPerrorMessage
Definition: pub_message.h:45
void SCIPmessagePrintVerbInfo(SCIP_MESSAGEHDLR *messagehdlr, SCIP_VERBLEVEL verblevel, SCIP_VERBLEVEL msgverblevel, const char *formatstr,...)
Definition: message.c:668
const char * SCIPvarGetName(SCIP_VAR *var)
Definition: var.c:16555
SCIP_Real SCIPclockGetTime(SCIP_CLOCK *clck)
Definition: clock.c:428
void SCIPhashmapFree(SCIP_HASHMAP **hashmap)
Definition: misc.c:2797
#define NULL
Definition: lpi_spx1.cpp:137
SCIP_HEUR * SCIPsolGetHeur(SCIP_SOL *sol)
Definition: sol.c:2382
SCIP_Real SCIPgetSolTransObj(SCIP *scip, SCIP_SOL *sol)
Definition: scip.c:38317
SCIP_VBCCOLOR lastcolor
Definition: struct_visual.h:48
internal methods for global SCIP settings
#define SCIP_CALL(x)
Definition: def.h:316
SCIP_HASHMAP * nodenum
Definition: struct_visual.h:45
SCIP_Longint ncreatednodesrun
Definition: struct_stat.h:80
internal methods for problem variables
SCIP_NODE * lastnode
Definition: struct_visual.h:47
FILE * bakfile
Definition: struct_visual.h:43
SCIP_VAR * var
Definition: struct_var.h:89
#define SCIP_Bool
Definition: def.h:61
SCIP_LPSOLSTAT SCIPgetLPSolstat(SCIP *scip)
Definition: scip.c:28948
unsigned int boundtype
Definition: struct_var.h:91
#define SCIP_HASHSIZE_VBC
Definition: def.h:241
void SCIPprintSysError(const char *message)
Definition: misc.c:9276
SCIP_RETCODE SCIPvisualUpdateChild(SCIP_VISUAL *visual, SCIP_SET *set, SCIP_STAT *stat, SCIP_NODE *node)
Definition: visual.c:328
SCIP_Real SCIPgetSolOrigObj(SCIP *scip, SCIP_SOL *sol)
Definition: scip.c:38268
SCIP_Bool userealtime
Definition: struct_visual.h:49
SCIP_Real newbound
Definition: struct_var.h:83
SCIP_DOMCHGBOUND domchgbound
Definition: struct_var.h:152
void SCIPvisualFoundConflict(SCIP_VISUAL *visual, SCIP_STAT *stat, SCIP_NODE *node)
Definition: visual.c:599
SCIP_NODE * parent
Definition: struct_tree.h:145
SCIP_Longint timestep
Definition: struct_visual.h:46
SCIP_MESSAGEHDLR * messagehdlr
Definition: struct_visual.h:44
SCIP_CLOCK * solvingtime
Definition: struct_stat.h:140
SCIP_Real SCIPretransformObj(SCIP *scip, SCIP_Real obj)
Definition: scip.c:38402
void SCIPmessageFPrintInfo(SCIP_MESSAGEHDLR *messagehdlr, FILE *file, const char *formatstr,...)
Definition: message.c:608
SCIP_RETCODE SCIPhashmapSetImage(SCIP_HASHMAP *hashmap, void *origin, void *image)
Definition: misc.c:2942
SCIP_NODETYPE SCIPnodeGetType(SCIP_NODE *node)
Definition: tree.c:7162
#define SCIP_Real
Definition: def.h:145
void SCIPvisualCutoffNode(SCIP_VISUAL *visual, SCIP_SET *set, SCIP_STAT *stat, SCIP_NODE *node, SCIP_Bool infeasible)
Definition: visual.c:520
internal methods for problem statistics
#define BMSallocMemory(ptr)
Definition: memory.h:78
#define SCIP_Longint
Definition: def.h:130
SCIP_OBJSENSE SCIPgetObjsense(SCIP *scip)
Definition: scip.c:10917
SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
Definition: var.c:17235
SCIP_Longint nnodes
Definition: struct_stat.h:71
void SCIPvisualMarkedRepropagateNode(SCIP_VISUAL *visual, SCIP_STAT *stat, SCIP_NODE *node)
Definition: visual.c:617
struct BMS_BlkMem BMS_BLKMEM
Definition: memory.h:396
#define SCIP_ALLOC(x)
Definition: def.h:327
void SCIPvisualUpperbound(SCIP_VISUAL *visual, SCIP_SET *set, SCIP_STAT *stat, SCIP_Real upperbound)
Definition: visual.c:778
void SCIPvisualFoundSolution(SCIP_VISUAL *visual, SCIP_SET *set, SCIP_STAT *stat, SCIP_NODE *node, SCIP_Bool bettersol, SCIP_SOL *sol)
Definition: visual.c:656
SCIP_RETCODE SCIPvisualInit(SCIP_VISUAL *visual, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr)
Definition: visual.c:109
SCIP callable library.
static void printTime(SCIP_VISUAL *visual, SCIP_STAT *stat, SCIP_Bool vbc)
Definition: visual.c:207
memory allocation routines