SCIP Doxygen Documentation
Loading...
Searching...
No Matches
reader_sch.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_sch.c
26 * @brief scheduling problem file reader for RCPSP/max format
27 * @author Stefan Heinz
28 *
29 * This reader is capabale of parsing resource-constrained project scheduling problem with minimal and maximal time lags
30 * (RCPSP/max) instances. The <a http://www.wior.uni-karlsruhe.de/LS_Neumann/Forschung/ProGenMax/rcpspmax.html">PSPlib</a>
31 * provides several instances set.
32 *
33 */
34
35/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
36
37#include <ctype.h>
38
39#include "reader_sch.h"
40#include "reader_sm.h"
41
43
44
45#define READER_NAME "schreader"
46#define READER_DESC "scheduling file reader for sch files (RCPSP/max format)"
47#define READER_EXTENSION "sch"
48
49
50#define SCH_MAX_LINELEN 65536 /**< size of the line buffer for reading or writing */
51
52/*
53 * Local methods
54 */
55
56static
58 SCIP* scip /**< SCIP data structure */
59 )
60{
61 SCIP_CONS* cons;
62 SCIP_VAR** vars;
63 SCIP_Real* bounds;
64 SCIP_BOUNDTYPE* boundtypes;
65 int nvars;
66 int v;
67
70
72 SCIP_CALL( SCIPallocBufferArray(scip, &boundtypes, nvars) );
73
74 for( v = 0; v < nvars; ++v )
75 {
76 bounds[v] = SCIPvarGetLbGlobal(vars[v]);
77 boundtypes[v] = SCIP_BOUNDTYPE_UPPER;
78 }
79
80 /* add a constraint that at least one jobs needs to start at its lower bound */
81 SCIP_CALL( SCIPcreateConsBounddisjunction(scip, &cons, "lowerbound", nvars, vars, boundtypes, bounds,
83
84 SCIP_CALL( SCIPaddCons(scip, cons) );
86
87 SCIPfreeBufferArray(scip, &boundtypes);
88 SCIPfreeBufferArray(scip, &bounds);
89
90 return SCIP_OKAY;
91}
92
93
94
95/** parse job id and check if only one job mode is present */
96static
98 SCIP* scip, /**< SCIP data structure */
99 const char* str, /**< string to search */
100 int* job, /**< pointer to store the parsed job id */
101 char** endptr /**< pointer to store the final string position if successfully parsed */
102 )
103{
104 int mode;
105
106 /* get job id */
107 if( !SCIPstrToIntValue(str, job, endptr) )
108 return SCIP_READERROR;
109
110 /* get job mode */
111 if( !SCIPstrToIntValue(*endptr, &mode, endptr) )
112 return SCIP_READERROR;
113
114 if( mode != 1 )
115 {
116 SCIPwarningMessage(scip, "jobs with different modes are not supported\n");
117 return SCIP_READERROR;
118 }
119
120 return SCIP_OKAY;
121}
122
123/** parse job and capacities details */
124static
126 SCIP* scip, /**< SCIP data structure */
127 SCIP_FILE* file, /**< file to parse */
128 int* lineno, /**< pointer to store line number of the file */
129 int** demands, /**< demand matrix resource job demand */
130 SCIP_DIGRAPH* precedencegraph, /**< direct graph to store the precedence conditions */
131 int* durations, /**< array to store the processing for each job */
132 int* capacities, /**< array to store the different capacities */
133 int njobs, /**< number of jobs to be parsed */
134 int nresources /**< number of capacities to be parsed */
135 )
136{
137 char buf[SCH_MAX_LINELEN];
138 char* endptr;
139 int j;
140
141 /* get data for each job including a dummy job at the beginning and a dummy job at the end */
142 for( j = 0; j < njobs; ++j )
143 {
144 if( NULL != SCIPfgets(buf, (int) sizeof(buf), file) )
145 {
146 int* successors;
147 int distance;
148 int nsuccessors;
149 int job;
150 int s;
151
152 /* get job id and check if only one mode is present */
153 SCIP_CALL( getJobId(scip, buf, &job, &endptr) );
154
155 SCIPdebugMessage("job %d -> ", j);
156
157 /* get number of direct successors */
158 if( !SCIPstrToIntValue(endptr, &nsuccessors, &endptr) )
159 return SCIP_READERROR;
160
161 /* allocate buffer to temporarily collect the successors */
162 SCIP_CALL( SCIPallocBufferArray(scip, &successors, nsuccessors) );
163
164 /* parse successor job ids */
165 for( s = 0; s < nsuccessors; ++s )
166 {
167 if( !SCIPstrToIntValue(endptr, &successors[s], &endptr) )
168 return SCIP_READERROR;
169 }
170
171 /* parse distances between the job and its successor and add the arc with their data to the precedence graph */
172 for( s = 0; s < nsuccessors; ++s )
173 {
174 char token[SCIP_MAXSTRLEN];
175 char* tmpptr;
176
177 SCIPstrCopySection(endptr, '[', ']', token, SCIP_MAXSTRLEN, &endptr);
178
179 if( SCIPstrToIntValue(token, &distance, &tmpptr) )
180 {
181 SCIP_CALL( SCIPdigraphAddArc(precedencegraph, job, successors[s], (void*)(size_t)distance) ); /*lint !e571*/
182
183 SCIPdebugPrintf(" %d[%d] ", successors[s], distance);
184 }
185 else
186 return SCIP_READERROR;
187 }
188
189 SCIPdebugPrintf("\n");
190
191 /* free the buffers */
192 SCIPfreeBufferArray(scip, &successors);
193 }
194 else
195 return SCIP_READERROR;
196
197 (*lineno)++;
198 }
199
200 /* get data for each job including a dummy job at the beginning and a dummy job at the end */
201 for( j = 0; j < njobs; ++j )
202 {
203 if( NULL != SCIPfgets(buf, (int) sizeof(buf), file) )
204 {
205 int job;
206 int r;
207
208 /* get job id and check if only one mode is present */
209 SCIP_CALL( getJobId(scip, buf, &job, &endptr) );
210
211 /* get processing time */
212 if( !SCIPstrToIntValue(endptr, &durations[job], &endptr) )
213 return SCIP_READERROR;
214
215 SCIPdebugMessage("job %d has a processing times: %d\n", job, durations[job]);
216
217 for( r = 0; r < nresources; ++r )
218 {
219 if( !SCIPstrToIntValue(endptr, &demands[job][r], &endptr) )
220 return SCIP_READERROR;
221 }
222 }
223 else
224 return SCIP_READERROR;
225
226 (*lineno)++;
227 }
228
229 /* get resources capacities */
230 if( nresources > 0 && NULL != SCIPfgets(buf, (int) sizeof(buf), file) )
231 {
232 int r;
233
234 SCIPdebugMessage("line %d %s", *lineno, buf);
235
236 if( !SCIPstrToIntValue(buf, &capacities[0], &endptr) )
237 return SCIP_READERROR;
238
239 SCIPdebugMessage("paresed capacities: <%d>", capacities[0]);
240
241 for( r = 1; r < nresources; ++r )
242 {
243 if( !SCIPstrToIntValue(endptr, &capacities[r], &endptr) )
244 return SCIP_READERROR;
245
246 SCIPdebugPrintf(", <%d>", capacities[r]);
247 }
248
249 SCIPdebugPrintf("\n");
250 }
251 else
252 return SCIP_READERROR;
253
254 (*lineno)++;
255
256 return SCIP_OKAY;
257}
258
259/** read file and create problem */
260static
262 SCIP* scip, /**< SCIP data structure */
263 SCIP_FILE* file, /**< file to pares */
264 const char* filename /**< name of input file */
265 )
266{
267 SCIP_RETCODE retcode;
268 char buf[SCH_MAX_LINELEN];
269 SCIP_DIGRAPH* precedencegraph;
270 int** demands;
271 int* durations;
272 int* capacities;
273 int lineno;
274 int njobs;
275 int nresources;
276 int j;
277
278 assert(scip != NULL);
279 assert(file != NULL);
280 assert(filename != NULL);
281
282 lineno = 0;
283
284 /* get number of jobs and resources */
285 if( NULL != SCIPfgets(buf, (int) sizeof(buf), file) )
286 {
287 char* endptr;
288 int value;
289
290 lineno++;
291
292 if( !SCIPstrToIntValue(buf, &value, &endptr) )
293 return SCIP_READERROR;
294
295 /* note that this format includes two dummy jobs */
296 njobs = value + 2;
297
298 /* get number of resources */
299 if( !SCIPstrToIntValue(endptr, &nresources, &endptr) )
300 return SCIP_READERROR;
301 }
302 else
303 return SCIP_READERROR;
304
305 SCIP_CALL( SCIPallocBufferArray(scip, &capacities, nresources) );
306 SCIP_CALL( SCIPallocBufferArray(scip, &durations, njobs) );
307 SCIP_CALL( SCIPallocBufferArray(scip, &demands, njobs) );
308
309 for( j = 0; j < njobs; ++j )
310 {
311 SCIP_CALL( SCIPallocBufferArray(scip, &demands[j], nresources) ); /*lint !e866*/
312 BMSclearMemoryArray(demands[j], nresources); /*lint !e866*/
313 }
314
315 SCIP_CALL( SCIPcreateDigraph(scip, &precedencegraph, njobs) );
316
317 SCIPdebugMessage("problem has <%d> jobs and <%d> resources\n", njobs, nresources);
318
319 retcode = parseDetails(scip, file, &lineno, demands, precedencegraph, durations, capacities, njobs, nresources);
320
321 if( retcode == SCIP_OKAY )
322 {
323 SCIP_CALL( SCIPcreateSchedulingProblem(scip, filename, NULL, NULL, demands,
324 precedencegraph, durations, capacities, njobs, nresources, FALSE) );
325 }
326
327 /* add constraint that at least one job needs to start on its lower bound */
329
330 /* free the precedence graph */
331 SCIPdigraphFree(&precedencegraph);
332
333 /* free buffer before evaluating the retcode */
334 for( j = njobs - 1; j >= 0; --j )
335 {
336 SCIPfreeBufferArray(scip, &demands[j]);
337 }
338 SCIPfreeBufferArray(scip, &demands);
339 SCIPfreeBufferArray(scip, &durations);
340 SCIPfreeBufferArray(scip, &capacities);
341
342 SCIP_CALL( retcode );
343
344 return SCIP_OKAY;
345}
346
347
348/*
349 * Callback methods of reader
350 */
351
352/** copy method for reader plugins (called when SCIP copies plugins) */
353static
355{ /*lint --e{715}*/
356 assert(scip != NULL);
357 assert(reader != NULL);
358
360
361 /* call inclusion method of reader handler */
363
364 return SCIP_OKAY;
365}/*lint !e830*/
366
367/** problem reading method of reader */
368static
370{ /*lint --e{715}*/
371 SCIP_FILE* file;
372 SCIP_RETCODE retcode;
373
374 if( NULL == (file = SCIPfopen(filename, "r")) )
375 {
376 SCIPerrorMessage("cannot open file <%s> for reading\n", filename);
377 SCIPprintSysError(filename);
378 return SCIP_NOFILE;
379 }
380
381 /* read file */
382 retcode = readFile(scip, file, filename);
383
384 /* close file */
385 SCIPfclose(file);
386
387 /* check retcode after the file was closed */
388 SCIP_CALL( retcode );
389
390 (*result) = SCIP_SUCCESS;
391
392 return SCIP_OKAY;
393}/*lint !e830*/
394
395#ifdef SCIP_DISABLED_CODE
396/** destructor of reader to free user data (called when SCIP is exiting) */
397#define readerFreeSch NULL
398
399/** problem writing method of reader */
400#define readerWriteSch NULL
401#endif
402
403/*
404 * reader specific interface methods
405 */
406
407/** includes the sch file reader in SCIP */
409 SCIP* scip /**< SCIP data structure */
410 )
411{
412 SCIP_READERDATA* readerdata;
413 SCIP_READER* reader;
414
415 /* create sch reader data */
416 readerdata = NULL;
417
418 /* include sch reader */
420 assert(reader != NULL);
421
422 SCIP_CALL( SCIPsetReaderCopy(scip, reader, readerCopySch) );
423 SCIP_CALL( SCIPsetReaderRead(scip, reader, readerReadSch) );
424
425 /* add reader parameters */
427 "reading/"READER_NAME"/mipmodel", "create MIP model?",
428 NULL, FALSE, FALSE, NULL, NULL) );
429
430 return SCIP_OKAY;
431}
constraint handler for bound disjunction constraints
#define NULL
Definition def.h:257
#define SCIP_MAXSTRLEN
Definition def.h:278
#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 SCIP_CALL(x)
Definition def.h:364
SCIP_FILE * SCIPfopen(const char *path, const char *mode)
Definition fileio.c:153
int SCIPfclose(SCIP_FILE *fp)
Definition fileio.c:232
char * SCIPfgets(char *s, int size, SCIP_FILE *stream)
Definition fileio.c:200
SCIP_RETCODE SCIPcreateConsBounddisjunction(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_BOUNDTYPE *boundtypes, SCIP_Real *bounds, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
SCIP_RETCODE SCIPdigraphAddArc(SCIP_DIGRAPH *digraph, int startnode, int endnode, void *data)
Definition misc.c:7739
void SCIPdigraphFree(SCIP_DIGRAPH **digraph)
Definition misc.c:7645
SCIP_RETCODE SCIPcreateDigraph(SCIP *scip, SCIP_DIGRAPH **digraph, int nnodes)
int SCIPgetNVars(SCIP *scip)
Definition scip_prob.c:2246
SCIP_RETCODE SCIPaddCons(SCIP *scip, SCIP_CONS *cons)
Definition scip_prob.c:3274
SCIP_VAR ** SCIPgetVars(SCIP *scip)
Definition scip_prob.c:2201
void SCIPwarningMessage(SCIP *scip, const char *formatstr,...)
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
SCIP_RETCODE SCIPreleaseCons(SCIP *scip, SCIP_CONS **cons)
Definition scip_cons.c:1173
#define SCIPallocBufferArray(scip, ptr, num)
Definition scip_mem.h:124
#define SCIPfreeBufferArray(scip, ptr)
Definition scip_mem.h:136
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_RETCODE SCIPsetReaderRead(SCIP *scip, SCIP_READER *reader,)
const char * SCIPreaderGetName(SCIP_READER *reader)
Definition reader.c:700
SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
Definition var.c:24152
SCIP_Bool SCIPstrToIntValue(const char *str, int *value, char **endptr)
Definition misc.c:10924
void SCIPstrCopySection(const char *str, char startchar, char endchar, char *token, int size, char **endptr)
Definition misc.c:10985
void SCIPprintSysError(const char *message)
Definition misc.c:10719
return SCIP_OKAY
int r
assert(minobj< SCIPgetCutoffbound(scip))
int nvars
static SCIP_VAR ** vars
#define BMSclearMemoryArray(ptr, num)
Definition memory.h:130
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 SCIPdebugPrintf
Definition pub_message.h:99
#define READER_DESC
Definition reader_bnd.c:62
#define READER_EXTENSION
Definition reader_bnd.c:63
#define READER_NAME
Definition reader_bnd.c:61
static SCIP_RETCODE addLowerboundCons(SCIP *scip)
Definition reader_sch.c:57
static SCIP_RETCODE readFile(SCIP *scip, SCIP_FILE *file, const char *filename)
Definition reader_sch.c:261
static SCIP_RETCODE getJobId(SCIP *scip, const char *str, int *job, char **endptr)
Definition reader_sch.c:97
#define SCH_MAX_LINELEN
Definition reader_sch.c:50
SCIP_RETCODE SCIPincludeReaderSch(SCIP *scip)
Definition reader_sch.c:408
static SCIP_RETCODE parseDetails(SCIP *scip, SCIP_FILE *file, int *lineno, int **demands, SCIP_DIGRAPH *precedencegraph, int *durations, int *capacities, int njobs, int nresources)
Definition reader_sch.c:125
scheduling problem file reader for RCPSP/max format
SCIP_RETCODE SCIPcreateSchedulingProblem(SCIP *scip, const char *problemname, const char **jobnames, const char **resourcenames, int **demands, SCIP_DIGRAPH *precedencegraph, int *durations, int *capacities, int njobs, int nresources, SCIP_Bool initialize)
Definition reader_sm.c:746
scheduling problem file reader for RCPSP format
struct SCIP_Cons SCIP_CONS
Definition type_cons.h:63
@ SCIP_BOUNDTYPE_UPPER
Definition type_lp.h:58
enum SCIP_BoundType SCIP_BOUNDTYPE
Definition type_lp.h:60
struct SCIP_Digraph SCIP_DIGRAPH
Definition type_misc.h:145
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
@ SCIP_SUCCESS
Definition type_result.h:58
@ SCIP_NOFILE
@ SCIP_READERROR
@ SCIP_INVALIDCALL
enum SCIP_Retcode SCIP_RETCODE
struct Scip SCIP
Definition type_scip.h:39
struct SCIP_Var SCIP_VAR
Definition type_var.h:166