Scippy

SoPlex

Sequential object-oriented simPlex

soplexmain.cpp
Go to the documentation of this file.
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2 /* */
3 /* This file is part of the class library */
4 /* SoPlex --- the Sequential object-oriented simPlex. */
5 /* */
6 /* Copyright (C) 1996-2022 Konrad-Zuse-Zentrum */
7 /* fuer Informationstechnik Berlin */
8 /* */
9 /* SoPlex is distributed under the terms of the ZIB Academic Licence. */
10 /* */
11 /* You should have received a copy of the ZIB Academic License */
12 /* along with SoPlex; see the file COPYING. If not email to soplex@zib.de. */
13 /* */
14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15 
16 /**@file soplexmain.cpp
17  * @brief Command line interface of SoPlex LP solver
18  */
19 
20 #include <assert.h>
21 #include <math.h>
22 #include <string.h>
23 
24 #include <iostream>
25 #include <iomanip>
26 #include <fstream>
27 
28 #include "soplex.h"
29 #include "soplex/validation.h"
30 
31 using namespace soplex;
32 
33 // function prototype
34 int main(int argc, char* argv[]);
35 
36 // prints usage and command line options
37 static
38 void printUsage(const char* const argv[], int idx)
39 {
40  const char* usage =
41  "general options:\n"
42  " --readbas=<basfile> read starting basis from file\n"
43  " --writebas=<basfile> write terminal basis to file\n"
44  " --writefile=<lpfile> write LP to file in LP or MPS format depending on extension\n"
45  " --writedual=<lpfile> write the dual LP to a file in LP or MPS formal depending on extension\n"
46  " --<type>:<name>=<val> change parameter value using syntax of settings file entries\n"
47  " --loadset=<setfile> load parameters from settings file (overruled by command line parameters)\n"
48  " --saveset=<setfile> save parameters to settings file\n"
49  " --diffset=<setfile> save modified parameters to settings file\n"
50  " --extsol=<value> external solution for soplex to use for validation\n"
51  "\n"
52  "limits and tolerances:\n"
53  " -t<s> set time limit to <s> seconds\n"
54  " -i<n> set iteration limit to <n>\n"
55  " -f<eps> set primal feasibility tolerance to <eps>\n"
56  " -o<eps> set dual feasibility (optimality) tolerance to <eps>\n"
57  " -l<eps> set validation tolerance to <eps>\n"
58  "\n"
59  "algorithmic settings (* indicates default):\n"
60  " --readmode=<value> choose reading mode for <lpfile> (0* - floating-point, 1 - rational)\n"
61  " --solvemode=<value> choose solving mode (0 - floating-point solve, 1* - auto, 2 - force iterative refinement)\n"
62  " --arithmetic=<value> choose base arithmetic type (0 - double, 1 - quadprecision, 2 - higher multiprecision)\n"
63 #ifdef SOPLEX_WITH_MPFR
64  " --precision=<value> choose precision for multiprecision solve (only active when arithmetic=2 minimal value = 50)\n"
65 #endif
66 #ifdef SOPLEX_WITH_CPPMPF
67  " --precision=<value> choose precision for multiprecision solve (only active when arithmetic=2, possible values 50,100,200, compile with mpfr for arbitrary precision)\n"
68 #endif
69  " -s<value> choose simplifier/presolver (0 - off, 1* - internal, 2*- PaPILO)\n"
70  " -g<value> choose scaling (0 - off, 1 - uni-equilibrium, 2* - bi-equilibrium, 3 - geometric, 4 - iterated geometric, 5 - least squares, 6 - geometric-equilibrium)\n"
71  " -p<value> choose pricing (0* - auto, 1 - dantzig, 2 - parmult, 3 - devex, 4 - quicksteep, 5 - steep)\n"
72  " -r<value> choose ratio tester (0 - textbook, 1 - harris, 2 - fast, 3* - boundflipping)\n"
73  "\n"
74  "display options:\n"
75  " -v<level> set verbosity to <level> (0 - error, 3 - normal, 5 - high)\n"
76  " -x print primal solution\n"
77  " -y print dual multipliers\n"
78  " -X print primal solution in rational numbers\n"
79  " -Y print dual multipliers in rational numbers\n"
80  " -q display detailed statistics\n"
81  " -c perform final check of optimal solution in original problem\n"
82  "\n";
83 
84  if(idx <= 0)
85  std::cerr << "missing input file\n\n";
86  else
87  std::cerr << "invalid option \"" << argv[idx] << "\"\n\n";
88 
89  std::cerr << "usage: " << argv[0] << " " << "[options] <lpfile>\n"
90 #ifdef SOPLEX_WITH_ZLIB
91  << " <lpfile> linear program as .mps[.gz] or .lp[.gz] file\n\n"
92 #else
93  << " <lpfile> linear program as .mps or .lp file\n\n"
94 #endif
95  << usage;
96 }
97 
98 // cleans up C strings
99 static
100 void freeStrings(char*& s1, char*& s2, char*& s3, char*& s4, char*& s5)
101 {
102  if(s1 != 0)
103  {
104  delete [] s1;
105  s1 = 0;
106  }
107 
108  if(s2 != 0)
109  {
110  delete [] s2;
111  s2 = 0;
112  }
113 
114  if(s3 != 0)
115  {
116  delete [] s3;
117  s3 = 0;
118  }
119 
120  if(s4 != 0)
121  {
122  delete [] s4;
123  s4 = 0;
124  }
125 
126  if(s5 != 0)
127  {
128  delete [] s5;
129  s5 = 0;
130  }
131 }
132 
133 /// performs external feasibility check with real type
134 ///@todo implement external check; currently we use the internal methods for convenience
135 
136 template <class R>
137 static
139 {
140  if(soplex.hasPrimal())
141  {
142  R boundviol;
143  R rowviol;
144  R sumviol;
145 
146  if(soplex.getBoundViolation(boundviol, sumviol) && soplex.getRowViolation(rowviol, sumviol))
147  {
148  MSG_INFO1(soplex.spxout,
149  R maxviol = boundviol > rowviol ? boundviol : rowviol;
150  bool feasible = (maxviol <= soplex.realParam(SoPlexBase<R>::FEASTOL));
151  soplex.spxout << "Primal solution " << (feasible ? "feasible" : "infeasible")
152  << " in original problem (max. violation = " << std::scientific << maxviol
153  << std::setprecision(8) << std::fixed << ").\n");
154  }
155  else
156  {
157  MSG_INFO1(soplex.spxout, soplex.spxout << "Could not check primal solution.\n");
158  }
159  }
160  else
161  {
162  MSG_INFO1(soplex.spxout, soplex.spxout << "No primal solution available.\n");
163  }
164 
165  if(soplex.hasDual())
166  {
167  R redcostviol;
168  R dualviol;
169  R sumviol;
170 
171  if(soplex.getRedCostViolation(redcostviol, sumviol) && soplex.getDualViolation(dualviol, sumviol))
172  {
173  MSG_INFO1(soplex.spxout,
174  R maxviol = redcostviol > dualviol ? redcostviol : dualviol;
175  bool feasible = (maxviol <= soplex.realParam(SoPlexBase<R>::OPTTOL));
176  soplex.spxout << "Dual solution " << (feasible ? "feasible" : "infeasible")
177  << " in original problem (max. violation = " << std::scientific << maxviol
178  << std::setprecision(8) << std::fixed << ").\n"
179  );
180  }
181  else
182  {
183  MSG_INFO1(soplex.spxout, soplex.spxout << "Could not check dual solution.\n");
184  }
185  }
186  else
187  {
188  MSG_INFO1(soplex.spxout, soplex.spxout << "No dual solution available.\n");
189  }
190 }
191 
192 /// performs external feasibility check with rational type
193 ///@todo implement external check; currently we use the internal methods for convenience
194 template <class R>
196 {
197  if(soplex.hasPrimal())
198  {
199  Rational boundviol;
200  Rational rowviol;
201  Rational sumviol;
202 
203  if(soplex.getBoundViolationRational(boundviol, sumviol)
204  && soplex.getRowViolationRational(rowviol, sumviol))
205  {
206  MSG_INFO1(soplex.spxout,
207  Rational maxviol = boundviol > rowviol ? boundviol : rowviol;
208  bool feasible = (maxviol <= soplex.realParam(SoPlexBase<R>::FEASTOL));
209  soplex.spxout << "Primal solution " << (feasible ? "feasible" : "infeasible") <<
210  " in original problem (max. violation = " << maxviol << ").\n"
211  );
212  }
213  else
214  {
215  MSG_INFO1(soplex.spxout, soplex.spxout << "Could not check primal solution.\n");
216  }
217  }
218  else
219  {
220  MSG_INFO1(soplex.spxout, soplex.spxout << "No primal solution available.\n");
221  }
222 
223  if(soplex.hasDual())
224  {
225  Rational redcostviol;
226  Rational dualviol;
227  Rational sumviol;
228 
229  if(soplex.getRedCostViolationRational(redcostviol, sumviol)
230  && soplex.getDualViolationRational(dualviol, sumviol))
231  {
232  MSG_INFO1(soplex.spxout,
233  Rational maxviol = redcostviol > dualviol ? redcostviol : dualviol;
234  bool feasible = (maxviol <= soplex.realParam(SoPlexBase<R>::OPTTOL));
235  soplex.spxout << "Dual solution " << (feasible ? "feasible" : "infeasible") <<
236  " in original problem (max. violation = " << maxviol << ").\n"
237  );
238  }
239  else
240  {
241  MSG_INFO1(soplex.spxout, soplex.spxout << "Could not check dual solution.\n");
242  }
243  }
244  else
245  {
246  MSG_INFO1(soplex.spxout, soplex.spxout << "No dual solution available.\n");
247  }
248 }
249 
250 /// performs external feasibility check according to check mode
251 template <class R>
253 {
257  {
258  checkSolutionRational(soplex);
259  }
260  else
261  {
262  checkSolutionReal(soplex);
263  }
264 
265  MSG_INFO1(soplex.spxout, soplex.spxout << "\n");
266 }
267 
268 template <class R>
269 static
271  bool real = true, bool rational = false)
272 {
273  int printprec;
274  int printwidth;
275  printprec = (int) - log10(Real(Param::epsilon()));
276  printwidth = printprec + 10;
277 
278  if(real)
279  {
280  VectorBase<R> primal(soplex.numCols());
281 
282  if(soplex.getPrimalRay(primal))
283  {
284  MSG_INFO1(soplex.spxout, soplex.spxout << "\nPrimal ray (name, value):\n";)
285 
286  for(int i = 0; i < soplex.numCols(); ++i)
287  {
288  if(isNotZero(primal[i]))
289  {
290  MSG_INFO1(soplex.spxout, soplex.spxout << colnames[i] << "\t"
291  << std::setw(printwidth) << std::setprecision(printprec)
292  << primal[i] << std::endl;)
293  }
294  }
295 
296  MSG_INFO1(soplex.spxout, soplex.spxout << "All other entries are zero (within "
297  << std::setprecision(1) << std::scientific << Param::epsilon()
298  << std::setprecision(8) << std::fixed
299  << ")." << std::endl;)
300  }
301  else if(soplex.isPrimalFeasible() && soplex.getPrimal(primal))
302  {
303  int nNonzeros = 0;
304  MSG_INFO1(soplex.spxout, soplex.spxout << "\nPrimal solution (name, value):\n";)
305 
306  for(int i = 0; i < soplex.numCols(); ++i)
307  {
308  if(isNotZero(primal[i]))
309  {
310  MSG_INFO1(soplex.spxout, soplex.spxout << colnames[i] << "\t"
311  << std::setw(printwidth) << std::setprecision(printprec)
312  << primal[i] << std::endl;)
313  ++nNonzeros;
314  }
315  }
316 
317  MSG_INFO1(soplex.spxout, soplex.spxout << "All other variables are zero (within "
318  << std::setprecision(1) << std::scientific << Param::epsilon()
319  << std::setprecision(8) << std::fixed
320  << "). Solution has " << nNonzeros << " nonzero entries." << std::endl;)
321  }
322  else
323  MSG_INFO1(soplex.spxout, soplex.spxout << "No primal information available.\n")
324  }
325 
326  if(rational)
327  {
328  VectorRational primal(soplex.numCols());
329 
330  if(soplex.getPrimalRayRational(primal))
331  {
332  MSG_INFO1(soplex.spxout, soplex.spxout << "\nPrimal ray (name, value):\n";)
333 
334  for(int i = 0; i < soplex.numCols(); ++i)
335  {
336  if(primal[i] != (Rational) 0)
337  {
338  MSG_INFO1(soplex.spxout, soplex.spxout << colnames[i] << "\t"
339  << std::setw(printwidth) << std::setprecision(printprec)
340  << primal[i] << std::endl;)
341  }
342  }
343 
344  MSG_INFO1(soplex.spxout, soplex.spxout << "All other entries are zero." << std::endl;)
345  }
346 
347  if(soplex.isPrimalFeasible() && soplex.getPrimalRational(primal))
348  {
349  int nNonzeros = 0;
350  MSG_INFO1(soplex.spxout, soplex.spxout << "\nPrimal solution (name, value):\n";)
351 
352  for(int i = 0; i < soplex.numColsRational(); ++i)
353  {
354  if(primal[i] != (Rational) 0)
355  {
356  MSG_INFO1(soplex.spxout, soplex.spxout << colnames[i] << "\t" << primal[i] << std::endl;)
357  ++nNonzeros;
358  }
359  }
360 
361  MSG_INFO1(soplex.spxout, soplex.spxout << "All other variables are zero. Solution has "
362  << nNonzeros << " nonzero entries." << std::endl;)
363  }
364  else
365  MSG_INFO1(soplex.spxout, soplex.spxout << "No primal (rational) solution available.\n")
366 
367  }
368 }
369 
370 template <class R>
371 static
373  bool real = true, bool rational = false)
374 {
375  int printprec;
376  int printwidth;
377  printprec = (int) - log10(Real(Param::epsilon()));
378  printwidth = printprec + 10;
379 
380  if(real)
381  {
382  VectorBase<R> dual(soplex.numRows());
383 
384  if(soplex.getDualFarkas(dual))
385  {
386  MSG_INFO1(soplex.spxout, soplex.spxout << "\nDual ray (name, value):\n";)
387 
388  for(int i = 0; i < soplex.numRows(); ++i)
389  {
390  if(isNotZero(dual[i]))
391  {
392  MSG_INFO1(soplex.spxout, soplex.spxout << rownames[i] << "\t"
393  << std::setw(printwidth) << std::setprecision(printprec)
394  << dual[i] << std::endl;)
395  }
396  }
397 
398  MSG_INFO1(soplex.spxout, soplex.spxout << "All other entries are zero (within "
399  << std::setprecision(1) << std::scientific << Param::epsilon()
400  << std::setprecision(8) << std::fixed << ")." << std::endl;)
401  }
402  else if(soplex.isDualFeasible() && soplex.getDual(dual))
403  {
404  MSG_INFO1(soplex.spxout, soplex.spxout << "\nDual solution (name, value):\n";)
405 
406  for(int i = 0; i < soplex.numRows(); ++i)
407  {
408  if(isNotZero(dual[i]))
409  {
410  MSG_INFO1(soplex.spxout, soplex.spxout << rownames[i] << "\t"
411  << std::setw(printwidth) << std::setprecision(printprec)
412  << dual[i] << std::endl;)
413  }
414  }
415 
416  MSG_INFO1(soplex.spxout, soplex.spxout << "All other dual values are zero (within "
417  << std::setprecision(1) << std::scientific << Param::epsilon()
418  << std::setprecision(8) << std::fixed << ")." << std::endl;)
419 
420  VectorBase<R> redcost(soplex.numCols());
421 
422  if(soplex.getRedCost(redcost))
423  {
424  MSG_INFO1(soplex.spxout, soplex.spxout << "\nReduced costs (name, value):\n";)
425 
426  for(int i = 0; i < soplex.numCols(); ++i)
427  {
428  if(isNotZero(redcost[i]))
429  {
430  MSG_INFO1(soplex.spxout, soplex.spxout << colnames[i] << "\t"
431  << std::setw(printwidth) << std::setprecision(printprec)
432  << redcost[i] << std::endl;)
433  }
434  }
435 
436  MSG_INFO1(soplex.spxout, soplex.spxout << "All other reduced costs are zero (within "
437  << std::setprecision(1) << std::scientific << Param::epsilon()
438  << std::setprecision(8) << std::fixed << ")." << std::endl;)
439  }
440  }
441  else
442  MSG_INFO1(soplex.spxout, soplex.spxout << "No dual information available.\n")
443  }
444 
445  if(rational)
446  {
447  VectorRational dual(soplex.numRows());
448 
449  if(soplex.getDualFarkasRational(dual))
450  {
451  MSG_INFO1(soplex.spxout, soplex.spxout << "\nDual ray (name, value):\n";)
452 
453  for(int i = 0; i < soplex.numRows(); ++i)
454  {
455  if(dual[i] != (Rational) 0)
456  {
457  MSG_INFO1(soplex.spxout, soplex.spxout << rownames[i] << "\t"
458  << std::setw(printwidth)
459  << std::setprecision(printprec)
460  << dual[i] << std::endl;)
461  }
462  }
463 
464  MSG_INFO1(soplex.spxout, soplex.spxout << "All other entries are zero." << std::endl;)
465  }
466 
467  if(soplex.isDualFeasible() && soplex.getDualRational(dual))
468  {
469  MSG_INFO1(soplex.spxout, soplex.spxout << "\nDual solution (name, value):\n";)
470 
471  for(int i = 0; i < soplex.numRowsRational(); ++i)
472  {
473  if(dual[i] != (Rational) 0)
474  MSG_INFO1(soplex.spxout, soplex.spxout << rownames[i] << "\t" << dual[i] << std::endl;)
475  }
476 
477  MSG_INFO1(soplex.spxout, soplex.spxout << "All other dual values are zero." << std::endl;)
478 
479  VectorRational redcost(soplex.numCols());
480 
481  if(soplex.getRedCostRational(redcost))
482  {
483  MSG_INFO1(soplex.spxout, soplex.spxout << "\nReduced costs (name, value):\n";)
484 
485  for(int i = 0; i < soplex.numCols(); ++i)
486  {
487  if(redcost[i] != (Rational) 0)
488  MSG_INFO1(soplex.spxout, soplex.spxout << colnames[i] << "\t" << redcost[i] << std::endl;)
489  }
490 
491  MSG_INFO1(soplex.spxout, soplex.spxout << "All other reduced costs are zero." << std::endl;)
492  }
493  }
494  else
495  MSG_INFO1(soplex.spxout, soplex.spxout << "No dual (rational) solution available.\n")
496  }
497 }
498 
499 // Runs SoPlex with the parsed boost variables map
500 template <class R>
501 int runSoPlex(int argc, char* argv[])
502 {
503  SoPlexBase<R>* soplex = nullptr;
504 
505  Timer* readingTime = nullptr;
506  Validation<R>* validation = nullptr;
507  int optidx;
508 
509  const char* lpfilename = nullptr;
510  char* readbasname = nullptr;
511  char* writebasname = nullptr;
512  char* writefilename = nullptr;
513  char* writedualfilename = nullptr;
514  char* loadsetname = nullptr;
515  char* savesetname = nullptr;
516  char* diffsetname = nullptr;
517  bool printPrimal = false;
518  bool printPrimalRational = false;
519  bool printDual = false;
520  bool printDualRational = false;
521  bool displayStatistics = false;
522  bool checkSol = false;
523 
524  int returnValue = 0;
525 
526  try
527  {
528  NameSet rownames;
529  NameSet colnames;
530 
531  // create default timer (CPU time)
533  soplex = nullptr;
534  spx_alloc(soplex);
535  new(soplex) SoPlexBase<R>();
536 
537  soplex->printVersion();
538  MSG_INFO1(soplex->spxout, soplex->spxout << SOPLEX_COPYRIGHT << std::endl << std::endl);
539 
540  validation = nullptr;
541  spx_alloc(validation);
542  new(validation) Validation<R>();
543 
544  // no options were given
545  if(argc <= 1)
546  {
547  printUsage(argv, 0);
548  returnValue = 1;
549  goto TERMINATE;
550  }
551 
552  // read arguments from command line
553  for(optidx = 1; optidx < argc; optidx++)
554  {
555  char* option = argv[optidx];
556 
557  // we reached <lpfile>
558  if(option[0] != '-')
559  {
560  lpfilename = argv[optidx];
561  continue;
562  }
563 
564  // option string must start with '-', must contain at least two characters, and exactly two characters if and
565  // only if it is -x, -y, -q, or -c
566  if(option[0] != '-' || option[1] == '\0'
567  || ((option[2] == '\0') != (option[1] == 'x' || option[1] == 'X' || option[1] == 'y'
568  || option[1] == 'Y' || option[1] == 'q' || option[1] == 'c')))
569  {
570  printUsage(argv, optidx);
571  returnValue = 1;
572  goto TERMINATE_FREESTRINGS;
573  }
574 
575  switch(option[1])
576  {
577  case '-' :
578  {
579  option = &option[2];
580 
581  // --readbas=<basfile> : read starting basis from file
582  if(strncmp(option, "readbas=", 8) == 0)
583  {
584  if(readbasname == nullptr)
585  {
586  char* filename = &option[8];
587  readbasname = new char[strlen(filename) + 1];
588  spxSnprintf(readbasname, strlen(filename) + 1, "%s", filename);
589  }
590  }
591  // --writebas=<basfile> : write terminal basis to file
592  else if(strncmp(option, "writebas=", 9) == 0)
593  {
594  if(writebasname == nullptr)
595  {
596  char* filename = &option[9];
597  writebasname = new char[strlen(filename) + 1];
598  spxSnprintf(writebasname, strlen(filename) + 1, "%s", filename);
599  }
600  }
601  // --writefile=<lpfile> : write LP to file
602  else if(strncmp(option, "writefile=", 10) == 0)
603  {
604  if(writefilename == nullptr)
605  {
606  char* filename = &option[10];
607  writefilename = new char[strlen(filename) + 1];
608  spxSnprintf(writefilename, strlen(filename) + 1, "%s", filename);
609  }
610  }
611  // --writedual=<lpfile> : write dual LP to a file
612  else if(strncmp(option, "writedual=", 10) == 0)
613  {
614  if(writedualfilename == nullptr)
615  {
616  char* dualfilename = &option[10];
617  writedualfilename = new char[strlen(dualfilename) + 1];
618  spxSnprintf(writedualfilename, strlen(dualfilename) + 1, "%s", dualfilename);
619  }
620  }
621  // --loadset=<setfile> : load parameters from settings file
622  else if(strncmp(option, "loadset=", 8) == 0)
623  {
624  if(loadsetname == nullptr)
625  {
626  char* filename = &option[8];
627  loadsetname = new char[strlen(filename) + 1];
628  spxSnprintf(loadsetname, strlen(filename) + 1, "%s", filename);
629 
630  if(!soplex->loadSettingsFile(loadsetname))
631  {
632  printUsage(argv, optidx);
633  returnValue = 1;
634  goto TERMINATE_FREESTRINGS;
635  }
636  else
637  {
638  // we need to start parsing again because some command line parameters might have been overwritten
639  optidx = 0;
640  }
641  }
642  }
643  // --saveset=<setfile> : save parameters to settings file
644  else if(strncmp(option, "saveset=", 8) == 0)
645  {
646  if(savesetname == nullptr)
647  {
648  char* filename = &option[8];
649  savesetname = new char[strlen(filename) + 1];
650  spxSnprintf(savesetname, strlen(filename) + 1, "%s", filename);
651  }
652  }
653  // --diffset=<setfile> : save modified parameters to settings file
654  else if(strncmp(option, "diffset=", 8) == 0)
655  {
656  if(diffsetname == nullptr)
657  {
658  char* filename = &option[8];
659  diffsetname = new char[strlen(filename) + 1];
660  spxSnprintf(diffsetname, strlen(filename) + 1, "%s", filename);
661  }
662  }
663  // --readmode=<value> : choose reading mode for <lpfile> (0* - floating-point, 1 - rational)
664  else if(strncmp(option, "readmode=", 9) == 0)
665  {
666  if(!soplex->setIntParam(soplex->READMODE, option[9] - '0'))
667  {
668  printUsage(argv, optidx);
669  returnValue = 1;
670  goto TERMINATE_FREESTRINGS;
671  }
672  }
673  // --solvemode=<value> : choose solving mode (0* - floating-point solve, 1 - auto, 2 - force iterative refinement)
674  else if(strncmp(option, "solvemode=", 10) == 0)
675  {
676  if(!soplex->setIntParam(soplex->SOLVEMODE, option[10] - '0'))
677  {
678  printUsage(argv, optidx);
679  returnValue = 1;
680  goto TERMINATE_FREESTRINGS;
681  }
682  // if the LP is parsed rationally and might be solved rationally, we choose automatic syncmode such that
683  // the rational LP is kept after reading
684  else if(soplex->intParam(soplex->READMODE) == soplex->READMODE_RATIONAL
685  && soplex->intParam(soplex->SOLVEMODE) != soplex->SOLVEMODE_REAL)
686  {
687  soplex->setIntParam(soplex->SYNCMODE, soplex->SYNCMODE_AUTO);
688  }
689  }
690  // --extsol=<value> : external solution for soplex to use for validation
691  else if(strncmp(option, "extsol=", 7) == 0)
692  {
693  char* input = &option[7];
694 
695  if(!validation->updateExternalSolution(input))
696  {
697  printUsage(argv, optidx);
698  returnValue = 1;
699  goto TERMINATE_FREESTRINGS;
700  }
701  }
702  // --arithmetic=<value> : base arithmetic type, directly handled in main()
703  else if(strncmp(option, "arithmetic=", 11) == 0)
704  {
705  continue;
706  }
707  // --precision=<value> : arithmetic precision, directly handled in main()
708  else if(strncmp(option, "precision=", 10) == 0)
709  {
710  continue;
711  }
712  // --<type>:<name>=<val> : change parameter value using syntax of settings file entries
713  else if(!soplex->parseSettingsString(option))
714  {
715  printUsage(argv, optidx);
716  returnValue = 1;
717  goto TERMINATE_FREESTRINGS;
718  }
719 
720  break;
721  }
722 
723  case 't' :
724 
725  // -t<s> : set time limit to <s> seconds
726  if(!soplex->setRealParam(soplex->TIMELIMIT, atoi(&option[2])))
727  {
728  printUsage(argv, optidx);
729  returnValue = 1;
730  goto TERMINATE_FREESTRINGS;
731  }
732 
733  break;
734 
735  case 'i' :
736 
737  // -i<n> : set iteration limit to <n>
738  if(!soplex->setIntParam(soplex->ITERLIMIT, atoi(&option[2])))
739  {
740  printUsage(argv, optidx);
741  returnValue = 1;
742  goto TERMINATE_FREESTRINGS;
743  }
744 
745  break;
746 
747  case 'f' :
748 
749  // -f<eps> : set primal feasibility tolerance to <eps>
750  if(!soplex->setRealParam(soplex->FEASTOL, atof(&option[2])))
751  {
752  printUsage(argv, optidx);
753  returnValue = 1;
754  goto TERMINATE_FREESTRINGS;
755  }
756 
757  break;
758 
759  case 'o' :
760 
761  // -o<eps> : set dual feasibility (optimality) tolerance to <eps>
762  if(!soplex->setRealParam(soplex->OPTTOL, atof(&option[2])))
763  {
764  printUsage(argv, optidx);
765  returnValue = 1;
766  goto TERMINATE_FREESTRINGS;
767  }
768 
769  break;
770 
771  case 'l' :
772 
773  // l<eps> : set validation tolerance to <eps>
774  if(!validation->updateValidationTolerance(&option[2]))
775  {
776  printUsage(argv, optidx);
777  returnValue = 1;
778  goto TERMINATE_FREESTRINGS;
779  }
780 
781  break;
782 
783  case 's' :
784 
785  // -s<value> : choose simplifier/presolver (0 - off, 1 - internal, 2* - PaPILO)
786  if(!soplex->setIntParam(soplex->SIMPLIFIER, option[2] - '0'))
787  {
788  printUsage(argv, optidx);
789  returnValue = 1;
790  goto TERMINATE_FREESTRINGS;
791  }
792 
793  break;
794 
795  case 'g' :
796 
797  // -g<value> : choose scaling (0 - off, 1 - uni-equilibrium, 2* - bi-equilibrium, 3 - geometric, 4 - iterated geometric, 5 - least squares, 6 - geometric-equilibrium)
798  if(!soplex->setIntParam(soplex->SCALER, option[2] - '0'))
799  {
800  printUsage(argv, optidx);
801  returnValue = 1;
802  goto TERMINATE_FREESTRINGS;
803  }
804 
805  break;
806 
807  case 'p' :
808 
809  // -p<value> : choose pricing (0* - auto, 1 - dantzig, 2 - parmult, 3 - devex, 4 - quicksteep, 5 - steep)
810  if(!soplex->setIntParam(soplex->PRICER, option[2] - '0'))
811  {
812  printUsage(argv, optidx);
813  returnValue = 1;
814  goto TERMINATE_FREESTRINGS;
815  }
816 
817  break;
818 
819  case 'r' :
820 
821  // -r<value> : choose ratio tester (0 - textbook, 1 - harris, 2* - fast, 3 - boundflipping)
822  if(!soplex->setIntParam(soplex->RATIOTESTER, option[2] - '0'))
823  {
824  printUsage(argv, optidx);
825  returnValue = 1;
826  goto TERMINATE_FREESTRINGS;
827  }
828 
829  break;
830 
831  case 'v' :
832 
833  // -v<level> : set verbosity to <level> (0 - error, 3 - normal, 5 - high)
834  if(!soplex->setIntParam(soplex->VERBOSITY, option[2] - '0'))
835  {
836  printUsage(argv, optidx);
837  returnValue = 1;
838  goto TERMINATE_FREESTRINGS;
839  }
840 
841  break;
842 
843  case 'x' :
844  // -x : print primal solution
845  printPrimal = true;
846  break;
847 
848  case 'X' :
849  // -X : print primal solution with rationals
850  printPrimalRational = true;
851  break;
852 
853  case 'y' :
854  // -y : print dual multipliers
855  printDual = true;
856  break;
857 
858  case 'Y' :
859  // -Y : print dual multipliers with rationals
860  printDualRational = true;
861  break;
862 
863  case 'q' :
864  // -q : display detailed statistics
865  displayStatistics = true;
866  break;
867 
868  case 'c' :
869  // -c : perform final check of optimal solution in original problem
870  checkSol = true;
871  break;
872 
873  case 'h' :
874 
875  // -h : display all parameters
876  if(!soplex->saveSettingsFile(0, false))
877  {
878  MSG_ERROR(std::cerr << "Error printing parameters\n");
879  }
880 
881  break;
882 
883  //lint -fallthrough
884  default :
885  {
886  printUsage(argv, optidx);
887  returnValue = 1;
888  goto TERMINATE_FREESTRINGS;
889  }
890  }
891  }
892 
893  MSG_INFO1(soplex->spxout, soplex->printUserSettings();)
894 
895  // no LP file was given and no settings files are written
896  if(lpfilename == nullptr && savesetname == nullptr && diffsetname == nullptr)
897  {
898  printUsage(argv, 0);
899  returnValue = 1;
900  goto TERMINATE_FREESTRINGS;
901  }
902 
903  // ensure that syncmode is not manual
904  if(soplex->intParam(soplex->SYNCMODE) == soplex->SYNCMODE_MANUAL)
905  {
906  MSG_ERROR(std::cerr <<
907  "Error: manual synchronization is invalid on command line. Change parameter int:syncmode.\n");
908  returnValue = 1;
909  goto TERMINATE_FREESTRINGS;
910  }
911 
912  // save settings files
913  if(savesetname != nullptr)
914  {
915  MSG_INFO1(soplex->spxout, soplex->spxout << "Saving parameters to settings file <" << savesetname <<
916  "> . . .\n");
917 
918  if(!soplex->saveSettingsFile(savesetname, false))
919  {
920  MSG_ERROR(std::cerr << "Error writing parameters to file <" << savesetname << ">\n");
921  }
922  }
923 
924  if(diffsetname != nullptr)
925  {
926  MSG_INFO1(soplex->spxout, soplex->spxout << "Saving modified parameters to settings file <" <<
927  diffsetname << "> . . .\n");
928 
929  if(!soplex->saveSettingsFile(diffsetname, true))
930  {
931  MSG_ERROR(std::cerr << "Error writing modified parameters to file <" << diffsetname << ">\n");
932  }
933  }
934 
935  // no LP file given: exit after saving settings
936  if(lpfilename == nullptr)
937  {
938  if(loadsetname != nullptr || savesetname != nullptr || diffsetname != nullptr)
939  {
940  MSG_INFO1(soplex->spxout, soplex->spxout << "\n");
941  }
942 
943  goto TERMINATE_FREESTRINGS;
944  }
945 
946  // measure time for reading LP file and basis file
947  readingTime->start();
948 
949  // if the LP is parsed rationally and might be solved rationally, we choose automatic syncmode such that
950  // the rational LP is kept after reading
951  if(soplex->intParam(soplex->READMODE) == soplex->READMODE_RATIONAL
952  && soplex->intParam(soplex->SOLVEMODE) != soplex->SOLVEMODE_REAL)
953  {
954  soplex->setIntParam(soplex->SYNCMODE, soplex->SYNCMODE_AUTO);
955  }
956 
957  // read LP from input file
958  MSG_INFO1(soplex->spxout, soplex->spxout << "Reading "
959  << (soplex->intParam(soplex->READMODE) == soplex->READMODE_REAL ? "(real)" : "(rational)")
960  << " LP file <" << lpfilename << "> . . .\n");
961 
962  if(!soplex->readFile(lpfilename, &rownames, &colnames))
963  {
964  MSG_ERROR(std::cerr << "Error while reading file <" << lpfilename << ">.\n");
965  returnValue = 1;
966  goto TERMINATE_FREESTRINGS;
967  }
968 
969  // write LP if specified
970  if(writefilename != nullptr)
971  {
972  if(!soplex->writeFile(writefilename, &rownames, &colnames))
973  {
974  MSG_ERROR(std::cerr << "Error while writing file <" << writefilename << ">.\n\n");
975  returnValue = 1;
976  goto TERMINATE_FREESTRINGS;
977  }
978  else
979  {
980  MSG_INFO1(soplex->spxout, soplex->spxout << "Written LP to file <" << writefilename << ">.\n\n");
981  }
982  }
983 
984  // write dual LP if specified
985  if(writedualfilename != nullptr)
986  {
987  if(!soplex->writeDualFileReal(writedualfilename, &rownames, &colnames))
988  {
989  MSG_ERROR(std::cerr << "Error while writing dual file <" << writedualfilename << ">.\n\n");
990  returnValue = 1;
991  goto TERMINATE_FREESTRINGS;
992  }
993  else
994  {
995  MSG_INFO1(soplex->spxout, soplex->spxout << "Written dual LP to file <" << writedualfilename <<
996  ">.\n\n");
997  }
998  }
999 
1000  // read basis file if specified
1001  if(readbasname != nullptr)
1002  {
1003  MSG_INFO1(soplex->spxout, soplex->spxout << "Reading basis file <" << readbasname << "> . . . ");
1004 
1005  if(!soplex->readBasisFile(readbasname, &rownames, &colnames))
1006  {
1007  MSG_ERROR(std::cerr << "Error while reading file <" << readbasname << ">.\n");
1008  returnValue = 1;
1009  goto TERMINATE_FREESTRINGS;
1010  }
1011  }
1012 
1013  readingTime->stop();
1014 
1015  MSG_INFO1(soplex->spxout,
1016  std::streamsize prec = soplex->spxout.precision();
1017  soplex->spxout << "Reading took "
1018  << std::fixed << std::setprecision(2) << readingTime->time()
1019  << std::scientific << std::setprecision(int(prec))
1020  << " seconds.\n\n");
1021 
1022  MSG_INFO1(soplex->spxout, soplex->spxout << "LP has " << soplex->numRows() << " rows "
1023  << soplex->numCols() << " columns and " << soplex->numNonzeros() << " nonzeros.\n\n");
1024 
1025  // solve the LP
1026  soplex->optimize();
1027 
1028  // print solution, check solution, and display statistics
1029  printPrimalSolution(*soplex, colnames, rownames, printPrimal, printPrimalRational);
1030  printDualSolution(*soplex, colnames, rownames, printDual, printDualRational);
1031 
1032  if(checkSol)
1033  checkSolution<R>(*soplex); // The type needs to get fixed here
1034 
1035  if(displayStatistics)
1036  {
1037  MSG_INFO1(soplex->spxout, soplex->spxout << "Statistics\n==========\n\n");
1038  soplex->printStatistics(soplex->spxout.getStream(SPxOut::INFO1));
1039  }
1040 
1041  if(validation->validate)
1042  validation->validateSolveReal(*soplex);
1043 
1044  // write basis file if specified
1045  if(writebasname != nullptr)
1046  {
1047  if(!soplex->hasBasis())
1048  {
1049  MSG_WARNING(soplex->spxout, soplex->spxout <<
1050  "No basis information available. Could not write file <" << writebasname << ">\n\n");
1051  }
1052  else if(!soplex->writeBasisFile(writebasname, &rownames, &colnames))
1053  {
1054  MSG_ERROR(std::cerr << "Error while writing file <" << writebasname << ">.\n\n");
1055  returnValue = 1;
1056  goto TERMINATE_FREESTRINGS;
1057  }
1058  else
1059  {
1060  MSG_INFO1(soplex->spxout, soplex->spxout << "Written basis information to file <" << writebasname <<
1061  ">.\n\n");
1062  }
1063  }
1064  }
1065  catch(const SPxException& x)
1066  {
1067  MSG_ERROR(std::cerr << "Exception caught: " << x.what() << "\n");
1068  returnValue = 1;
1069  goto TERMINATE_FREESTRINGS;
1070  }
1071 
1072 TERMINATE_FREESTRINGS:
1073  freeStrings(readbasname, writebasname, loadsetname, savesetname, diffsetname);
1074 
1075 TERMINATE:
1076 
1077  // because EGlpNumClear() calls mpq_clear() for all mpq_t variables, we need to destroy all objects of class Rational
1078  // beforehand; hence all Rational objects and all data that uses Rational objects must be allocated dynamically via
1079  // spx_alloc() and freed here; disabling the list memory is crucial
1080  if(nullptr != soplex)
1081  {
1082  soplex->~SoPlexBase();
1083  spx_free(soplex);
1084  }
1085 
1086  if(nullptr != validation)
1087  {
1088  validation->~Validation();
1089  spx_free(validation);
1090  }
1091 
1092  if(nullptr != readingTime)
1093  {
1094  readingTime->~Timer();
1095  spx_free(readingTime);
1096  }
1097 
1098  return returnValue;
1099 }
1100 
1101 /// runs SoPlexBase command line
1102 int main(int argc, char* argv[])
1103 {
1104  int arithmetic = 0;
1105  int precision = 0;
1106  int optidx;
1107 
1108  // find out which precision/solvemode soplex should be run in. the rest happens in runSoPlex
1109  // no options were given
1110  if(argc <= 1)
1111  {
1112  printUsage(argv, 0);
1113  return 1;
1114  }
1115 
1116  // read arguments from command line
1117  for(optidx = 1; optidx < argc; optidx++)
1118  {
1119  char* option = argv[optidx];
1120 
1121  // we reached <lpfile>
1122  if(option[0] != '-')
1123  continue;
1124 
1125  // option string must start with '-', must contain at least two characters, and exactly two characters if and
1126  // only if it is -x, -y, -q, or -c
1127  if(option[0] != '-' || option[1] == '\0'
1128  || ((option[2] == '\0') != (option[1] == 'x' || option[1] == 'X' || option[1] == 'y'
1129  || option[1] == 'Y' || option[1] == 'q' || option[1] == 'c')))
1130  {
1131  printUsage(argv, optidx);
1132  return 1;
1133  }
1134 
1135  switch(option[1])
1136  {
1137  case '-' :
1138  option = &option[2];
1139 
1140  // --arithmetic=<value> : choose base arithmetic type (0 - double, 1 - quadprecision, 2 - higher multiprecision)
1141  // only need to do something here if multi or quad, the rest is handled in runSoPlex
1142  if(strncmp(option, "arithmetic=", 11) == 0)
1143  {
1144  if(option[11] == '1')
1145  {
1146 #ifndef SOPLEX_WITH_FLOAT128
1147  MSG_ERROR(std::cerr <<
1148  "Cannot set arithmetic type to quadprecision - Soplex compiled without quadprecision support\n";)
1149  printUsage(argv, 0);
1150  return 1;
1151 #else
1152  arithmetic = 1;
1153 #endif
1154  }
1155  else if(option[11] == '2')
1156  {
1157 #ifndef SOPLEX_WITH_BOOST
1158  MSG_ERROR(std::cerr <<
1159  "Cannot set arithmetic type to multiprecision - Soplex compiled without boost\n";)
1160  printUsage(argv, 0);
1161  return 1;
1162 #else
1163  arithmetic = 2;
1164 
1165  // default precision in multiprecision solve is 50
1166  if(precision == 0)
1167  precision = 50;
1168 
1169 #endif
1170  }
1171  }
1172  // set precision
1173  else if(strncmp(option, "precision=", 10) == 0)
1174  {
1175  precision = atoi(option + 10);
1176 #ifndef SOPLEX_WITH_BOOST
1177  MSG_ERROR(std::cerr << "Setting precision to non-default value without Boost has no effect\n";)
1178 #endif
1179  }
1180 
1181  break;
1182 
1183  default:
1184  break;
1185  }
1186  }
1187 
1188  if(precision != 0 && arithmetic != 2)
1189  {
1190  MSG_ERROR(std::cerr <<
1191  "Setting precision to non-default value without enabling multiprecision solve has no effect\n";)
1192  }
1193 
1194  switch(arithmetic)
1195  {
1196  case 0: // double
1197  runSoPlex<Real>(argc, argv);
1198  break;
1199 
1200 #ifdef SOPLEX_WITH_BOOST
1201 #ifdef SOPLEX_WITH_FLOAT128
1202 
1203  case 1: // quadprecision
1204 #if BOOST_VERSION < 107000
1205  std::cerr << "Error: Boost version too old." << std:: endl <<
1206  "In order to use the quadprecision feature of SoPlex," <<
1207  " Boost Version 1.70.0 or higher is required." << std::endl << \
1208  "Included Boost version is " << BOOST_VERSION / 100000 << "." // maj. version
1209  << BOOST_VERSION / 100 % 1000 << "." // min. version
1210  << BOOST_VERSION % 100 // patch version;
1211  << std::endl;
1212 #else
1213  using namespace boost::multiprecision;
1214  using Quad = boost::multiprecision::float128;
1215  runSoPlex<Quad>(argc, argv);
1216 #endif
1217  break;
1218 #endif
1219 
1220  case 2: // soplex mpf
1221  using namespace boost::multiprecision;
1222 
1223 #if BOOST_VERSION < 107000
1224  std::cerr << "Error: Boost version too old." << std:: endl <<
1225  "In order to use the multiprecision feature of SoPlex," <<
1226  " Boost Version 1.70.0 or higher is required." << std::endl << \
1227  "Included Boost version is " << BOOST_VERSION / 100000 << "." // maj. version
1228  << BOOST_VERSION / 100 % 1000 << "." // min. version
1229  << BOOST_VERSION % 100 // patch version;
1230  << std::endl;
1231 #else
1232 #ifdef SOPLEX_WITH_MPFR
1233 
1234  // et_off means the expression templates options is turned off. TODO:
1235  // The documentation also mentions about static vs dynamic memory
1236  // allocation for the mpfr types. Is it relevant here? I probably also
1237  // need to have the mpfr_float_eto in the global soplex namespace
1238  using multiprecision = number<mpfr_float_backend<0>, et_off>;
1239  multiprecision::default_precision(precision);
1240  runSoPlex<multiprecision>(argc, argv);
1241 #endif // SOPLEX_WITH_MPFR
1242 
1243 #ifdef SOPLEX_WITH_CPPMPF
1244  // It seems that precision cannot be set on run time for cpp_float
1245  // backend for boost::number. So a precision of 50 decimal points is
1246  // set.
1247  using multiprecision1 = number<cpp_dec_float<50>, et_off>;
1248  using multiprecision2 = number<cpp_dec_float<100>, et_off>;
1249  using multiprecision3 = number<cpp_dec_float<200>, et_off>;
1250 
1251  if(precision <= 50)
1252  runSoPlex<multiprecision1>(argc, argv);
1253  else if(precision <= 100)
1254  runSoPlex<multiprecision2>(argc, argv);
1255  else
1256  runSoPlex<multiprecision3>(argc, argv);
1257 
1258 #endif // SOPLEX_WITH_CPPMPF
1259 #endif
1260  break;
1261 #endif
1262 
1263  default:
1264  std::cerr << "Wrong value for the arithmetic mode\n";
1265  return 0;
1266  }
1267 }
bool writeFile(const char *filename, const NameSet *rowNames=0, const NameSet *colNames=0, const DIdxSet *intvars=0, const bool unscale=true) const
Templated write function Real writes real LP to file; LP or MPS format is chosen from the extension i...
virtual ~SoPlexBase()
destructor
number< gmp_rational, et_off > Rational
Definition: rational.h:30
bool getBoundViolationRational(Rational &maxviol, Rational &sumviol)
Dense vector.Class VectorBase provides dense linear algebra vectors. Internally, VectorBase wraps std...
Definition: dsvectorbase.h:28
automatic sync of real and rational LP
Definition: soplex.h:1255
bool getDualRational(VectorRational &vector)
int numNonzeros() const
returns number of nonzeros
type of ratio test
Definition: soplex.h:1037
int numRowsRational() const
virtual ~Timer()
Definition: timer.h:124
bool getPrimalRational(VectorRational &vector)
dual feasibility tolerance
Definition: soplex.h:1343
bool writeDualFileReal(const char *filename, const NameSet *rowNames=0, const NameSet *colNames=0, const DIdxSet *intvars=0) const
writes the dual of the real LP to file; LP or MPS format is chosen from the extension in filename; if...
bool isDualFeasible() const
is stored dual solution feasible?
bool updateValidationTolerance(const std::string &tolerance)
updates the tolerance used for validation
static void checkSolutionReal(SoPlexBase< R > &soplex)
performs external feasibility check with real type
Definition: soplexmain.cpp:138
bool getDual(VectorBase< R > &vector)
gets the dual solution vector if available; returns true on success
bool getRowViolationRational(Rational &maxviol, Rational &sumviol)
SPxSolverBase< R >::Status optimize(volatile bool *interrupt=NULL)
optimize the given LP
type of scaler
Definition: soplex.h:1028
bool getPrimalRay(VectorBase< R > &vector)
gets the primal ray if available; returns true on success
bool getRedCostViolation(R &maxviol, R &sumviol)
gets violation of reduced costs; returns true on success
void validateSolveReal(SoPlexBase< R > &soplex)
validates the soplex solution using the external solution
virtual const std::string what() const
returns exception message
Definition: exceptions.h:57
bool parseSettingsString(char *str)
parses one setting string and returns true on success; note that string is modified ...
virtual void start()=0
start timer, resume accounting user, system and real time.
virtual Real stop()=0
stop timer, return accounted user time.
void spx_alloc(T &p, int n=1)
Allocate memory.
Definition: spxalloc.h:49
apply standard floating-point algorithm
Definition: soplex.h:1275
double Real
Definition: spxdefines.h:256
int main(int argc, char *argv[])
runs SoPlexBase command line
bool getDualViolationRational(Rational &maxviol, Rational &sumviol)
bool getRedCostRational(VectorRational &vector)
int runSoPlex(int argc, char *argv[])
Definition: soplexmain.cpp:501
static void printUsage(const char *const argv[], int idx)
Definition: soplexmain.cpp:38
int intParam(const IntParam param) const
returns integer parameter value
bool getDualFarkas(VectorBase< R > &vector)
gets the Farkas proof if available; returns true on success
#define MSG_ERROR(x)
Prints out message x if the verbosity level is at least SPxOut::ERROR.
Definition: spxdefines.h:152
Real realParam(const RealParam param) const
returns real parameter value
iteration limit (-1 if unlimited)
Definition: soplex.h:1010
bool getBoundViolation(R &maxviol, R &sumviol)
gets violation of bounds; returns true on success
primal feasibility tolerance
Definition: soplex.h:1340
bool hasDual() const
deprecated: use hasSol() instead
Definition: soplex.h:618
int spxSnprintf(char *t, size_t len, const char *s,...)
safe version of snprintf
Definition: spxdefines.h:392
bool saveSettingsFile(const char *filename, const bool onlyChanged=false, int solvemode=1) const
writes settings file; returns true on success
bool getPrimal(VectorBase< R > &vector)
gets the primal solution vector if available; returns true on success
bool readBasisFile(const char *filename, const NameSet *rowNames=0, const NameSet *colNames=0)
reads basis information from filename and returns true on success; if rowNames and colNames are NULL...
bool hasPrimal() const
deprecated: use hasSol() instead
Definition: soplex.h:612
bool getDualFarkasRational(VectorRational &vector)
int numCols() const
Templated function that returns number of columns.
static void checkSolutionRational(SoPlexBase< R > &soplex)
performs external feasibility check with rational type
Definition: soplexmain.cpp:195
virtual Real time() const =0
bool getRedCostViolationRational(Rational &maxviol, Rational &sumviol)
static Timer * createTimer(Timer::TYPE ttype)
create timers and allocate memory for them
Definition: timerfactory.h:44
bool setRealParam(const RealParam param, const Real value, const bool init=true)
sets real parameter value; returns true on success
Preconfigured SoPlex LP solver.
static Real epsilon()
Definition: spxdefines.cpp:55
Set of strings.Class NameSet implements a symbol or name table. It allows to store or remove names (i...
Definition: nameset.h:61
bool getDualViolation(R &maxviol, R &sumviol)
gets violation of dual multipliers; returns true on success
type of simplifier
Definition: soplex.h:1025
void checkSolution(SoPlexBase< R > &soplex)
performs external feasibility check according to check mode
Definition: soplexmain.cpp:252
bool validate
should the soplex solution be validated?
Definition: validation.h:34
Exception base class.This class implements a base class for our SoPlex exceptions We provide a what()...
Definition: exceptions.h:32
Everything should be within this namespace.
static void printPrimalSolution(SoPlexBase< R > &soplex, NameSet &colnames, NameSet &rownames, bool real=true, bool rational=false)
Definition: soplexmain.cpp:270
mode for iterative refinement strategy
Definition: soplex.h:1046
bool getRowViolation(R &maxviol, R &sumviol)
gets violation of constraints; returns true on success
int numRows() const
returns number of rows
time limit in seconds (INFTY if unlimited)
Definition: soplex.h:1361
user sync of real and rational LP
Definition: soplex.h:1258
#define MSG_WARNING(spxout, x)
Prints out message x if the verbosity level is at least SPxOut::WARNING.
Definition: spxdefines.h:154
mode for reading LP files
Definition: soplex.h:1043
std::streamsize precision() const
Definition: spxout.h:139
static void printDualSolution(SoPlexBase< R > &soplex, NameSet &colnames, NameSet &rownames, bool real=true, bool rational=false)
Definition: soplexmain.cpp:372
bool readFile(const char *filename, NameSet *rowNames=0, NameSet *colNames=0, DIdxSet *intVars=0)
reads LP file in LP or MPS format according to READMODE parameter; gets row names, column names, and integer variables if desired; returns true on success
~Validation()
default destructor
Definition: validation.h:50
void printVersion() const
prints version and compilation options
bool updateExternalSolution(const std::string &solution)
updates the external solution used for validation
bool getPrimalRayRational(VectorRational &vector)
standard floating-point parsing
Definition: soplex.h:1265
#define MSG_INFO1(spxout, x)
Prints out message x if the verbosity level is at least SPxOut::INFO1.
Definition: spxdefines.h:156
verbosity level
Definition: soplex.h:1022
int numColsRational() const
bool isPrimalFeasible() const
is stored primal solution feasible?
Validation object for soplex solutions.
static void freeStrings(char *&s1, char *&s2, char *&s3, char *&s4, char *&s5)
Definition: soplexmain.cpp:100
type of pricer
Definition: soplex.h:1034
#define SOPLEX_COPYRIGHT
Definition: spxdefines.h:86
bool setIntParam(const IntParam param, const int value, const bool init=true)
sets integer parameter value; returns true on success
mode for synchronizing real and rational LP
Definition: soplex.h:1040
Wrapper for the system time query methods.
Definition: timer.h:76
void spx_free(T &p)
Release memory.
Definition: spxalloc.h:111
bool loadSettingsFile(const char *filename)
reads settings file; returns true on success
bool getRedCost(VectorBase< R > &vector)
gets the vector of reduced cost values if available; returns true on success
void printUserSettings()
print non-default parameter values