Scippy

GCG

Branch-and-Price & Column Generation for Everyone

event_solvingstats.c
Go to the documentation of this file.
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2 /* */
3 /* This file is part of the program */
4 /* GCG --- Generic Column Generation */
5 /* a Dantzig-Wolfe decomposition based extension */
6 /* of the branch-cut-and-price framework */
7 /* SCIP --- Solving Constraint Integer Programs */
8 /* */
9 /* Copyright (C) 2010-2021 Operations Research, RWTH Aachen University */
10 /* Zuse Institute Berlin (ZIB) */
11 /* */
12 /* This program is free software; you can redistribute it and/or */
13 /* modify it under the terms of the GNU Lesser General Public License */
14 /* as published by the Free Software Foundation; either version 3 */
15 /* of the License, or (at your option) any later version. */
16 /* */
17 /* This program is distributed in the hope that it will be useful, */
18 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
19 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
20 /* GNU Lesser General Public License for more details. */
21 /* */
22 /* You should have received a copy of the GNU Lesser General Public License */
23 /* along with this program; if not, write to the Free Software */
24 /* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.*/
25 /* */
26 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
27 
28 /**@file event_solvingstats.c
29  * @brief eventhdlr for writing various types of information during the solving process
30  * @author Gerald Gamrath
31  *
32  * If the filename is specified, a file is created and the eventhandler is installed to catch all events announcing that
33  * a node was solved or that a new best solution was found.
34  * Whenever one of these things happens, a line is printed to the file with the following information:
35  * 1) solving time
36  * 2) number of processed nodes (including the current node)
37  * 3) number of open nodes
38  * 4) number of LP iterations
39  * 5) number of variables in the master problem
40  * 6) current global dual bound
41  * 7) current primal bound
42  */
43 
44 /*--+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
45 
46 #include "event_solvingstats.h"
47 #include "pricer_gcg.h"
48 #include <string.h>
49 
50 #define EVENTHDLR_NAME "solvingstats"
51 #define EVENTHDLR_DESC "event handler for best solutions found"
52 
53 #define DEFAULT_FILENAME "" /**< filename to write to */
54 
55 /*
56  * Data structures
57  */
58 
59 /** event handler data */
60 struct SCIP_EventhdlrData
61 {
62  SCIP* origprob; /**< pointer to the original SCIP instance */
63  FILE* file; /**< file to which statistics should be written */
64  char* filename; /**< name of file to which statistics should be written */
65 };
66 
67 /** destructor of event handler to free user data (called when SCIP is exiting) */
68 static
69 SCIP_DECL_EVENTFREE(eventFreeSolvingstats)
70 { /*lint --e{715}*/
71  SCIP_EVENTHDLRDATA* eventhdlrdata;
72 
73  assert(scip != NULL);
74  assert(eventhdlr != NULL);
75 
76  eventhdlrdata = SCIPeventhdlrGetData(eventhdlr);
77  assert(eventhdlrdata != NULL);
78  assert(eventhdlrdata->file == NULL);
79 
80  SCIPfreeMemory(scip, &eventhdlrdata);
81 
82  return SCIP_OKAY;
83 }
84 
85 /** initialization method of event handler (called after problem was transformed) */
86 static
87 SCIP_DECL_EVENTINIT(eventInitSolvingstats)
88 { /*lint --e{715}*/
89  SCIP_EVENTHDLRDATA* eventhdlrdata;
90 
91  assert(scip != NULL);
92  assert(eventhdlr != NULL);
93  assert(strcmp(SCIPeventhdlrGetName(eventhdlr), EVENTHDLR_NAME) == 0);
94 
95  eventhdlrdata = SCIPeventhdlrGetData(eventhdlr);
96  assert(eventhdlrdata != NULL);
97 
98  /* check if we need to open the file */
99  if( strlen(eventhdlrdata->filename) > 0 )
100  {
101  assert(eventhdlrdata->origprob != NULL);
102  assert(eventhdlrdata->file == NULL);
103 
104  eventhdlrdata->file = fopen(eventhdlrdata->filename, "w");
105 
106  if( eventhdlrdata->file == NULL )
107  {
108  SCIPerrorMessage("cannot create file <%s> for writing\n", eventhdlrdata->filename);
109  SCIPprintSysError(eventhdlrdata->filename);
110  return SCIP_FILECREATEERROR;
111  }
112 
113  /* notify SCIP that your event handler wants to react on the event types best solution found and node solved */
114  SCIP_CALL( SCIPcatchEvent(scip, SCIP_EVENTTYPE_BESTSOLFOUND | SCIP_EVENTTYPE_NODESOLVED, eventhdlr, NULL, NULL) );
115  }
116 
117  return SCIP_OKAY;
118 }
119 
120 /** deinitialization method of event handler (called before transformed problem is freed) */
121 static
122 SCIP_DECL_EVENTEXIT(eventExitSolvingstats)
123 { /*lint --e{715}*/
124  SCIP_EVENTHDLRDATA* eventhdlrdata;
125 
126  assert(scip != NULL);
127  assert(eventhdlr != NULL);
128  assert(strcmp(SCIPeventhdlrGetName(eventhdlr), EVENTHDLR_NAME) == 0);
129 
130  eventhdlrdata = SCIPeventhdlrGetData(eventhdlr);
131  assert(eventhdlrdata != NULL);
132 
133  if( eventhdlrdata->file != NULL )
134  {
135  (void) fclose(eventhdlrdata->file);
136 
137  /* notify SCIP that your event handler wants to drop the event types best solution found and node solved */
138  SCIP_CALL( SCIPdropEvent(scip, SCIP_EVENTTYPE_BESTSOLFOUND | SCIP_EVENTTYPE_NODESOLVED, eventhdlr, NULL, -1) );
139 
140  eventhdlrdata->file = NULL;
141  }
142 
143  return SCIP_OKAY;
144 }
145 
146 /** execution method of event handler */
147 static
148 SCIP_DECL_EVENTEXEC(eventExecSolvingstats)
149 { /*lint --e{715}*/
150  SCIP_EVENTHDLRDATA* eventhdlrdata;
151 
152  assert(eventhdlr != NULL);
153  assert(strcmp(SCIPeventhdlrGetName(eventhdlr), EVENTHDLR_NAME) == 0);
154  assert(event != NULL);
155  assert(scip != NULL);
156  /*assert(SCIPeventGetType(event) & (SCIP_EVENTTYPE_BESTSOLFOUND | SCIP_EVENTTYPE_NODESOLVED) != 0);*/
157 
158  eventhdlrdata = SCIPeventhdlrGetData(eventhdlr);
159  assert(eventhdlrdata != NULL);
160  assert(eventhdlrdata->file != NULL);
161 
162  SCIPdebugMessage("exec method of event handler for writing information during the solving process\n");
163 
164  SCIPinfoMessage(scip, eventhdlrdata->file, "%8.2f %7"SCIP_LONGINT_FORMAT" %7d %10"SCIP_LONGINT_FORMAT" %d %16.9g %16.9g\n",
165  SCIPgetSolvingTime(scip), SCIPgetNNodes(scip), SCIPgetNNodesLeft(scip), SCIPgetNLPIterations(scip),
166  SCIPgetNVars(scip), SCIPretransformObj(eventhdlrdata->origprob, SCIPgetDualbound(scip)),
167  SCIPretransformObj(eventhdlrdata->origprob, SCIPgetPrimalbound(scip)));
168 
169  return SCIP_OKAY;
170 }
171 
172 /** includes event handler for best solution found */
174  SCIP* scip /**< SCIP data structure */
175  )
176 {
177  SCIP_EVENTHDLRDATA* eventhdlrdata;
178  SCIP_EVENTHDLR* eventhdlr;
179 
180  /* create bounds reader data */
181  SCIP_CALL( SCIPallocMemory(scip, &eventhdlrdata) );
182  eventhdlrdata->origprob = GCGmasterGetOrigprob(scip);
183  eventhdlrdata->file = NULL;
184  eventhdlrdata->filename = NULL;
185  eventhdlr = NULL;
186 
187  /* create event handler for events on watched variables */
188  SCIP_CALL( SCIPincludeEventhdlrBasic(scip, &eventhdlr, EVENTHDLR_NAME, EVENTHDLR_DESC, eventExecSolvingstats, eventhdlrdata) );
189  assert(eventhdlr != NULL);
190 
191  SCIP_CALL( SCIPsetEventhdlrFree(scip, eventhdlr, eventFreeSolvingstats) );
192  SCIP_CALL( SCIPsetEventhdlrInit(scip, eventhdlr, eventInitSolvingstats) );
193  SCIP_CALL( SCIPsetEventhdlrExit(scip, eventhdlr, eventExitSolvingstats) );
194 
195  /* add boundwriting parameters */
196  SCIP_CALL( SCIPaddStringParam(eventhdlrdata->origprob,
197  "eventhdlr/"EVENTHDLR_NAME"/filename",
198  "filename to write all bounds to",
199  &eventhdlrdata->filename, FALSE, DEFAULT_FILENAME, NULL, NULL) );
200 
201  return SCIP_OKAY;
202 }
static SCIP_DECL_EVENTEXEC(eventExecSolvingstats)
eventhdlr for writing various types of information during the solving process
static SCIP_DECL_EVENTFREE(eventFreeSolvingstats)
GCG variable pricer.
#define EVENTHDLR_NAME
SCIP * GCGmasterGetOrigprob(SCIP *scip)
#define EVENTHDLR_DESC
#define DEFAULT_FILENAME
static SCIP_DECL_EVENTEXIT(eventExitSolvingstats)
SCIP_RETCODE SCIPincludeEventHdlrSolvingstats(SCIP *scip)
static SCIP_DECL_EVENTINIT(eventInitSolvingstats)