Scippy

SCIP

Solving Constraint Integer Programs

event_boundwriting.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 examples/Eventhdlr/src/event_boundwriting.c
17  * @ingroup EVENTHDLR
18  * @brief event handler for writing primal and dual bound for all open nodes
19  * @author Michael Winkler
20  *
21  *
22  * This event handler writes to a specified file at a given frequency the dual bounds of all open nodes and the current
23  * primal bound.
24  *
25  * setting "set misc boundwriting freq 1000" will lead to write every 1000 nodes the primal bound and the dual bound
26  * front of all open nodes
27  *
28  * setting "set misc boundwriting filename bounds.txt" will write the bounds to the files
29  * ascending from bounds1.txt over bounds2.txt to boundsN.txt were N is the last number for writing bounds (no
30  * filename means to write to standard out)
31  *
32  * setting "set misc writesubmipdualbound TRUE" will lead to resolve each open node in a subSCIP until the root in the
33  * subSCIP is solved and as a result will print this resulting dual bound
34  *
35  * An output could look as follows (here writesubmipdualbound is set to TRUE):
36  *
37  * PB 201
38  *
39  * 5913 34 192.1 193.5
40  *
41  * 2884 26 162.1 162.1
42  *
43  * The first line above shows the Primalbound. All following lines will show first the node number, second the depth of
44  * this open node, third the dual bound of the open node, and last the dual bound of the root node in a subSCIP of the
45  * resolved node.
46  *
47  * @note you can write all bounds to a single file by adding the line
48  * \code
49  * #define ONEFILE
50  * \endcode
51  * and recompiling this example.
52  *
53  * @note If you want to get a better human readable format for printing, define
54  * \code
55  * #define LONGSTATS
56  * \endcode
57  * and recompile this example.
58  */
59 
60 /*--+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
61 
62 
63 #include <string.h>
64 
65 #include "event_boundwriting.h"
66 
67 
68 #define EVENTHDLR_NAME "boundwriting"
69 #define EVENTHDLR_DESC "event handler for writing current primalbound and global dualbound and for all open nodes the dualbound"
70 
71 #define DEFAULT_FREQ 0LL /**< frequency for writing primal and dual bounds */
72 #define DEFAULT_FILENAME "" /**< filename to write to */
73 #define DEFAULT_WRITESUBMIPDUALBOUND FALSE /**< write dualbound after solving supmip root for all open node */
74 
75 /* should the printing be with more information */
76 /*#define LONGSTATS*/
77 
78 /* do we want to create for each printing new files or only one */
79 /*#define ONEFILE*/
80 
81 /* do we want to print the information only on the focusnode or for all open nodes */
82 /*#define FOCUSNODE*/
83 
84 /*
85  * Data structures
86  */
87 
88 /** LP reading data */
89 struct SCIP_EventhdlrData
90 {
91  char oldfilename[SCIP_MAXSTRLEN];
92  FILE* file;
93  char* filename;
94  SCIP_Real lastpb;
95  SCIP_Longint freq;
96  SCIP_Bool isopen;
97  SCIP_Bool writesubmipdualbound;
98  int filenumber;
99 };
100 
101 
102 /*
103  * Local methods
104  */
105 
106 /** initializes the reader data */
107 static
109  SCIP_EVENTHDLRDATA* eventhdlrdata /**< event handler data */
110  )
111 {
112  assert(eventhdlrdata != NULL);
113 
114  eventhdlrdata->filename = NULL;
115  eventhdlrdata->file = NULL;
116  eventhdlrdata->isopen = FALSE;
117  eventhdlrdata->oldfilename[0] = '\0';
118  eventhdlrdata->filenumber = 1;
119 }
120 
121 #ifndef FOCUSNODE
122 /* apply all changes to the submip */
123 static
125  SCIP* subscip, /**< scip to apply domain changes */
126  SCIP_VAR** vars, /**< variables in original scip instance */
127  SCIP_Real* bounds, /**< bounds which should be applied */
128  SCIP_BOUNDTYPE* boundtypes, /**< bound types for bounds which should be applied */
129  int nvars, /**< number of variables */
130  SCIP_HASHMAP* varmap /**< hashmap for identifiing the corresponding variables in subscip */
131  )
132 {
133  SCIP_VAR* subscipvar;
134  int v;
135 
136  assert(subscip != NULL);
137  assert(vars != NULL);
138  assert(bounds != NULL);
139  assert(boundtypes != NULL);
140  assert(nvars > 0);
141  assert(varmap != NULL);
142 
143  /* need to do a downwards loop, because ing decisions are collect from bottom to root and if we ed twice on a variable, then the weaker bound is behind the stronger in this array */
144  for( v = nvars - 1; v >= 0; --v )
145  {
146  subscipvar = (SCIP_VAR*) SCIPhashmapGetImage(varmap, vars[v]);
147  assert(subscipvar != NULL);
148 
149  if( boundtypes[v] == SCIP_BOUNDTYPE_LOWER )
150  {
151  SCIP_CALL( SCIPchgVarLbGlobal(subscip, subscipvar, bounds[v]) );
152  }
153  else
154  {
155  assert(boundtypes[v] == SCIP_BOUNDTYPE_UPPER);
156  SCIP_CALL( SCIPchgVarUbGlobal(subscip, subscipvar, bounds[v]) );
157  }
158  }
159 
160  return SCIP_OKAY;
161 }
162 #endif
163 
164 #ifdef FOCUSNODE
165 /** call writing method */
166 static
167 SCIP_RETCODE writeBoundsFocusNode(
168  SCIP* scip, /**< SCIP data structure */
169  SCIP_EVENTHDLRDATA* eventhdlrdata /**< event handler data */
170  )
171 {
172  FILE* file;
173  SCIP_Bool writesubmipdualbound;
174  SCIP_NODE* node;
175 
176  assert(scip != NULL);
177  assert(eventhdlrdata != NULL);
178 
179  file = eventhdlrdata->file;
180  writesubmipdualbound = eventhdlrdata->writesubmipdualbound;
181  node = SCIPgetCurrentNode(scip);
182 
183  /* do not process probing nodes */
185  return SCIP_OKAY;
186 
187  /* do not process cutoff nodes */
188  if( SCIPisInfinity(scip, SCIPgetNodeDualbound(scip, node)) )
189  return SCIP_OKAY;
190 
191  if( !SCIPisEQ(scip, eventhdlrdata->lastpb, SCIPgetPrimalbound(scip)) )
192  {
193 #ifdef LONGSTATS
194  SCIPinfoMessage(scip, file, "Status after %"SCIP_LONGINT_FORMAT" processed nodes (%d open)\n", SCIPgetNNodes(scip), SCIPgetNNodesLeft(scip));
195 
196  SCIPinfoMessage(scip, file, "Primalbound: %g\n", SCIPgetPrimalbound(scip));
197  SCIPinfoMessage(scip, file, "Dualbound: %g\n", SCIPgetDualbound(scip));
198 #else
199  SCIPinfoMessage(scip, file, "PB %g\n", SCIPgetPrimalbound(scip));
200 #endif
201  eventhdlrdata->lastpb = SCIPgetPrimalbound(scip);
202  }
203 
204  if( writesubmipdualbound )
205  {
206  SCIP* subscip;
207  SCIP_Bool valid;
208  SCIP_Real submipdb;
209  SCIP_Bool cutoff;
210 
211  SCIP_CALL( SCIPcreate(&subscip) );
212 
213  submipdb = SCIP_INVALID;
214  valid = FALSE;
215  cutoff = FALSE;
216  SCIP_CALL( SCIPcopy(scip, subscip, NULL, NULL, "__boundwriting", FALSE, FALSE, TRUE, &valid) );
217 
218  if( valid )
219  {
220  /* do not abort subproblem on CTRL-C */
221  SCIP_CALL( SCIPsetBoolParam(subscip, "misc/catchctrlc", FALSE) );
222  /* disable output to console */
223  SCIP_CALL( SCIPsetIntParam(subscip, "display/verblevel", 0) );
224  /* solve only root node */
225  SCIP_CALL( SCIPsetLongintParam(subscip, "limits/nodes", 1LL) );
226 
227 #if 0
228  /* disable heuristics in subscip */
230 #endif
231 
232  /* set cutoffbound as objective limit for subscip */
233  SCIP_CALL( SCIPsetObjlimit(subscip, SCIPgetCutoffbound(scip)) );
234 
235  SCIP_CALL( SCIPsolve(subscip) );
236 
237  cutoff = (SCIPgetStatus(subscip) == SCIP_STATUS_INFEASIBLE);
238  submipdb = SCIPgetDualbound(subscip) * SCIPgetTransObjscale(scip) + SCIPgetTransObjoffset(scip);
239  }
240 
241 #ifdef LONGSTATS
242  SCIPinfoMessage(scip, file, "Node %"SCIP_LONGINT_FORMAT" (depth %d): dualbound: %g, nodesubmiprootdualbound: %g %s\n", SCIPnodeGetNumber(node), SCIPnodeGetDepth(node), SCIPgetNodeDualbound(scip, node), submipdb, cutoff ? "(cutoff)" : "");
243 #else
244  SCIPinfoMessage(scip, file, "%"SCIP_LONGINT_FORMAT" %d %g %g %s\n", SCIPnodeGetNumber(node), SCIPnodeGetDepth(node), SCIPgetNodeDualbound(scip, node), submipdb, cutoff ? "(cutoff)" : "");
245 #endif
246 
247  SCIP_CALL( SCIPfree(&subscip) );
248  }
249  else
250  {
251 #ifdef LONGSTATS
252  SCIPinfoMessage(scip, file, "Node %"SCIP_LONGINT_FORMAT" (depth %d): dualbound: %g\n", SCIPnodeGetNumber(node), SCIPnodeGetDepth(node), SCIPgetNodeDualbound(scip, node));
253 #else
254  SCIPinfoMessage(scip, file, "%"SCIP_LONGINT_FORMAT" %d %g\n", SCIPnodeGetNumber(node), SCIPnodeGetDepth(node), SCIPgetNodeDualbound(scip, node));
255 #endif
256  }
257 
258 #ifdef LONGSTATS
259  SCIPinfoMessage(scip, file, "\n");
260 #endif
261 
262  return SCIP_OKAY;
263 }
264 
265 #else
266 
267 /** call writing method */
268 static
270  SCIP* scip, /**< SCIP data structure */
271  FILE* file, /**< file to write to or NULL */
272  SCIP_Bool writesubmipdualbound/**< write dualbounds of submip roots for all open nodes */
273  )
274 {
275  SCIP_NODE** opennodes;
276  int nopennodes;
277  int n;
278  int v;
279 
280  assert(scip != NULL);
281 
282  nopennodes = -1;
283 
284 #ifdef LONGSTATS
285  SCIPinfoMessage(scip, file, "Status after %"SCIP_LONGINT_FORMAT" processed nodes (%d open)\n", SCIPgetNNodes(scip), SCIPgetNNodesLeft(scip));
286 
287  SCIPinfoMessage(scip, file, "Primalbound: %g\n", SCIPgetPrimalbound(scip));
288  SCIPinfoMessage(scip, file, "Dualbound: %g\n", SCIPgetDualbound(scip));
289 #else
290  SCIPinfoMessage(scip, file, "PB %g\n", SCIPgetPrimalbound(scip));
291 #endif
292 
293  /* get all open nodes and therefor print all dualbounds */
294  for( v = 2; v >= 0; --v )
295  {
296  SCIP_NODE* node;
297 
298  switch( v )
299  {
300  case 2:
301  SCIP_CALL( SCIPgetChildren(scip, &opennodes, &nopennodes) );
302  break;
303  case 1:
304  SCIP_CALL( SCIPgetSiblings(scip, &opennodes, &nopennodes) );
305  break;
306  case 0:
307  SCIP_CALL( SCIPgetLeaves(scip, &opennodes, &nopennodes) );
308  break;
309  default:
310  assert(0);
311  break;
312  }
313  assert(nopennodes >= 0);
314 
315  /* print all node information */
316  for( n = nopennodes - 1; n >= 0 && !SCIPisStopped(scip); --n )
317  {
318  node = opennodes[n];
319 
320  if( writesubmipdualbound )
321  {
322  SCIP* subscip;
323  SCIP_Bool valid;
324  SCIP_HASHMAP* varmap; /* mapping of SCIP variables to sub-SCIP variables */
325  SCIP_VAR** vars; /* original problem's variables */
326  int nvars;
327  SCIP_Real submipdb;
328  SCIP_Bool cutoff;
329 
330  SCIP_CALL( SCIPcreate(&subscip) );
331 
332  SCIP_CALL( SCIPgetVarsData(scip, &vars, &nvars, NULL, NULL, NULL, NULL) );
333 
334  /* create the variable mapping hash map */
335  SCIP_CALL( SCIPhashmapCreate(&varmap, SCIPblkmem(subscip), nvars) );
336 
337  submipdb = SCIP_INVALID;
338  valid = FALSE;
339  cutoff = FALSE;
340  SCIP_CALL( SCIPcopy(scip, subscip, varmap, NULL, "__boundwriting", TRUE, FALSE, TRUE, &valid) );
341 
342  if( valid )
343  {
344  SCIP_VAR** branchvars;
345  SCIP_Real* branchbounds;
346  SCIP_BOUNDTYPE* boundtypes;
347  int nbranchvars;
348  int size;
349 
350  size = SCIPnodeGetDepth(node);
351 
352  /* allocate memory for all branching decisions */
353  SCIP_CALL( SCIPallocBufferArray(scip, &branchvars, size) );
354  SCIP_CALL( SCIPallocBufferArray(scip, &branchbounds, size) );
355  SCIP_CALL( SCIPallocBufferArray(scip, &boundtypes, size) );
356 
357  /* we assume that we only have one branching decision at each node */
358  SCIPnodeGetAncestorBranchings( node, branchvars, branchbounds, boundtypes, &nbranchvars, size );
359 
360  /* check if did not have enough memory */
361  if( nbranchvars > size )
362  {
363  size = nbranchvars;
364  SCIP_CALL( SCIPallocBufferArray(scip, &branchvars, size) );
365  SCIP_CALL( SCIPallocBufferArray(scip, &branchbounds, size) );
366  SCIP_CALL( SCIPallocBufferArray(scip, &boundtypes, size) );
367 
368  /* now getting all information */
369  SCIPnodeGetAncestorBranchings( node, branchvars, branchbounds, boundtypes, &nbranchvars, size );
370  }
371 
372  /* apply all changes to the submip */
373  SCIP_CALL( applyDomainChanges(subscip, branchvars, branchbounds, boundtypes, nbranchvars, varmap) );
374 
375  /* free memory for all branching decisions */
376  SCIPfreeBufferArray(scip, &boundtypes);
377  SCIPfreeBufferArray(scip, &branchbounds);
378  SCIPfreeBufferArray(scip, &branchvars);
379 
380  /* do not abort subproblem on CTRL-C */
381  SCIP_CALL( SCIPsetBoolParam(subscip, "misc/catchctrlc", FALSE) );
382  /* disable output to console */
383  SCIP_CALL( SCIPsetIntParam(subscip, "display/verblevel", 0) );
384  /* solve only root node */
385  SCIP_CALL( SCIPsetLongintParam(subscip, "limits/nodes", 1LL) );
386 
387  /* set cutoffbound as objective limit for subscip */
388  SCIP_CALL( SCIPsetObjlimit(subscip, SCIPgetCutoffbound(scip)) );
389 
390  SCIP_CALL( SCIPsolve(subscip) );
391 
392  cutoff = (SCIPgetStatus(subscip) == SCIP_STATUS_INFEASIBLE);
393  submipdb = SCIPgetDualbound(subscip) * SCIPgetTransObjscale(scip) + SCIPgetTransObjoffset(scip);
394  }
395 
396 #ifdef LONGSTATS
397  SCIPinfoMessage(scip, file, "Node %"SCIP_LONGINT_FORMAT" (depth %d): dualbound: %g, nodesubmiprootdualbound: %g %s\n", SCIPnodeGetNumber(node), SCIPnodeGetDepth(node), SCIPgetNodeDualbound(scip, node), submipdb, cutoff ? "(cutoff)" : "");
398 #else
399  SCIPinfoMessage(scip, file, "%"SCIP_LONGINT_FORMAT" %d %g %g %s\n", SCIPnodeGetNumber(node), SCIPnodeGetDepth(node), SCIPgetNodeDualbound(scip, node), submipdb, cutoff ? "(cutoff)" : "");
400 #endif
401 
402  /* free hash map */
403  SCIPhashmapFree(&varmap);
404 
405  SCIP_CALL( SCIPfree(&subscip) );
406  }
407  else
408  {
409 #ifdef LONGSTATS
410  SCIPinfoMessage(scip, file, "Node %"SCIP_LONGINT_FORMAT" (depth %d): dualbound: %g\n", SCIPnodeGetNumber(node), SCIPnodeGetDepth(node), SCIPgetNodeDualbound(scip, node));
411 #else
412  SCIPinfoMessage(scip, file, "%"SCIP_LONGINT_FORMAT" %d %g\n", SCIPnodeGetNumber(node), SCIPnodeGetDepth(node), SCIPgetNodeDualbound(scip, node));
413 #endif
414  }
415  }
416  }
417 
418 #ifdef LONGSTATS
419  SCIPinfoMessage(scip, file, "\n");
420 #endif
421 
422  return SCIP_OKAY;
423 }
424 #endif
425 
426 /*
427  * Callback methods of event handler
428  */
429 
430 /** copy method for event handler plugins (called when SCIP copies plugins) */
431 static
432 SCIP_DECL_EVENTCOPY(eventCopyBoundwriting)
433 { /*lint --e{715}*/
434  assert(scip != NULL);
435  assert(eventhdlr != NULL);
436  assert(strcmp(SCIPeventhdlrGetName(eventhdlr), EVENTHDLR_NAME) == 0);
437 
438  /* call inclusion method of event handler */
439 #if 0
441 #endif
442 
443  return SCIP_OKAY;
444 }
445 
446 /** destructor of event handler to free user data (called when SCIP is exiting) */
447 static
448 SCIP_DECL_EVENTFREE(eventFreeBoundwriting)
449 { /*lint --e{715}*/
450  SCIP_EVENTHDLRDATA* eventhdlrdata;
451 
452  assert(scip != NULL);
453  assert(eventhdlr != NULL);
454 
455  eventhdlrdata = SCIPeventhdlrGetData(eventhdlr);
456  assert(eventhdlrdata != NULL);
457  assert(!eventhdlrdata->isopen);
458  assert(eventhdlrdata->file == NULL);
459 
460  SCIPfreeBlockMemory(scip, &eventhdlrdata);
461 
462  return SCIP_OKAY;
463 }
464 
465 /** initialization method of event handler (called after problem was transformed) */
466 static
467 SCIP_DECL_EVENTINIT(eventInitBoundwriting)
468 { /*lint --e{715}*/
469  SCIP_EVENTHDLRDATA* eventhdlrdata;
470 
471  assert(scip != NULL);
472  assert(eventhdlr != NULL);
473  assert(strcmp(SCIPeventhdlrGetName(eventhdlr), EVENTHDLR_NAME) == 0);
474 
475  /* notify SCIP that your event handler wants to react on the event type best solution found */
477 
478  eventhdlrdata = SCIPeventhdlrGetData(eventhdlr);
479  assert(eventhdlrdata != NULL);
480  eventhdlrdata->lastpb = SCIPinfinity(scip) * (SCIPgetObjsense(scip) == SCIP_OBJSENSE_MINIMIZE ? 1.0 : -1.0);
481 
482  return SCIP_OKAY;
483 }
484 
485 /** deinitialization method of event handler (called before transformed problem is freed) */
486 static
487 SCIP_DECL_EVENTEXIT(eventExitBoundwriting)
488 { /*lint --e{715}*/
489  SCIP_EVENTHDLRDATA* eventhdlrdata;
490 
491  assert(scip != NULL);
492  assert(eventhdlr != NULL);
493  assert(strcmp(SCIPeventhdlrGetName(eventhdlr), EVENTHDLR_NAME) == 0);
494 
495  /* notify SCIP that your event handler wants to drop the event type best solution found */
496  SCIP_CALL( SCIPdropEvent(scip, SCIP_EVENTTYPE_NODESOLVED, eventhdlr, NULL, -1) );
497 
498  eventhdlrdata = SCIPeventhdlrGetData(eventhdlr);
499  assert(eventhdlrdata != NULL);
500 
501  if( eventhdlrdata->isopen )
502  {
503  (void) fclose(eventhdlrdata->file);
504  eventhdlrdata->isopen = FALSE;
505  }
506  eventhdlrdata->file = NULL;
507  eventhdlrdata->oldfilename[0] = '\0';
508  eventhdlrdata->filenumber = 1;
509 
510  return SCIP_OKAY;
511 }
512 
513 /** execution method of event handler */
514 static
515 SCIP_DECL_EVENTEXEC(eventExecBoundwriting)
516 { /*lint --e{715}*/
517  SCIP_EVENTHDLRDATA* eventhdlrdata;
518 
519  assert(scip != NULL);
520  assert(eventhdlr != NULL);
521  assert(strcmp(SCIPeventhdlrGetName(eventhdlr), EVENTHDLR_NAME) == 0);
522  assert(event != NULL);
523  assert(((SCIPeventGetType(event) & SCIP_EVENTTYPE_NODESOLVED) == SCIP_EVENTTYPE_NODEFEASIBLE) || ((SCIPeventGetType(event) & SCIP_EVENTTYPE_NODESOLVED) == SCIP_EVENTTYPE_NODEINFEASIBLE) || ((SCIPeventGetType(event) & SCIP_EVENTTYPE_NODESOLVED) == SCIP_EVENTTYPE_NODEBRANCHED));
524 
525  SCIPdebugMsg(scip, "exec method of event handler for writing primal- and dualbounds\n");
526 
527  eventhdlrdata = SCIPeventhdlrGetData(eventhdlr);
528  assert(eventhdlrdata != NULL);
529 
530 #ifdef ONEFILE
531  /* check if we need to open the file */
532  if( strlen(eventhdlrdata->filename) > 0 && !eventhdlrdata->isopen )
533  {
534  assert(eventhdlrdata->file == NULL);
535  assert(eventhdlrdata->oldfilename[0] == '\0');
536 
537  eventhdlrdata->file = fopen(eventhdlrdata->filename, "w");
538  (void)strncpy(eventhdlrdata->oldfilename, eventhdlrdata->filename, SCIP_MAXSTRLEN);
539 
540  if( eventhdlrdata->file == NULL )
541  {
542  SCIPerrorMessage("cannot create file <%s> for writing\n", eventhdlrdata->filename);
543  SCIPprintSysError(eventhdlrdata->filename);
544  return SCIP_FILECREATEERROR;
545  }
546  eventhdlrdata->isopen = TRUE;
547 
548 #ifdef LONGSTATS
549  SCIPinfoMessage(scip, eventhdlrdata->file, "Problem: %s (%d Original Constraints, %d Original Variables)\n", SCIPgetProbName(scip), SCIPgetNOrigConss(scip), SCIPgetNOrigVars(scip) );
550  SCIPinfoMessage(scip, eventhdlrdata->file, "\t (%d Presolved Constraints, %d Presolved Variables, (%d binary, %d integer, %d implicit integer, %d continuous))\n", SCIPgetNConss(scip), SCIPgetNVars(scip), SCIPgetNBinVars(scip), SCIPgetNIntVars(scip), SCIPgetNImplVars(scip), SCIPgetNContVars(scip));
551  SCIPinfoMessage(scip, eventhdlrdata->file, "\n");
552 #endif
553  }
554 #endif
555 
556  /* call writing only at right moment */
557  if( eventhdlrdata->freq == 0 || (SCIPgetNNodes(scip) % eventhdlrdata->freq) != 0 )
558  return SCIP_OKAY;
559 
560 #ifndef ONEFILE
561  if( strlen(eventhdlrdata->filename) > 0 )
562  {
563  char name[SCIP_MAXSTRLEN];
564  char number[SCIP_MAXSTRLEN];
565  char* pch;
566  int n;
567 
568  assert(eventhdlrdata->file == NULL);
569  assert(!eventhdlrdata->isopen);
570 
571  if( eventhdlrdata->oldfilename[0] == '\0' )
572  (void)strncpy(eventhdlrdata->oldfilename, eventhdlrdata->filename, SCIP_MAXSTRLEN);
573 
574  /* find last '.' to append filenumber */
575  pch=strrchr(eventhdlrdata->filename,'.');
576 
577  assert(eventhdlrdata->filenumber > 0);
578  n=sprintf(number, "%"SCIP_LONGINT_FORMAT"", eventhdlrdata->filenumber * eventhdlrdata->freq);
579  assert(n > 0);
580  assert(n < SCIP_MAXSTRLEN);
581 
582  /* if no point is found, extend directly */
583  if( pch == NULL )
584  {
585  (void)strncpy(name, eventhdlrdata->filename, (unsigned int)(SCIP_MAXSTRLEN - n));
586  strncat(name, number, (unsigned int)n);
587  }
588  else
589  {
590  int len;
591 
592  if( (pch-(eventhdlrdata->filename)) > (SCIP_MAXSTRLEN - n) ) /*lint !e776*/
593  len = SCIP_MAXSTRLEN - n;
594  else
595  len = (int) (pch-(eventhdlrdata->filename));
596 
597  (void)strncpy(name, eventhdlrdata->filename, (unsigned int)len);
598  name[len] = '\0';
599  strncat(name, number, (unsigned int)n);
600  assert(len+n < SCIP_MAXSTRLEN);
601  name[len+n] = '\0';
602 
603  if( len + n + strlen(&(eventhdlrdata->filename[len])) < SCIP_MAXSTRLEN ) /*lint !e776*/
604  {
605  strncat(name, &(eventhdlrdata->filename[len]), strlen(&(eventhdlrdata->filename[len])));
606  name[strlen(eventhdlrdata->filename)+n] = '\0';
607  }
608  }
609 
610  eventhdlrdata->file = fopen(name, "w");
611 
612  if( eventhdlrdata->file == NULL )
613  {
614  SCIPerrorMessage("cannot create file <%s> for writing\n", eventhdlrdata->filename);
615  SCIPprintSysError(eventhdlrdata->filename);
616  return SCIP_FILECREATEERROR;
617  }
618  eventhdlrdata->isopen = TRUE;
619 
620 #ifdef LONGSTATS
621  SCIPinfoMessage(scip, eventhdlrdata->file, "Problem: %s (%d Original Constraints, %d Original Variables)\n", SCIPgetProbName(scip), SCIPgetNOrigConss(scip), SCIPgetNOrigVars(scip) );
622  SCIPinfoMessage(scip, eventhdlrdata->file, "\t (%d Active Constraints, %d Active Variables, (%d binary, %d integer, %d implicit integer, %d continuous))\n", SCIPgetNConss(scip), SCIPgetNVars(scip), SCIPgetNBinVars(scip), SCIPgetNIntVars(scip), SCIPgetNImplVars(scip), SCIPgetNContVars(scip));
623  SCIPinfoMessage(scip, eventhdlrdata->file, "\n");
624 #endif
625  }
626 #endif
627 
628 #ifndef NDEBUG
629  /* check the filename did not change during the solving */
630  if( strlen(eventhdlrdata->filename) > 0 && eventhdlrdata->isopen )
631  {
632  char tmp[SCIP_MAXSTRLEN];
633 
634  (void)strncpy(tmp, eventhdlrdata->filename, SCIP_MAXSTRLEN);
635 
636  /* the name should stay the same */
637  assert(strcmp(tmp, eventhdlrdata->oldfilename) == 0);
638  }
639 #endif
640 
641 #ifdef FOCUSNODE
642  /* call writing method */
643  SCIP_CALL( writeBoundsFocusNode(scip, eventhdlrdata) );
644 #else
645  /* call writing method */
646  SCIP_CALL( writeBounds(scip, eventhdlrdata->file, eventhdlrdata->writesubmipdualbound) );
647 #endif
648 
649 #ifndef ONEFILE
650  if( strlen(eventhdlrdata->filename) > 0 )
651  {
652  assert(eventhdlrdata->isopen);
653 
654  (void) fclose(eventhdlrdata->file);
655  eventhdlrdata->isopen = FALSE;
656  eventhdlrdata->file = NULL;
657  ++(eventhdlrdata->filenumber);
658  }
659 #endif
660 
661  return SCIP_OKAY;
662 }
663 
664 /** includes event handler for writing primal- and dualbound for all open nodes */
666  SCIP* scip /**< SCIP data structure */
667  )
668 {
669  SCIP_EVENTHDLRDATA* eventhdlrdata;
670  SCIP_EVENTHDLR* eventhdlr;
671 
672  /* create bounds reader data */
673  SCIP_CALL( SCIPallocBlockMemory(scip, &eventhdlrdata) );
674  initEventhdlrdata(eventhdlrdata);
675 
676  eventhdlr = NULL;
677  /* create event handler for events on watched variables */
679  eventExecBoundwriting, eventhdlrdata) );
680  assert(eventhdlr != NULL);
681 
682  SCIP_CALL( SCIPsetEventhdlrCopy(scip, eventhdlr, eventCopyBoundwriting) );
683  SCIP_CALL( SCIPsetEventhdlrFree(scip, eventhdlr, eventFreeBoundwriting) );
684  SCIP_CALL( SCIPsetEventhdlrInit(scip, eventhdlr, eventInitBoundwriting) );
685  SCIP_CALL( SCIPsetEventhdlrExit(scip, eventhdlr, eventExitBoundwriting) );
686 
687  /* add boundwriting parameters */
689  "eventhdlr/"EVENTHDLR_NAME"/freq",
690  "in which frequency should all bounds be written(0: never)",
691  &eventhdlrdata->freq, FALSE, DEFAULT_FREQ, 0LL, SCIP_LONGINT_MAX, NULL, NULL) );
693  "eventhdlr/"EVENTHDLR_NAME"/filename",
694  "filename to write all bounds to",
695  &eventhdlrdata->filename, FALSE, DEFAULT_FILENAME, NULL, NULL) );
697  "eventhdlr/"EVENTHDLR_NAME"/writesubmipdualbound",
698  "should the dualbound of the submip-root which was created out of an open node be printed",
699  &eventhdlrdata->writesubmipdualbound, FALSE, DEFAULT_WRITESUBMIPDUALBOUND, NULL, NULL) );
700 
701  return SCIP_OKAY;
702 }
static SCIP_DECL_EVENTEXEC(eventExecBoundwriting)
enum SCIP_BoundType SCIP_BOUNDTYPE
Definition: type_lp.h:50
int SCIPgetNIntVars(SCIP *scip)
Definition: scip.c:11770
static SCIP_RETCODE writeBounds(SCIP *scip, FILE *file, SCIP_Bool writesubmipdualbound)
SCIP_RETCODE SCIPchgVarLbGlobal(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip.c:21971
SCIP_NODE * SCIPgetCurrentNode(SCIP *scip)
Definition: scip.c:40680
SCIP_Real SCIPgetCutoffbound(SCIP *scip)
Definition: scip.c:42726
SCIP_Real SCIPgetPrimalbound(SCIP *scip)
Definition: scip.c:42675
#define SCIP_MAXSTRLEN
Definition: def.h:225
static SCIP_DECL_EVENTEXIT(eventExitBoundwriting)
SCIP_RETCODE SCIPgetLeaves(SCIP *scip, SCIP_NODE ***leaves, int *nleaves)
Definition: scip.c:40837
SCIP_RETCODE SCIPsetEventhdlrExit(SCIP *scip, SCIP_EVENTHDLR *eventhdlr, SCIP_DECL_EVENTEXIT((*eventexit)))
Definition: scip.c:8635
int SCIPgetNOrigVars(SCIP *scip)
Definition: scip.c:12120
SCIP_RETCODE SCIPincludeEventhdlrBasic(SCIP *scip, SCIP_EVENTHDLR **eventhdlrptr, const char *name, const char *desc, SCIP_DECL_EVENTEXEC((*eventexec)), SCIP_EVENTHDLRDATA *eventhdlrdata)
Definition: scip.c:8561
struct SCIP_EventhdlrData SCIP_EVENTHDLRDATA
Definition: type_event.h:138
static SCIP_DECL_EVENTFREE(eventFreeBoundwriting)
SCIP_RETCODE SCIPgetVarsData(SCIP *scip, SCIP_VAR ***vars, int *nvars, int *nbinvars, int *nintvars, int *nimplvars, int *ncontvars)
Definition: scip.c:11554
SCIP_RETCODE SCIPsetHeuristics(SCIP *scip, SCIP_PARAMSETTING paramsetting, SCIP_Bool quiet)
Definition: scip.c:5078
#define FALSE
Definition: def.h:64
#define EVENTHDLR_DESC
SCIP_RETCODE SCIPhashmapCreate(SCIP_HASHMAP **hashmap, BMS_BLKMEM *blkmem, int mapsize)
Definition: misc.c:2764
const char * SCIPeventhdlrGetName(SCIP_EVENTHDLR *eventhdlr)
Definition: event.c:278
SCIP_RETCODE SCIPaddLongintParam(SCIP *scip, const char *name, const char *desc, SCIP_Longint *valueptr, SCIP_Bool isadvanced, SCIP_Longint defaultvalue, SCIP_Longint minvalue, SCIP_Longint maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition: scip.c:4265
SCIP_Real SCIPinfinity(SCIP *scip)
Definition: scip.c:46050
#define TRUE
Definition: def.h:63
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:53
int SCIPgetNNodesLeft(SCIP *scip)
Definition: scip.c:41454
#define SCIPfreeBlockMemory(scip, ptr)
Definition: scip.h:21973
SCIP_RETCODE SCIPaddStringParam(SCIP *scip, const char *name, const char *desc, char **valueptr, SCIP_Bool isadvanced, const char *defaultvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition: scip.c:4348
void * SCIPhashmapGetImage(SCIP_HASHMAP *hashmap, void *origin)
Definition: misc.c:2902
SCIP_Bool SCIPisEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:45985
int SCIPnodeGetDepth(SCIP_NODE *node)
Definition: tree.c:7182
#define SCIP_LONGINT_MAX
Definition: def.h:131
#define SCIPfreeBufferArray(scip, ptr)
Definition: scip.h:22003
static SCIP_DECL_EVENTCOPY(eventCopyBoundwriting)
SCIP_RETCODE SCIPcreate(SCIP **scip)
Definition: scip.c:696
#define SCIPallocBlockMemory(scip, ptr)
Definition: scip.h:21956
static void initEventhdlrdata(SCIP_EVENTHDLRDATA *eventhdlrdata)
SCIP_RETCODE SCIPchgVarUbGlobal(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip.c:22058
#define SCIPdebugMsg
Definition: scip.h:451
static SCIP_DECL_EVENTINIT(eventInitBoundwriting)
void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
Definition: scip.c:1336
int SCIPgetNContVars(SCIP *scip)
Definition: scip.c:11860
SCIP_RETCODE SCIPgetSiblings(SCIP *scip, SCIP_NODE ***siblings, int *nsiblings)
Definition: scip.c:40795
void SCIPnodeGetAncestorBranchings(SCIP_NODE *node, SCIP_VAR **branchvars, SCIP_Real *branchbounds, SCIP_BOUNDTYPE *boundtypes, int *nbranchvars, int branchvarssize)
Definition: tree.c:7526
const char * SCIPgetProbName(SCIP *scip)
Definition: scip.c:10759
#define SCIP_EVENTTYPE_NODEFEASIBLE
Definition: type_event.h:78
#define SCIP_EVENTTYPE_NODEBRANCHED
Definition: type_event.h:80
SCIP_Longint SCIPnodeGetNumber(SCIP_NODE *node)
Definition: tree.c:7172
SCIP_RETCODE SCIPsolve(SCIP *scip)
Definition: scip.c:15846
#define SCIPerrorMessage
Definition: pub_message.h:45
SCIP_RETCODE SCIPsetEventhdlrFree(SCIP *scip, SCIP_EVENTHDLR *eventhdlr, SCIP_DECL_EVENTFREE((*eventfree)))
Definition: scip.c:8607
SCIP_RETCODE SCIPsetEventhdlrCopy(SCIP *scip, SCIP_EVENTHDLR *eventhdlr, SCIP_DECL_EVENTCOPY((*eventcopy)))
Definition: scip.c:8593
SCIP_RETCODE SCIPincludeEventHdlrBoundwriting(SCIP *scip)
SCIP_RETCODE SCIPgetChildren(SCIP *scip, SCIP_NODE ***children, int *nchildren)
Definition: scip.c:40753
SCIP_Real SCIPgetDualbound(SCIP *scip)
Definition: scip.c:42529
SCIP_RETCODE SCIPsetBoolParam(SCIP *scip, const char *name, SCIP_Bool value)
Definition: scip.c:4602
SCIP_STATUS SCIPgetStatus(SCIP *scip)
Definition: scip.c:921
SCIP_RETCODE SCIPsetEventhdlrInit(SCIP *scip, SCIP_EVENTHDLR *eventhdlr, SCIP_DECL_EVENTINIT((*eventinit)))
Definition: scip.c:8621
BMS_BLKMEM * SCIPblkmem(SCIP *scip)
Definition: scip.c:45753
void SCIPhashmapFree(SCIP_HASHMAP **hashmap)
Definition: misc.c:2797
SCIP_Real SCIPgetNodeDualbound(SCIP *scip, SCIP_NODE *node)
Definition: scip.c:13291
#define NULL
Definition: lpi_spx1.cpp:137
#define SCIP_CALL(x)
Definition: def.h:316
int SCIPgetNOrigConss(SCIP *scip)
Definition: scip.c:12820
event handler for writing primal- and dual bound for all open nodes
#define DEFAULT_FREQ
#define SCIPallocBufferArray(scip, ptr, num)
Definition: scip.h:21991
#define SCIP_Bool
Definition: def.h:61
SCIP_RETCODE SCIPcatchEvent(SCIP *scip, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int *filterpos)
Definition: scip.c:40434
int SCIPgetNImplVars(SCIP *scip)
Definition: scip.c:11815
SCIP_EVENTTYPE SCIPeventGetType(SCIP_EVENT *event)
Definition: event.c:959
void SCIPprintSysError(const char *message)
Definition: misc.c:9276
SCIP_RETCODE SCIPsetObjlimit(SCIP *scip, SCIP_Real objlimit)
Definition: scip.c:11114
SCIP_RETCODE SCIPsetIntParam(SCIP *scip, const char *name, int value)
Definition: scip.c:4660
#define SCIP_EVENTTYPE_NODEINFEASIBLE
Definition: type_event.h:79
SCIP_RETCODE SCIPdropEvent(SCIP *scip, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int filterpos)
Definition: scip.c:40468
SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
Definition: scip.c:46061
static long * number
SCIP_Real SCIPgetTransObjscale(SCIP *scip)
Definition: scip.c:11082
int SCIPgetNBinVars(SCIP *scip)
Definition: scip.c:11725
#define SCIP_EVENTTYPE_NODESOLVED
Definition: type_event.h:119
#define EVENTHDLR_NAME
int SCIPgetNVars(SCIP *scip)
Definition: scip.c:11680
SCIP_Real SCIPgetTransObjoffset(SCIP *scip)
Definition: scip.c:11059
int SCIPgetNConss(SCIP *scip)
Definition: scip.c:12728
SCIP_RETCODE SCIPcopy(SCIP *sourcescip, SCIP *targetscip, SCIP_HASHMAP *varmap, SCIP_HASHMAP *consmap, const char *suffix, SCIP_Bool global, SCIP_Bool enablepricing, SCIP_Bool passmessagehdlr, SCIP_Bool *valid)
Definition: scip.c:3767
SCIP_NODETYPE SCIPnodeGetType(SCIP_NODE *node)
Definition: tree.c:7162
#define SCIP_Real
Definition: def.h:145
SCIP_Bool SCIPisStopped(SCIP *scip)
Definition: scip.c:1138
#define SCIP_INVALID
Definition: def.h:165
static SCIP_RETCODE applyDomainChanges(SCIP *subscip, SCIP_VAR **vars, SCIP_Real *bounds, SCIP_BOUNDTYPE *boundtypes, int nvars, SCIP_HASHMAP *varmap)
#define SCIP_Longint
Definition: def.h:130
SCIP_OBJSENSE SCIPgetObjsense(SCIP *scip)
Definition: scip.c:10917
#define DEFAULT_WRITESUBMIPDUALBOUND
SCIP_EVENTHDLRDATA * SCIPeventhdlrGetData(SCIP_EVENTHDLR *eventhdlr)
Definition: event.c:288
SCIP_Longint SCIPgetNNodes(SCIP *scip)
Definition: scip.c:41409
#define DEFAULT_FILENAME
SCIP_RETCODE SCIPsetLongintParam(SCIP *scip, const char *name, SCIP_Longint value)
Definition: scip.c:4718
SCIP_RETCODE SCIPaddBoolParam(SCIP *scip, const char *name, const char *desc, SCIP_Bool *valueptr, SCIP_Bool isadvanced, SCIP_Bool defaultvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition: scip.c:4211
SCIP_RETCODE SCIPfree(SCIP **scip)
Definition: scip.c:774