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-2018 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 email to 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 
75  retcode = SCIPreadProb(scip, filename, NULL);
76 
77  switch( retcode )
78  {
79  case SCIP_NOFILE:
80  SCIPinfoMessage(scip, NULL, "file <%s> not found\n", filename);
81  return SCIP_OKAY;
83  SCIPinfoMessage(scip, NULL, "no reader for input file <%s> available\n", filename);
84  return SCIP_OKAY;
85  case SCIP_READERROR:
86  SCIPinfoMessage(scip, NULL, "error reading file <%s>\n", filename);
87  return SCIP_OKAY;
88  default:
89  SCIP_CALL( retcode );
90  } /*lint !e788*/
91 
92  /*******************
93  * Problem Solving *
94  *******************/
95 
96  /* solve problem */
97  SCIPinfoMessage(scip, NULL, "\nsolve problem\n");
98  SCIPinfoMessage(scip, NULL, "=============\n\n");
99 
100  SCIP_CALL( SCIPsolve(scip) );
101 
102  /*******************
103  * Solution Output *
104  *******************/
105 
106  SCIP_CALL( SCIPgetBoolParam(scip, "misc/outputorigsol", &outputorigsol) );
107  if ( outputorigsol )
108  {
109  SCIP_SOL* bestsol;
110 
111  SCIPinfoMessage(scip, NULL, "\nprimal solution (original space):\n");
112  SCIPinfoMessage(scip, NULL, "=================================\n\n");
113 
114  bestsol = SCIPgetBestSol(scip);
115  if ( bestsol == NULL )
116  SCIPinfoMessage(scip, NULL, "no solution available\n");
117  else
118  {
119  SCIP_SOL* origsol;
120 
121  SCIP_CALL( SCIPcreateSolCopy(scip, &origsol, bestsol) );
122  SCIP_CALL( SCIPretransformSol(scip, origsol) );
123  SCIP_CALL( SCIPprintSol(scip, origsol, NULL, FALSE) );
124  SCIP_CALL( SCIPfreeSol(scip, &origsol) );
125  }
126  }
127  else
128  {
129  SCIPinfoMessage(scip, NULL, "\nprimal solution (transformed space):\n");
130  SCIPinfoMessage(scip, NULL, "====================================\n\n");
131 
132  SCIP_CALL( SCIPprintBestSol(scip, NULL, FALSE) );
133  }
134 
135 
136  /**************
137  * Statistics *
138  **************/
139 
140  SCIPinfoMessage(scip, NULL, "\nStatistics\n");
141  SCIPinfoMessage(scip, NULL, "==========\n\n");
142 
143  SCIP_CALL( SCIPprintStatistics(scip, NULL) );
144 
145  return SCIP_OKAY;
146 }
147 
148 /** evaluates command line parameters and runs SCIP appropriately in the given SCIP instance */
150  SCIP* scip, /**< SCIP data structure */
151  int argc, /**< number of shell parameters */
152  char** argv, /**< array with shell parameters */
153  const char* defaultsetname /**< name of default settings file */
154  )
155 { /*lint --e{850}*/
156  char* probname = NULL;
157  char* settingsname = NULL;
158  char* logname = NULL;
159  int randomseed;
160  SCIP_Bool randomseedread;
161  SCIP_Bool quiet;
162  SCIP_Bool paramerror;
164  SCIP_Bool onlyversion;
165  SCIP_Real primalreference = SCIP_UNKNOWN;
166  SCIP_Real dualreference = SCIP_UNKNOWN;
167  const char* dualrefstring;
168  const char* primalrefstring;
169  int i;
170 
171  /********************
172  * Parse parameters *
173  ********************/
174 
175  quiet = FALSE;
176  paramerror = FALSE;
177  interactive = FALSE;
178  onlyversion = FALSE;
179  randomseedread = FALSE;
180  randomseed = 0;
181  primalrefstring = NULL;
182  dualrefstring = NULL;
183 
184  for( i = 1; i < argc; ++i )
185  {
186  if( strcmp(argv[i], "-l") == 0 )
187  {
188  i++;
189  if( i < argc )
190  logname = argv[i];
191  else
192  {
193  printf("missing log filename after parameter '-l'\n");
194  paramerror = TRUE;
195  }
196  }
197  else if( strcmp(argv[i], "-q") == 0 )
198  quiet = TRUE;
199  else if( strcmp(argv[i], "-v") == 0 )
200  onlyversion = TRUE;
201  else if( strcmp(argv[i], "--version") == 0 )
202  onlyversion = TRUE;
203  else if( strcmp(argv[i], "-s") == 0 )
204  {
205  i++;
206  if( i < argc )
207  settingsname = argv[i];
208  else
209  {
210  printf("missing settings filename after parameter '-s'\n");
211  paramerror = TRUE;
212  }
213  }
214  else if( strcmp(argv[i], "-f") == 0 )
215  {
216  i++;
217  if( i < argc )
218  probname = argv[i];
219  else
220  {
221  printf("missing problem filename after parameter '-f'\n");
222  paramerror = TRUE;
223  }
224  }
225  else if( strcmp(argv[i], "-c") == 0 )
226  {
227  i++;
228  if( i < argc )
229  {
230  SCIP_CALL( SCIPaddDialogInputLine(scip, argv[i]) );
231  interactive = TRUE;
232  }
233  else
234  {
235  printf("missing command line after parameter '-c'\n");
236  paramerror = TRUE;
237  }
238  }
239  else if( strcmp(argv[i], "-b") == 0 )
240  {
241  i++;
242  if( i < argc )
243  {
244  SCIP_FILE* file;
245 
246  file = SCIPfopen(argv[i], "r");
247  if( file == NULL )
248  {
249  printf("cannot read command batch file <%s>\n", argv[i]);
250  SCIPprintSysError(argv[i]);
251  paramerror = TRUE;
252  }
253  else
254  {
255  while( !SCIPfeof(file) )
256  {
257  char buffer[SCIP_MAXSTRLEN];
258 
259  (void)SCIPfgets(buffer, (int) sizeof(buffer), file);
260  if( buffer[0] != '\0' )
261  {
262  SCIP_CALL_FINALLY( SCIPaddDialogInputLine(scip, buffer), SCIPfclose(file) );
263  }
264  }
265  SCIPfclose(file);
266  interactive = TRUE;
267  }
268  }
269  else
270  {
271  printf("missing command batch filename after parameter '-b'\n");
272  paramerror = TRUE;
273  }
274  }
275  else if( strcmp(argv[i], "-r") == 0 )
276  {
277  /*read a random seed from the command line */
278  i++;
279  if( i < argc && isdigit(argv[i][0]) )
280  {
281  randomseed = atoi(argv[i]);
282  randomseedread = TRUE;
283  }
284  else
285  {
286  printf("Random seed parameter '-r' followed by something that is not an integer\n");
287  paramerror = TRUE;
288  }
289  }
290  else if( strcmp(argv[i], "-o") == 0 )
291  {
292  if( i >= argc - 2 )
293  {
294  printf("wrong usage of reference objective parameter '-o': -o <primref> <dualref>\n");
295  paramerror = TRUE;
296  }
297  else
298  {
299  /* do not parse the strings directly, the settings could still influence the value of +-infinity */
300  primalrefstring = argv[i + 1];
301  dualrefstring = argv[i+2];
302  }
303  i += 2;
304  }
305  else
306  {
307  printf("invalid parameter <%s>\n", argv[i]);
308  paramerror = TRUE;
309  }
310  }
311 
312  if( interactive && probname != NULL )
313  {
314  printf("cannot mix batch mode '-c' and '-b' with file mode '-f'\n");
315  paramerror = TRUE;
316  }
317 
318  if( !paramerror )
319  {
320  /***********************************
321  * create log file message handler *
322  ***********************************/
323 
324  if( quiet )
325  {
326  SCIPsetMessagehdlrQuiet(scip, quiet);
327  }
328 
329  if( logname != NULL )
330  {
331  SCIPsetMessagehdlrLogfile(scip, logname);
332  }
333 
334  /***********************************
335  * Version and library information *
336  ***********************************/
337 
338  SCIPprintVersion(scip, NULL);
339  SCIPinfoMessage(scip, NULL, "\n");
340 
341  SCIPprintExternalCodes(scip, NULL);
342  SCIPinfoMessage(scip, NULL, "\n");
343 
344  if( onlyversion )
345  {
346  SCIPprintBuildOptions(scip, NULL);
347  SCIPinfoMessage(scip, NULL, "\n");
348  return SCIP_OKAY;
349  }
350 
351  /*****************
352  * Load settings *
353  *****************/
354 
355  if( settingsname != NULL )
356  {
357  SCIP_CALL( readParams(scip, settingsname) );
358  }
359  else if( defaultsetname != NULL )
360  {
361  SCIP_CALL( readParams(scip, defaultsetname) );
362  }
363 
364  /************************************
365  * Change random seed, if specified *
366  ***********************************/
367  if( randomseedread )
368  {
369  SCIP_CALL( SCIPsetIntParam(scip, "randomization/randomseedshift", randomseed) );
370  }
371 
372  /**************
373  * Start SCIP *
374  **************/
375 
376  if( probname != NULL )
377  {
378  SCIP_Bool validatesolve = FALSE;
379 
380  if( primalrefstring != NULL && dualrefstring != NULL )
381  {
382  char *endptr;
383  if( ! SCIPparseReal(scip, primalrefstring, &primalreference, &endptr) ||
384  ! SCIPparseReal(scip, dualrefstring, &dualreference, &endptr) )
385  {
386  printf("error parsing primal and dual reference values for validation: %s %s\n", primalrefstring, dualrefstring);
387  return SCIP_ERROR;
388  }
389  else
390  validatesolve = TRUE;
391  }
392  SCIP_CALL( fromCommandLine(scip, probname) );
393 
394  /* validate the solve */
395  if( validatesolve )
396  {
397  SCIP_CALL( SCIPvalidateSolve(scip, primalreference, dualreference, SCIPfeastol(scip), FALSE, NULL, NULL, NULL) );
398  }
399  }
400  else
401  {
402  SCIPinfoMessage(scip, NULL, "\n");
404  }
405  }
406  else
407  {
408  printf("\nsyntax: %s [-l <logfile>] [-q] [-s <settings>] [-r <randseed>] [-f <problem>] [-b <batchfile>] [-c \"command\"]\n"
409  " -v, --version : print version and build options\n"
410  " -l <logfile> : copy output into log file\n"
411  " -q : suppress screen messages\n"
412  " -s <settings> : load parameter settings (.set) file\n"
413  " -f <problem> : load and solve problem file\n"
414  " -o <primref> <dualref> : pass primal and dual objective reference values for validation at the end of the solve\n"
415  " -b <batchfile>: load and execute dialog command batch file (can be used multiple times)\n"
416  " -r <randseed> : nonnegative integer to be used as random seed. "
417  "Has priority over random seed specified through parameter settings (.set) file\n"
418  " -c \"command\" : execute single line of dialog commands (can be used multiple times)\n\n",
419  argv[0]);
420  }
421 
422  return SCIP_OKAY;
423 }
424 
425 /** creates a SCIP instance with default plugins, evaluates command line parameters, runs SCIP appropriately,
426  * and frees the SCIP instance
427  */
429  int argc, /**< number of shell parameters */
430  char** argv, /**< array with shell parameters */
431  const char* defaultsetname /**< name of default settings file */
432  )
433 {
434  SCIP* scip = NULL;
435  SCIP_RETCODE retcode = SCIP_OKAY;
436  /*********
437  * Setup *
438  *********/
439 
440  /* initialize SCIP */
441  SCIP_CALL( SCIPcreate(&scip) );
442 
443  /* we explicitly enable the use of a debug solution for this main SCIP instance */
444  SCIPenableDebugSol(scip);
445 
446  /* include default SCIP plugins */
447  SCIP_CALL_TERMINATE( retcode, SCIPincludeDefaultPlugins(scip), TERMINATE );
448 
449  /**********************************
450  * Process command line arguments *
451  **********************************/
452 
453  SCIP_CALL_TERMINATE( retcode, SCIPprocessShellArguments(scip, argc, argv, defaultsetname), TERMINATE );
454 
455 
456  /********************
457  * Deinitialization *
458  ********************/
459 TERMINATE:
460  SCIP_CALL( SCIPfree(&scip) );
461 
463 
464  return retcode;
465 }
SCIP_RETCODE SCIPprintBestSol(SCIP *scip, FILE *file, SCIP_Bool printzeros)
Definition: scip.c:39948
#define BMScheckEmptyMemory()
Definition: memory.h:137
SCIP_Real SCIPfeastol(SCIP *scip)
Definition: scip.c:46443
default message handler
#define SCIP_MAXSTRLEN
Definition: def.h:259
SCIP_Bool SCIPparseReal(SCIP *scip, const char *str, SCIP_Real *value, char **endptr)
Definition: scip.c:46683
#define SCIP_CALL_FINALLY(x, y)
Definition: def.h:392
#define FALSE
Definition: def.h:64
static SCIP_RETCODE fromCommandLine(SCIP *scip, const char *filename)
Definition: scipshell.c:54
void SCIPprintExternalCodes(SCIP *scip, FILE *file)
Definition: scip.c:9684
#define TRUE
Definition: def.h:63
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.c:748
SCIP_RETCODE SCIPprintStatistics(SCIP *scip, FILE *file)
Definition: scip.c:45651
void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
Definition: scip.c:1343
SCIP_Bool SCIPfileExists(const char *filename)
Definition: misc.c:10184
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.c:38168
SCIP_RETCODE SCIPsolve(SCIP *scip)
Definition: scip.c:16115
SCIP command line interface.
SCIP_RETCODE SCIPreadProb(SCIP *scip, const char *filename, const char *extension)
Definition: scip.c:10156
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.c:4432
SCIP_RETCODE SCIPrunShell(int argc, char **argv, const char *defaultsetname)
Definition: scipshell.c:428
#define SCIP_CALL(x)
Definition: def.h:350
#define SCIP_UNKNOWN
Definition: def.h:170
#define SCIP_Bool
Definition: def.h:61
SCIP_RETCODE SCIPincludeDefaultPlugins(SCIP *scip)
void SCIPprintVersion(SCIP *scip, FILE *file)
Definition: scip.c:611
void SCIPprintSysError(const char *message)
Definition: misc.c:9920
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)
Definition: scip.c:48435
void SCIPsetMessagehdlrQuiet(SCIP *scip, SCIP_Bool quiet)
Definition: scip.c:1255
SCIP_RETCODE SCIPsetIntParam(SCIP *scip, const char *name, int value)
Definition: scip.c:4688
SCIP_RETCODE SCIPfreeSol(SCIP *scip, SCIP_SOL **sol)
Definition: scip.c:38535
SCIP_RETCODE SCIPretransformSol(SCIP *scip, SCIP_SOL *sol)
Definition: scip.c:40060
SCIP_RETCODE SCIPprocessShellArguments(SCIP *scip, int argc, char **argv, const char *defaultsetname)
Definition: scipshell.c:149
SCIP_RETCODE SCIPstartInteraction(SCIP *scip)
Definition: scip.c:9898
SCIP_SOL * SCIPgetBestSol(SCIP *scip)
Definition: scip.c:39882
void SCIPsetMessagehdlrLogfile(SCIP *scip, const char *filename)
Definition: scip.c:1243
SCIP_RETCODE SCIPreadParams(SCIP *scip, const char *filename)
Definition: scip.c:4952
#define SCIP_Real
Definition: def.h:149
#define SCIP_CALL_TERMINATE(retcode, x, TERM)
Definition: def.h:371
int SCIPfclose(SCIP_FILE *fp)
Definition: fileio.c:219
default SCIP plugins
void SCIPprintBuildOptions(SCIP *scip, FILE *file)
Definition: scip.c:646
static SCIP_RETCODE interactive(SCIP *scip)
Definition: cmain.c:92
SCIP_RETCODE SCIPaddDialogInputLine(SCIP *scip, const char *inputline)
Definition: scip.c:9848
SCIP callable library.
SCIP_RETCODE SCIPfree(SCIP **scip)
Definition: scip.c:780
void SCIPenableDebugSol(SCIP *scip)
Definition: scip.c:1162
SCIP_RETCODE SCIPprintSol(SCIP *scip, SCIP_SOL *sol, FILE *file, SCIP_Bool printzeros)
Definition: scip.c:39325