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