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-2024 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#include <string.h>
60
61#if !defined(_WIN32) && !defined(_WIN64)
62#include <strings.h> /*lint --e{766}*/ /* needed for strncasecmp() */
63#endif
64
65
66#define READER_NAME "bndreader"
67#define READER_DESC "file reader for variable bounds"
68#define READER_EXTENSION "bnd"
69
70#define DEFAULT_IMPROVEONLY FALSE /**< only use improving bounds */
71
72
73/** BND reader data */
74struct SCIP_ReaderData
75{
76 SCIP_Bool improveonly; /**< only use improving bounds */
77};
78
79
80/*
81 * Local methods of reader
82 */
83
84/** reads a given bound file, problem has to be in problem stage */
85static
87 SCIP* scip, /**< SCIP data structure */
88 const char* fname, /**< name of the input file */
89 SCIP_READERDATA* readerdata /**< pointer to the data of the reader */
90 )
91{
92 SCIP_RETCODE retcode;
93 SCIP_FILE* file;
94 SCIP_Bool error;
95 SCIP_Bool unknownvariablemessage;
96 SCIP_Bool usevartable;
97 int lineno;
98
99 assert(scip != NULL);
100 assert(fname != NULL);
101
102 SCIP_CALL( SCIPgetBoolParam(scip, "misc/usevartable", &usevartable) );
103
104 if( !usevartable )
105 {
106 SCIPerrorMessage("Cannot read bounds file if vartable is disabled. Make sure parameter 'misc/usevartable' is set to TRUE.\n");
107 return SCIP_READERROR;
108 }
109
110 /* open input file */
111 file = SCIPfopen(fname, "r");
112 if( file == NULL )
113 {
114 SCIPerrorMessage("cannot open file <%s> for reading\n", fname);
116 return SCIP_NOFILE;
117 }
118
119 /* read the file */
120 error = FALSE;
122 lineno = 0;
123 while( !SCIPfeof(file) && !error )
124 {
125 char buffer[SCIP_MAXSTRLEN];
130 SCIP_VAR* var;
131 SCIP_Real lb;
132 SCIP_Real ub;
133 int nread;
134 char* endptr;
135
136 /* get next line */
137 if( SCIPfgets(buffer, (int) sizeof(buffer), file) == NULL )
138 break;
139 lineno++;
140
141 /* parse the line */
144
145 retcode = SCIPparseVarName(scip, buffer, &var, &endptr);
146 if( retcode != SCIP_OKAY )
147 {
148 SCIPerrorMessage("Error parsing variable name in line %d of bounds file <%s>\n", lineno, fname);
149 error = TRUE;
150 break;
151 }
152
155 if( nread < 1 )
156 {
157 SCIPerrorMessage("invalid input line %d in bounds file <%s>: <%s>\n", lineno, fname, buffer);
158 error = TRUE;
159 break;
160 }
161
162 if( var == NULL )
163 {
165 {
166 SCIPwarningMessage(scip, "unable to parse variable name in line %d of bounds file <%s>:\n", lineno, fname);
167 SCIPwarningMessage(scip, "line is: %s", buffer);
168 SCIPwarningMessage(scip, " (further unknown variables are ignored)\n");
170 }
171 continue;
172 }
173
174 /* cast the lower bound value */
175 if( strncasecmp(lbstring, "inv", 3) == 0 )
176 continue;
177 else if( strncasecmp(lbstring, "+inf", 4) == 0 || strncasecmp(lbstring, "inf", 3) == 0 )
178 lb = SCIPinfinity(scip);
179 else if( strncasecmp(lbstring, "-inf", 4) == 0 )
180 lb = -SCIPinfinity(scip);
181 else
182 {
183 nread = sscanf(lbstring, "%lf", &lb);
184 if( nread != 1 )
185 {
186 SCIPerrorMessage("invalid lower bound value <%s> for variable <%s> in line %d of bounds file <%s>\n",
187 lbstring, varname, lineno, fname);
188 error = TRUE;
189 break;
190 }
191 }
192
193 /* cast the upper bound value */
194 if( strncasecmp(ubstring, "inv", 3) == 0 )
195 continue;
196 else if( strncasecmp(ubstring, "+inf", 4) == 0 || strncasecmp(ubstring, "inf", 3) == 0 )
197 ub = SCIPinfinity(scip);
198 else if( strncasecmp(ubstring, "-inf", 4) == 0 )
199 ub = -SCIPinfinity(scip);
200 else
201 {
202 /* coverity[secure_coding] */
203 nread = sscanf(ubstring, "%lf", &ub);
204 if( nread != 1 )
205 {
206 SCIPerrorMessage("invalid lower bound value <%s> for variable <%s> in line %d of bounds file <%s>\n",
207 ubstring, varname, lineno, fname);
208 error = TRUE;
209 break;
210 }
211 }
212
213 if( readerdata->improveonly )
214 {
216 {
217 SCIPwarningMessage(scip, "not applying lower bound value %s for variable <%s> in line %d of bounds file %s,"
218 " because it does not improve existing bound of %f\n",
220 }
222 {
223 SCIPwarningMessage(scip, "not applying upper bound value %s for variable <%s> in line %d of bounds file %s, "
224 "because it does not improve existing bound of %f\n",
226 }
227
228 /* collect best variable bounds */
229 lb = MAX(lb, SCIPvarGetLbGlobal(var)); /*lint !e666*/
230 ub = MIN(ub, SCIPvarGetUbGlobal(var)); /*lint !e666*/
231 }
232
233 /* note that we don't need to check if lb > ub in SCIPchgVar{Lb,Ub} */
234 retcode = SCIPchgVarLb(scip, var, lb);
235 if( retcode != SCIP_OKAY )
236 {
237 SCIPerrorMessage("Error changing lower bound for variable <%s> in line %d of bounds file <%s>\n", varname, lineno, fname);
238 error = TRUE;
239 break;
240 }
241
242 retcode = SCIPchgVarUb(scip, var, ub);
243 if( retcode != SCIP_OKAY )
244 {
245 SCIPerrorMessage("Error changing upper bound for variable <%s> in line %d of bounds file <%s>\n", varname, lineno, fname);
246 error = TRUE;
247 break;
248 }
249 }
250
251 /* close input file */
252 SCIPfclose(file);
253
254 /* return error if necessary */
255 if ( error )
256 return SCIP_READERROR;
257
258 return SCIP_OKAY;
259}
260
261
262/*
263 * Callback methods of reader
264 */
265
266/** copy method for reader plugins (called when SCIP copies plugins) */
267static
269{ /*lint --e{715}*/
270 assert(scip != NULL);
271 assert(reader != NULL);
273
274 /* call inclusion method of reader */
276
277 return SCIP_OKAY;
278}
279
280
281/** problem reading method of reader
282 *
283 * In order to determine the type of the file, we have to open it. Thus, it has to be opened
284 * twice. This might be removed, but is likely to not hurt the performance too much.
285 */
286static
288{ /*lint --e{715}*/
289 assert(reader != NULL);
291 assert(result != NULL);
292
294
296 {
297 SCIPerrorMessage("reading of bounds file is only possible after a problem was created\n");
298 return SCIP_READERROR;
299 }
300
302 {
303 SCIPerrorMessage("reading of bounds file is only possible during problem creation stage\n");
304 return SCIP_READERROR;
305 }
306
307 /* read bounds file */
309
311
312 return SCIP_OKAY;
313}
314
315/** outputs given bounds into a file stream */
316static
318 SCIP* scip, /**< SCIP data structure */
319 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
320 FILE* file, /**< file stream to print into, or NULL for stdout */
321 SCIP_Real lb, /**< lower bound */
322 SCIP_Real ub /**< upper bound */
323 )
324{
325 /* print lower bound */
326 if( SCIPisInfinity(scip, lb) )
327 SCIPmessageFPrintInfo(messagehdlr, file, "+inf ");
328 else if( SCIPisInfinity(scip, -lb) )
329 SCIPmessageFPrintInfo(messagehdlr, file, "-inf ");
330 else
331 SCIPmessageFPrintInfo(messagehdlr, file, "%.15" SCIP_REAL_FORMAT " ", lb);
332
333 /* print upper bound */
334 if( SCIPisInfinity(scip, ub) )
335 SCIPmessageFPrintInfo(messagehdlr, file, "+inf");
336 else if( SCIPisInfinity(scip, -ub) )
337 SCIPmessageFPrintInfo(messagehdlr, file, "-inf");
338 else
339 SCIPmessageFPrintInfo(messagehdlr, file, "%.15" SCIP_REAL_FORMAT, ub);
340}
341
342/** writes problem to file */
343static
345 SCIP* scip, /**< SCIP data structure */
346 FILE* file, /**< file stream to print into, or NULL for stdout */
347 SCIP_VAR** vars, /**< array with active variables ordered binary, integer, implicit, continuous */
348 int nvars, /**< number of active variables in the problem */
349 SCIP_RESULT* result /**< pointer to store the result of the file writing call */
350 )
351{
352 SCIP_MESSAGEHDLR* messagehdlr;
353 SCIP_Real lb;
354 SCIP_Real ub;
355 int i;
356
357 assert(result != NULL);
358
359 messagehdlr = SCIPgetMessagehdlr(scip);
361
362 if( nvars == 0 )
363 {
364 SCIPwarningMessage(scip, "Problem has no variables, no bounds written.\n");
365 return SCIP_OKAY;
366 }
367
368 for( i = 0; i < nvars; ++i )
369 {
370 SCIP_VAR* var;
371 const char* varname;
372
373 var = vars[i];
374 assert( var != NULL );
376
377 /* strip 't_' from varname */
379 {
380 varname = varname + 2;
381 }
382
383 SCIPinfoMessage(scip, file, "<%s> ", varname);
384
385 /* print global bounds for transformed variables, original bounds for original variables */
387 {
390 }
391 else
392 {
395 }
396
397 /* print bounds into the file */
398 printBounds(scip, messagehdlr, file, lb, ub);
399 SCIPmessageFPrintInfo(messagehdlr, file, "\n");
400 }
401
402 return SCIP_OKAY;
403}
404
405/** problem writing method of reader */
406static
408{ /*lint --e{715}*/
409 assert(reader != NULL);
411
413
414 return SCIP_OKAY;
415}
416
417/** destructor of reader to free reader data (called when SCIP is exiting) */
418static
420{
421 SCIP_READERDATA* readerdata;
422
424 readerdata = SCIPreaderGetData(reader);
425 assert(readerdata != NULL);
426 SCIPfreeBlockMemory(scip, &readerdata);
427
428 return SCIP_OKAY;
429}
430
431/*
432 * bnd file reader specific interface methods
433 */
434
435/** includes the bnd file reader in SCIP */
437 SCIP* scip /**< SCIP data structure */
438 )
439{
440 SCIP_READERDATA* readerdata;
442
443 /* create reader data */
444 SCIP_CALL( SCIPallocBlockMemory(scip, &readerdata) );
445
446 /* include reader */
448
449 /* set non fundamental callbacks via setter functions */
454
455 /* add bnd reader parameters */
457 "reading/bndreader/improveonly", "only use improving bounds",
458 &readerdata->improveonly, FALSE, DEFAULT_IMPROVEONLY, NULL, NULL) );
459
460 return SCIP_OKAY;
461}
#define NULL
Definition def.h:267
#define SCIP_MAXSTRLEN
Definition def.h:288
#define MIN(x, y)
Definition def.h:243
#define TRUE
Definition def.h:93
#define FALSE
Definition def.h:94
#define MAX(x, y)
Definition def.h:239
#define SCIP_REAL_FORMAT
Definition def.h:176
#define SCIP_CALL(x)
Definition def.h:374
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:436
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:492
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:557
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:4678
SCIP_Real SCIPvarGetLbOriginal(SCIP_VAR *var)
Definition var.c:18024
SCIP_Bool SCIPvarIsTransformed(SCIP_VAR *var)
Definition var.c:17561
SCIP_RETCODE SCIPchgVarUb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
Definition scip_var.c:4768
SCIP_RETCODE SCIPparseVarName(SCIP *scip, const char *str, SCIP_VAR **var, char **endptr)
Definition scip_var.c:533
SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
Definition var.c:18088
const char * SCIPvarGetName(SCIP_VAR *var)
Definition var.c:17419
SCIP_Real SCIPvarGetUbOriginal(SCIP_VAR *var)
Definition var.c:18044
SCIP_Bool SCIPvarIsTransformedOrigvar(SCIP_VAR *var)
Definition var.c:12861
SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
Definition var.c:18078
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition misc.c:10877
void SCIPprintSysError(const char *message)
Definition misc.c:10769
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:70
static SCIP_RETCODE readBounds(SCIP *scip, const char *fname, SCIP_READERDATA *readerdata)
Definition reader_bnd.c:86
#define READER_DESC
Definition reader_bnd.c:67
static void printBounds(SCIP *scip, SCIP_MESSAGEHDLR *messagehdlr, FILE *file, SCIP_Real lb, SCIP_Real ub)
Definition reader_bnd.c:317
#define READER_EXTENSION
Definition reader_bnd.c:68
#define READER_NAME
Definition reader_bnd.c:66
static SCIP_RETCODE SCIPwriteBnd(SCIP *scip, FILE *file, SCIP_VAR **vars, int nvars, SCIP_RESULT *result)
Definition reader_bnd.c:344
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
#define SCIP_DECL_READERWRITE(x)
struct SCIP_ReaderData SCIP_READERDATA
Definition type_reader.h:53
#define SCIP_DECL_READERREAD(x)
Definition type_reader.h:87
#define SCIP_DECL_READERCOPY(x)
Definition type_reader.h:62
#define SCIP_DECL_READERFREE(x)
Definition type_reader.h:71
@ 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
enum SCIP_Retcode SCIP_RETCODE
@ SCIP_STAGE_PROBLEM
Definition type_set.h:45