Scippy

SCIP

Solving Constraint Integer Programs

reader_scflp.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_scflp.c
26 * @brief SCFLP reader file reader
27 * @author Stephen J. Maher
28 *
29 * This file implements the reader/parser used to read the CAP input data and builds a SCFLP instance. For more details
30 * see \ref SCFLP_READER.
31 *
32 * @page SCFLP_READER Parsing the input format
33 *
34 * In the <code>data</code> directory you find a few data files which contain each one CAP problem. These data
35 * files have the following structure:
36 * - The first line specifies the number of facilities (n) and the number of customers (m).
37 * - The next n lines specifies for each facility the setup cost and propduction capacity.
38 * - The following lines state the parameters for each of the customers.
39 * - First, the demand of customer is given.
40 * - The next set of lines states the transportation cost from each facility to the customer. Each line contains 7
41 * facilities, so there are ceil(n/7) lines for the transportation costs for each customer.
42 *
43 * For parsing that data, we implemented a reader plugin for \SCIP. A reader has several callback methods and at least
44 * one interface methods (the one including the reader into \SCIP). For our purpose we only implemented the \ref
45 * READERREAD callback and the interface method which adds the reader plugin to \SCIP.
46 *
47 * @section SCFLP_READERINCLUDE The SCIPincludeReaderScflp() interface method
48 *
49 * The interface method <code>SCIPincludeReaderScflp()</code> is called to add the reader plugin to \SCIP (see
50 * cmain.c). This means \SCIP gets informed that this reader is available for reading input files. Therefore, the
51 * function <code>SCIPincludeReader()</code> is called within this method which passes all necessary information of the
52 * reader to SCIP. This information includes the name of the reader, a description, and the file extension for which the
53 * file reader is in charge. In our case we selected the file extension "cap". This means that all files which have
54 * this file extension are passed to our reader for parsing. Besides these information the call
55 * <code>SCIPincludeReader()</code> also passes for each callback of the reader a function pointers
56 * (some of them might be NULL pointers). These function
57 * pointers are used by \SCIP to run the reader. For more information about all available reader callbacks we refer to
58 * the \ref READER "How to add file readers" tutorial. In the remaining section
59 * we restrict ourself to the callback <code>READERREAD</code> which is the only one we implemented for the SCFLP
60 * example. All other callbacks are not required for this example.
61 *
62 * @section SCFLP_READERREAD The READERREAD callback method
63 *
64 * The READERREAD callback is in charge of parsing a file and creating the problem. To see the list of arguments this
65 * functions gets see the file type_reader.h in the source of \SCIP. The following arguments are of interest in our
66 * case. First of all the \SCIP pointer, the file name, and the SCIP_RESULT pointer. The \SCIP pointer gives us the
67 * current environment. The file name states the file which we should open and parse. Last but not least, the SCIP_RESULT
68 * pointer is required to tell \SCIP if the parsing process was successfully or
69 * not. Note that in type_reader.h you also find a list of allowable result values for the SCIP_RESULT pointer and the
70 * <code>SCIP_RETCODE</code> which is the return value of this function.
71 *
72 * In the READERREAD callback, the scenarios for the stochastic program are generated. A scenario represents a different
73 * realisation of demand for each customer. The scenarios are generated by sampling demands from a normal distribution
74 * with a mean given by the deterministic demand and the standard deviation sampled from a uniform distribution with the
75 * range [0.1*mean, 0.3*mean]. The number of scenarios can be set using a runtime parameter.
76 *
77 * @subsection SCFLP_PARSING Parsing the problem
78 *
79 * The file can be opened and parsed with your favorite methods. In this case we are using the functionality provided by
80 * \SCIP since this has some nice side effects. We are using the function SCIPfopen() which can besides standard
81 * 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
82 * in the source of SCIP. Parsing the data out of the file is not that hard. Please look at the code and comments
83 * therein for more details.
84 *
85 * @subsection SCFLP_CREATING Creating the problem
86 *
87 * After parsing the file the final task for the reader is to create the problem. In our case, we pass the collected data
88 * to the \ref probdata_scflp.h "main problem data plugin". For this, we use the interface methods
89 * SCIPprobdataCreate() which is provided by the
90 * problem data plugin (see probdata_scflp.c). After that, the reader sets the result value for the SCIP_RESULT
91 * pointer to <code>SCIP_SUCCESS</code> and returns with a proper <code>SCIP_RETCODE</code>.
92 */
93
94/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
95
96#include <assert.h>
97#include <string.h>
98#include <math.h>
99#include <stdlib.h>
100
101#include "probdata_scflp.h"
102#include "reader_scflp.h"
103
104/**@name Reader properties
105 *
106 * @{
107 */
108
109#define READER_NAME "scflpreader"
110#define READER_DESC "file reader for CAP data format and creates a SCFLP instance"
111#define READER_EXTENSION "cap"
112
113
114#define DEFAULT_USEBENDERS TRUE
115#define DEFAULT_NUMSCENARIOS 250
116#define DEFAULT_RANDOMSEED 1
117#define DEFAULT_QUADCOSTS FALSE /**< should the problem be formulated with quadratic costs */
118
119
120#define MAXNCOSTS 7
121
122struct SCIP_ReaderData
123{
124 SCIP_Bool usebenders; /**< should Benders' decomposition be used to solve the problem */
125 int nscenarios; /**< the number of scenarios */
126 int randomseed; /**< the random seed used to generate the scenarios */
127 SCIP_Bool quadcosts; /**< should the problem be formulated with quadratic costs */
128};
129
130/**@} */
131
132/** generates a normally distributed random number */
133static
135 SCIP_RANDNUMGEN* randomgen, /**< the random number generator */
136 SCIP_Real mean, /**< the mean of the normal distribution */
137 SCIP_Real stdDev, /**< the standard deviation of the normal distribution */
138 SCIP_Real* spare, /**< the spare value that has been collected */
139 SCIP_Bool* hasspare /**< whether a spare value exists */
140 )
141{
142 SCIP_Real u;
143 SCIP_Real v;
144 SCIP_Real s;
145
146 /* if a spare exists, then it is returned */
147 if( (*hasspare) )
148 {
149 (*hasspare) = FALSE;
150 return mean + stdDev * (*spare);
151 }
152
153 (*hasspare) = TRUE;
154 do {
155 u = SCIPrandomGetReal(randomgen, 0.0, 1.0);
156 v = SCIPrandomGetReal(randomgen, 0.0, 1.0);
157 s = u * u + v * v;
158 }
159 while( (s >= 1.0) || (s == 0.0) );
160
161 s = sqrt(-2.0 * log(s) / s);
162 (*spare) = v * s;
163
164 return mean + stdDev * u * s;
165}
166
167
168/** creates the reader data */
169static
171 SCIP* scip, /**< SCIP data structure */
172 SCIP_READERDATA** readerdata /**< pointer to store the reader data */
173 )
174{
175 assert(scip != NULL);
176 assert(readerdata != NULL);
177
178 SCIP_CALL( SCIPallocBlockMemory(scip, readerdata) );
179 (*readerdata)->usebenders = TRUE;
180
181 return SCIP_OKAY;
182}
183
184/** frees the reader data */
185static
187 SCIP* scip, /**< SCIP data structure */
188 SCIP_READERDATA** readerdata /**< pointer to store the reader data */
189 )
190{
191 assert(scip != NULL);
192 assert(readerdata != NULL);
193 assert(*readerdata != NULL);
194
195 SCIPfreeBlockMemory(scip, readerdata);
196
197 return SCIP_OKAY;
198}
199
200
201/**@name Callback methods
202 *
203 * @{
204 */
205
206/** destructor of reader to free user data (called when SCIP is exiting)*/
207static
208SCIP_DECL_READERFREE(readerFreeScflp)
209{
210 SCIP_READERDATA* readerdata;
211
212 assert(scip != NULL);
213 assert(reader != NULL);
214
215 readerdata = SCIPreaderGetData(reader);
216
217 SCIP_CALL( readerdataFree(scip, &readerdata) );
218
219 return SCIP_OKAY;
220}
221
222
223/** problem reading method of reader */
224static
225SCIP_DECL_READERREAD(readerReadScflp)
226{ /*lint --e{715}*/
227 SCIP_READERDATA* readerdata;
228
229 SCIP_RANDNUMGEN* randomgen;
230
231 SCIP_FILE* file;
232 SCIP_Bool error;
233
234 char name[SCIP_MAXSTRLEN];
235 char buffer[SCIP_MAXSTRLEN];
236 SCIP_Real* fixedcost;
237 SCIP_Real* capacity;
238 SCIP_Real* detdemands;
239 SCIP_Real** demands;
240 SCIP_Real** costs;
241 int nfacilities;
242 int ncustomers;
243 int nscenarios;
244
245 SCIP_Real facilitycost;
246 SCIP_Real facilitycap;
247 SCIP_Real demand;
248 int facility;
249 int customer;
250 int ncostlines; /* this is the number of lines that have facility costs */
251
252 int nread;
253 int lineno;
254 int i;
255 int j;
256
257 readerdata = SCIPreaderGetData(reader);
258
259 /* creating the random number generator */
260 SCIP_CALL( SCIPcreateRandom(scip, &randomgen, readerdata->randomseed, FALSE) );
261
262 nscenarios = readerdata->nscenarios;
263
264 *result = SCIP_DIDNOTRUN;
265
266 /* open file */
267 file = SCIPfopen(filename, "r");
268 if( file == NULL )
269 {
270 SCIPerrorMessage("cannot open file <%s> for reading\n", filename);
271 SCIPprintSysError(filename);
272 return SCIP_NOFILE;
273 }
274
275 lineno = 0;
276 sprintf(name, "SCFLP");
277
278 nfacilities = 0;
279 ncustomers = 0;
280
281 /* read problem name */
282 if( !SCIPfeof(file) )
283 {
284 if( SCIPfgets(buffer, (int)sizeof(buffer), file) == NULL )
285 return SCIP_READERROR;
286
287 /* parse dimension line */
288 nread = sscanf(buffer, " %d %d\n", &nfacilities, &ncustomers);
289 if( nread == 0 )
290 {
291 SCIPwarningMessage(scip, "invalid input line %d in file <%s>: <%s>\n", lineno, filename, buffer);
292 return SCIP_READERROR;
293 }
294
295 SCIPdebugMsg(scip, "number of facilities = <%d> number of customers = <%d>\n", nfacilities, ncustomers);
296 }
297
298 /* computing the number of customer cost lines */
299 ncostlines = SCIPceil(scip, (SCIP_Real)nfacilities/MAXNCOSTS);
300
301 /* allocate buffer memory for storing the demand and the transport cost temporarily */
302 SCIP_CALL( SCIPallocBufferArray(scip, &capacity, nfacilities) );
303 SCIP_CALL( SCIPallocBufferArray(scip, &fixedcost, nfacilities) );
304
305 for( i = 0; i < nfacilities; i++ )
306 {
307 capacity[i] = 0.0;
308 fixedcost[i] = 0.0;
309 }
310
311 error = FALSE;
312
313 /* read facility data */
314 facility = 0;
315 while( !SCIPfeof(file) && !error && facility < nfacilities )
316 {
317 if( SCIPfgets(buffer, (int)sizeof(buffer), file) == NULL )
318 break;
319
320 /* parse dimension line */
321 nread = sscanf(buffer, " %lf %lf\n", &facilitycap, &facilitycost);
322 if( nread < 2 )
323 {
324 SCIPwarningMessage(scip, "invalid input line %d in file <%s>: <%s>\n", lineno, filename, buffer);
325 error = TRUE;
326 break;
327 }
328
329 SCIPdebugMsg(scip, "facility %d capacity = <%f>, fixed cost = <%f>\n", facility, facilitycap, facilitycost);
330 capacity[facility] = facilitycap;
331 fixedcost[facility] = facilitycost;
332 facility++;
333 assert(facility <= nfacilities);
334 }
335
336 /* allocate buffer memory for storing the demand and the transport cost temporarily */
337 SCIP_CALL( SCIPallocBufferArray(scip, &detdemands, ncustomers) );
338 SCIP_CALL( SCIPallocBufferArray(scip, &demands, ncustomers) );
339 SCIP_CALL( SCIPallocBufferArray(scip, &costs, ncustomers) );
340
341 /* TODO: convert the 2D arrays into contiguous arrays. This has benefits from a memory management point of view. */
342 for( i = 0; i < ncustomers; i++ )
343 {
344 SCIP_CALL( SCIPallocBufferArray(scip, &costs[i], nfacilities) );
345 SCIP_CALL( SCIPallocBufferArray(scip, &demands[i], nscenarios) );
346
347 for( j = 0; j < nfacilities; j++ )
348 costs[i][j] = 0.0;
349
350 for( j = 0; j < nscenarios; j++ )
351 demands[i][j] = 0.0;
352
353 detdemands[i] = 0.0;
354 }
355
356 /* parse demands and costs */
357
358 lineno = 0;
359 customer = 0;
360 facility = 0;
361 while( !SCIPfeof(file) && !error )
362 {
363 /* get next line */
364 if( SCIPfgets(buffer, (int)sizeof(buffer), file) == NULL )
365 break;
366
367 if( lineno == 0 )
368 {
369 /* parse the line */
370 nread = sscanf(buffer, " %lf\n", &demand);
371 if( nread == 0 )
372 {
373 SCIPwarningMessage(scip, "invalid input line %d in file <%s>: <%s>\n", lineno, filename, buffer);
374 error = TRUE;
375 break;
376 }
377
378 SCIPdebugMsg(scip, "customer %d demand <%f>\n", customer, demand);
379 detdemands[customer] = demand;
380 }
381 else if( lineno <= ncostlines )
382 {
383 SCIP_Real tmpcosts[MAXNCOSTS];
384 /* parse the line */
385 nread = sscanf(buffer, " %lf %lf %lf %lf %lf %lf %lf\n", &tmpcosts[0], &tmpcosts[1], &tmpcosts[2],
386 &tmpcosts[3], &tmpcosts[4], &tmpcosts[5], &tmpcosts[6]);
387
388 if( nread == 0 )
389 {
390 SCIPwarningMessage(scip, "invalid input line %d in file <%s>: <%s>\n", lineno, filename, buffer);
391 error = TRUE;
392 break;
393 }
394
395 for( i = 0; i < nread; i++ )
396 {
397 SCIPdebugMsg(scip, "(%d, %d) found cost <%e>\n", customer, facility, tmpcosts[i]);
398 costs[customer][facility] = tmpcosts[i]/demand;
399 facility++;
400 }
401 }
402
403 if( lineno == ncostlines )
404 {
405 lineno = 0;
406 facility = 0;
407 customer++;
408 }
409 else
410 lineno++;
411 }
412
413 /* if there has been no error in reading the data, then we generate the scenarios */
414 if( !error )
415 {
416 SCIP_Real mean;
417 SCIP_Real stdDev;
418 SCIP_Real spare;
419 SCIP_Bool hasspare;
420
421 /* creating the scenario data */
422 for( i = 0; i < ncustomers; i++ )
423 {
424 mean = detdemands[i];
425 stdDev = SCIPrandomGetReal(randomgen, 0.1*mean, 0.2*mean);
426 hasspare = FALSE;
427 for( j = 0; j < nscenarios; j++ )
428 {
429 demands[i][j] = SCIPround(scip, generateGaussianNoise(randomgen, mean, stdDev, &spare, &hasspare));
430
431 SCIPdebugMsg(scip, "Scenario %d: customer %d demand <%f>\n", j, i, demands[i][j]);
432 }
433 }
434
435 /* create a new problem in SCIP */
436 SCIP_CALL( SCIPprobdataCreate(scip, name, costs, demands, capacity, fixedcost, ncustomers, nfacilities,
437 nscenarios, readerdata->usebenders, readerdata->quadcosts) );
438 }
439
440 (void)SCIPfclose(file);
441
442 for( i = ncustomers - 1; i >= 0; i-- )
443 {
444 SCIPfreeBufferArray(scip, &demands[i]);
445 SCIPfreeBufferArray(scip, &costs[i]);
446 }
447
448 SCIPfreeBufferArray(scip, &costs);
449 SCIPfreeBufferArray(scip, &demands);
450 SCIPfreeBufferArray(scip, &detdemands);
451
452 SCIPfreeBufferArray(scip, &fixedcost);
453 SCIPfreeBufferArray(scip, &capacity);
454
455 /* freeing the random number generator */
456 SCIPfreeRandom(scip, &randomgen);
457
458 if( error )
459 return SCIP_READERROR;
460
461 *result = SCIP_SUCCESS;
462
463 return SCIP_OKAY;
464}
465
466/**@} */
467
468
469/**@name Interface methods
470 *
471 * @{
472 */
473
474/** includes the scflp file reader in SCIP */
476 SCIP* scip /**< SCIP data structure */
477 )
478{
479 SCIP_READERDATA* readerdata;
480 SCIP_READER* reader;
481
482 /* create scflp reader data */
483 readerdata = NULL;
484
485 SCIP_CALL( readerdataCreate(scip, &readerdata) );
486
487 /* include scflp reader */
489 assert(reader != NULL);
490
491 SCIP_CALL( SCIPsetReaderFree(scip, reader, readerFreeScflp) );
492 SCIP_CALL( SCIPsetReaderRead(scip, reader, readerReadScflp) );
493
495 "reading/" READER_NAME "/usebenders", "Should Benders' decomposition be used to solve the problem?",
496 &readerdata->usebenders, FALSE, DEFAULT_USEBENDERS, NULL, NULL) );
497
499 "reading/" READER_NAME "/numscenarios",
500 "the number of scenarios that will be randomly generated",
501 &readerdata->nscenarios, FALSE, DEFAULT_NUMSCENARIOS, 1, INT_MAX, NULL, NULL) );
502
504 "reading/" READER_NAME "/randomseed",
505 "the random seed used to generate the scenarios",
506 &readerdata->randomseed, FALSE, DEFAULT_RANDOMSEED, 1, INT_MAX, NULL, NULL) );
507
509 "reading/" READER_NAME "/quadcosts", "should the problem be formulated with quadratic costs",
510 &readerdata->quadcosts, FALSE, DEFAULT_QUADCOSTS, NULL, NULL) );
511
512 return SCIP_OKAY;
513}
514
515/**@} */
#define NULL
Definition: def.h:266
#define SCIP_MAXSTRLEN
Definition: def.h:287
#define SCIP_Bool
Definition: def.h:91
#define SCIP_Real
Definition: def.h:172
#define TRUE
Definition: def.h:93
#define FALSE
Definition: def.h:94
#define SCIP_CALL(x)
Definition: def.h:373
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
#define SCIPdebugMsg
Definition: scip_message.h:78
void SCIPwarningMessage(SCIP *scip, const char *formatstr,...)
Definition: scip_message.c:120
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 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 SCIPallocBufferArray(scip, ptr, num)
Definition: scip_mem.h:124
#define SCIPfreeBufferArray(scip, ptr)
Definition: scip_mem.h:136
#define SCIPfreeBlockMemory(scip, ptr)
Definition: scip_mem.h:108
#define SCIPallocBlockMemory(scip, ptr)
Definition: scip_mem.h:89
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_READERDATA * SCIPreaderGetData(SCIP_READER *reader)
Definition: reader.c:492
SCIP_RETCODE SCIPsetReaderFree(SCIP *scip, SCIP_READER *reader, SCIP_DECL_READERFREE((*readerfree)))
Definition: scip_reader.c:171
SCIP_RETCODE SCIPsetReaderRead(SCIP *scip, SCIP_READER *reader, SCIP_DECL_READERREAD((*readerread)))
Definition: scip_reader.c:195
SCIP_Real SCIPround(SCIP *scip, SCIP_Real val)
SCIP_Real SCIPceil(SCIP *scip, SCIP_Real val)
void SCIPfreeRandom(SCIP *scip, SCIP_RANDNUMGEN **randnumgen)
SCIP_Real SCIPrandomGetReal(SCIP_RANDNUMGEN *randnumgen, SCIP_Real minrandval, SCIP_Real maxrandval)
Definition: misc.c:10133
SCIP_RETCODE SCIPcreateRandom(SCIP *scip, SCIP_RANDNUMGEN **randnumgen, unsigned int initialseed, SCIP_Bool useglobalseed)
void SCIPprintSysError(const char *message)
Definition: misc.c:10772
SCIP_RETCODE SCIPprobdataCreate(SCIP *scip, const char *probname, int *demands, SCIP_Real *rints, SCIP_Real *rexts, int ntypes, SCIP_Real width, SCIP_Real height)
Problem data for Stochastic Capacitated Facility Location problem.
struct SCIP_File SCIP_FILE
Definition: pub_fileio.h:43
#define SCIPerrorMessage
Definition: pub_message.h:64
#define DEFAULT_USEBENDERS
Definition: reader_scflp.c:114
SCIP_RETCODE SCIPincludeReaderScflp(SCIP *scip)
Definition: reader_scflp.c:475
#define MAXNCOSTS
Definition: reader_scflp.c:120
static SCIP_Real generateGaussianNoise(SCIP_RANDNUMGEN *randomgen, SCIP_Real mean, SCIP_Real stdDev, SCIP_Real *spare, SCIP_Bool *hasspare)
Definition: reader_scflp.c:134
#define READER_DESC
Definition: reader_scflp.c:110
static SCIP_DECL_READERREAD(readerReadScflp)
Definition: reader_scflp.c:225
#define READER_EXTENSION
Definition: reader_scflp.c:111
#define DEFAULT_QUADCOSTS
Definition: reader_scflp.c:117
static SCIP_RETCODE readerdataFree(SCIP *scip, SCIP_READERDATA **readerdata)
Definition: reader_scflp.c:186
#define DEFAULT_NUMSCENARIOS
Definition: reader_scflp.c:115
#define READER_NAME
Definition: reader_scflp.c:109
static SCIP_RETCODE readerdataCreate(SCIP *scip, SCIP_READERDATA **readerdata)
Definition: reader_scflp.c:170
static SCIP_DECL_READERFREE(readerFreeScflp)
Definition: reader_scflp.c:208
#define DEFAULT_RANDOMSEED
Definition: reader_scflp.c:116
SCFLP problem reader file reader.
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