@@ -134,7 +134,7 @@ SCIP_Bool debugSolutionAvailable(
134
134
static
135
135
SCIP_RETCODE readSolfile (
136
136
SCIP_SET * set , /**< global SCIP settings */
137
- const char * solfilename , /**< solution filename to read */
137
+ const char * filename , /**< solution filename to read */
138
138
SCIP_SOL * * debugsolptr ,
139
139
SCIP_Real * debugsolvalptr ,
140
140
SCIP_STAGE * debugsolstageptr ,
@@ -144,160 +144,198 @@ SCIP_RETCODE readSolfile(
144
144
int * valssize /**< pointer to store the length of the variable names and solution values arrays */
145
145
)
146
146
{
147
+ SCIP_FILE * file ;
147
148
SCIP_VAR * * vars ;
148
149
SCIP_Real * solvalues ;
149
- SCIP_FILE * file ;
150
150
SCIP_SOL * debugsol ;
151
151
SCIP_Real debugsolval ;
152
- int nonvalues ;
153
- int nfound ;
154
- int i ;
155
152
SCIP_Bool unknownvariablemessage ;
153
+ int lineno ;
154
+ int i ;
156
155
157
156
assert (set != NULL );
158
- assert (solfilename != NULL );
157
+ assert (filename != NULL );
159
158
assert (names != NULL );
160
159
assert (* names == NULL );
161
160
assert (vals != NULL );
162
161
assert (* vals == NULL );
163
162
assert (nvals != NULL );
164
163
assert (valssize != NULL );
165
164
166
- printf ("***** debug: reading solution file <%s>\n" , solfilename );
165
+ printf ("***** debug: reading solution file <%s>\n" , filename );
167
166
168
167
/* open solution file */
169
- file = SCIPfopen (solfilename , "r" );
168
+ file = SCIPfopen (filename , "r" );
170
169
if ( file == NULL )
171
170
{
172
- SCIPerrorMessage ("cannot open solution file <%s> specified in scip/debug.h\n" , solfilename );
173
- SCIPprintSysError (solfilename );
171
+ SCIPerrorMessage ("cannot open solution file <%s> specified in scip/debug.h\n" , filename );
172
+ SCIPprintSysError (filename );
174
173
return SCIP_NOFILE ;
175
174
}
176
175
177
176
/* read data */
178
- nonvalues = 0 ;
179
177
* valssize = 0 ;
180
178
unknownvariablemessage = FALSE;
179
+ lineno = 0 ;
181
180
182
181
while ( !SCIPfeof (file ) )
183
182
{
184
- char buf [SCIP_MAXSTRLEN ];
185
- char name [SCIP_MAXSTRLEN ];
186
- char objstring [SCIP_MAXSTRLEN ];
187
- char valuestring [SCIP_MAXSTRLEN ];
183
+ /**@todo unlimit buffer size */
184
+ char buffer [SCIP_MAXSTRLEN ];
185
+ const char * varname ;
186
+ const char * valuestring ;
187
+ char * endptr ;
188
188
SCIP_VAR * var ;
189
- SCIP_Real val ;
190
- int nread ;
191
189
192
- if ( SCIPfgets (buf , SCIP_MAXSTRLEN , file ) == NULL )
190
+ /* get next line */
191
+ if ( SCIPfgets (buffer , (int )sizeof (buffer ), file ) == NULL )
193
192
{
194
193
if ( SCIPfeof (file ) )
195
194
break ;
196
195
else
196
+ {
197
+ SCIPfclose (file );
197
198
return SCIP_READERROR ;
199
+ }
198
200
}
199
-
200
- /* there are some lines which may preceed the solution information */
201
- if ( SCIPstrncasecmp (buf , "solution status:" , 16 ) == 0 || SCIPstrncasecmp (buf , "objective value:" , 16 ) == 0 ||
202
- SCIPstrncasecmp (buf , "Log started" , 11 ) == 0 || SCIPstrncasecmp (buf , "Variable Name" , 13 ) == 0 ||
203
- SCIPstrncasecmp (buf , "All other variables" , 19 ) == 0 || strspn (buf , " \n\r\t\f" ) == strlen (buf ) ||
204
- SCIPstrncasecmp (buf , "NAME" , 4 ) == 0 || SCIPstrncasecmp (buf , "ENDATA" , 6 ) == 0 || /* allow parsing of SOL-format on the MIPLIB 2003 pages */
205
- SCIPstrncasecmp (buf , "=obj=" , 5 ) == 0 ) /* avoid "unknown variable" warning when reading MIPLIB SOL files */
206
- {
207
- ++ nonvalues ;
201
+ ++ lineno ;
202
+
203
+ /* there are some lines which may precede the solution information */
204
+ if ( SCIPstrncasecmp (buffer , "solution status:" , 16 ) == 0 || SCIPstrncasecmp (buffer , "objective value:" , 16 ) == 0
205
+ || buffer [strspn (buffer , " \t\n\v\f\r" )] == '\0' || SCIPstrncasecmp (buffer , "Log started" , 11 ) == 0
206
+ || SCIPstrncasecmp (buffer , "Variable Name" , 13 ) == 0 || SCIPstrncasecmp (buffer , "All other variables" , 19 ) == 0
207
+ || SCIPstrncasecmp (buffer , "NAME" , 4 ) == 0 || SCIPstrncasecmp (buffer , "ENDATA" , 6 ) == 0 /* allow parsing of SOL-format on the MIPLIB 2003 pages */
208
+ || SCIPstrncasecmp (buffer , "=obj=" , 5 ) == 0 ) /* avoid "unknown variable" warning when reading MIPLIB SOL files */
208
209
continue ;
209
- }
210
210
211
- /* cppcheck-suppress invalidscanf */
212
- nread = sscanf (buf , "%s %s %s\n" , name , valuestring , objstring );
213
- if ( nread < 2 )
211
+ /* tokenize the line */
212
+ varname = SCIPstrtok (buffer , " \t\v" , & endptr );
213
+ valuestring = SCIPstrtok (NULL , " \t\n\v\f\r" , & endptr );
214
+ if ( valuestring == NULL )
214
215
{
215
- printf ( "invalid input line %d in solution file <%s>: <%s>\n" , * nvals + nonvalues , solfilename , name );
216
+ SCIPerrorMessage ( "Invalid input line %d in solution file <%s>: <%s>. \n" , lineno , filename , buffer );
216
217
SCIPfclose (file );
217
218
return SCIP_READERROR ;
218
219
}
219
220
220
221
/* find the variable */
221
- var = SCIPfindVar (set -> scip , name );
222
+ var = SCIPfindVar (set -> scip , varname );
222
223
if ( var == NULL )
223
224
{
224
225
if ( !unknownvariablemessage )
225
226
{
226
227
SCIPverbMessage (set -> scip , SCIP_VERBLEVEL_NORMAL , NULL , "unknown variable <%s> in line %d of solution file <%s>\n" ,
227
- name , * nvals + nonvalues , solfilename );
228
+ varname , lineno , filename );
228
229
SCIPverbMessage (set -> scip , SCIP_VERBLEVEL_NORMAL , NULL , " (further unknown variables are ignored)\n" );
229
230
unknownvariablemessage = TRUE;
230
231
}
231
232
continue ;
232
233
}
233
234
234
- /* cast the value, check first for inv(alid) or inf(inite) ones that need special treatment */
235
+ /* ignore invalid value */
235
236
if ( SCIPstrncasecmp (valuestring , "inv" , 3 ) == 0 )
237
+ {
238
+ SCIPdebugMsg (set -> scip , "ignored invalid assignment for variable <%s>\n" , varname );
236
239
continue ;
237
- else if ( SCIPstrncasecmp (valuestring , "+inf" , 4 ) == 0 || SCIPstrncasecmp (valuestring , "inf" , 3 ) == 0 )
238
- val = SCIPsetInfinity (set );
239
- else if ( SCIPstrncasecmp (valuestring , "-inf" , 4 ) == 0 )
240
- val = - SCIPsetInfinity (set );
241
- else
240
+ }
241
+
242
+ /**@todo: store exact debugsol */
242
243
{
243
- /* cppcheck-suppress invalidscanf */
244
- nread = sscanf (valuestring , "%lf" , & val );
245
- if ( nread != 1 )
244
+ SCIP_Real value ;
245
+
246
+ if ( SCIPstrncasecmp (valuestring , "+inf" , 4 ) == 0 || SCIPstrncasecmp (valuestring , "inf" , 3 ) == 0 )
247
+ value = SCIPsetInfinity (set );
248
+ else if ( SCIPstrncasecmp (valuestring , "-inf" , 4 ) == 0 )
249
+ value = - SCIPsetInfinity (set );
250
+ else if ( !SCIPstrToRealValue (valuestring , & value , & endptr ) || * endptr != '\0' )
246
251
{
247
- SCIPerrorMessage ("Invalid solution value <%s> for variable <%s> in line %d of solution file <%s>.\n" ,
248
- valuestring , name , * nvals + nonvalues , solfilename );
249
- SCIPfclose (file );
250
- return SCIP_READERROR ;
252
+ #ifdef SCIP_WITH_EXACTSOLVE
253
+ /* convert exact value */
254
+ if ( SCIPrationalIsString (valuestring ) )
255
+ {
256
+ SCIP_RATIONAL * valueexact ;
257
+
258
+ SCIP_CALL ( SCIPrationalCreateString (SCIPblkmem (set -> scip ), & valueexact , valuestring ) );
259
+
260
+ value = SCIPrationalGetReal (valueexact );
261
+
262
+ SCIPrationalFreeBlock (SCIPblkmem (set -> scip ), & valueexact );
263
+ }
264
+ else
265
+ #endif
266
+ {
267
+ SCIPerrorMessage ("Invalid solution value <%s> for variable <%s> in line %d of solution file <%s>.\n" ,
268
+ valuestring , varname , lineno , filename );
269
+ SCIPfclose (file );
270
+ return SCIP_READERROR ;
271
+ }
251
272
}
252
- }
253
273
254
- /* allocate memory */
255
- if ( * nvals >= * valssize )
256
- {
257
- * valssize = MAX (2 * * valssize , (* nvals )+ 1 );
258
- SCIP_ALLOC ( BMSreallocMemoryArray (names , * valssize ) );
259
- SCIP_ALLOC ( BMSreallocMemoryArray (vals , * valssize ) );
260
- }
261
- assert (* nvals < * valssize );
274
+ /* skip zero entry */
275
+ if ( value == 0.0 ) /*lint !e777*/
276
+ continue ;
262
277
263
- /* store solution value in sorted list */
264
- for ( i = * nvals ; i > 0 && strcmp (name , (* names )[i - 1 ]) < 0 ; -- i )
265
- {
266
- (* names )[i ] = (* names )[i - 1 ];
267
- (* vals )[i ] = (* vals )[i - 1 ];
278
+ /* search insertion index in sorted list */
279
+ i = * nvals - 1 ;
280
+ while ( i >= 0 && strcmp (varname , (* names )[i ]) < 0 )
281
+ -- i ;
282
+
283
+ /* overwrite real solution */
284
+ if ( i >= 0 && strcmp (varname , (* names )[i ]) == 0 )
285
+ {
286
+ SCIPwarningMessage (set -> scip , "Overwriting %lf with %lf for <%s> in line %d of solution file <%s>.\n" ,
287
+ (* vals )[i ], value , varname , lineno , filename );
288
+ (* vals )[i ] = value ;
289
+ }
290
+ /* add real solution */
291
+ else
292
+ {
293
+ int j ;
294
+
295
+ if ( * nvals >= * valssize )
296
+ {
297
+ * valssize = MAX (2 * (* valssize ), (* nvals ) + 1 );
298
+ SCIP_ALLOC ( BMSreallocMemoryArray (names , * valssize ) );
299
+ SCIP_ALLOC ( BMSreallocMemoryArray (vals , * valssize ) );
300
+ }
301
+ assert (* nvals < * valssize );
302
+
303
+ ++ i ;
304
+ for ( j = * nvals ; j > i ; -- j )
305
+ {
306
+ (* names )[j ] = (* names )[j - 1 ];
307
+ (* vals )[j ] = (* vals )[j - 1 ];
308
+ }
309
+ SCIP_ALLOC ( BMSduplicateMemoryArray (& (* names )[i ], varname , strlen (varname )+ 1 ) );
310
+ (* vals )[i ] = value ;
311
+ ++ (* nvals );
312
+ }
313
+
314
+ SCIPdebugMsg (set -> scip , "found variable <%s>: value <%g>\n" , varname , value );
268
315
}
269
- SCIP_ALLOC ( BMSduplicateMemoryArray (& (* names )[i ], name , strlen (name )+ 1 ) );
270
- SCIPdebugMsg (set -> scip , "found variable <%s>: value <%g>\n" , (* names )[i ], val );
271
- (* vals )[i ] = val ;
272
- (* nvals )++ ;
273
316
}
274
317
275
318
/* get memory for SCIP solution */
276
319
SCIP_ALLOC ( BMSallocMemoryArray (& vars , * valssize ) );
277
320
SCIP_ALLOC ( BMSallocMemoryArray (& solvalues , * valssize ) );
278
321
279
322
debugsolval = 0.0 ;
280
- nfound = 0 ;
281
323
282
324
/* get solution value */
283
325
for ( i = 0 ; i < * nvals ; ++ i )
284
326
{
285
- SCIP_VAR * var ;
286
- var = SCIPfindVar (set -> scip , (* names )[i ]);
287
- if ( var != NULL )
288
- {
289
- vars [nfound ] = var ;
290
- solvalues [nfound ] = (* vals )[i ];
291
- ++ nfound ;
292
- debugsolval += (* vals )[i ] * SCIPvarGetObj (var );
293
- }
327
+ SCIP_VAR * var = SCIPfindVar (set -> scip , (* names )[i ]);
328
+ assert (var != NULL );
329
+ vars [i ] = var ;
330
+ solvalues [i ] = (* vals )[i ];
331
+ debugsolval += solvalues [i ] * SCIPvarGetObj (var );
294
332
}
295
333
SCIPdebugMsg (set -> scip , "Debug Solution value is %g.\n" , debugsolval );
296
334
297
335
#ifdef SCIP_MORE_DEBUG
298
- SCIPsortPtrReal ((void * * )vars , solvalues , sortVarsAfterNames , nfound );
336
+ SCIPsortPtrReal ((void * * )vars , solvalues , sortVarsAfterNames , * nvals );
299
337
300
- for ( i = 0 ; i < nfound - 1 ; ++ i )
338
+ for ( i = 0 ; i < * nvals - 1 ; ++ i )
301
339
{
302
340
assert (strcmp (SCIPvarGetName (vars [i ]), SCIPvarGetName (vars [i + 1 ])) != 0 );
303
341
}
@@ -310,7 +348,7 @@ SCIP_RETCODE readSolfile(
310
348
* debugsolstageptr = SCIPgetStage (set -> scip );
311
349
312
350
/* set SCIP solution values */
313
- SCIP_CALL ( SCIPsetSolVals (set -> scip , debugsol , nfound , vars , solvalues ) );
351
+ SCIP_CALL ( SCIPsetSolVals (set -> scip , debugsol , * nvals , vars , solvalues ) );
314
352
}
315
353
316
354
BMSfreeMemoryArray (& vars );
@@ -325,7 +363,7 @@ SCIP_RETCODE readSolfile(
325
363
/* close file */
326
364
SCIPfclose (file );
327
365
328
- printf ("***** debug: read %d non-zero entries (%d variables found) \n" , * nvals , nfound );
366
+ printf ("***** debug: found %d non-zero entries\n" , * nvals );
329
367
330
368
return SCIP_OKAY ;
331
369
}
0 commit comments