Scippy

SCIP

Solving Constraint Integer Programs

scipshell.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-2019 Konrad-Zuse-Zentrum */
7 /* fuer Informationstechnik Berlin */
8 /* */
9 /* SCIP is distributed under the terms of the ZIB Academic License. */
10 /* */
11 /* You should have received a copy of the ZIB Academic License */
12 /* along with SCIP; see the file COPYING. If not visit scip.zib.de. */
13 /* */
14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15 
16 /**@file scipshell.c
17  * @brief SCIP command line interface
18  * @author Tobias Achterberg
19  */
20 
21 /*--+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
22 
23 #include <stdio.h>
24 #include <string.h>
25 #include <ctype.h>
26 
27 #include "scip/scip.h"
28 #include "scip/scipdefplugins.h"
29 #include "scip/scipshell.h"
30 #include "scip/message_default.h"
31 
32 /*
33  * Message Handler
34  */
35 
36 static
38  SCIP* scip, /**< SCIP data structure */
39  const char* filename /**< parameter file name */
40  )
41 {
42  if( SCIPfileExists(filename) )
43  {
44  SCIPinfoMessage(scip, NULL, "reading user parameter file <%s>\n", filename);
45  SCIP_CALL( SCIPreadParams(scip, filename) );
46  }
47  else
48  SCIPinfoMessage(scip, NULL, "user parameter file <%s> not found - using default parameters\n", filename);
49 
50  return SCIP_OKAY;
51 }
52 
53 static
55  SCIP* scip, /**< SCIP data structure */
56  const char* filename /**< input file name */
57  )
58 {
59  SCIP_RETCODE retcode;
60  SCIP_Bool outputorigsol = FALSE;
61 
62  /********************
63  * Problem Creation *
64  ********************/
65 
66  /** @note The message handler should be only fed line by line such the message has the chance to add string in front
67  * of each message
68  */
69  SCIPinfoMessage(scip, NULL, "\n");
70  SCIPinfoMessage(scip, NULL, "read problem <%s>\n", filename);
71  SCIPinfoMessage(scip, NULL, "============\n");
72  SCIPinfoMessage(scip, NULL, "\n");
73 
74  retcode = SCIPreadProb(scip, filename, NULL);
75 
76  switch( retcode )
77  {
78  case SCIP_NOFILE:
79  SCIPinfoMessage(scip, NULL, "file <%s> not found\n", filename);
80  return SCIP_OKAY;
82  SCIPinfoMessage(scip, NULL, "no reader for input file <%s> available\n", filename);
83  return SCIP_OKAY;
84  case SCIP_READERROR:
85  SCIPinfoMessage(scip, NULL, "error reading file <%s>\n", filename);
86  return SCIP_OKAY;
87  default:
88  SCIP_CALL( retcode );
89  } /*lint !e788*/
90 
91  /*******************
92  * Problem Solving *
93  *******************/
94 
95  /* solve problem */
96  SCIPinfoMessage(scip, NULL, "\nsolve problem\n");
97  SCIPinfoMessage(scip, NULL, "=============\n\n");
98 
99  SCIP_CALL( SCIPsolve(scip) );
100 
101  /*******************
102  * Solution Output *
103  *******************/
104 
105  SCIP_CALL( SCIPgetBoolParam(scip, "misc/outputorigsol", &outputorigsol) );
106  if ( outputorigsol )
107  {
108  SCIP_SOL* bestsol;
109 
110  SCIPinfoMessage(scip, NULL, "\nprimal solution (original space):\n");
111  SCIPinfoMessage(scip, NULL, "=================================\n\n");
112 
113  bestsol = SCIPgetBestSol(scip);
114  if ( bestsol == NULL )
115  SCIPinfoMessage(scip, NULL, "no solution available\n");
116  else
117  {
118  SCIP_SOL* origsol;
119 
120  SCIP_CALL( SCIPcreateSolCopy(scip, &origsol, bestsol) );
121  SCIP_CALL( SCIPretransformSol(scip, origsol) );
122  SCIP_CALL( SCIPprintSol(scip, origsol, NULL, FALSE) );
123  SCIP_CALL( SCIPfreeSol(scip, &origsol) );
124  }
125  }
126  else
127  {
128  SCIPinfoMessage(scip, NULL, "\nprimal solution (transformed space):\n");
129  SCIPinfoMessage(scip, NULL, "====================================\n\n");
130 
132  }
133 
134  /**************
135  * Statistics *
136  **************/
137 
138  SCIPinfoMessage(scip, NULL, "\nStatistics\n");
139  SCIPinfoMessage(scip, NULL, "==========\n\n");
140 
142 
143  return SCIP_OKAY;
144 }
145 
146 /** evaluates command line parameters and runs SCIP appropriately in the given SCIP instance */
148  SCIP* scip, /**< SCIP data structure */
149  int argc, /**< number of shell parameters */
150  char** argv, /**< array with shell parameters */
151  const char* defaultsetname /**< name of default settings file */
152  )
153 { /*lint --e{850}*/
154  char* probname = NULL;
155  char* settingsname = NULL;
156  char* logname = NULL;
157  int randomseed;
158  SCIP_Bool randomseedread;
159  SCIP_Bool quiet;
160  SCIP_Bool paramerror;
162  SCIP_Bool onlyversion;
163  SCIP_Real primalreference = SCIP_UNKNOWN;
164  SCIP_Real dualreference = SCIP_UNKNOWN;
165  const char* dualrefstring;
166  const char* primalrefstring;
167  int i;
168 
169  /********************
170  * Parse parameters *
171  ********************/
172 
173  quiet = FALSE;
174  paramerror = FALSE;
175  interactive = FALSE;
176  onlyversion = FALSE;
177  randomseedread = FALSE;
178  randomseed = 0;
179  primalrefstring = NULL;
180  dualrefstring = NULL;
181 
182  for( i = 1; i < argc; ++i )
183  {
184  if( strcmp(argv[i], "-l") == 0 )
185  {
186  i++;
187  if( i < argc )
188  logname = argv[i];
189  else
190  {
191  printf("missing log filename after parameter '-l'\n");
192  paramerror = TRUE;
193  }
194  }
195  else if( strcmp(argv[i], "-q") == 0 )
196  quiet = TRUE;
197  else if( strcmp(argv[i], "-v") == 0 )
198  onlyversion = TRUE;
199  else if( strcmp(argv[i], "--version") == 0 )
200  onlyversion = TRUE;
201  else if( strcmp(argv[i], "-s") == 0 )
202  {
203  i++;
204  if( i < argc )
205  settingsname = argv[i];
206  else
207  {
208  printf("missing settings filename after parameter '-s'\n");
209  paramerror = TRUE;
210  }
211  }
212  else if( strcmp(argv[i], "-f") == 0 )
213  {
214  i++;
215  if( i < argc )
216  probname = argv[i];
217  else
218  {
219  printf("missing problem filename after parameter '-f'\n");
220  paramerror = TRUE;
221  }
222  }
223  else if( strcmp(argv[i], "-c") == 0 )
224  {
225  i++;
226  if( i < argc )
227  {
228  SCIP_CALL( SCIPaddDialogInputLine(scip, argv[i]) );
229  interactive = TRUE;
230  }
231  else
232  {
233  printf("missing command line after parameter '-c'\n");
234  paramerror = TRUE;
235  }
236  }
237  else if( strcmp(argv[i], "-b") == 0 )
238  {
239  i++;
240  if( i < argc )
241  {
242  SCIP_FILE* file;
243 
244  file = SCIPfopen(argv[i], "r");
245  if( file == NULL )
246  {
247  printf("cannot read command batch file <%s>\n", argv[i]);
248  SCIPprintSysError(argv[i]);
249  paramerror = TRUE;
250  }
251  else
252  {
253  while( !SCIPfeof(file) )
254  {
255  char buffer[SCIP_MAXSTRLEN];
256 
257  (void)SCIPfgets(buffer, (int) sizeof(buffer), file);
258  if( buffer[0] != '\0' )
259  {
260  SCIP_CALL_FINALLY( SCIPaddDialogInputLine(scip, buffer), SCIPfclose(file) );
261  }
262  }
263  SCIPfclose(file);
264  interactive = TRUE;
265  }
266  }
267  else
268  {
269  printf("missing command batch filename after parameter '-b'\n");
270  paramerror = TRUE;
271  }
272  }
273  else if( strcmp(argv[i], "-r") == 0 )
274  {
275  /*read a random seed from the command line */
276  i++;
277  if( i < argc && isdigit(argv[i][0]) )
278  {
279  randomseed = atoi(argv[i]);
280  randomseedread = TRUE;
281  }
282  else
283  {
284  printf("Random seed parameter '-r' followed by something that is not an integer\n");
285  paramerror = TRUE;
286  }
287  }
288  else if( strcmp(argv[i], "-o") == 0 )
289  {
290  if( i >= argc - 2 )
291  {
292  printf("wrong usage of reference objective parameter '-o': -o <primref> <dualref>\n");
293  paramerror = TRUE;
294  }
295  else
296  {
297  /* do not parse the strings directly, the settings could still influence the value of +-infinity */
298  primalrefstring = argv[i + 1];
299  dualrefstring = argv[i+2];
300  }
301  i += 2;
302  }
303  else
304  {
305  printf("invalid parameter <%s>\n", argv[i]);
306  paramerror = TRUE;
307  }
308  }
309 
310  if( interactive && probname != NULL )
311  {
312  printf("cannot mix batch mode '-c' and '-b' with file mode '-f'\n");
313  paramerror = TRUE;
314  }
315 
316  if( !paramerror )
317  {
318  /***********************************
319  * create log file message handler *
320  ***********************************/
321 
322  if( quiet )
323  {
324  SCIPsetMessagehdlrQuiet(scip, quiet);
325  }
326 
327  if( logname != NULL )
328  {
329  SCIPsetMessagehdlrLogfile(scip, logname);
330  }
331 
332  /***********************************
333  * Version and library information *
334  ***********************************/
335 
336  SCIPprintVersion(scip, NULL);
337  SCIPinfoMessage(scip, NULL, "\n");
338 
340  SCIPinfoMessage(scip, NULL, "\n");
341 
342  if( onlyversion )
343  {
345  SCIPinfoMessage(scip, NULL, "\n");
346  return SCIP_OKAY;
347  }
348 
349  /*****************
350  * Load settings *
351  *****************/
352 
353  if( settingsname != NULL )
354  {
355  SCIP_CALL( readParams(scip, settingsname) );
356  }
357  else if( defaultsetname != NULL )
358  {
359  SCIP_CALL( readParams(scip, defaultsetname) );
360  }
361 
362  /************************************
363  * Change random seed, if specified *
364  ***********************************/
365  if( randomseedread )
366  {
367  SCIP_CALL( SCIPsetIntParam(scip, "randomization/randomseedshift", randomseed) );
368  }
369 
370  /**************
371  * Start SCIP *
372  **************/
373 
374  if( probname != NULL )
375  {
376  SCIP_Bool validatesolve = FALSE;
377 
378  if( primalrefstring != NULL && dualrefstring != NULL )
379  {
380  char *endptr;
381  if( ! SCIPparseReal(scip, primalrefstring, &primalreference, &endptr) ||
382  ! SCIPparseReal(scip, dualrefstring, &dualreference, &endptr) )
383  {
384  printf("error parsing primal and dual reference values for validation: %s %s\n", primalrefstring, dualrefstring);
385  return SCIP_ERROR;
386  }
387  else
388  validatesolve = TRUE;
389  }
390  SCIP_CALL( fromCommandLine(scip, probname) );
391 
392  /* validate the solve */
393  if( validatesolve )
394  {
395  SCIP_CALL( SCIPvalidateSolve(scip, primalreference, dualreference, SCIPfeastol(scip), FALSE, NULL, NULL, NULL) );
396  }
397  }
398  else
399  {
400  SCIPinfoMessage(scip, NULL, "\n");
402  }
403  }
404  else
405  {
406  printf("\nsyntax: %s [-l <logfile>] [-q] [-s <settings>] [-r <randseed>] [-f <problem>] [-b <batchfile>] [-c \"command\"]\n"
407  " -v, --version : print version and build options\n"
408  " -l <logfile> : copy output into log file\n"
409  " -q : suppress screen messages\n"
410  " -s <settings> : load parameter settings (.set) file\n"
411  " -f <problem> : load and solve problem file\n"
412  " -o <primref> <dualref> : pass primal and dual objective reference values for validation at the end of the solve\n"
413  " -b <batchfile>: load and execute dialog command batch file (can be used multiple times)\n"
414  " -r <randseed> : nonnegative integer to be used as random seed. "
415  "Has priority over random seed specified through parameter settings (.set) file\n"
416  " -c \"command\" : execute single line of dialog commands (can be used multiple times)\n\n",
417  argv[0]);
418  }
419 
420  return SCIP_OKAY;
421 }
422 
423 /** creates a SCIP instance with default plugins, evaluates command line parameters, runs SCIP appropriately,
424  * and frees the SCIP instance
425  */
427  int argc, /**< number of shell parameters */
428  char** argv, /**< array with shell parameters */
429  const char* defaultsetname /**< name of default settings file */
430  )
431 {
432  SCIP* scip = NULL;
433 
434  /*********
435  * Setup *
436  *********/
437 
438  /* initialize SCIP */
439  SCIP_CALL( SCIPcreate(&scip) );
440 
441  /* we explicitly enable the use of a debug solution for this main SCIP instance */
442  SCIPenableDebugSol(scip);
443 
444  /* include default SCIP plugins */
446 
447  /**********************************
448  * Process command line arguments *
449  **********************************/
450  SCIP_CALL( SCIPprocessShellArguments(scip, argc, argv, defaultsetname) );
451 
452  /********************
453  * Deinitialization *
454  ********************/
455  SCIP_CALL( SCIPfree(&scip) );
456 
458 
459  return SCIP_OKAY;
460 }
SCIP_RETCODE SCIPprintBestSol(SCIP *scip, FILE *file, SCIP_Bool printzeros)
Definition: scip_sol.c:2428
#define NULL
Definition: def.h:246
#define BMScheckEmptyMemory()
Definition: memory.h:144
SCIP_Real SCIPfeastol(SCIP *scip)
default message handler
#define SCIP_MAXSTRLEN
Definition: def.h:267
SCIP_Bool SCIPparseReal(SCIP *scip, const char *str, SCIP_Real *value, char **endptr)
#define SCIP_CALL_FINALLY(x, y)
Definition: def.h:400
char probname[TIM_MAX_NAMELEN]
Definition: reader_tim.c:97
#define FALSE
Definition: def.h:72
static SCIP_RETCODE fromCommandLine(SCIP *scip, const char *filename)
Definition: scipshell.c:54
void SCIPprintExternalCodes(SCIP *scip, FILE *file)
Definition: scip_general.c:804
#define TRUE
Definition: def.h:71
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:53
static SCIP_RETCODE readParams(SCIP *scip, const char *filename)
Definition: scipshell.c:37
SCIP_RETCODE SCIPcreate(SCIP **scip)
Definition: scip_general.c:338
static SCIP_RETCODE interactive(SCIP *scip)
Definition: cmain.c:90
SCIP_RETCODE SCIPprintStatistics(SCIP *scip, FILE *file)
void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
Definition: scip_message.c:279
SCIP_Bool SCIPfileExists(const char *filename)
Definition: misc.c:10456
SCIP_FILE * SCIPfopen(const char *path, const char *mode)
Definition: fileio.c:140
SCIP_RETCODE SCIPcreateSolCopy(SCIP *scip, SCIP_SOL **sol, SCIP_SOL *sourcesol)
Definition: scip_sol.c:667
SCIP_RETCODE SCIPsolve(SCIP *scip)
Definition: scip_solve.c:2577
SCIP command line interface.
SCIP_RETCODE SCIPreadProb(SCIP *scip, const char *filename, const char *extension)
Definition: scip_prob.c:382
int SCIPfeof(SCIP_FILE *stream)
Definition: fileio.c:214
struct SCIP_File SCIP_FILE
Definition: pub_fileio.h:34
char * SCIPfgets(char *s, int size, SCIP_FILE *stream)
Definition: fileio.c:187
SCIP_RETCODE SCIPgetBoolParam(SCIP *scip, const char *name, SCIP_Bool *value)
Definition: scip_param.c:322
SCIP_RETCODE SCIPrunShell(int argc, char **argv, const char *defaultsetname)
Definition: scipshell.c:426
#define SCIP_CALL(x)
Definition: def.h:358
#define SCIP_UNKNOWN
Definition: def.h:178
#define SCIP_Bool
Definition: def.h:69
SCIP_RETCODE SCIPincludeDefaultPlugins(SCIP *scip)
void SCIPprintVersion(SCIP *scip, FILE *file)
Definition: scip_general.c:201
void SCIPprintSysError(const char *message)
Definition: misc.c:10162
SCIP_RETCODE SCIPvalidateSolve(SCIP *scip, SCIP_Real primalreference, SCIP_Real dualreference, SCIP_Real reftol, SCIP_Bool quiet, SCIP_Bool *feasible, SCIP_Bool *primalboundcheck, SCIP_Bool *dualboundcheck)
void SCIPsetMessagehdlrQuiet(SCIP *scip, SCIP_Bool quiet)
Definition: scip_message.c:191
SCIP_RETCODE SCIPsetIntParam(SCIP *scip, const char *name, int value)
Definition: scip_param.c:578
SCIP_RETCODE SCIPfreeSol(SCIP *scip, SCIP_SOL **sol)
Definition: scip_sol.c:1034
SCIP_RETCODE SCIPretransformSol(SCIP *scip, SCIP_SOL *sol)
Definition: scip_sol.c:2540
SCIP_RETCODE SCIPprocessShellArguments(SCIP *scip, int argc, char **argv, const char *defaultsetname)
Definition: scipshell.c:147
SCIP_RETCODE SCIPstartInteraction(SCIP *scip)
Definition: scip_dialog.c:313
SCIP_SOL * SCIPgetBestSol(SCIP *scip)
Definition: scip_sol.c:2362
void SCIPsetMessagehdlrLogfile(SCIP *scip, const char *filename)
Definition: scip_message.c:179
SCIP_RETCODE SCIPreadParams(SCIP *scip, const char *filename)
Definition: scip_param.c:842
#define SCIP_Real
Definition: def.h:157
int SCIPfclose(SCIP_FILE *fp)
Definition: fileio.c:219
default SCIP plugins
void SCIPprintBuildOptions(SCIP *scip, FILE *file)
Definition: scip_general.c:236
SCIP_RETCODE SCIPaddDialogInputLine(SCIP *scip, const char *inputline)
Definition: scip_dialog.c:263
SCIP callable library.
SCIP_RETCODE SCIPfree(SCIP **scip)
Definition: scip_general.c:370
void SCIPenableDebugSol(SCIP *scip)
Definition: scip_debug.c:132
SCIP_RETCODE SCIPprintSol(SCIP *scip, SCIP_SOL *sol, FILE *file, SCIP_Bool printzeros)
Definition: scip_sol.c:1824