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