Scippy

SCIP

Solving Constraint Integer Programs

reader_rpa.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_rpa.c
26 * @brief Ringpacking problem reader
27 * @author Benjamin Mueller
28 *
29 * This file implements the reader/parser used to read the ringpacking input data. For more details see \ref RINGPACKING_READER.
30 *
31 * @page RINGPACKING_READER Parsing the input format and creating the problem
32 *
33 * In the <code>data</code> directory you find a few data files which contain each one ringpacking problem. They have
34 * the following structure. In the first line the name of the instance is stated. In the second line you find three
35 * integer numbers. The first one gives you the number of different ring types \f$T\f$, the second and third the width
36 * and height of the rectangles, respectively. The remaining lines each contain one integer and two floats which
37 * together specify one ring type. The integer gives the demand and the floats correspond to the inner and outer radius
38 * of the respective type.
39 *
40 * For parsing that data, we implemented a reader plugin for \SCIP. A reader has several callback methods and at least
41 * one interface methods (the one including the reader into \SCIP). For our purpose we only implemented the \ref
42 * READERREAD "READERREAD" callback and the interface method which adds the reader plugin to \SCIP.
43 *
44 * @section RINGPACKING_READERINCLUDE The SCIPincludeReaderRpa() interface method
45 *
46 * The interface method <code>SCIPincludeReaderRpa()</code> is called to add the reader plugin to \SCIP (see
47 * cmain.c). This means \SCIP gets informed that this reader is available for reading input files. Therefore, the
48 * function <code>SCIPincludeReader()</code> is called within this method which passes all necessary information of the
49 * reader to SCIP. This information includes the name of the reader, a description, and the file extension for which the
50 * file reader is in charge. In our case we selected the file extension "rpa". This means that all files which have
51 * this file extension are passed to our reader for parsing. Besides these information the call
52 * <code>SCIPincludeReader()</code> also passes for each callback of the reader a function pointers
53 * (some of them might be NULL pointers). These function pointers are used by \SCIP to run the reader. For more
54 * information about all available reader callbacks we refer to the \ref READER "How to add file readers" tutorial. In
55 * the remaining section we restrict ourself to the callback <code>READERREAD</code> which is the only one we
56 * implemented for the ringpacking example. All other callbacks are not required for this example.
57 *
58 * @section RINGPACKING_READERREAD The READERREAD callback method
59 *
60 * The READERREAD callback is in charge of parsing a file and creating the problem. To see the list of arguments this
61 * functions gets to see the file type_reader.h in the source of \SCIP. The following arguments are of interest in our
62 * case. First of all the \SCIP pointer, the file name, and the SCIP_RESULT pointer. The \SCIP pointer gives us the
63 * current environment. The file name states the file which we should open and parse. Last but not least, the SCIP_RESULT
64 * pointer is required to tell \SCIP if the parsing process was successfully or not. Note that in type_reader.h you also
65 * find a list of allowable result values for the SCIP_RESULT pointer and the <code>SCIP_RETCODE</code> which is the
66 * return value of this function.
67 *
68 * @subsection RINGPACKING_PARSING Parsing the problem
69 *
70 * The file can be opened and parsed with your favorite methods. In this case we are using the functionality provided by
71 * \SCIP since this has some nice side effects. We are using the function SCIPfopen() which can besides standard
72 * files also handle files which are packed. To find all files related to the parsing of a file, we refer to the file pub_misc.h
73 * in the source of SCIP. Parsing the data out of the file is not that hard. Please look at the code and comments
74 * therein for more details.
75 *
76 * @subsection RINGPACKING_CREATING Creating the problem
77 *
78 * After parsing the file the final task for the reader is to create the problem. In our case, we pass the collected data
79 * to the \ref probdata_rpa.h "main problem data plugin". For this, we use the interface methods
80 * SCIPprobdataCreate() which is provided by the
81 * problem data plugin (see probdata_rpa.c). After that, the reader sets the result value for the SCIP_RESULT
82 * pointer to <code>SCIP_SUCCESS</code> and returns with a proper <code>SCIP_RETCODE</code>.
83 *
84 */
85
86/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
87
88#include <assert.h>
89#include <string.h>
90
91#include "reader_rpa.h"
92#include "probdata_rpa.h"
93
94/**@name Reader properties
95 *
96 * @{
97 */
98
99#define READER_NAME "rpareader"
100#define READER_DESC "file reader for ringpacking data format"
101#define READER_EXTENSION "rpa"
102
103/**@} */
104
105/* default values of parameters */
106#define DEFAULT_VERIFICATION_NLPTILIMSOFT 1e+20 /**< soft time limit for each verification NLP */
107#define DEFAULT_VERIFICATION_NLPNODELIMSOFT 100L /**< soft node limit for each verification NLP */
108#define DEFAULT_VERIFICATION_HEURTILIMSOFT 1e+20 /**< soft time limit for heuristic verification */
109#define DEFAULT_VERIFICATION_HEURITERLIMSOFT 100 /**< soft iteration limit for each heuristic verification */
110#define DEFAULT_VERIFICATION_TOTALTILIMSOFT 1e+20 /**< total time limit for all verification problems during the enumeration */
111
112
113/**@name Callback methods
114 *
115 * @{
116 */
117
118/** problem reading method of reader */
119static
121{ /*lint --e{715}*/
122 SCIP_FILE* file;
123 SCIP_Real* rints;
124 SCIP_Real* rexts;
125 int* demands;
126 SCIP_Bool error;
127 char name[SCIP_MAXSTRLEN];
128 char buffer[SCIP_MAXSTRLEN];
129 SCIP_Real width;
130 SCIP_Real height;
131 SCIP_Real r_int;
132 SCIP_Real r_ext;
133 int demand;
134 int ntypes;
135 int nread;
136 int lineno;
137 int i;
138
139 *result = SCIP_DIDNOTRUN;
140 width = -1.0;
141 height = -1.0;
142
143 /* open file */
144 file = SCIPfopen(filename, "r");
145 if( file == NULL )
146 {
147 SCIPerrorMessage("cannot open file <%s> for reading\n", filename);
148 SCIPprintSysError(filename);
149 return SCIP_NOFILE;
150 }
151
152 lineno = 0;
153 sprintf(name, "++ uninitialized ++");
154 ntypes = 0;
155
156 /* read problem dimension */
157 if( !SCIPfeof(file) )
158 {
159 /* get next line */
160 if( SCIPfgets(buffer, (int)sizeof(buffer), file) == NULL )
161 return SCIP_READERROR;
162 lineno++;
163
164 /* parse instance name line */
165 nread = sscanf(buffer, "%s", name);
166 if( nread != 1 )
167 {
168 SCIPwarningMessage(scip, "invalid input line %d in file <%s>: <%s>\n", lineno, filename, buffer);
169 return SCIP_READERROR;
170 }
171
172 /* get next line */
173 if( SCIPfgets(buffer, (int)sizeof(buffer), file) == NULL )
174 return SCIP_READERROR;
175 lineno++;
176
177 /* parse dimension line */
178 nread = sscanf(buffer, "%d %" SCIP_REAL_FORMAT " %" SCIP_REAL_FORMAT "\n", &ntypes, &width, &height);
179 if( nread < 3 )
180 {
181 SCIPwarningMessage(scip, "invalid input line %d in file <%s>: <%s>\n", lineno, filename, buffer);
182 return SCIP_READERROR;
183 }
184 }
185
186 SCIPdebugMessage("instance name = %s\n", name);
187 SCIPdebugMessage("width = %e height = %e\n", MAX(width,height), MIN(width,height));
188
189 /* allocate buffer memory for storing the demands, rints, rexts */
190 SCIP_CALL( SCIPallocBufferArray(scip, &demands, ntypes) );
191 SCIP_CALL( SCIPallocBufferArray(scip, &rints, ntypes) );
192 SCIP_CALL( SCIPallocBufferArray(scip, &rexts, ntypes) );
193
194 /* ring types */
195 r_int = 0.0;
196 r_ext = 0.0;
197 demand = 0;
198 i = 0;
199 error = FALSE;
200
201 while( !SCIPfeof(file) && !error )
202 {
203 /* get next line */
204 if( SCIPfgets(buffer, (int)sizeof(buffer), file) == NULL )
205 break;
206 lineno++;
207
208 /* parse the line */
209 nread = sscanf(buffer, "%d %" SCIP_REAL_FORMAT " %" SCIP_REAL_FORMAT "\n", &demand, &r_int, &r_ext);
210 if( nread == 0 )
211 {
212 SCIPwarningMessage(scip, "invalid input line %d in file <%s>: <%s>\n", lineno, filename, buffer);
213 error = TRUE;
214 break;
215 }
216
217 if( r_int > r_ext )
218 {
219 SCIPwarningMessage(scip, "invalid input line %d in file <%s>: internal radius is greater than the external one\n", lineno, filename);
220 error = TRUE;
221 break;
222 }
223
224 if( demand <= 0 )
225 {
226 SCIPwarningMessage(scip, "invalid input line %d in file <%s>: demand has to be positive\n", lineno, filename);
227 error = TRUE;
228 break;
229 }
230
231 demands[i] = demand;
232 rints[i] = r_int;
233 rexts[i] = r_ext;
234 ++i;
235
236 if( i == ntypes )
237 break;
238 }
239
240 if( i < ntypes )
241 {
242 SCIPwarningMessage(scip, "found %d different types of rings, needed %d\n", i, ntypes);
243 error = TRUE;
244 }
245
246 if( !SCIPisPositive(scip, width) || !SCIPisPositive(scip, height) )
247 {
248 SCIPwarningMessage(scip, "non-positive width and height = (%f, %f)!\n", width, height);
249 error = TRUE;
250 }
251
252 if( !error )
253 {
254 /* sort rings by their external radii */
255 SCIPsortDownRealRealInt(rexts, rints, demands, ntypes);
256
257 /* create and set problem data */
258 SCIP_CALL( SCIPprobdataCreate(scip, filename, demands, rints, rexts, ntypes, MAX(width,height), MIN(width,height)) );
260 }
261
262 (void)SCIPfclose(file);
263 SCIPfreeBufferArray(scip, &rints);
264 SCIPfreeBufferArray(scip, &rexts);
265 SCIPfreeBufferArray(scip, &demands);
266
267 if( error )
268 return SCIP_READERROR;
269
270 *result = SCIP_SUCCESS;
271
272 return SCIP_OKAY;
273}
274
275/**@} */
276
277
278/**@name Interface methods
279 *
280 * @{
281 */
282
283/** includes the rpa file reader in SCIP */
285 SCIP* scip /**< SCIP data structure */
286 )
287{
288 SCIP_READERDATA* readerdata;
289 SCIP_READER* reader;
290
291 /* create ringpacking reader data */
292 readerdata = NULL;
293
294 /* include ringpacking reader */
296 assert(reader != NULL);
297
298 /* add soft verification parameters */
299 SCIP_CALL( SCIPaddRealParam(scip, "ringpacking/verification/nlptilimsoft", "soft time limit for verification NLP",
301
302 SCIP_CALL( SCIPaddLongintParam(scip, "ringpacking/verification/nlpnodelimsoft",
303 "soft node limit for verification NLP", NULL, FALSE,
305
306 SCIP_CALL( SCIPaddRealParam(scip, "ringpacking/verification/heurtilimsoft",
307 "soft time limit for heuristic verification", NULL, FALSE,
309
310 SCIP_CALL( SCIPaddIntParam(scip, "ringpacking/verification/heuriterlimsoft",
311 "soft iteration limit for heuristic verification", NULL, FALSE,
313
314 SCIP_CALL( SCIPaddRealParam(scip, "ringpacking/verification/totaltilimsoft",
315 "total time limit for all verification problems during the enumeration", NULL, FALSE,
317
318 SCIP_CALL( SCIPsetReaderRead(scip, reader, readerReadRpa) );
319
320 return SCIP_OKAY;
321}
322
323/**@} */
#define NULL
Definition: def.h:267
#define SCIP_MAXSTRLEN
Definition: def.h:288
#define SCIP_REAL_MAX
Definition: def.h:174
#define SCIP_Bool
Definition: def.h:91
#define MIN(x, y)
Definition: def.h:243
#define SCIP_Real
Definition: def.h:173
#define TRUE
Definition: def.h:93
#define FALSE
Definition: def.h:94
#define MAX(x, y)
Definition: def.h:239
#define SCIP_LONGINT_MAX
Definition: def.h:159
#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
void SCIPwarningMessage(SCIP *scip, const char *formatstr,...)
Definition: scip_message.c:120
SCIP_RETCODE SCIPaddLongintParam(SCIP *scip, const char *name, const char *desc, SCIP_Longint *valueptr, SCIP_Bool isadvanced, SCIP_Longint defaultvalue, SCIP_Longint minvalue, SCIP_Longint maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition: scip_param.c:111
SCIP_RETCODE SCIPaddIntParam(SCIP *scip, const char *name, const char *desc, int *valueptr, SCIP_Bool isadvanced, int defaultvalue, int minvalue, int maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition: scip_param.c:83
SCIP_RETCODE SCIPaddRealParam(SCIP *scip, const char *name, const char *desc, SCIP_Real *valueptr, SCIP_Bool isadvanced, SCIP_Real defaultvalue, SCIP_Real minvalue, SCIP_Real maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition: scip_param.c:139
#define SCIPallocBufferArray(scip, ptr, num)
Definition: scip_mem.h:124
#define SCIPfreeBufferArray(scip, ptr)
Definition: scip_mem.h:136
SCIP_RETCODE SCIPincludeReaderBasic(SCIP *scip, SCIP_READER **readerptr, const char *name, const char *desc, const char *extension, SCIP_READERDATA *readerdata)
Definition: scip_reader.c:109
SCIP_RETCODE SCIPsetReaderRead(SCIP *scip, SCIP_READER *reader, SCIP_DECL_READERREAD((*readerread)))
Definition: scip_reader.c:195
SCIP_Bool SCIPisPositive(SCIP *scip, SCIP_Real val)
void SCIPsortDownRealRealInt(SCIP_Real *realarray1, SCIP_Real *realarray2, int *intarray, int len)
void SCIPprintSysError(const char *message)
Definition: misc.c:10769
SCIP_RETCODE SCIPprobdataCreate(SCIP *scip, const char *probname, int *demands, SCIP_Real *rints, SCIP_Real *rexts, int ntypes, SCIP_Real width, SCIP_Real height)
SCIP_RETCODE SCIPprobdataSetupProblem(SCIP *scip)
Problem data for ringpacking problem.
struct SCIP_File SCIP_FILE
Definition: pub_fileio.h:43
#define SCIPerrorMessage
Definition: pub_message.h:64
#define SCIPdebugMessage
Definition: pub_message.h:96
#define DEFAULT_VERIFICATION_HEURITERLIMSOFT
Definition: reader_rpa.c:109
#define DEFAULT_VERIFICATION_TOTALTILIMSOFT
Definition: reader_rpa.c:110
#define READER_DESC
Definition: reader_rpa.c:100
SCIP_RETCODE SCIPincludeReaderRpa(SCIP *scip)
Definition: reader_rpa.c:284
#define DEFAULT_VERIFICATION_HEURTILIMSOFT
Definition: reader_rpa.c:108
#define READER_EXTENSION
Definition: reader_rpa.c:101
#define DEFAULT_VERIFICATION_NLPTILIMSOFT
Definition: reader_rpa.c:106
#define READER_NAME
Definition: reader_rpa.c:99
static SCIP_DECL_READERREAD(readerReadRpa)
Definition: reader_rpa.c:120
#define DEFAULT_VERIFICATION_NLPNODELIMSOFT
Definition: reader_rpa.c:107
struct SCIP_ReaderData SCIP_READERDATA
Definition: type_reader.h:53
@ SCIP_DIDNOTRUN
Definition: type_result.h:42
@ SCIP_SUCCESS
Definition: type_result.h:58
@ SCIP_NOFILE
Definition: type_retcode.h:47
@ SCIP_READERROR
Definition: type_retcode.h:45
@ SCIP_OKAY
Definition: type_retcode.h:42
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:63