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-2018 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 )
666  return;
667 
668  if( visual->vbcfile != NULL )
669  {
670  SCIP_Real obj;
671  size_t nodenum;
672 
673  /* if we are in probing, determine original parent node */
674  while ( SCIPnodeGetType(node) == SCIP_NODETYPE_PROBINGNODE )
675  node = SCIPnodeGetParent(node);
676 
677  /* get node num from hash map */
678  assert(node != NULL);
679  nodenum = (size_t)SCIPhashmapGetImage(visual->nodenum, node);
680  assert(nodenum > 0);
681 
682  /* get objective of solution */
683  if( set->visual_objextern )
684  obj = SCIPgetSolOrigObj(set->scip, sol);
685  else
686  obj = SCIPgetSolTransObj(set->scip, sol);
687 
688  printTime(visual, stat, TRUE);
689  if( bettersol )
690  {
691  /* note that this output is in addition to the one by SCIPvisualUpperbound() */
692  SCIPmessageFPrintInfo(visual->messagehdlr, visual->vbcfile, "A %d \\nfound better solution: %f\n", (int)nodenum, obj);
693  }
694  else
695  SCIPmessageFPrintInfo(visual->messagehdlr, visual->vbcfile, "A %d \\nfound solution: %f\n", (int)nodenum, obj);
696 
697  vbcSetColor(visual, stat, node, SCIP_VBCCOLOR_SOLUTION);
698  }
699 
700  if( visual->bakfile != NULL && bettersol )
701  {
702  SCIP_Real obj;
703 
704  if( set->visual_objextern )
705  obj = SCIPgetSolOrigObj(set->scip, sol);
706  else
707  obj = SCIPgetSolTransObj(set->scip, sol);
708 
709  if( SCIPsolGetHeur(sol) == NULL )
710  {
711  /* if LP solution was feasible ... */
712  SCIP_VAR* branchvar;
713  SCIP_BOUNDTYPE branchtype;
714  SCIP_Real branchbound;
715  SCIP_NODE *pnode;
716  size_t parentnodenum;
717  size_t nodenum;
718  char t = 'M';
719 
720  /* find first parent that is not a probing node */
721  assert(node != NULL);
722  pnode = node;
723  while( pnode != NULL && SCIPnodeGetType(pnode) == SCIP_NODETYPE_PROBINGNODE )
724  pnode = pnode->parent;
725 
726  if( pnode != NULL )
727  {
728  /* get node num from hash map */
729  nodenum = (size_t)SCIPhashmapGetImage(visual->nodenum, pnode);
730 
731  /* get nodenum of parent node from hash map */
732  parentnodenum = (pnode->parent != NULL ? (size_t)SCIPhashmapGetImage(visual->nodenum, pnode->parent) : 0);
733  assert(pnode->parent == NULL || parentnodenum > 0);
734 
735  /* get branching information */
736  getBranchInfo(pnode, &branchvar, &branchtype, &branchbound);
737 
738  /* determine branching type */
739  if( branchvar != NULL )
740  t = (branchtype == SCIP_BOUNDTYPE_LOWER ? 'R' : 'L');
741 
742  printTime(visual, stat, FALSE);
743  SCIPmessageFPrintInfo(visual->messagehdlr, visual->bakfile, "integer %d %d %c %f\n", (int)nodenum, (int)parentnodenum, t, obj);
744  }
745  }
746  else
747  {
748  printTime(visual, stat, FALSE);
749  SCIPmessageFPrintInfo(visual->messagehdlr, visual->bakfile, "heuristic %f\n", obj);
750  }
751  }
752 }
753 
754 /** outputs a new global lower bound to the visualization output file */
756  SCIP_VISUAL* visual, /**< visualization information */
757  SCIP_SET* set, /**< global SCIP settings */
758  SCIP_STAT* stat, /**< problem statistics */
759  SCIP_Real lowerbound /**< new lower bound */
760  )
761 {
762  assert(visual != NULL);
763 
764  /* check, if VBC output should be created */
765  if( visual->vbcfile == NULL )
766  return;
767 
768  /* determine external lower bound */
769  if( set->visual_objextern )
770  lowerbound = SCIPretransformObj(set->scip, lowerbound);
771 
772  printTime(visual, stat, TRUE);
773  if( SCIPgetObjsense(set->scip) == SCIP_OBJSENSE_MINIMIZE )
774  SCIPmessageFPrintInfo(visual->messagehdlr, visual->vbcfile, "L %f\n", lowerbound);
775  else
776  SCIPmessageFPrintInfo(visual->messagehdlr, visual->vbcfile, "U %f\n", lowerbound);
777 
778  /* do nothing for BAK */
779 }
780 
781 /** outputs a new global upper bound to the visualization output file */
783  SCIP_VISUAL* visual, /**< visualization information */
784  SCIP_SET* set, /**< global SCIP settings */
785  SCIP_STAT* stat, /**< problem statistics */
786  SCIP_Real upperbound /**< new upper bound */
787  )
788 {
789  assert(visual != NULL);
790 
791  /* check, if VBC output should be created */
792  if( visual->vbcfile == NULL )
793  return;
794 
795  /* determine external upper bound */
796  if( set->visual_objextern )
797  upperbound = SCIPretransformObj(set->scip, upperbound);
798 
799  printTime(visual, stat, TRUE);
800  if( SCIPgetObjsense(set->scip) == SCIP_OBJSENSE_MINIMIZE )
801  SCIPmessageFPrintInfo(visual->messagehdlr, visual->vbcfile, "U %f\n", upperbound);
802  else
803  SCIPmessageFPrintInfo(visual->messagehdlr, visual->vbcfile, "L %f\n", upperbound);
804 
805  /* do nothing for BAK */
806 }
SCIP_RETCODE SCIPgetLPBranchCands(SCIP *scip, SCIP_VAR ***lpcands, SCIP_Real **lpcandssol, SCIP_Real **lpcandsfrac, int *nlpcands, int *npriolpcands, int *nfracimplvars)
Definition: scip.c:37001
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:7362
internal methods for clocks and timing issues
SCIP_BOUNDCHG * boundchgs
Definition: struct_var.h:125
static long bound
SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition: var.c:17332
SCIP_NODE * SCIPnodeGetParent(SCIP_NODE *node)
Definition: tree.c:7622
unsigned int nboundchgs
Definition: struct_var.h:123
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:2793
#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:2931
int SCIPnodeGetDepth(SCIP_NODE *node)
Definition: tree.c:7352
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:127
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:755
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:7342
SCIP_DOMCHG * domchg
Definition: struct_tree.h:148
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:16662
SCIP_Real SCIPclockGetTime(SCIP_CLOCK *clck)
Definition: clock.c:428
void SCIPhashmapFree(SCIP_HASHMAP **hashmap)
Definition: misc.c:2826
SCIP_HEUR * SCIPsolGetHeur(SCIP_SOL *sol)
Definition: sol.c:2548
SCIP_Real SCIPgetSolTransObj(SCIP *scip, SCIP_SOL *sol)
Definition: scip.c:39041
SCIP_VBCCOLOR lastcolor
Definition: struct_visual.h:48
internal methods for global SCIP settings
#define SCIP_CALL(x)
Definition: def.h:350
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:90
#define SCIP_Bool
Definition: def.h:61
SCIP_LPSOLSTAT SCIPgetLPSolstat(SCIP *scip)
Definition: scip.c:29293
unsigned int boundtype
Definition: struct_var.h:92
#define SCIP_HASHSIZE_VBC
Definition: def.h:275
void SCIPprintSysError(const char *message)
Definition: misc.c:9920
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:38994
SCIP_Bool userealtime
Definition: struct_visual.h:49
SCIP_Real newbound
Definition: struct_var.h:84
SCIP_DOMCHGBOUND domchgbound
Definition: struct_var.h:153
void SCIPvisualFoundConflict(SCIP_VISUAL *visual, SCIP_STAT *stat, SCIP_NODE *node)
Definition: visual.c:599
SCIP_NODE * parent
Definition: struct_tree.h:146
SCIP_Longint timestep
Definition: struct_visual.h:46
SCIP_MESSAGEHDLR * messagehdlr
Definition: struct_visual.h:44
SCIP_CLOCK * solvingtime
Definition: struct_stat.h:142
SCIP_Real SCIPretransformObj(SCIP *scip, SCIP_Real obj)
Definition: scip.c:39126
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:2971
SCIP_NODETYPE SCIPnodeGetType(SCIP_NODE *node)
Definition: tree.c:7332
#define SCIP_Real
Definition: def.h:149
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:101
#define SCIP_Longint
Definition: def.h:134
SCIP_OBJSENSE SCIPgetObjsense(SCIP *scip)
Definition: scip.c:11049
SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
Definition: var.c:17342
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:419
#define SCIP_ALLOC(x)
Definition: def.h:361
void SCIPvisualUpperbound(SCIP_VISUAL *visual, SCIP_SET *set, SCIP_STAT *stat, SCIP_Real upperbound)
Definition: visual.c:782
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