Scippy

SCIP

Solving Constraint Integer Programs

reader_smps.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-2019 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 visit scip.zib.de. */
13 /* */
14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15 
16 /**@file reader_smps.c
17  * @brief SMPS file reader - smps files list the cor, tim and sto files for a single instance
18  * @author Stephen J. Maher
19  */
20 
21 
22 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
23 
24 #include "blockmemshell/memory.h"
25 #include "scip/pub_fileio.h"
26 #include "scip/pub_message.h"
27 #include "scip/pub_misc.h"
28 #include "scip/pub_reader.h"
29 #include "scip/reader_cor.h"
30 #include "scip/reader_smps.h"
31 #include "scip/reader_sto.h"
32 #include "scip/reader_tim.h"
33 #include "scip/scip_mem.h"
34 #include "scip/scip_message.h"
35 #include "scip/scip_prob.h"
36 #include "scip/scip_reader.h"
37 #include <string.h>
38 
39 #if !defined(_WIN32) && !defined(_WIN64)
40 #include <strings.h> /*lint --e{766}*/ /* needed for strncasecmp() */
41 #endif
42 
43 /*
44  * The SMPS reader coordinates the reading of the cor, tim and sto files. The public reading methods from the cor, tim
45  * and sto readers are called from the SMPS reader. So, the header files for the cor, tim and sto readers are required.
46  */
47 
48 #define READER_NAME "smpsreader"
49 #define READER_DESC "file reader for core problem of stochastic programs in the SMPS file format"
50 #define READER_EXTENSION "smps"
51 
52 #define SMPS_MAX_LINELEN 1024
53 #define BLANK ' '
54 #define LINEWIDTH 80
55 
56 #define COR_FILEEXTENSION "cor"
57 #define TIM_FILEEXTENSION "tim"
58 #define STO_FILEEXTENSION "sto"
59 
60 /** enum for the file types that are read by the SMPS reader */
62 {
66 };
68 
69 
70 /** smps input structure */
71 struct SmpsInput
72 {
74  int lineno;
77  const char* f0;
78  const char* f1;
79 };
80 typedef struct SmpsInput SMPSINPUT;
81 
82 
83 /** creates the smps input structure */
84 static
86  SCIP* scip, /**< SCIP data structure */
87  SMPSINPUT** smpsi, /**< smps input structure */
88  SCIP_FILE* fp /**< file object for the input file */
89  )
90 {
91  assert(smpsi != NULL);
92  assert(fp != NULL);
93 
94  SCIP_CALL( SCIPallocBlockMemory(scip, smpsi) );
95 
96  (*smpsi)->fp = fp;
97  (*smpsi)->lineno = 0;
98  (*smpsi)->haserror = FALSE;
99  (*smpsi)->buf [0] = '\0';
100  (*smpsi)->f0 = NULL;
101  (*smpsi)->f1 = NULL;
102 
103  return SCIP_OKAY;
104 }
105 
106 /** free the smps input structure */
107 static
109  SCIP* scip, /**< SCIP data structure */
110  SMPSINPUT** smpsi /**< smps input structure */
111  )
112 {
113  SCIPfreeBlockMemory(scip, smpsi);
114 }
115 
116 /** return the current value of field 0 */
117 static
118 const char* smpsinputField0(
119  const SMPSINPUT* smpsi /**< smps input structure */
120  )
121 {
122  assert(smpsi != NULL);
123 
124  return smpsi->f0;
125 }
126 
127 /** fill the line from \p pos up to column LINEWIDTH with blanks. */
128 static
130  char* buf, /**< buffer to clear */
131  unsigned int pos /**< position to start the clearing process */
132  )
133 {
134  unsigned int i;
135 
136  for(i = pos; i < LINEWIDTH; i++)
137  buf[i] = BLANK;
138  buf[LINEWIDTH] = '\0';
139 }
140 
141 /** read a smps format data line and parse the fields. */
142 static
144  SMPSINPUT* smpsi /**< smps input structure */
145  )
146 {
147  unsigned int len;
148  unsigned int i;
149  SCIP_Bool is_marker;
150  SCIP_Bool is_empty;
151  char* nexttok;
152 
153  do
154  {
155  smpsi->f0 = smpsi->f1 = 0;
156  is_marker = FALSE;
157 
158  /* Read until we have not a comment line. */
159  do
160  {
161  smpsi->buf[SMPS_MAX_LINELEN-1] = '\0';
162  if( NULL == SCIPfgets(smpsi->buf, (int) sizeof(smpsi->buf), smpsi->fp) )
163  return FALSE;
164  smpsi->lineno++;
165  }
166  while( *smpsi->buf == '*' );
167 
168  /* Normalize line */
169  len = (unsigned int) strlen(smpsi->buf);
170 
171  /* replace tabs and new lines by blanks */
172  for( i = 0; i < len; i++ )
173  {
174  if( (smpsi->buf[i] == '\t') || (smpsi->buf[i] == '\n') || (smpsi->buf[i] == '\r') )
175  smpsi->buf[i] = BLANK;
176  }
177 
178  if( len < LINEWIDTH )
179  clearFrom(smpsi->buf, len);
180 
181  SCIPdebugMessage("line %d: <%s>\n", smpsi->lineno, smpsi->buf);
182 
183  assert(strlen(smpsi->buf) >= LINEWIDTH);
184 
185  /* Look for new section */
186  if( *smpsi->buf != BLANK )
187  {
188  smpsi->f0 = SCIPstrtok(&smpsi->buf[0], " ", &nexttok);
189 
190  assert(smpsi->f0 != 0);
191 
192  smpsi->f1 = SCIPstrtok(NULL, " ", &nexttok);
193 
194  return TRUE;
195  }
196 
197  /* check for empty lines */
198  is_empty = (smpsi->f0 == NULL && smpsi->f1 == NULL);
199  }
200  while( is_marker || is_empty );
201 
202  return TRUE;
203 }
204 
205 /*
206  * Callback methods of reader
207  */
208 
209 /** copy method for reader plugins (called when SCIP copies plugins) */
210 static
211 SCIP_DECL_READERCOPY(readerCopySmps)
212 { /*lint --e{715}*/
213  assert(scip != NULL);
214  assert(reader != NULL);
215  assert(strcmp(SCIPreaderGetName(reader), READER_NAME) == 0);
216 
217  /* call inclusion method of reader */
219 
220  return SCIP_OKAY;
221 }
222 
223 
224 /** problem reading method of reader */
225 static
226 SCIP_DECL_READERREAD(readerReadSmps)
227 { /*lint --e{715}*/
228  SCIP_FILE* fp;
229  SMPSINPUT* smpsi;
230  SCIP_RETCODE retcode = SCIP_OKAY;
231 
232  char corfilename[SCIP_MAXSTRLEN];
233  char timfilename[SCIP_MAXSTRLEN];
234  char stofilename[SCIP_MAXSTRLEN];
235  char* tmpfilename;
236  char* probname;
237  char* fileextension;
238  char* fromlastslash;
239  char parent[SCIP_MAXSTRLEN];
240  size_t parentlen;
241 
242  SCIP_Bool hascorfile;
243  SCIP_Bool hastimfile;
244  SCIP_Bool hasstofile;
245 
246  int i;
247 
248  assert(scip != NULL);
249  assert(filename != NULL);
250 
251  /* copy filename */
252  SCIP_CALL( SCIPduplicateBufferArray(scip, &tmpfilename, filename, (int)strlen(filename)+1) );
253 
254  /* getting the problem name from the SMPS file name */
255  SCIPsplitFilename(tmpfilename, NULL, &probname, NULL, NULL);
256 
257  fromlastslash = (char*) strrchr(filename, '/');
258 
259  if( fromlastslash == NULL )
260  parentlen = 0;
261  else
262  parentlen = strlen(filename) - (strlen(fromlastslash) - 1);
263 
264  (void)SCIPstrncpy(parent, filename, (int)parentlen + 1);
265 
266  fp = SCIPfopen(filename, "r");
267  if( fp == NULL )
268  {
269  SCIPerrorMessage("cannot open file <%s> for reading\n", filename);
270  SCIPprintSysError(filename);
271 
272  return SCIP_NOFILE;
273  }
274 
275  SCIP_CALL( smpsinputCreate(scip, &smpsi, fp) );
276 
277  hascorfile = FALSE;
278  hastimfile = FALSE;
279  hasstofile = FALSE;
280  while( smpsinputReadLine(smpsi) )
281  {
282  char* tmpinput;
283 
284  /* copy the input */
286  (int)strlen(smpsinputField0(smpsi))+1) ); /*lint !e666*/
287 
288  /* get extension from filename */
289  SCIPsplitFilename(tmpinput, NULL, NULL, &fileextension, NULL);
290 
291  if( strcasecmp(fileextension, COR_FILEEXTENSION) == 0 )
292  {
293  (void) SCIPsnprintf(corfilename, SCIP_MAXSTRLEN, "%s%s", parent, smpsinputField0(smpsi));
294  hascorfile = TRUE;
295  }
296  else if( strcasecmp(fileextension, TIM_FILEEXTENSION) == 0 )
297  {
298  (void) SCIPsnprintf(timfilename, SCIP_MAXSTRLEN, "%s%s", parent, smpsinputField0(smpsi));
299  hastimfile = TRUE;
300  }
301  else if( strcasecmp(fileextension, STO_FILEEXTENSION) == 0 )
302  {
303  (void) SCIPsnprintf(stofilename, SCIP_MAXSTRLEN, "%s%s", parent, smpsinputField0(smpsi));
304  hasstofile = TRUE;
305  }
306 
307  SCIPfreeBufferArray(scip, &tmpinput);
308  }
309 
310  /* printing errors if the correct files have not been provided */
311  if( !hascorfile )
312  {
313  SCIPerrorMessage("The core file has not been listed in <%s>\n", filename);
314  }
315 
316  if( !hastimfile )
317  {
318  SCIPerrorMessage("The tim file has not been listed in <%s>\n", filename);
319  }
320 
321  if( !hasstofile )
322  {
323  SCIPerrorMessage("The sto file has not been listed in <%s>\n", filename);
324  }
325 
326  /* if one of the necessary file has not been provided, then an error will be returned */
327  if( !hascorfile || !hastimfile || !hasstofile )
328  {
329  retcode = SCIP_READERROR;
330  goto TERMINATE;
331  }
332 
333  for( i = 0; i < 3; i++ )
334  {
335  int nvars;
336  int nbinvars;
337  int nintvars;
338  int nimplintvars;
339  int ncontvars;
340  SCIP_SMPSFILETYPE type;
341 
342  type = (SCIP_SMPSFILETYPE) i;
343  switch( type )
344  {
346  SCIPinfoMessage(scip, NULL, "reading core file <%s> for problem %s\n", corfilename, probname);
347  SCIPinfoMessage(scip, NULL, "============\n");
348 
349  /* reading the CORE file */
350  SCIP_CALL_TERMINATE( retcode, SCIPreadCor(scip, corfilename, result), TERMINATE );
351 
352  /* getting the variable information */
353  SCIP_CALL( SCIPgetOrigVarsData(scip, NULL, &nvars, &nbinvars, &nintvars, &nimplintvars, &ncontvars) );
355  "core problem has %d variables (%d bin, %d int, %d impl, %d cont) and %d constraints\n",
356  nvars, nbinvars, nintvars, nimplintvars, ncontvars, SCIPgetNOrigConss(scip));
357  break;
359  SCIPinfoMessage(scip, NULL, "reading the time file <%s> for problem %s\n", timfilename, probname);
360  SCIPinfoMessage(scip, NULL, "============\n");
361 
362  /* reading the TIME file */
363  SCIP_CALL_TERMINATE( retcode, SCIPreadTim(scip, timfilename, result), TERMINATE );
364 
365  SCIPinfoMessage(scip, NULL, "problem %s has %d stages\n", probname, SCIPtimGetNStages(scip));
366  break;
368 #ifdef BENDERSBRANCH
369  SCIP_Bool usebenders;
370 #endif
371 
372  SCIPinfoMessage(scip, NULL, "read problem <%s>\n", stofilename);
373  SCIPinfoMessage(scip, NULL, "============\n");
374 
375  /* reading the STO file */
376  SCIP_CALL_TERMINATE( retcode, SCIPreadSto(scip, stofilename, result), TERMINATE );
377 
378  SCIPinfoMessage(scip, NULL, "problem %s has extended with a total of %d scenarios\n", probname,
380 
381  /* getting the variable information */
382  SCIP_CALL( SCIPgetOrigVarsData(scip, NULL, &nvars, &nbinvars, &nintvars, &nimplintvars, &ncontvars) );
383 
384  /* if Benders' decomposition is used, the variable will be distributed to a number of subproblems */
385 #ifdef BENDERSBRANCH
386  SCIP_CALL( SCIPgetBoolParam(scip, "reading/sto/usebenders", &usebenders) );
387  if( usebenders )
388  {
389  SCIPinfoMessage(scip, NULL, "Benders' decomposition master problem ");
390  }
391  else
392 #endif
393  {
394  SCIPinfoMessage(scip, NULL, "deterministic equivalent problem ");
395  }
396 
398  "has %d variables (%d bin, %d int, %d impl, %d cont) and %d constraints\n",
399  nvars, nbinvars, nintvars, nimplintvars, ncontvars, SCIPgetNOrigConss(scip));
400  break;
401  /* coverity[dead_error_begin] */
402  default:
403  SCIPerrorMessage("This should not happen. Aborting.\n");
404  SCIPABORT();
405  retcode = SCIP_READERROR;
406  goto TERMINATE;
407  }
408 
409  SCIPinfoMessage(scip, NULL, "\n\n");
410  }
411 
412  SCIPfclose(fp);
413 
414  /* cppcheck-suppress unusedLabel */
415 TERMINATE:
416  smpsinputFree(scip, &smpsi);
417 
418  /* freeing buffer array */
419  SCIPfreeBufferArray(scip, &tmpfilename);
420 
421  if( retcode == SCIP_PLUGINNOTFOUND )
422  retcode = SCIP_READERROR;
423 
424  if( retcode == SCIP_NOFILE || retcode == SCIP_READERROR )
425  return retcode;
426 
427  SCIP_CALL( retcode );
428 
429  *result = SCIP_SUCCESS;
430 
431  return SCIP_OKAY;
432 }
433 
434 
435 /*
436  * reader specific interface methods
437  */
438 
439 /** includes the smps file reader in SCIP */
441  SCIP* scip /**< SCIP data structure */
442  )
443 {
444  SCIP_READER* reader;
445 
446  /* include reader */
448 
449  assert(reader != NULL);
450 
451  /* set non fundamental callbacks via setter functions */
452  SCIP_CALL( SCIPsetReaderCopy(scip, reader, readerCopySmps) );
453  SCIP_CALL( SCIPsetReaderRead(scip, reader, readerReadSmps) );
454 
455  return SCIP_OKAY;
456 }
static SCIP_Bool smpsinputReadLine(SMPSINPUT *smpsi)
Definition: reader_smps.c:143
SCIP_EXPORT const char * SCIPreaderGetName(SCIP_READER *reader)
Definition: reader.c:547
enum SCIP_SmpsFileType SCIP_SMPSFILETYPE
Definition: reader_smps.c:67
#define NULL
Definition: def.h:253
const char * f0
Definition: reader_smps.c:77
TIM file reader - the stage information for a stochastic programming instance in SMPS format...
static SCIP_DECL_READERREAD(readerReadSmps)
Definition: reader_smps.c:226
public methods for memory management
#define BLANK
Definition: reader_smps.c:53
#define SCIP_MAXSTRLEN
Definition: def.h:274
COR file reader (MPS format of the core problem for stochastic programs)
static void clearFrom(char *buf, unsigned int pos)
Definition: reader_smps.c:129
char buf[SMPS_MAX_LINELEN]
Definition: reader_smps.c:76
SCIP_RETCODE SCIPgetBoolParam(SCIP *scip, const char *name, SCIP_Bool *value)
Definition: scip_param.c:240
SCIP_Bool haserror
Definition: reader_smps.c:75
SCIP_RETCODE SCIPsetReaderRead(SCIP *scip, SCIP_READER *reader, SCIP_DECL_READERREAD((*readerread)))
Definition: scip_reader.c:185
#define FALSE
Definition: def.h:73
SCIP_RETCODE SCIPsetReaderCopy(SCIP *scip, SCIP_READER *reader, SCIP_DECL_READERCOPY((*readercopy)))
Definition: scip_reader.c:137
#define TRUE
Definition: def.h:72
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:53
#define READER_NAME
Definition: reader_smps.c:48
STO file reader - the stochastic information of an instance in SMPS format.
#define READER_EXTENSION
Definition: reader_smps.c:50
#define SCIPfreeBlockMemory(scip, ptr)
Definition: scip_mem.h:95
#define SCIPdebugMessage
Definition: pub_message.h:77
#define SCIPduplicateBufferArray(scip, ptr, source, num)
Definition: scip_mem.h:119
char * SCIPstrtok(char *s, const char *delim, char **ptrptr)
Definition: misc.c:10221
#define SCIPfreeBufferArray(scip, ptr)
Definition: scip_mem.h:123
#define SCIPallocBlockMemory(scip, ptr)
Definition: scip_mem.h:78
static SCIP_RETCODE smpsinputCreate(SCIP *scip, SMPSINPUT **smpsi, SCIP_FILE *fp)
Definition: reader_smps.c:85
int lineno
Definition: reader_smps.c:74
SCIP_FILE * SCIPfopen(const char *path, const char *mode)
Definition: fileio.c:140
static void smpsinputFree(SCIP *scip, SMPSINPUT **smpsi)
Definition: reader_smps.c:108
int SCIPstrncpy(char *t, const char *s, int size)
Definition: misc.c:10306
#define SCIPerrorMessage
Definition: pub_message.h:45
SCIP_RETCODE SCIPreadCor(SCIP *scip, const char *filename, SCIP_RESULT *result)
Definition: reader_cor.c:177
#define COR_FILEEXTENSION
Definition: reader_smps.c:56
static SCIP_DECL_READERCOPY(readerCopySmps)
Definition: reader_smps.c:211
struct SCIP_File SCIP_FILE
Definition: pub_fileio.h:34
char * SCIPfgets(char *s, int size, SCIP_FILE *stream)
Definition: fileio.c:187
int SCIPtimGetNStages(SCIP *scip)
Definition: reader_tim.c:924
#define STO_FILEEXTENSION
Definition: reader_smps.c:58
int SCIPgetNOrigConss(SCIP *scip)
Definition: scip_prob.c:3129
#define SCIP_CALL(x)
Definition: def.h:365
void SCIPsplitFilename(char *filename, char **path, char **name, char **extension, char **compression)
Definition: misc.c:10482
static const char * smpsinputField0(const SMPSINPUT *smpsi)
Definition: reader_smps.c:118
const char * f1
Definition: reader_smps.c:78
wrapper functions to map file i/o to standard or zlib file i/o
SCIP_SmpsFileType
Definition: reader_smps.c:61
public data structures and miscellaneous methods
#define SCIP_Bool
Definition: def.h:70
SCIP_RETCODE SCIPincludeReaderBasic(SCIP *scip, SCIP_READER **readerptr, const char *name, const char *desc, const char *extension, SCIP_READERDATA *readerdata)
Definition: scip_reader.c:99
int SCIPstoGetNScenarios(SCIP *scip)
Definition: reader_sto.c:2686
public methods for message output
#define TIM_FILEEXTENSION
Definition: reader_smps.c:57
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition: misc.c:10263
SCIP_FILE * fp
Definition: reader_smps.c:73
#define READER_DESC
Definition: reader_smps.c:49
public methods for input file readers
#define SCIP_CALL_TERMINATE(retcode, x, TERM)
Definition: def.h:386
SMPS file reader - SMPS files lists the cor, tim and sto files for a single instance to be read...
public methods for message handling
void SCIPprintSysError(const char *message)
Definition: misc.c:10172
#define LINEWIDTH
Definition: reader_smps.c:54
SCIP_RETCODE SCIPreadSto(SCIP *scip, const char *filename, SCIP_RESULT *result)
Definition: reader_sto.c:2653
SCIP_RETCODE SCIPreadTim(SCIP *scip, const char *filename, SCIP_RESULT *result)
Definition: reader_tim.c:864
void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
Definition: scip_message.c:198
int SCIPfclose(SCIP_FILE *fp)
Definition: fileio.c:219
public methods for reader plugins
#define SCIPABORT()
Definition: def.h:337
public methods for global and local (sub)problems
#define SMPS_MAX_LINELEN
Definition: reader_smps.c:52
SCIP_RETCODE SCIPgetOrigVarsData(SCIP *scip, SCIP_VAR ***vars, int *nvars, int *nbinvars, int *nintvars, int *nimplvars, int *ncontvars)
Definition: scip_prob.c:2352
SCIP_RETCODE SCIPincludeReaderSmps(SCIP *scip)
Definition: reader_smps.c:440
memory allocation routines