SCIP Doxygen Documentation
Loading...
Searching...
No Matches
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-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 reader_bnd.c
26 * @ingroup DEFPLUGINS_READER
27 * @brief file reader for variable bounds
28 * @author Ambros Gleixner
29 * @author Ingmar Vierhaus
30 * @author Benjamin Mueller
31 *
32 * This reader allows to read a file containing new bounds for variables of the current problem. Each line of the file
33 * should have format
34 *
35 * <variable name> <lower bound> <upper bound>
36 *
37 * where infinite bounds can be written as inf, +inf or -inf. Note that only a subset of the variables may appear in
38 * the file. Lines with unknown variable names are ignored.
39 * The writing functionality can be used in problem and transformed stages. Note that in transformed stage,
40 * the leading "t_" in the name of a transformed variable will not appear in the output. This way, bounds written in transformed stage
41 * can be read again in problem stage.
42 */
43
44/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
45
46#include "scip/pub_fileio.h"
47#include "scip/pub_message.h"
48#include "scip/pub_misc.h"
49#include "scip/pub_reader.h"
50#include "scip/pub_var.h"
51#include "scip/reader_bnd.h"
52#include "scip/scip_general.h"
53#include "scip/scip_mem.h"
54#include "scip/scip_message.h"
55#include "scip/scip_numerics.h"
56#include "scip/scip_param.h"
57#include "scip/scip_reader.h"
58#include "scip/scip_var.h"
59
60
61#define READER_NAME "bndreader"
62#define READER_DESC "file reader for variable bounds"
63#define READER_EXTENSION "bnd"
64
65#define DEFAULT_IMPROVEONLY FALSE /**< only use improving bounds */
66
67
68/** BND reader data */
69struct SCIP_ReaderData
70{
71 SCIP_Bool improveonly; /**< only use improving bounds */
72};
73
74
75/*
76 * Local methods of reader
77 */
78
79/** reads a given bound file, problem has to be in problem stage */
80static
82 SCIP* scip, /**< SCIP data structure */
83 const char* fname, /**< name of the input file */
84 SCIP_READERDATA* readerdata /**< pointer to the data of the reader */
85 )
86{
87 SCIP_RETCODE retcode;
88 SCIP_FILE* file;
89 SCIP_Bool error;
90 SCIP_Bool unknownvariablemessage;
91 SCIP_Bool usevartable;
92 int lineno;
93
94 assert(scip != NULL);
95 assert(fname != NULL);
96
97 SCIP_CALL( SCIPgetBoolParam(scip, "misc/usevartable", &usevartable) );
98
99 if( !usevartable )
100 {
101 SCIPerrorMessage("Cannot read bounds file if vartable is disabled. Make sure parameter 'misc/usevartable' is set to TRUE.\n");
102 return SCIP_READERROR;
103 }
104
105 /* open input file */
106 file = SCIPfopen(fname, "r");
107 if( file == NULL )
108 {
109 SCIPerrorMessage("cannot open file <%s> for reading\n", fname);
110 SCIPprintSysError(fname);
111 return SCIP_NOFILE;
112 }
113
114 /* read the file */
115 error = FALSE;
116 unknownvariablemessage = FALSE;
117 lineno = 0;
118 while( !SCIPfeof(file) && !error )
119 {
120 char buffer[SCIP_MAXSTRLEN];
121 char varname[SCIP_MAXSTRLEN];
122 char lbstring[SCIP_MAXSTRLEN];
123 char ubstring[SCIP_MAXSTRLEN];
124 char format[SCIP_MAXSTRLEN];
125 SCIP_VAR* var;
126 SCIP_Real lb;
127 SCIP_Real ub;
128 int nread;
129 char* endptr;
130
131 /* get next line */
132 if( SCIPfgets(buffer, (int) sizeof(buffer), file) == NULL )
133 break;
134 lineno++;
135
136 /* parse the line */
137 (void) SCIPsnprintf(format, SCIP_MAXSTRLEN, "%%%ds %%%ds %%%ds\n", SCIP_MAXSTRLEN, SCIP_MAXSTRLEN, SCIP_MAXSTRLEN);
138 (void) sscanf(buffer, format, varname, lbstring, ubstring);
139
140 retcode = SCIPparseVarName(scip, buffer, &var, &endptr);
141 if( retcode != SCIP_OKAY )
142 {
143 SCIPerrorMessage("Error parsing variable name in line %d of bounds file <%s>\n", lineno, fname);
144 error = TRUE;
145 break;
146 }
147
148 (void) SCIPsnprintf(format, SCIP_MAXSTRLEN, "%%%ds %%%ds\n", SCIP_MAXSTRLEN, SCIP_MAXSTRLEN);
149 nread = sscanf(endptr, format, lbstring, ubstring);
150 if( nread < 1 )
151 {
152 SCIPerrorMessage("invalid input line %d in bounds file <%s>: <%s>\n", lineno, fname, buffer);
153 error = TRUE;
154 break;
155 }
156
157 if( var == NULL )
158 {
159 if( !unknownvariablemessage )
160 {
161 SCIPwarningMessage(scip, "unable to parse variable name in line %d of bounds file <%s>:\n", lineno, fname);
162 SCIPwarningMessage(scip, "line is: %s", buffer);
163 SCIPwarningMessage(scip, " (further unknown variables are ignored)\n");
164 unknownvariablemessage = TRUE;
165 }
166 continue;
167 }
168
169 /* cast the lower bound value */
170 if( SCIPstrncasecmp(lbstring, "inv", 3) == 0 )
171 continue;
172 else if( SCIPstrncasecmp(lbstring, "+inf", 4) == 0 || SCIPstrncasecmp(lbstring, "inf", 3) == 0 )
173 lb = SCIPinfinity(scip);
174 else if( SCIPstrncasecmp(lbstring, "-inf", 4) == 0 )
175 lb = -SCIPinfinity(scip);
176 else
177 {
178 nread = sscanf(lbstring, "%lf", &lb);
179 if( nread != 1 )
180 {
181 SCIPerrorMessage("invalid lower bound value <%s> for variable <%s> in line %d of bounds file <%s>\n",
182 lbstring, varname, lineno, fname);
183 error = TRUE;
184 break;
185 }
186 }
187
188 /* cast the upper bound value */
189 if( SCIPstrncasecmp(ubstring, "inv", 3) == 0 )
190 continue;
191 else if( SCIPstrncasecmp(ubstring, "+inf", 4) == 0 || SCIPstrncasecmp(ubstring, "inf", 3) == 0 )
192 ub = SCIPinfinity(scip);
193 else if( SCIPstrncasecmp(ubstring, "-inf", 4) == 0 )
194 ub = -SCIPinfinity(scip);
195 else
196 {
197 /* coverity[secure_coding] */
198 nread = sscanf(ubstring, "%lf", &ub);
199 if( nread != 1 )
200 {
201 SCIPerrorMessage("invalid lower bound value <%s> for variable <%s> in line %d of bounds file <%s>\n",
202 ubstring, varname, lineno, fname);
203 error = TRUE;
204 break;
205 }
206 }
207
208 if( readerdata->improveonly )
209 {
211 {
212 SCIPwarningMessage(scip, "not applying lower bound value %s for variable <%s> in line %d of bounds file %s,"
213 " because it does not improve existing bound of %f\n",
214 lbstring, SCIPvarGetName(var), lineno, fname, SCIPvarGetLbGlobal(var));
215 }
217 {
218 SCIPwarningMessage(scip, "not applying upper bound value %s for variable <%s> in line %d of bounds file %s, "
219 "because it does not improve existing bound of %f\n",
220 ubstring, SCIPvarGetName(var), lineno, fname, SCIPvarGetUbGlobal(var));
221 }
222
223 /* collect best variable bounds */
224 lb = MAX(lb, SCIPvarGetLbGlobal(var)); /*lint !e666*/
225 ub = MIN(ub, SCIPvarGetUbGlobal(var)); /*lint !e666*/
226 }
227
228 /* note that we don't need to check if lb > ub in SCIPchgVar{Lb,Ub} */
229 retcode = SCIPchgVarLb(scip, var, lb);
230 if( retcode != SCIP_OKAY )
231 {
232 SCIPerrorMessage("Error changing lower bound for variable <%s> in line %d of bounds file <%s>\n", varname, lineno, fname);
233 error = TRUE;
234 break;
235 }
236
237 retcode = SCIPchgVarUb(scip, var, ub);
238 if( retcode != SCIP_OKAY )
239 {
240 SCIPerrorMessage("Error changing upper bound for variable <%s> in line %d of bounds file <%s>\n", varname, lineno, fname);
241 error = TRUE;
242 break;
243 }
244 }
245
246 /* close input file */
247 SCIPfclose(file);
248
249 /* return error if necessary */
250 if ( error )
251 return SCIP_READERROR;
252
253 return SCIP_OKAY;
254}
255
256
257/*
258 * Callback methods of reader
259 */
260
261/** copy method for reader plugins (called when SCIP copies plugins) */
262static
264{ /*lint --e{715}*/
265 assert(scip != NULL);
266 assert(reader != NULL);
267
269
270 /* call inclusion method of reader */
272
273 return SCIP_OKAY;
274}
275
276
277/** problem reading method of reader
278 *
279 * In order to determine the type of the file, we have to open it. Thus, it has to be opened
280 * twice. This might be removed, but is likely to not hurt the performance too much.
281 */
282static
284{ /*lint --e{715}*/
285 assert(reader != NULL);
286 assert(result != NULL);
287
289
291
293 {
294 SCIPerrorMessage("reading of bounds file is only possible after a problem was created\n");
295 return SCIP_READERROR;
296 }
297
299 {
300 SCIPerrorMessage("reading of bounds file is only possible during problem creation stage\n");
301 return SCIP_READERROR;
302 }
303
304 /* read bounds file */
305 SCIP_CALL( readBounds(scip, filename, SCIPreaderGetData(reader)) );
306
308
309 return SCIP_OKAY;
310}
311
312/** outputs given bounds into a file stream */
313static
315 SCIP* scip, /**< SCIP data structure */
316 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
317 FILE* file, /**< file stream to print into, or NULL for stdout */
318 SCIP_Real lb, /**< lower bound */
319 SCIP_Real ub /**< upper bound */
320 )
321{
322 /* print lower bound */
323 if( SCIPisInfinity(scip, lb) )
324 SCIPmessageFPrintInfo(messagehdlr, file, "+inf ");
325 else if( SCIPisInfinity(scip, -lb) )
326 SCIPmessageFPrintInfo(messagehdlr, file, "-inf ");
327 else
328 SCIPmessageFPrintInfo(messagehdlr, file, "%.15" SCIP_REAL_FORMAT " ", lb);
329
330 /* print upper bound */
331 if( SCIPisInfinity(scip, ub) )
332 SCIPmessageFPrintInfo(messagehdlr, file, "+inf");
333 else if( SCIPisInfinity(scip, -ub) )
334 SCIPmessageFPrintInfo(messagehdlr, file, "-inf");
335 else
336 SCIPmessageFPrintInfo(messagehdlr, file, "%.15" SCIP_REAL_FORMAT, ub);
337}
338
339/** writes problem to file */
340static
342 SCIP* scip, /**< SCIP data structure */
343 FILE* file, /**< file stream to print into, or NULL for stdout */
344 SCIP_VAR** vars, /**< array with active variables ordered binary, integer, implicit, continuous */
345 int nvars, /**< number of active variables in the problem */
346 SCIP_RESULT* result /**< pointer to store the result of the file writing call */
347 )
348{
349 SCIP_MESSAGEHDLR* messagehdlr;
350 SCIP_Real lb;
351 SCIP_Real ub;
352 int i;
353
354 assert(result != NULL);
355
356 messagehdlr = SCIPgetMessagehdlr(scip);
358
359 if( nvars == 0 )
360 {
361 SCIPwarningMessage(scip, "Problem has no variables, no bounds written.\n");
362 return SCIP_OKAY;
363 }
364
365 for( i = 0; i < nvars; ++i )
366 {
367 SCIP_VAR* var;
368 const char* varname;
369
370 var = vars[i];
371 assert( var != NULL );
372 varname = SCIPvarGetName(var);
373
374 /* strip 't_' from varname */
375 if( SCIPvarIsTransformedOrigvar(var) && strncmp(SCIPvarGetName(var), "t_", 2) == 0)
376 {
377 varname = varname + 2;
378 }
379
380 SCIPinfoMessage(scip, file, "<%s> ", varname);
381
382 /* print global bounds for transformed variables, original bounds for original variables */
384 {
387 }
388 else
389 {
392 }
393
394 /* print bounds into the file */
395 printBounds(scip, messagehdlr, file, lb, ub);
396 SCIPmessageFPrintInfo(messagehdlr, file, "\n");
397 }
398
399 return SCIP_OKAY;
400}
401
402/** problem writing method of reader */
403static
405{ /*lint --e{715}*/
406 assert(reader != NULL);
407
409
411
412 return SCIP_OKAY;
413}
414
415/** destructor of reader to free reader data (called when SCIP is exiting) */
416static
418{
419 SCIP_READERDATA* readerdata;
420
422
423 readerdata = SCIPreaderGetData(reader);
424 assert(readerdata != NULL);
425 SCIPfreeBlockMemory(scip, &readerdata);
426
427 return SCIP_OKAY;
428}
429
430/*
431 * bnd file reader specific interface methods
432 */
433
434/** includes the bnd file reader in SCIP */
436 SCIP* scip /**< SCIP data structure */
437 )
438{
439 SCIP_READERDATA* readerdata;
440 SCIP_READER* reader;
441
442 /* create reader data */
443 SCIP_CALL( SCIPallocBlockMemory(scip, &readerdata) );
444
445 /* include reader */
447
448 /* set non fundamental callbacks via setter functions */
449 SCIP_CALL( SCIPsetReaderCopy(scip, reader, readerCopyBnd) );
450 SCIP_CALL( SCIPsetReaderRead(scip, reader, readerReadBnd) );
451 SCIP_CALL( SCIPsetReaderWrite(scip, reader, readerWriteBnd) );
452 SCIP_CALL( SCIPsetReaderFree(scip, reader, readerFreeBnd) );
453
454 /* add bnd reader parameters */
456 "reading/bndreader/improveonly", "only use improving bounds",
457 &readerdata->improveonly, FALSE, DEFAULT_IMPROVEONLY, NULL, NULL) );
458
459 return SCIP_OKAY;
460}
#define NULL
Definition def.h:257
#define SCIP_MAXSTRLEN
Definition def.h:278
#define SCIP_Bool
Definition def.h:100
#define MIN(x, y)
Definition def.h:233
#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 MAX(x, y)
Definition def.h:229
#define SCIP_REAL_FORMAT
Definition def.h:170
#define SCIP_CALL(x)
Definition def.h:364
SCIP_FILE * SCIPfopen(const char *path, const char *mode)
Definition fileio.c:153
int SCIPfeof(SCIP_FILE *stream)
Definition fileio.c:227
int SCIPfclose(SCIP_FILE *fp)
Definition fileio.c:232
char * SCIPfgets(char *s, int size, SCIP_FILE *stream)
Definition fileio.c:200
SCIP_RETCODE SCIPincludeReaderBnd(SCIP *scip)
Definition reader_bnd.c:435
SCIP_STAGE SCIPgetStage(SCIP *scip)
void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
SCIP_MESSAGEHDLR * SCIPgetMessagehdlr(SCIP *scip)
void SCIPwarningMessage(SCIP *scip, const char *formatstr,...)
SCIP_RETCODE SCIPgetBoolParam(SCIP *scip, const char *name, SCIP_Bool *value)
Definition scip_param.c:250
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
#define SCIPfreeBlockMemory(scip, ptr)
Definition scip_mem.h:108
#define SCIPallocBlockMemory(scip, ptr)
Definition scip_mem.h:89
SCIP_RETCODE SCIPsetReaderCopy(SCIP *scip, SCIP_READER *reader,)
SCIP_RETCODE SCIPincludeReaderBasic(SCIP *scip, SCIP_READER **readerptr, const char *name, const char *desc, const char *extension, SCIP_READERDATA *readerdata)
SCIP_READERDATA * SCIPreaderGetData(SCIP_READER *reader)
Definition reader.c:625
SCIP_RETCODE SCIPsetReaderWrite(SCIP *scip, SCIP_READER *reader,)
SCIP_RETCODE SCIPsetReaderRead(SCIP *scip, SCIP_READER *reader,)
const char * SCIPreaderGetName(SCIP_READER *reader)
Definition reader.c:700
SCIP_RETCODE SCIPsetReaderFree(SCIP *scip, SCIP_READER *reader,)
SCIP_Real SCIPinfinity(SCIP *scip)
SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_RETCODE SCIPchgVarLb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
Definition scip_var.c:5697
SCIP_Real SCIPvarGetLbOriginal(SCIP_VAR *var)
Definition var.c:24052
SCIP_Bool SCIPvarIsTransformed(SCIP_VAR *var)
Definition var.c:23462
SCIP_RETCODE SCIPchgVarUb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
Definition scip_var.c:5875
SCIP_RETCODE SCIPparseVarName(SCIP *scip, const char *str, SCIP_VAR **var, char **endptr)
Definition scip_var.c:728
SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
Definition var.c:24174
const char * SCIPvarGetName(SCIP_VAR *var)
Definition var.c:23299
SCIP_Real SCIPvarGetUbOriginal(SCIP_VAR *var)
Definition var.c:24095
SCIP_Bool SCIPvarIsTransformedOrigvar(SCIP_VAR *var)
Definition var.c:18532
SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
Definition var.c:24152
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition misc.c:10827
void SCIPprintSysError(const char *message)
Definition misc.c:10719
int SCIPstrncasecmp(const char *s1, const char *s2, int length)
Definition misc.c:10876
return SCIP_OKAY
assert(minobj< SCIPgetCutoffbound(scip))
int nvars
SCIP_VAR * var
static SCIP_VAR ** vars
void SCIPmessageFPrintInfo(SCIP_MESSAGEHDLR *messagehdlr, FILE *file, const char *formatstr,...)
Definition message.c:618
wrapper functions to map file i/o to standard or zlib file i/o
struct SCIP_File SCIP_FILE
Definition pub_fileio.h:43
public methods for message output
#define SCIPerrorMessage
Definition pub_message.h:64
public data structures and miscellaneous methods
public methods for input file readers
public methods for problem variables
#define DEFAULT_IMPROVEONLY
Definition reader_bnd.c:65
static SCIP_RETCODE readBounds(SCIP *scip, const char *fname, SCIP_READERDATA *readerdata)
Definition reader_bnd.c:81
#define READER_DESC
Definition reader_bnd.c:62
static void printBounds(SCIP *scip, SCIP_MESSAGEHDLR *messagehdlr, FILE *file, SCIP_Real lb, SCIP_Real ub)
Definition reader_bnd.c:314
#define READER_EXTENSION
Definition reader_bnd.c:63
#define READER_NAME
Definition reader_bnd.c:61
static SCIP_RETCODE SCIPwriteBnd(SCIP *scip, FILE *file, SCIP_VAR **vars, int nvars, SCIP_RESULT *result)
Definition reader_bnd.c:341
file reader for variable bounds
general public methods
public methods for memory management
public methods for message handling
public methods for numerical tolerances
public methods for SCIP parameter handling
public methods for reader plugins
public methods for SCIP variables
struct SCIP_Messagehdlr SCIP_MESSAGEHDLR
#define SCIP_DECL_READERWRITE(x)
struct SCIP_ReaderData SCIP_READERDATA
Definition type_reader.h:54
struct SCIP_Reader SCIP_READER
Definition type_reader.h:53
#define SCIP_DECL_READERREAD(x)
Definition type_reader.h:88
#define SCIP_DECL_READERCOPY(x)
Definition type_reader.h:63
#define SCIP_DECL_READERFREE(x)
Definition type_reader.h:72
@ SCIP_DIDNOTRUN
Definition type_result.h:42
@ SCIP_SUCCESS
Definition type_result.h:58
enum SCIP_Result SCIP_RESULT
Definition type_result.h:61
@ SCIP_NOFILE
@ SCIP_READERROR
@ SCIP_INVALIDCALL
enum SCIP_Retcode SCIP_RETCODE
struct Scip SCIP
Definition type_scip.h:39
@ SCIP_STAGE_PROBLEM
Definition type_set.h:45
struct SCIP_Var SCIP_VAR
Definition type_var.h:166