Scippy

SCIP

Solving Constraint Integer Programs

reader_bnd.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-2014 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 reader_bnd.c
17  * @brief file reader for variable bounds
18  * @author Ambros Gleixner
19  *
20  * This reader allows to read a file containing new bounds for variables of the current problem. Each line of the file
21  * should have format
22  *
23  * <variable name> <lower bound> <upper bound>
24  *
25  * where infinite bounds can be written as inf, +inf or -inf. Note that only a subset of the variables may appear in
26  * the file. Lines with unknown variable names are ignored. The writing functionality is currently not supported.
27  */
28 
29 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
30 
31 #include <assert.h>
32 #include <string.h>
33 
34 #include "scip/reader_bnd.h"
35 
36 #define READER_NAME "bndreader"
37 #define READER_DESC "file reader for variable bounds"
38 #define READER_EXTENSION "bnd"
39 
40 
41 /*
42  * Local methods of reader
43  */
44 
45 /** reads a given bound file, problem has to be in problem stage */
46 static
48  SCIP* scip, /**< SCIP data structure */
49  const char* fname /**< name of the input file */
50  )
51 {
52  SCIP_FILE* file;
53  SCIP_Bool error;
54  SCIP_Bool unknownvariablemessage;
55  SCIP_Bool usevartable;
56  int lineno;
57 
58  assert(scip != NULL);
59  assert(fname != NULL);
60 
61  SCIP_CALL( SCIPgetBoolParam(scip, "misc/usevartable", &usevartable) );
62 
63  if( !usevartable )
64  {
65  SCIPerrorMessage("Cannot read bounds file if vartable is disabled. Make sure parameter 'misc/usevartable' is set to TRUE.\n");
66  return SCIP_READERROR;
67  }
68 
69  /* open input file */
70  file = SCIPfopen(fname, "r");
71  if( file == NULL )
72  {
73  SCIPerrorMessage("cannot open file <%s> for reading\n", fname);
74  SCIPprintSysError(fname);
75  return SCIP_NOFILE;
76  }
77 
78  /* read the file */
79  error = FALSE;
80  unknownvariablemessage = FALSE;
81  lineno = 0;
82  while( !SCIPfeof(file) && !error )
83  {
84  char buffer[SCIP_MAXSTRLEN];
85  char varname[SCIP_MAXSTRLEN];
86  char lbstring[SCIP_MAXSTRLEN];
87  char ubstring[SCIP_MAXSTRLEN];
88  SCIP_VAR* var;
89  SCIP_Real lb;
90  SCIP_Real ub;
91  int nread;
92 
93  /* get next line */
94  if( SCIPfgets(buffer, (int) sizeof(buffer), file) == NULL )
95  break;
96  lineno++;
97 
98  /* parse the line */
99  nread = sscanf(buffer, "%s %s %s\n", varname, lbstring, ubstring);
100  if( nread < 2 )
101  {
102  SCIPerrorMessage("invalid input line %d in bounds file <%s>: <%s>\n", lineno, fname, buffer);
103  error = TRUE;
104  break;
105  }
106 
107  /* find the variable */
108  var = SCIPfindVar(scip, varname);
109  if( var == NULL )
110  {
111  if( !unknownvariablemessage )
112  {
113  SCIPwarningMessage(scip, "unknown variable <%s> in line %d of bounds file <%s>\n", varname, lineno, fname);
114  SCIPwarningMessage(scip, " (further unknown variables are ignored)\n");
115  unknownvariablemessage = TRUE;
116  }
117  continue;
118  }
119 
120  /* cast the lower bound value */
121  if( strncasecmp(lbstring, "inv", 3) == 0 )
122  continue;
123  else if( strncasecmp(lbstring, "+inf", 4) == 0 || strncasecmp(lbstring, "inf", 3) == 0 )
124  lb = SCIPinfinity(scip);
125  else if( strncasecmp(lbstring, "-inf", 4) == 0 )
126  lb = -SCIPinfinity(scip);
127  else
128  {
129  nread = sscanf(lbstring, "%lf", &lb);
130  if( nread != 1 )
131  {
132  SCIPerrorMessage("invalid lower bound value <%s> for variable <%s> in line %d of bounds file <%s>\n",
133  lbstring, varname, lineno, fname);
134  error = TRUE;
135  break;
136  }
137  }
138 
139  /* cast the upper bound value */
140  if( strncasecmp(ubstring, "inv", 3) == 0 )
141  continue;
142  else if( strncasecmp(ubstring, "+inf", 4) == 0 || strncasecmp(ubstring, "inf", 3) == 0 )
143  ub = SCIPinfinity(scip);
144  else if( strncasecmp(ubstring, "-inf", 4) == 0 )
145  ub = -SCIPinfinity(scip);
146  else
147  {
148  nread = sscanf(ubstring, "%lf", &ub);
149  if( nread != 1 )
150  {
151  SCIPerrorMessage("invalid lower bound value <%s> for variable <%s> in line %d of bounds file <%s>\n",
152  ubstring, varname, lineno, fname);
153  error = TRUE;
154  break;
155  }
156  }
157 
158  /* set the bounds of the variable */
159  if( lb <= SCIPvarGetUbGlobal(var) )
160  {
161  SCIP_CALL( SCIPchgVarLb(scip, var, lb) );
162  SCIP_CALL( SCIPchgVarUb(scip, var, ub) );
163  }
164  else
165  {
166  SCIP_CALL( SCIPchgVarUb(scip, var, ub) );
167  SCIP_CALL( SCIPchgVarLb(scip, var, lb) );
168  }
169  }
170 
171  /* close input file */
172  SCIPfclose(file);
173 
174  /* return error if necessary */
175  if ( error )
176  return SCIP_READERROR;
177 
178  return SCIP_OKAY;
179 }
180 
181 
182 /*
183  * Callback methods of reader
184  */
185 
186 /** copy method for reader plugins (called when SCIP copies plugins) */
187 static
188 SCIP_DECL_READERCOPY(readerCopyBnd)
189 { /*lint --e{715}*/
190  assert(scip != NULL);
191  assert(reader != NULL);
192  assert(strcmp(SCIPreaderGetName(reader), READER_NAME) == 0);
193 
194  /* call inclusion method of reader */
196 
197  return SCIP_OKAY;
198 }
199 
200 
201 /** problem reading method of reader
202  *
203  * In order to determine the type of the file, we have to open it. Thus, it has to be opened
204  * twice. This might be removed, but is likely to not hurt the performance too much.
205  */
206 static
207 SCIP_DECL_READERREAD(readerReadBnd)
208 { /*lint --e{715}*/
209  assert(reader != NULL);
210  assert(strcmp(SCIPreaderGetName(reader), READER_NAME) == 0);
211  assert(result != NULL);
212 
213  *result = SCIP_DIDNOTRUN;
214 
215  if( SCIPgetStage(scip) < SCIP_STAGE_PROBLEM )
216  {
217  SCIPerrorMessage("reading of bounds file is only possible after a problem was created\n");
218  return SCIP_READERROR;
219  }
220 
221  if( SCIPgetStage(scip) > SCIP_STAGE_PROBLEM )
222  {
223  SCIPerrorMessage("reading of bounds file is only possible during problem creation stage\n");
224  return SCIP_READERROR;
225  }
226 
227  /* read bounds file */
228  SCIP_CALL( readBounds(scip, filename) );
229 
230  *result = SCIP_SUCCESS;
231 
232  return SCIP_OKAY;
233 }
234 
235 
236 /*
237  * bnd file reader specific interface methods
238  */
239 
240 /** includes the bnd file reader in SCIP */
242  SCIP* scip /**< SCIP data structure */
243  )
244 {
245  SCIP_READERDATA* readerdata;
246  SCIP_READER* reader;
247 
248  /* create reader data */
249  readerdata = NULL;
250 
251  /* include reader */
253 
254  /* set non fundamental callbacks via setter functions */
255  SCIP_CALL( SCIPsetReaderCopy(scip, reader, readerCopyBnd) );
256  SCIP_CALL( SCIPsetReaderRead(scip, reader, readerReadBnd) );
257 
258  return SCIP_OKAY;
259 }
260