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