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-2017 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 #ifndef SOPLEX_LEGACY
21 #include <assert.h>
22 #include <math.h>
23 #include <string.h>
24 
25 #include <iostream>
26 #include <iomanip>
27 #include <fstream>
28 
29 #include "soplex.h"
30 #include "spxgithash.h"
31 #include "timerfactory.h"
32 
33 #include "validation.h"
34 
35 #ifdef SOPLEX_WITH_EGLIB
36 extern "C" {
37 #include "EGlib.h"
38 }
39 #else
40 #define EGlpNumStart() {}
41 #define EGlpNumClear() {}
42 #endif
43 
44 using namespace soplex;
45 
46 // function prototype
47 int main(int argc, char* argv[]);
48 
49 // prints usage and command line options
50 static
51 void printUsage(const char* const argv[], int idx)
52 {
53  const char* usage =
54  "general options:\n"
55  " --readbas=<basfile> read starting basis from file\n"
56  " --writebas=<basfile> write terminal basis to file\n"
57  " --writefile=<lpfile> write LP to file in LP or MPS format depending on extension\n"
58  " --writedual=<lpfile> write the dual LP to a file in LP or MPS formal depending on extension\n"
59  " --<type>:<name>=<val> change parameter value using syntax of settings file entries\n"
60  " --loadset=<setfile> load parameters from settings file (overruled by command line parameters)\n"
61  " --saveset=<setfile> save parameters to settings file\n"
62  " --diffset=<setfile> save modified parameters to settings file\n"
63  " --extsol=<value> external solution for soplex to use for validation\n"
64  "\n"
65  "limits and tolerances:\n"
66  " -t<s> set time limit to <s> seconds\n"
67  " -i<n> set iteration limit to <n>\n"
68  " -f<eps> set primal feasibility tolerance to <eps>\n"
69  " -o<eps> set dual feasibility (optimality) tolerance to <eps>\n"
70  " -l<eps> set validation tolerance to <eps>\n"
71  "\n"
72  "algorithmic settings (* indicates default):\n"
73  " --readmode=<value> choose reading mode for <lpfile> (0* - floating-point, 1 - rational)\n"
74  " --solvemode=<value> choose solving mode (0 - floating-point solve, 1* - auto, 2 - force iterative refinement)\n"
75  " -s<value> choose simplifier/presolver (0 - off, 1* - auto)\n"
76  " -g<value> choose scaling (0 - off, 1 - uni-equilibrium, 2* - bi-equilibrium, 3 - geometric, 4 - iterated geometric, 5 - least squares)\n"
77  " -p<value> choose pricing (0* - auto, 1 - dantzig, 2 - parmult, 3 - devex, 4 - quicksteep, 5 - steep)\n"
78  " -r<value> choose ratio tester (0 - textbook, 1 - harris, 2 - fast, 3* - boundflipping)\n"
79  "\n"
80  "display options:\n"
81  " -v<level> set verbosity to <level> (0 - error, 3 - normal, 5 - high)\n"
82  " -x print primal solution\n"
83  " -y print dual multipliers\n"
84  " -X print primal solution in rational numbers\n"
85  " -Y print dual multipliers in rational numbers\n"
86  " -q display detailed statistics\n"
87  " -c perform final check of optimal solution in original problem\n"
88  "\n";
89 
90  if( idx <= 0 )
91  std::cerr << "missing input file\n\n";
92  else
93  std::cerr << "invalid option \"" << argv[idx] << "\"\n\n";
94 
95  std::cerr << "usage: " << argv[0] << " " << "[options] <lpfile>\n"
96 #ifdef SOPLEX_WITH_ZLIB
97  << " <lpfile> linear program as .mps[.gz] or .lp[.gz] file\n\n"
98 #else
99  << " <lpfile> linear program as .mps or .lp file\n\n"
100 #endif
101  << usage;
102 }
103 
104 // cleans up C strings
105 static
106 void freeStrings(char*& s1, char*& s2, char*& s3, char*& s4, char*& s5)
107 {
108  if( s1 != 0 )
109  {
110  delete [] s1;
111  s1 = 0;
112  }
113  if( s2 != 0 )
114  {
115  delete [] s2;
116  s2 = 0;
117  }
118  if( s3 != 0 )
119  {
120  delete [] s3;
121  s3 = 0;
122  }
123  if( s4 != 0 )
124  {
125  delete [] s4;
126  s4 = 0;
127  }
128  if( s5 != 0 )
129  {
130  delete [] s5;
131  s5 = 0;
132  }
133 }
134 
135 /// performs external feasibility check with real type
136 ///@todo implement external check; currently we use the internal methods for convenience
137 static
139 {
140  if( soplex.hasPrimal() )
141  {
142  Real boundviol;
143  Real rowviol;
144  Real sumviol;
145 
146  if( soplex.getBoundViolationReal(boundviol, sumviol) && soplex.getRowViolationReal(rowviol, sumviol) )
147  {
148  MSG_INFO1( soplex.spxout,
149  Real maxviol = boundviol > rowviol ? boundviol : rowviol;
150  bool feasible = (maxviol <= soplex.realParam(SoPlex::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  }
156  else
157  {
158  MSG_INFO1( soplex.spxout, soplex.spxout << "Could not check primal solution.\n" );
159  }
160  }
161  else
162  {
163  MSG_INFO1( soplex.spxout, soplex.spxout << "No primal solution available.\n" );
164  }
165 
166  if( soplex.hasDual() )
167  {
168  Real redcostviol;
169  Real dualviol;
170  Real sumviol;
171 
172  if( soplex.getRedCostViolationReal(redcostviol, sumviol) && soplex.getDualViolationReal(dualviol, sumviol) )
173  {
174  MSG_INFO1( soplex.spxout,
175  Real maxviol = redcostviol > dualviol ? redcostviol : dualviol;
176  bool feasible = (maxviol <= soplex.realParam(SoPlex::OPTTOL));
177  soplex.spxout << "Dual solution " << (feasible ? "feasible" : "infeasible")
178  << " in original problem (max. violation = " << std::scientific << maxviol
179  << std::setprecision(8) << std::fixed << ").\n"
180  );
181  }
182  else
183  {
184  MSG_INFO1( soplex.spxout, soplex.spxout << "Could not check dual solution.\n" );
185  }
186  }
187  else
188  {
189  MSG_INFO1( soplex.spxout, soplex.spxout << "No dual solution available.\n" );
190  }
191 }
192 
193 /// performs external feasibility check with rational type
194 ///@todo implement external check; currently we use the internal methods for convenience
195 static
197 {
198  if( soplex.hasPrimal() )
199  {
200  Rational boundviol;
201  Rational rowviol;
202  Rational sumviol;
203 
204  if( soplex.getBoundViolationRational(boundviol, sumviol) && soplex.getRowViolationRational(rowviol, sumviol) )
205  {
206  MSG_INFO1( soplex.spxout,
207  Rational maxviol = boundviol > rowviol ? boundviol : rowviol;
208  bool feasible = (maxviol <= soplex.realParam(SoPlex::FEASTOL));
209  soplex.spxout << "Primal solution " << (feasible ? "feasible" : "infeasible") << " in original problem (max. violation = " << rationalToString(maxviol) << ").\n"
210  );
211  }
212  else
213  {
214  MSG_INFO1( soplex.spxout, soplex.spxout << "Could not check primal solution.\n" );
215  }
216  }
217  else
218  {
219  MSG_INFO1( soplex.spxout, soplex.spxout << "No primal solution available.\n" );
220  }
221 
222  if( soplex.hasDual() )
223  {
224  Rational redcostviol;
225  Rational dualviol;
226  Rational sumviol;
227 
228  if( soplex.getRedCostViolationRational(redcostviol, sumviol) && soplex.getDualViolationRational(dualviol, sumviol) )
229  {
230  MSG_INFO1( soplex.spxout,
231  Rational maxviol = redcostviol > dualviol ? redcostviol : dualviol;
232  bool feasible = (maxviol <= soplex.realParam(SoPlex::OPTTOL));
233  soplex.spxout << "Dual solution " << (feasible ? "feasible" : "infeasible") << " in original problem (max. violation = " << rationalToString(maxviol) << ").\n"
234  );
235  }
236  else
237  {
238  MSG_INFO1( soplex.spxout, soplex.spxout << "Could not check dual solution.\n" );
239  }
240  }
241  else
242  {
243  MSG_INFO1( soplex.spxout, soplex.spxout << "No dual solution available.\n" );
244  }
245 }
246 
247 /// performs external feasibility check according to check mode
248 static
250 {
254  {
255  checkSolutionRational(soplex);
256  }
257  else
258  {
259  checkSolutionReal(soplex);
260  }
261 
262  MSG_INFO1( soplex.spxout, soplex.spxout << "\n" );
263 }
264 
265 /// runs SoPlex command line
266 int main(int argc, char* argv[])
267 {
268  ///@todo the EGlib version info should be printed after the SoPlex version info
269  // initialize EGlib's GMP memory management before any rational numbers are created
270  EGlpNumStart();
271 
272  SoPlex* soplex;
273  NameSet rownames;
274  NameSet colnames;
275  Timer* readingTime;
276  Validation* validation;
277  int optidx;
278 
279  const char* lpfilename = 0;
280  char* readbasname = 0;
281  char* writebasname = 0;
282  char* writefilename = 0;
283  char* writedualfilename = 0;
284  char* loadsetname = 0;
285  char* savesetname = 0;
286  char* diffsetname = 0;
287  bool printPrimal = false;
288  bool printPrimalRational = false;
289  bool printDual = false;
290  bool printDualRational = false;
291  bool displayStatistics = false;
292  bool checkSol = false;
293 
294  int returnValue = 0;
295 
296  // create default timer (CPU time)
298  soplex = 0;
299  spx_alloc(soplex);
300  new (soplex) SoPlex();
301 
302  soplex->printVersion();
303  MSG_INFO1( soplex->spxout, soplex->spxout << SOPLEX_COPYRIGHT << std::endl << std::endl );
304 
305  validation = 0;
306  spx_alloc(validation);
307  new (validation) Validation();
308 
309  try
310  {
311  // no options were given
312  if( argc <= 1 )
313  {
314  printUsage(argv, 0);
315  returnValue = 1;
316  goto TERMINATE;
317  }
318 
319  // read arguments from command line
320  for( optidx = 1; optidx < argc; optidx++ )
321  {
322  char* option = argv[optidx];
323 
324  // we reached <lpfile>
325  if( option[0] != '-' )
326  {
327  lpfilename = argv[optidx];
328  continue;
329  }
330 
331  // option string must start with '-', must contain at least two characters, and exactly two characters if and
332  // only if it is -x, -y, -q, or -c
333  if( option[0] != '-' || option[1] == '\0'
334  || ((option[2] == '\0') != (option[1] == 'x' || option[1] == 'X' || option[1] == 'y' || option[1] == 'Y' || option[1] == 'q' || option[1] == 'c')) )
335  {
336  printUsage(argv, optidx);
337  returnValue = 1;
338  goto TERMINATE_FREESTRINGS;
339  }
340 
341  switch( option[1] )
342  {
343  case '-' :
344  {
345  option = &option[2];
346 
347  // --readbas=<basfile> : read starting basis from file
348  if( strncmp(option, "readbas=", 8) == 0 )
349  {
350  if( readbasname == 0 )
351  {
352  char* filename = &option[8];
353  readbasname = strncpy(new char[strlen(filename) + 1], filename, strlen(filename) + 1);
354  }
355  }
356  // --writebas=<basfile> : write terminal basis to file
357  else if( strncmp(option, "writebas=", 9) == 0 )
358  {
359  if( writebasname == 0 )
360  {
361  char* filename = &option[9];
362  writebasname = strncpy(new char[strlen(filename) + 1], filename, strlen(filename) + 1);
363  }
364  }
365  // --writefile=<lpfile> : write LP to file
366  else if( strncmp(option, "writefile=", 10) == 0 )
367  {
368  if( writefilename == 0 )
369  {
370  char* filename = &option[10];
371  writefilename = strncpy(new char[strlen(filename) + 1], filename, strlen(filename) + 1);
372  }
373  }
374  // --writedual=<lpfile> : write dual LP to a file
375  else if( strncmp(option, "writedual=", 10) == 0 )
376  {
377  if( writedualfilename == 0 )
378  {
379  char* dualfilename = &option[10];
380  writedualfilename = strncpy(new char[strlen(dualfilename) + 1], dualfilename, strlen(dualfilename) + 1);
381  }
382  }
383  // --loadset=<setfile> : load parameters from settings file
384  else if( strncmp(option, "loadset=", 8) == 0 )
385  {
386  if( loadsetname == 0 )
387  {
388  char* filename = &option[8];
389  loadsetname = strncpy(new char[strlen(filename) + 1], filename, strlen(filename) + 1);
390  if( !soplex->loadSettingsFile(loadsetname) )
391  {
392  printUsage(argv, optidx);
393  returnValue = 1;
394  goto TERMINATE_FREESTRINGS;
395  }
396  else
397  {
398  // we need to start parsing again because some command line parameters might have been overwritten
399  optidx = 0;
400  }
401  }
402  }
403  // --saveset=<setfile> : save parameters to settings file
404  else if( strncmp(option, "saveset=", 8) == 0 )
405  {
406  if( savesetname == 0 )
407  {
408  char* filename = &option[8];
409  savesetname = strncpy(new char[strlen(filename) + 1], filename, strlen(filename) + 1);
410  }
411  }
412  // --diffset=<setfile> : save modified parameters to settings file
413  else if( strncmp(option, "diffset=", 8) == 0 )
414  {
415  if( diffsetname == 0 )
416  {
417  char* filename = &option[8];
418  diffsetname = strncpy(new char[strlen(filename) + 1], filename, strlen(filename) + 1);
419  }
420  }
421  // --readmode=<value> : choose reading mode for <lpfile> (0* - floating-point, 1 - rational)
422  else if( strncmp(option, "readmode=", 9) == 0 )
423  {
424  if( !soplex->setIntParam(SoPlex::READMODE, option[9] - '0') )
425  {
426  printUsage(argv, optidx);
427  returnValue = 1;
428  goto TERMINATE_FREESTRINGS;
429  }
430  }
431  // --solvemode=<value> : choose solving mode (0* - floating-point solve, 1 - auto, 2 - force iterative refinement)
432  else if( strncmp(option, "solvemode=", 10) == 0 )
433  {
434  if( !soplex->setIntParam(SoPlex::SOLVEMODE, option[10] - '0') )
435  {
436  printUsage(argv, optidx);
437  returnValue = 1;
438  goto TERMINATE_FREESTRINGS;
439  }
440  // if the LP is parsed rationally and might be solved rationally, we choose automatic syncmode such that
441  // the rational LP is kept after reading
444  {
446  }
447  }
448  // --extsol=<value> : external solution for soplex to use for validation
449  else if( strncmp(option, "extsol=", 7) == 0 )
450  {
451  char* input = &option[7];
452  if( !validation->updateExternalSolution(input) )
453  {
454  printUsage(argv, optidx);
455  returnValue = 1;
456  goto TERMINATE_FREESTRINGS;
457  }
458  }
459  // --<type>:<name>=<val> : change parameter value using syntax of settings file entries
460  else if( !soplex->parseSettingsString(option) )
461  {
462  printUsage(argv, optidx);
463  returnValue = 1;
464  goto TERMINATE_FREESTRINGS;
465  }
466  break;
467  }
468 
469  case 't' :
470  // -t<s> : set time limit to <s> seconds
471  if( !soplex->setRealParam(SoPlex::TIMELIMIT, atoi(&option[2])) )
472  {
473  printUsage(argv, optidx);
474  returnValue = 1;
475  goto TERMINATE_FREESTRINGS;
476  }
477  break;
478 
479  case 'i' :
480  // -i<n> : set iteration limit to <n>
481  if( !soplex->setIntParam(SoPlex::ITERLIMIT, atoi(&option[2])) )
482  {
483  printUsage(argv, optidx);
484  returnValue = 1;
485  goto TERMINATE_FREESTRINGS;
486  }
487  break;
488 
489  case 'f' :
490  // -f<eps> : set primal feasibility tolerance to <eps>
491  if( !soplex->setRealParam(SoPlex::FEASTOL, atof(&option[2])) )
492  {
493  printUsage(argv, optidx);
494  returnValue = 1;
495  goto TERMINATE_FREESTRINGS;
496  }
497  break;
498 
499  case 'o' :
500  // -o<eps> : set dual feasibility (optimality) tolerance to <eps>
501  if( !soplex->setRealParam(SoPlex::OPTTOL, atof(&option[2])) )
502  {
503  printUsage(argv, optidx);
504  returnValue = 1;
505  goto TERMINATE_FREESTRINGS;
506  }
507  break;
508 
509  case 'l' :
510  // l<eps> : set validation tolerance to <eps>
511  if( !validation->updateValidationTolerance(&option[2]) )
512  {
513  printUsage(argv, optidx);
514  returnValue = 1;
515  goto TERMINATE_FREESTRINGS;
516  }
517  break;
518 
519  case 's' :
520  // -s<value> : choose simplifier/presolver (0 - off, 1* - auto)
521  if( !soplex->setIntParam(SoPlex::SIMPLIFIER, option[2] - '0') )
522  {
523  printUsage(argv, optidx);
524  returnValue = 1;
525  goto TERMINATE_FREESTRINGS;
526  }
527  break;
528 
529  case 'g' :
530  // -g<value> : choose scaling (0 - off, 1 - uni-equilibrium, 2* - bi-equilibrium, 3 - geometric, 4 - iterated geometric, 5 - least squares)
531  if( !soplex->setIntParam(SoPlex::SCALER, option[2] - '0') )
532  {
533  printUsage(argv, optidx);
534  returnValue = 1;
535  goto TERMINATE_FREESTRINGS;
536  }
537  break;
538 
539  case 'p' :
540  // -p<value> : choose pricing (0* - auto, 1 - dantzig, 2 - parmult, 3 - devex, 4 - quicksteep, 5 - steep)
541  if( !soplex->setIntParam(SoPlex::PRICER, option[2] - '0') )
542  {
543  printUsage(argv, optidx);
544  returnValue = 1;
545  goto TERMINATE_FREESTRINGS;
546  }
547  break;
548 
549  case 'r' :
550  // -r<value> : choose ratio tester (0 - textbook, 1 - harris, 2* - fast, 3 - boundflipping)
551  if( !soplex->setIntParam(SoPlex::RATIOTESTER, option[2] - '0') )
552  {
553  printUsage(argv, optidx);
554  returnValue = 1;
555  goto TERMINATE_FREESTRINGS;
556  }
557  break;
558 
559  case 'v' :
560  // -v<level> : set verbosity to <level> (0 - error, 3 - normal, 5 - high)
561  if( !soplex->setIntParam(SoPlex::VERBOSITY, option[2] - '0') )
562  {
563  printUsage(argv, optidx);
564  returnValue = 1;
565  goto TERMINATE_FREESTRINGS;
566  }
567  break;
568 
569  case 'x' :
570  // -x : print primal solution
571  printPrimal = true;
572  break;
573 
574  case 'X' :
575  // -X : print primal solution with rationals
576  printPrimalRational = true;
577  break;
578 
579  case 'y' :
580  // -y : print dual multipliers
581  printDual = true;
582  break;
583 
584  case 'Y' :
585  // -Y : print dual multipliers with rationals
586  printDualRational = true;
587  break;
588 
589  case 'q' :
590  // -q : display detailed statistics
591  displayStatistics = true;
592  break;
593 
594  case 'c' :
595  // -c : perform final check of optimal solution in original problem
596  checkSol = true;
597  break;
598 
599  case 'h' :
600  // -h : display all parameters
601  if( !soplex->saveSettingsFile(0, false) )
602  {
603  MSG_ERROR( std::cerr << "Error printing parameters\n" );
604  }
605  break;
606 
607  //lint -fallthrough
608  default :
609  {
610  printUsage(argv, optidx);
611  returnValue = 1;
612  goto TERMINATE_FREESTRINGS;
613  }
614  }
615  }
616 
617  MSG_INFO1( soplex->spxout, soplex->printUserSettings(); )
618 
619  // no LP file was given and no settings files are written
620  if( lpfilename == 0 && savesetname == 0 && diffsetname == 0 )
621  {
622  printUsage(argv, 0);
623  returnValue = 1;
624  goto TERMINATE_FREESTRINGS;
625  }
626 
627  // ensure that syncmode is not manual
629  {
630  MSG_ERROR( std::cerr << "Error: manual synchronization is invalid on command line. Change parameter int:syncmode.\n" );
631  returnValue = 1;
632  goto TERMINATE_FREESTRINGS;
633  }
634 
635  // save settings files
636  if( savesetname != 0 )
637  {
638  MSG_INFO1( soplex->spxout, soplex->spxout << "Saving parameters to settings file <" << savesetname << "> . . .\n" );
639  if( !soplex->saveSettingsFile(savesetname, false) )
640  {
641  MSG_ERROR( std::cerr << "Error writing parameters to file <" << savesetname << ">\n" );
642  }
643  }
644  if( diffsetname != 0 )
645  {
646  MSG_INFO1( soplex->spxout, soplex->spxout << "Saving modified parameters to settings file <" << diffsetname << "> . . .\n" );
647  if( !soplex->saveSettingsFile(diffsetname, true) )
648  {
649  MSG_ERROR( std::cerr << "Error writing modified parameters to file <" << diffsetname << ">\n" );
650  }
651  }
652 
653  // no LP file given: exit after saving settings
654  if( lpfilename == 0 )
655  {
656  if( loadsetname != 0 || savesetname != 0 || diffsetname != 0 )
657  {
658  MSG_INFO1( soplex->spxout, soplex->spxout << "\n" );
659  }
660  goto TERMINATE_FREESTRINGS;
661  }
662 
663  // measure time for reading LP file and basis file
664  readingTime->start();
665 
666  // if the LP is parsed rationally and might be solved rationally, we choose automatic syncmode such that
667  // the rational LP is kept after reading
670  {
672  }
673 
674  // read LP from input file
675  MSG_INFO1( soplex->spxout, soplex->spxout << "Reading "
676  << (soplex->intParam(SoPlex::READMODE) == SoPlex::READMODE_REAL ? "(real)" : "(rational)")
677  << " LP file <" << lpfilename << "> . . .\n" );
678 
679  if( !soplex->readFile(lpfilename, &rownames, &colnames) )
680  {
681  MSG_ERROR( std::cerr << "Error while reading file <" << lpfilename << ">.\n" );
682  returnValue = 1;
683  goto TERMINATE_FREESTRINGS;
684  }
685 
686  // write LP if specified
687  if( writefilename != 0 )
688  {
689  if( !soplex->writeFileReal(writefilename, &rownames, &colnames) )
690  {
691  MSG_ERROR( std::cerr << "Error while writing file <" << writefilename << ">.\n\n" );
692  returnValue = 1;
693  goto TERMINATE_FREESTRINGS;
694  }
695  else
696  {
697  MSG_INFO1( soplex->spxout, soplex->spxout << "Written LP to file <" << writefilename << ">.\n\n" );
698  }
699  }
700 
701  // write dual LP if specified
702  if( writedualfilename != 0 )
703  {
704  if( !soplex->writeDualFileReal(writedualfilename, &rownames, &colnames) )
705  {
706  MSG_ERROR( std::cerr << "Error while writing dual file <" << writedualfilename << ">.\n\n" );
707  returnValue = 1;
708  goto TERMINATE_FREESTRINGS;
709  }
710  else
711  {
712  MSG_INFO1( soplex->spxout, soplex->spxout << "Written dual LP to file <" << writedualfilename << ">.\n\n" );
713  }
714  }
715 
716  // read basis file if specified
717  if( readbasname != 0 )
718  {
719  MSG_INFO1( soplex->spxout, soplex->spxout << "Reading basis file <" << readbasname << "> . . . " );
720  if( !soplex->readBasisFile(readbasname, &rownames, &colnames) )
721  {
722  MSG_ERROR( std::cerr << "Error while reading file <" << readbasname << ">.\n" );
723  returnValue = 1;
724  goto TERMINATE_FREESTRINGS;
725  }
726  }
727 
728  readingTime->stop();
729 
730  MSG_INFO1( soplex->spxout,
731  std::streamsize prec = soplex->spxout.precision();
732  soplex->spxout << "Reading took "
733  << std::fixed << std::setprecision(2) << readingTime->time()
734  << std::scientific << std::setprecision(int(prec))
735  << " seconds.\n\n" );
736 
737  MSG_INFO1( soplex->spxout, soplex->spxout << "LP has " << soplex->numRowsReal() << " rows "
738  << soplex->numColsReal() << " columns and " << soplex->numNonzerosReal() << " nonzeros.\n\n" );
739 
740  // solve the LP
741  soplex->optimize();
742 
743  int printprec;
744  int printwidth;
745  printprec = (int) -log10(double(Param::epsilon()));
746  printwidth = printprec + 10;
747 
748  // print solution, check solution, and display statistics
749  if( printPrimal )
750  {
751  DVector primal(soplex->numColsReal());
752  if( soplex->getPrimalRayReal(primal) )
753  {
754  MSG_INFO1( soplex->spxout, soplex->spxout << "\nPrimal ray (name, value):\n"; )
755  for( int i = 0; i < soplex->numColsReal(); ++i )
756  {
757  if ( isNotZero( primal[i] ) )
758  MSG_INFO1( soplex->spxout, soplex->spxout << colnames[i] << "\t"
759  << std::setw(printwidth)
760  << std::setprecision(printprec)
761  << primal[i] << std::endl; )
762  }
763  MSG_INFO1( soplex->spxout, soplex->spxout << "All other entries are zero (within "
764  << std::setprecision(1) << std::scientific << Param::epsilon()
765  << std::setprecision(8) << std::fixed << ")." << std::endl; )
766  }
767  else if( soplex->getPrimalReal(primal) )
768  {
769  int nNonzeros = 0;
770  MSG_INFO1( soplex->spxout, soplex->spxout << "\nPrimal solution (name, value):\n"; )
771  for( int i = 0; i < soplex->numColsReal(); ++i )
772  {
773  if ( isNotZero( primal[i] ) )
774  {
775  MSG_INFO1( soplex->spxout, soplex->spxout << colnames[i] << "\t"
776  << std::setw(printwidth)
777  << std::setprecision(printprec)
778  << primal[i] << std::endl; )
779  ++nNonzeros;
780  }
781  }
782  MSG_INFO1( soplex->spxout, soplex->spxout << "All other variables are zero (within "
783  << std::setprecision(1) << std::scientific << Param::epsilon()
784  << std::setprecision(8) << std::fixed << "). Solution has " << nNonzeros << " nonzero entries." << std::endl; )
785  }
786  else
787  MSG_INFO1( soplex->spxout, soplex->spxout << "No primal information available.\n")
788 
789  }
790 
791 
792  if( printPrimalRational )
793  {
794  DVectorRational primal(soplex->numColsReal());
795  if( soplex->getPrimalRational(primal) )
796  {
797  int nNonzeros = 0;
798  MSG_INFO1( soplex->spxout, soplex->spxout << "\nPrimal solution (name, value):\n"; )
799  for( int i = 0; i < soplex->numColsRational(); ++i )
800  {
801  if ( primal[i] != (Rational) 0 )
802  {
803  MSG_INFO1( soplex->spxout, soplex->spxout << colnames[i] << "\t" << primal[i] << std::endl; )
804  ++nNonzeros;
805  }
806  }
807  MSG_INFO1( soplex->spxout, soplex->spxout << "All other variables are zero. Solution has " << nNonzeros << " nonzero entries." << std::endl; )
808  }
809  else
810  MSG_INFO1( soplex->spxout, soplex->spxout << "No primal (rational) solution available.\n")
811  }
812 
813 
814  if( printDual )
815  {
816  DVector dual(soplex->numRowsReal());
817  if( soplex->getDualFarkasReal(dual) )
818  {
819  MSG_INFO1( soplex->spxout, soplex->spxout << "\nDual ray (name, value):\n"; )
820  for( int i = 0; i < soplex->numRowsReal(); ++i )
821  {
822  if ( isNotZero( dual[i] ) )
823  MSG_INFO1( soplex->spxout, soplex->spxout << rownames[i] << "\t"
824  << std::setw(printwidth)
825  << std::setprecision(printprec)
826  << dual[i] << std::endl; )
827  }
828  MSG_INFO1( soplex->spxout, soplex->spxout << "All other entries are zero (within "
829  << std::setprecision(1) << std::scientific << Param::epsilon()
830  << std::setprecision(8) << std::fixed << ")." << std::endl; )
831  }
832  else if( soplex->getDualReal(dual) )
833  {
834  MSG_INFO1( soplex->spxout, soplex->spxout << "\nDual solution (name, value):\n"; )
835  for( int i = 0; i < soplex->numRowsReal(); ++i )
836  {
837  if ( isNotZero( dual[i] ) )
838  MSG_INFO1( soplex->spxout, soplex->spxout << rownames[i] << "\t"
839  << std::setw(printwidth)
840  << std::setprecision(printprec)
841  << dual[i] << std::endl; )
842  }
843  MSG_INFO1( soplex->spxout, soplex->spxout << "All other dual values are zero (within "
844  << std::setprecision(1) << std::scientific << Param::epsilon()
845  << std::setprecision(8) << std::fixed << ")." << std::endl; )
846  }
847  else
848  MSG_INFO1( soplex->spxout, soplex->spxout << "No dual information available.\n")
849 
850  }
851 
852 
853  if( printDualRational )
854  {
855  DVectorRational dual(soplex->numRowsReal());
856  if( soplex->getDualRational(dual) )
857  {
858  MSG_INFO1( soplex->spxout, soplex->spxout << "\nDual multipliers (name, value):\n"; )
859  for( int i = 0; i < soplex->numRowsRational(); ++i )
860  {
861  if ( dual[i] != (Rational) 0 )
862  MSG_INFO1( soplex->spxout, soplex->spxout << rownames[i] << "\t" << dual[i] << std::endl; )
863  }
864  MSG_INFO1( soplex->spxout, soplex->spxout << "All other dual values are zero." << std::endl; )
865  }
866  else
867  MSG_INFO1( soplex->spxout, soplex->spxout << "No dual (rational) solution available.\n")
868  }
869 
870 
871  if( checkSol )
872  checkSolution(*soplex);
873 
874  if( displayStatistics )
875  {
876  MSG_INFO1( soplex->spxout, soplex->spxout << "Statistics\n==========\n\n" );
877  soplex->printStatistics(soplex->spxout.getStream(SPxOut::INFO1));
878  }
879 
880  if(validation->validate)
881  validation->validateSolveReal(*soplex);
882 
883  // write basis file if specified
884  if( writebasname != 0 )
885  {
886  if( !soplex->hasBasis() )
887  {
888  MSG_WARNING( soplex->spxout, soplex->spxout << "No basis information available. Could not write file <" << writebasname << ">\n\n" );
889  }
890  else if( !soplex->writeBasisFile(writebasname, &rownames, &colnames) )
891  {
892  MSG_ERROR( std::cerr << "Error while writing file <" << writebasname << ">.\n\n" );
893  returnValue = 1;
894  goto TERMINATE_FREESTRINGS;
895  }
896  else
897  {
898  MSG_INFO1( soplex->spxout, soplex->spxout << "Written basis information to file <" << writebasname << ">.\n\n" );
899  }
900  }
901  }
902  catch( const SPxException& x )
903  {
904  MSG_ERROR( std::cerr << "Exception caught: " << x.what() << "\n" );
905  returnValue = 1;
906  goto TERMINATE_FREESTRINGS;
907  }
908 
909  TERMINATE_FREESTRINGS:
910  freeStrings(readbasname, writebasname, loadsetname, savesetname, diffsetname);
911 
912  TERMINATE:
913  // because EGlpNumClear() calls mpq_clear() for all mpq_t variables, we need to destroy all objects of class Rational
914  // beforehand; hence all Rational objects and all data that uses Rational objects must be allocated dynamically via
915  // spx_alloc() and freed here; disabling the list memory is crucial
916  soplex->~SoPlex();
917  spx_free(soplex);
918  validation->~Validation();
919  spx_free(validation);
921  EGlpNumClear();
922  readingTime->~Timer();
923  spx_free(readingTime);
924 
925  return returnValue;
926 }
927 #else
928 #include <assert.h>
929 #include <math.h>
930 #include <string.h>
931 #include <iostream>
932 #include <iomanip>
933 #include <fstream>
934 
935 #include "spxdefines.h"
936 #include "soplex.h"
937 #include "spxsolver.h"
938 
939 #include "timer.h"
940 #include "spxgithash.h"
941 #include "spxpricer.h"
942 #include "spxdantzigpr.h"
943 #include "spxparmultpr.h"
944 #include "spxdevexpr.h"
945 #include "spxhybridpr.h"
946 #include "spxsteeppr.h"
947 #include "spxsteepexpr.h"
948 #include "spxweightpr.h"
949 #include "spxratiotester.h"
950 #include "spxharrisrt.h"
951 #include "spxdefaultrt.h"
952 #include "spxfastrt.h"
953 #include "spxboundflippingrt.h"
954 #include "spxsimplifier.h"
955 #include "spxmainsm.h"
956 #include "spxscaler.h"
957 #include "spxequilisc.h"
958 #include "spxleastsqsc.h"
959 #include "spxgeometsc.h"
960 #include "spxsumst.h"
961 #include "spxweightst.h"
962 #include "spxvectorst.h"
963 #include "slufactor.h"
964 #include "spxout.h"
965 
966 using namespace soplex;
967 
968 
969 //------------------------------------------------------------------------
970 // for simplicity: store whether we are in check mode:
971 static bool checkMode = false;
972 //------------------------------------------------------------------------
973 
974 
975 //------------------------------------------------------------------------
976 // class MySoPlex
977 //------------------------------------------------------------------------
978 
979 /** LP solver class for the command line. */
980 class MySoPlex : public SoPlex
981 {
982 public:
983  /// default constructor
984  MySoPlex( SPxOut& outstream,
987  : SoPlex(outstream, p_type, p_rep)
988  {}
989  //------------------------------------------------------------------------
990  /// virtual destructor
991  virtual ~MySoPlex()
992  {}
993  //------------------------------------------------------------------------
994  void displayQuality() const
995  {
996  Real maxviol;
997  Real sumviol;
998 
999  if ( checkMode )
1000  {
1001  MSG_INFO1( (*spxout), (*spxout) << "IEXAMP05 Violations (max/sum)" << std::endl; )
1002 
1003  m_solver.qualConstraintViolation(maxviol, sumviol);
1004 
1005  MSG_INFO1( (*spxout), (*spxout) << "IEXAMP06 Constraints :"
1006  << std::setw(16) << maxviol << " "
1007  << std::setw(16) << sumviol << std::endl; )
1008 
1009  qualConstraintViolation(maxviol, sumviol);
1010 
1011  MSG_INFO1( (*spxout), (*spxout) << "IEXAMP07 (unscaled) :"
1012  << std::setw(16) << maxviol << " "
1013  << std::setw(16) << sumviol << std::endl; )
1014 
1015  m_solver.qualBoundViolation(maxviol, sumviol);
1016 
1017  MSG_INFO1( (*spxout), (*spxout) << "IEXAMP08 Bounds :"
1018  << std::setw(16) << maxviol << " "
1019  << std::setw(16) << sumviol << std::endl; )
1020 
1021  qualBoundViolation(maxviol, sumviol);
1022 
1023  MSG_INFO1( (*spxout), (*spxout) << "IEXAMP09 (unscaled) :"
1024  << std::setw(16) << maxviol << " "
1025  << std::setw(16) << sumviol << std::endl; )
1026 
1027  if (!m_vanished)
1028  {
1029  m_solver.qualSlackViolation(maxviol, sumviol);
1030 
1031  MSG_INFO1( (*spxout), (*spxout) << "IEXAMP10 Slacks :"
1032  << std::setw(16) << maxviol << " "
1033  << std::setw(16) << sumviol << std::endl; )
1034 
1035  m_solver.qualRedCostViolation(maxviol, sumviol);
1036 
1037  MSG_INFO1( (*spxout), (*spxout) << "IEXAMP11 Reduced costs :"
1038  << std::setw(16) << maxviol << " "
1039  << std::setw(16) << sumviol << std::endl; )
1040 #if 0
1041  MSG_INFO1( (*spxout), (*spxout) << "IEXAMP12 Proven dual bound:"
1042  << std::setw(20)
1043  << std::setprecision(20)
1044  << m_solver.provedDualbound() << std::endl; )
1045 #endif
1046  }
1047  }
1048  else
1049  {
1050  MSG_INFO1( (*spxout), (*spxout) << "Violations (max/sum)" << std::endl; )
1051 
1052  m_solver.qualConstraintViolation(maxviol, sumviol);
1053 
1054  MSG_INFO1( (*spxout), (*spxout) << "Constraints :"
1055  << std::setw(16) << maxviol << " "
1056  << std::setw(16) << sumviol << std::endl; )
1057 
1058  qualConstraintViolation(maxviol, sumviol);
1059 
1060  MSG_INFO1( (*spxout), (*spxout) << " (unscaled) :"
1061  << std::setw(16) << maxviol << " "
1062  << std::setw(16) << sumviol << std::endl; )
1063 
1064  m_solver.qualBoundViolation(maxviol, sumviol);
1065 
1066  MSG_INFO1( (*spxout), (*spxout) << "Bounds :"
1067  << std::setw(16) << maxviol << " "
1068  << std::setw(16) << sumviol << std::endl; )
1069 
1070  qualBoundViolation(maxviol, sumviol);
1071 
1072  MSG_INFO1( (*spxout), (*spxout) << " (unscaled) :"
1073  << std::setw(16) << maxviol << " "
1074  << std::setw(16) << sumviol << std::endl; )
1075 
1076  if (!m_vanished)
1077  {
1078  m_solver.qualSlackViolation(maxviol, sumviol);
1079 
1080  MSG_INFO1( (*spxout), (*spxout) << "Slacks :"
1081  << std::setw(16) << maxviol << " "
1082  << std::setw(16) << sumviol << std::endl; )
1083 
1084  m_solver.qualRedCostViolation(maxviol, sumviol);
1085 
1086  MSG_INFO1( (*spxout), (*spxout) << "Reduced costs :"
1087  << std::setw(16) << maxviol << " "
1088  << std::setw(16) << sumviol << std::endl; )
1089 #if 0
1090  MSG_INFO1( (*spxout), (*spxout) << "Proven dual bound:"
1091  << std::setw(20)
1092  << std::setprecision(20)
1093  << m_solver.provedDualbound() << std::endl; )
1094 #endif
1095  }
1096  }
1097  }
1098  //------------------------------------------------------------------------
1099  void displayInfeasibility() const
1100  {
1101  assert(m_solver.status() == SPxSolver::INFEASIBLE);
1102 
1103 #if 0
1104  if ( checkMode )
1105  {
1106  if( m_solver.isProvenInfeasible() )
1107  MSG_INFO1( (*spxout), (*spxout) << "IEXAMP13 Infeasibility is proven." << std::endl; )
1108  else
1109  MSG_INFO1( (*spxout), (*spxout) << "IEXAMP13 Infeasibility could not be proven!" << std::endl; )
1110  }
1111  else
1112  {
1113  if ( m_solver.isProvenInfeasible() )
1114  {
1115  MSG_INFO1( (*spxout), (*spxout) << "Infeasibility is proven." << std::endl; )
1116  }
1117  else
1118  {
1119  MSG_INFO1( (*spxout), (*spxout) << "Infeasibility could not be proven!" << std::endl; )
1120  }
1121  }
1122 #endif
1123  }
1124 };
1125 
1126 
1127 //------------------------------------------------------------------------
1128 // Helpers
1129 //------------------------------------------------------------------------
1130 
1131 static
1132 void print_version_info()
1133 {
1134  const char* banner1 =
1135  "************************************************************************\n"
1136  "* *\n"
1137  "* SoPlex --- the Sequential object-oriented simPlex. *\n"
1138  ;
1139 
1140  const char* banner2 =
1141  "* *\n"
1142  "* Copyright (C) 1996-2017 Konrad-Zuse-Zentrum *\n"
1143  "* fuer Informationstechnik Berlin *\n"
1144  "* *\n"
1145  "* SoPlex is distributed under the terms of the ZIB Academic Licence. *\n"
1146  "* You should have received a copy of the ZIB Academic License *\n"
1147  "* along with SoPlex; If not email to soplex@zib.de. *\n"
1148  "* *\n"
1149  "************************************************************************\n"
1150  ;
1151 
1152  if( !checkMode )
1153  std::cout << banner1;
1154 
1155 #if (SOPLEX_SUBVERSION > 0)
1156  if( !checkMode )
1157  std::cout << "* Version ";
1158  else
1159  std::cout << "SoPlex version ";
1160  std::cout << SOPLEX_VERSION/100 << "."
1161  << (SOPLEX_VERSION % 100)/10 << "."
1162  << SOPLEX_VERSION % 10 << "."
1164  << " - Githash "
1165  << std::setw(13) << std::setiosflags(std::ios::left) << getGitHash();
1166  if( !checkMode )
1167  std::cout << " *\n" << banner2 << std::endl;
1168  else
1169  std::cout << "\n";
1170 #else
1171  if( !checkMode )
1172  std::cout << "* Release ";
1173  else
1174  std::cout << "SoPlex release ";
1175  std::cout << SOPLEX_VERSION/100 << "."
1176  << (SOPLEX_VERSION % 100)/10 << "."
1177  << SOPLEX_VERSION % 10
1178  << " - Githash "
1179  << std::setw(13) << std::setiosflags(std::ios::left) << getGitHash();
1180  if( !checkMode )
1181  std::cout << " *\n" << banner2 << std::endl;
1182  else
1183  std::cout << "\n";
1184 #endif
1185 
1186  /// The following code block is tests and shows compilation parameters.
1187  std::cout << "[NDEBUG:"
1188 #ifdef NDEBUG
1189  << "YES"
1190 #else
1191  << "NO"
1192 #endif
1193  << "]";
1194 
1195  std::cout << "[WITH_WARNINGS:"
1196 #ifdef WITH_WARNINGS
1197  << "YES"
1198 #else
1199  << "NO"
1200 #endif
1201  << "]";
1202 
1203  std::cout << "[ENABLE_ADDITIONAL_CHECKS:"
1204 #ifdef ENABLE_ADDITIONAL_CHECKS
1205  << "YES"
1206 #else
1207  << "NO"
1208 #endif
1209  << "]";
1210 
1211  std::cout << "[ENABLE_CONSISTENCY_CHECKS:"
1212 #ifdef ENABLE_CONSISTENCY_CHECKS
1213  << "YES"
1214 #else
1215  << "NO"
1216 #endif
1217  << "]";
1218 
1219  std::cout << "[SOPLEX_WITH_GMP:"
1220 #ifdef SOPLEX_WITH_GMP
1221  << "YES"
1222 #else
1223  << "NO"
1224 #endif
1225  << "]" << std::endl;
1226 
1227  std::cout << std::endl;
1228 }
1229 
1230 #if 0
1231 static
1232 void print_short_version_info()
1233 {
1234  const char* banner1 =
1235  "************************************************************************\n"
1236  "* SoPlex --- the Sequential object-oriented simPlex. ";
1237  const char* banner2 =
1238  "* Copyright (C) 1996-2017 Konrad-Zuse-Zentrum *\n"
1239  "* fuer Informationstechnik Berlin *\n"
1240  "************************************************************************\n";
1241 
1242  std::cout << banner1;
1243 #if (SOPLEX_SUBVERSION > 0)
1244  std::cout << "Version "
1245  << SOPLEX_VERSION/100 << "."
1246  << (SOPLEX_VERSION % 100)/10 << "."
1247  << SOPLEX_VERSION % 10 << "."
1249  << " *\n";
1250 #else
1251  std::cout << "Release "
1252  << SOPLEX_VERSION/100 << "."
1253  << (SOPLEX_VERSION % 100)/10 << "."
1254  << SOPLEX_VERSION % 10
1255  << " *\n";
1256 #endif
1257  std::cout << banner2 << std::endl;
1258 }
1259 #endif
1260 
1261 //------------------------------------------------------------------------
1262 static
1263 void print_usage_and_exit( const char* const argv[] )
1264 {
1265  const char* usage =
1266  "[options] LPfile [Basfile]\n\n"
1267  " LPfile can be either in MPS or LPF format\n\n"
1268  "options: (*) indicates default\n"
1269  " (!) indicates experimental features which may give wrong results\n"
1270  " -e select entering algorithm (default is leaving)\n"
1271  " -r select row wise representation (default is column)\n"
1272  " -i select Eta-update (default is Forest-Tomlin)\n"
1273  " -x output solution vector\n"
1274  " -y output dual multipliers\n"
1275  " -q display solution quality\n"
1276  " -br read file with starting basis from Basfile\n"
1277  " -bw write file with optimal basis to Basfile\n"
1278  " -l set time limit in seconds\n"
1279  " -L set iteration limit\n"
1280  " -f set primal feasibility tolerance\n"
1281  " -o set optimality, i.e., dual feasibility tolerance\n"
1282  " -d set primal and dual feasibility tolerance to same value\n"
1283  " -zz set general zero tolerance\n"
1284  " -zf set factorization zero tolerance\n"
1285  " -zu set update zero tolerance\n"
1286  " -v set verbosity Level: from 0 (ERROR) to 5 (INFO3), default 3 (INFO1)\n"
1287  " -V show program version\n"
1288  " -C check mode (for check scripts)\n"
1289  " -h show this help\n\n"
1290  "Simplifier: Scaler: Starter: Pricer: Ratiotester:\n"
1291  " -s0 none -g0 none -c0 none* -p0 Textbook -t0 Textbook\n"
1292  " -s1 Main* -g1 uni-Equi -c1 Weight -p1 ParMult -t1 Harris\n"
1293  " -g2 bi-Equi* -c2 Sum -p2 Devex -t2 Fast\n"
1294  " -g3 Geo1 -c3 Vector -p3 Hybrid! -t3 Bound Flipping*\n"
1295  " -g4 Geo8 -p4 Steep*\n"
1296  " -p5 Weight\n"
1297  " -p6 SteepExactSetup\n"
1298  ;
1299 
1300  std::cerr << "usage: " << argv[0] << " " << usage << std::endl;
1301  exit(0);
1302 }
1303 
1304 //------------------------------------------------------------------------
1305 static
1306 void check_parameter(const char param, const char* const argv[])
1307 {
1308  if (param == '\0')
1309  print_usage_and_exit( argv );
1310 }
1311 
1312 //------------------------------------------------------------------------
1313 static
1314 void print_algorithm_parameters(
1315  MySoPlex& work,
1316  const SPxSolver::Representation representation,
1317  const SLUFactor::UpdateType update
1318  )
1319 {
1320  if ( checkMode )
1321  {
1322  MSG_INFO1( (*work.spxout), (*work.spxout)
1323  << "IEXAMP12 Feastol = "
1324  << std::setw(16) << work.feastol() << std::endl
1325  << "IEXAMP52 Opttol = "
1326  << std::setw(16) << work.opttol() << std::endl
1327  << "IEXAMP13 Epsilon Zero = "
1328  << std::setw(16) << Param::epsilon() << std::endl
1329  << "IEXAMP37 Epsilon Factor = "
1330  << std::setw(16) << Param::epsilonFactorization() << std::endl
1331  << "IEXAMP38 Epsilon Update = "
1332  << std::setw(16) << Param::epsilonUpdate() << std::endl
1333  << "IEXAMP14 "
1334  << (work.type() == SPxSolver::ENTER ? "Entering" : "Leaving")
1335  << " algorithm" << std::endl
1336  << "IEXAMP15 "
1337  << (representation == SPxSolver::ROW ? "Row" : "Column")
1338  << " representation" << std::endl
1339  << "IEXAMP16 "
1340  << (update == SLUFactor::ETA ? "Eta" : "Forest-Tomlin")
1341  << " update" << std::endl; )
1342  }
1343  else
1344  {
1345  MSG_INFO1( (*work.spxout), (*work.spxout)
1346  << "SoPlex parameters: " << std::endl
1347  << "Feastol = "
1348  << std::setw(16) << work.feastol() << std::endl
1349  << "Opttol = "
1350  << std::setw(16) << work.opttol() << std::endl
1351  << "Epsilon Zero = "
1352  << std::setw(16) << Param::epsilon() << std::endl
1353  << "Epsilon Factor = "
1354  << std::setw(16) << Param::epsilonFactorization() << std::endl
1355  << "Epsilon Update = "
1356  << std::setw(16) << Param::epsilonUpdate() << std::endl
1357  << std::endl
1358  << "algorithm = " << (work.type() == SPxSolver::ENTER ? "Entering" : "Leaving")
1359  << std::endl
1360  << "representation = " << (representation == SPxSolver::ROW ? "Row" : "Column")
1361  << std::endl
1362  << "update = " << (update == SLUFactor::ETA ? "Eta" : "Forest-Tomlin")
1363  << std::endl; )
1364  }
1365 }
1366 
1367 //------------------------------------------------------------------------
1368 static
1369 SPxPricer* get_pricer(const int pricing, SPxOut* spxout)
1370 {
1371  SPxPricer* pricer = 0;
1372  switch(pricing)
1373  {
1374  case 6 :
1375  pricer = new SPxSteepExPR;
1376  break;
1377  case 5 :
1378  pricer = new SPxWeightPR;
1379  break;
1380  case 4 :
1381  pricer = new SPxSteepPR;
1382  break;
1383  case 3 :
1384  pricer = new SPxHybridPR;
1385  break;
1386  case 2 :
1387  pricer = new SPxDevexPR;
1388  break;
1389  case 1 :
1390  pricer = new SPxParMultPR;
1391  break;
1392  case 0 :
1393  /*FALLTHROUGH*/
1394  default :
1395  pricer = new SPxDantzigPR;
1396  break;
1397  }
1398 
1399  assert(pricer != 0);
1400  if ( checkMode )
1401 #ifdef PARTIAL_PRICING
1402  MSG_INFO1( (*spxout), (*spxout) << "IEXAMP17 " << pricer->getName() << " pricing"
1403  << " (partial, size = " << MAX_PRICING_CANDIDATES << ")"
1404  << std::endl; )
1405 #else
1406  MSG_INFO1( (*spxout), (*spxout) << "IEXAMP17 " << pricer->getName() << " pricing"
1407  << std::endl; )
1408 #endif
1409  else
1410 #ifdef PARTIAL_PRICING
1411  MSG_INFO1( (*spxout), (*spxout) << "pricing = " << pricer->getName()
1412  << " (partial, size = " << MAX_PRICING_CANDIDATES << ")"
1413  << std::endl; )
1414 #else
1415  MSG_INFO1( (*spxout), (*spxout) << "pricing = " << pricer->getName()
1416  << std::endl; )
1417 #endif
1418  return pricer;
1419 }
1420 
1421 //------------------------------------------------------------------------
1422 static
1423 SPxRatioTester* get_ratio_tester(const int ratiotest, SPxOut* spxout)
1424 {
1425  SPxRatioTester* ratiotester = 0;
1426  switch(ratiotest)
1427  {
1428  case 3 :
1429  ratiotester = new SPxBoundFlippingRT;
1430  break;
1431  case 2 :
1432  ratiotester = new SPxFastRT;
1433  break;
1434  case 1 :
1435  ratiotester = new SPxHarrisRT;
1436  break;
1437  case 0 :
1438  /*FALLTHROUGH*/
1439  default:
1440  ratiotester = new SPxDefaultRT;
1441  break;
1442  }
1443 
1444  assert(ratiotester != 0);
1445  if ( checkMode )
1446  MSG_INFO1( (*spxout), (*spxout) << "IEXAMP18 " << ratiotester->getName() << " ratiotest" << std::endl; )
1447  else
1448  MSG_INFO1( (*spxout), (*spxout) << "ratiotest = " << ratiotester->getName() << std::endl; )
1449  return ratiotester;
1450 }
1451 
1452 //------------------------------------------------------------------------
1453 static
1454 void get_scalers(
1455  SPxScaler*& postscaler,
1456  const int scaling,
1457  SPxOut* spxout
1458  )
1459 {
1460 
1461  switch(scaling)
1462  {
1463  case 4:
1464  postscaler = new SPxGeometSC(8);
1465  break;
1466  case 3:
1467  postscaler = new SPxGeometSC(1);
1468  break;
1469  case 2 :
1470  postscaler = new SPxEquiliSC(true);
1471  break;
1472  case 1 :
1473  postscaler = new SPxEquiliSC(false);
1474  break;
1475  case 0 :
1476  /*FALLTHROUGH*/
1477  default :
1478  postscaler = 0;
1479  break;
1480  }
1481 
1482  if ( checkMode )
1483  {
1484  MSG_INFO1( (*spxout), (*spxout) << "IEXAMP19 "
1485  << ((postscaler != 0) ? postscaler->getName() : "no")
1486  << " scaling" << std::endl; )
1487  }
1488  else
1489  {
1490  MSG_INFO1( (*spxout), (*spxout) << "scaling = "
1491  << ((postscaler != 0) ? postscaler->getName() : "no")
1492  << std::endl; )
1493  }
1494 }
1495 
1496 //------------------------------------------------------------------------
1497 static
1498 SPxSimplifier* get_simplifier(const int simplifying, SPxOut* spxout)
1499 {
1500  SPxSimplifier* simplifier = 0;
1501  switch(simplifying)
1502  {
1503  case 1 :
1504  simplifier = new SPxMainSM;
1505  break;
1506  case 0 :
1507  /*FALLTHROUGH*/
1508  default :
1509  assert(simplifier == 0);
1510  break;
1511  }
1512 
1513  if ( checkMode )
1514  MSG_INFO1( (*spxout), (*spxout) << "IEXAMP20 " << ((simplifier == 0) ? "no" : simplifier->getName()) << " simplifier" << std::endl; )
1515  else
1516  MSG_INFO1( (*spxout), (*spxout) << "simplifier = " << ((simplifier == 0) ? "no" : simplifier->getName()) << std::endl; )
1517  return simplifier;
1518 }
1519 
1520 //------------------------------------------------------------------------
1521 static
1522 SPxStarter* get_starter(const int starting, SPxOut* spxout)
1523 {
1524  SPxStarter* starter = 0;
1525  switch(starting)
1526  {
1527  case 3 :
1528  starter = new SPxVectorST;
1529  break;
1530  case 2 :
1531  starter = new SPxSumST;
1532  break;
1533  case 1 :
1534  starter = new SPxWeightST;
1535  break;
1536  case 0 :
1537  /*FALLTHROUGH*/
1538  default :
1539  break;
1540  }
1541 
1542  if ( checkMode )
1543  MSG_INFO1( (*spxout), (*spxout) << "IEXAMP21 " << ((starter == 0) ? "no" : starter->getName()) << " starter" << std::endl; )
1544  else
1545  MSG_INFO1( (*spxout), (*spxout) << "starter = " << ((starter == 0) ? "no" : starter->getName()) << std::endl; )
1546 
1547  return starter;
1548 }
1549 
1550 //------------------------------------------------------------------------
1551 #ifdef SEND_ALL_OUTPUT_TO_FILES
1552 static
1553 void redirect_output(
1554  std::ostream& myerrstream,
1555  std::ostream& myinfostream
1556  )
1557 {
1558  myerrstream .setf( std::ios::scientific | std::ios::showpoint );
1559  myinfostream.setf( std::ios::scientific | std::ios::showpoint );
1560  spxout.setStream( SPxOut::ERROR, myerrstream );
1561  spxout.setStream( SPxOut::WARNING, myerrstream );
1562  spxout.setStream( SPxOut::INFO1, myinfostream );
1563  spxout.setStream( SPxOut::INFO2, myinfostream );
1564  spxout.setStream( SPxOut::INFO3, myinfostream );
1565  spxout.setStream( SPxOut::DEBUG, myinfostream );
1566 }
1567 #endif
1568 //------------------------------------------------------------------------
1569 static
1570 void read_input_file(
1571  MySoPlex& work,
1572  const char* filename,
1573  NameSet& rownames,
1574  NameSet& colnames)
1575 {
1576  if ( checkMode )
1577  MSG_INFO1( (*work.spxout), (*work.spxout) << "IEXAMP22 loading LP file " << filename << std::endl; )
1578  else
1579  MSG_INFO1( (*work.spxout), (*work.spxout) << "\nLoading LP file " << filename << std::endl; )
1580 
1581  UserTimer timer;
1582  timer.start();
1583 
1584  if ( ! work.readFile(filename, &rownames, &colnames, 0) )
1585  {
1586  if ( checkMode )
1587  MSG_INFO1( (*work.spxout), (*work.spxout) << "EEXAMP23 error while reading file \"" << filename << "\"" << std::endl; )
1588  else
1589  MSG_INFO1( (*work.spxout), (*work.spxout) << "error while reading file \"" << filename << "\"" << std::endl; )
1590  exit(1);
1591  }
1592  assert(work.isConsistent());
1593 
1594  timer.stop();
1595 
1596  if ( checkMode )
1597  {
1598  MSG_INFO1( (*work.spxout), (*work.spxout) << "IEXAMP24 LP has "
1599  << work.nRows() << " rows "
1600  << work.nCols() << " columns "
1601  << work.nNzos() << " nonzeros"
1602  << std::endl; )
1603 
1604  MSG_INFO1( (*work.spxout), (*work.spxout) << "IEXAMP41 LP reading time: " << timer.time() << std::endl; )
1605  }
1606  else
1607  {
1608  MSG_INFO1( (*work.spxout), (*work.spxout) << "LP has "
1609  << work.nRows() << " rows "
1610  << work.nCols() << " columns "
1611  << work.nNzos() << " nonzeros"
1612  << std::endl; )
1613 
1614  MSG_INFO1( (*work.spxout),
1615  std::streamsize prec = (*work.spxout).precision();
1616  (*work.spxout) << "LP reading time: " << std::fixed << std::setprecision(2) << timer.time();
1617  (*work.spxout) << std::scientific << std::setprecision(int(prec)) << std::endl; )
1618  }
1619 }
1620 
1621 //------------------------------------------------------------------------
1622 static
1623 void read_basis_file(
1624  MySoPlex& work ,
1625  const char* filename,
1626  const NameSet* rownames,
1627  const NameSet* colnames)
1628 {
1629  MSG_INFO1( (*work.spxout), (*work.spxout) << "Reading basis from file (disables simplifier)" << std::endl; )
1630  if (!work.readBasisFile(filename, rownames, colnames))
1631  {
1632  if ( checkMode )
1633  MSG_INFO1( (*work.spxout), (*work.spxout) << "EEXAMP25 error while reading file \"" << filename << "\"" << std::endl; )
1634  else
1635  MSG_INFO1( (*work.spxout), (*work.spxout) << "Error while reading file \"" << filename << "\"" << std::endl; )
1636  exit(1);
1637  }
1638 }
1639 
1640 //------------------------------------------------------------------------
1641 static
1642 void solve_LP(MySoPlex& work)
1643 {
1644  UserTimer timer;
1645  timer.start();
1646 
1647  if ( checkMode )
1648  MSG_INFO1( (*work.spxout), (*work.spxout) << "IEXAMP26 solving LP" << std::endl; )
1649  else
1650  MSG_INFO1( (*work.spxout), (*work.spxout) << "\nSolving LP ..." << std::endl; )
1651 
1652  work.solve();
1653  timer.stop();
1654 
1655  MSG_INFO1( (*work.spxout), (*work.spxout) << "\nSoPlex statistics:\n" << work.statistics(); )
1656 }
1657 
1658 //------------------------------------------------------------------------
1659 static
1660 void print_solution_and_status(
1661  MySoPlex& work,
1662  const NameSet& rownames,
1663  const NameSet& colnames,
1664  const int precision,
1665  const bool print_quality,
1666  const bool print_solution,
1667  const bool print_dual,
1668  const bool write_basis,
1669  const char* basisname
1670  )
1671 {
1672  // get the solution status
1673  SPxSolver::Status stat = work.status();
1674 
1675  if ( ! checkMode )
1676  MSG_INFO1( (*work.spxout), (*work.spxout) << std::endl; )
1677  switch (stat)
1678  {
1679  case SPxSolver::OPTIMAL:
1680  if ( checkMode )
1681  MSG_INFO1( (*work.spxout), (*work.spxout) << "IEXAMP29 solution value is: " << std::setprecision( precision ) << work.objValue() << std::endl; )
1682  else
1683  MSG_INFO1( (*work.spxout), (*work.spxout) << "Solution value is: " << std::setprecision( precision ) << work.objValue() << std::endl; )
1684 
1685  if ( print_quality )
1686  work.displayQuality();
1687 
1688  if ( print_solution )
1689  {
1690  DVector objx(work.nCols());
1691 
1692  if( work.getPrimal(objx) != SPxSolver::ERROR )
1693  {
1694  MSG_INFO1( (*work.spxout), (*work.spxout) << std::endl << "Primal solution (name, id, value):" << std::endl; )
1695  for( int i = 0; i < work.nCols(); ++i )
1696  {
1697  if ( isNotZero( objx[i], 0.001 * work.feastol() ) )
1698  MSG_INFO1( (*work.spxout), (*work.spxout) << colnames[ work.cId(i) ] << "\t"
1699  << i << "\t"
1700  << std::setw(17)
1701  << std::setprecision( precision )
1702  << objx[i] << std::endl; )
1703  }
1704  MSG_INFO1( (*work.spxout), (*work.spxout) << "All other variables are zero (within " << std::setprecision(1) << 0.001*work.feastol() << ")." << std::endl; )
1705  }
1706  }
1707  if ( print_dual )
1708  {
1709  DVector objy(work.nRows());
1710  bool allzero = true;
1711 
1712  if( work.getDual(objy) != SPxSolver::ERROR )
1713  {
1714  MSG_INFO1( (*work.spxout), (*work.spxout) << std::endl << "Dual multipliers (name, id, value):" << std::endl; )
1715  for( int i = 0; i < work.nRows(); ++i )
1716  {
1717  if ( isNotZero( objy[i] , 0.001 * work.opttol() ) )
1718  {
1719  MSG_INFO1( (*work.spxout), (*work.spxout) << rownames[ work.rId(i) ] << "\t"
1720  << i << "\t"
1721  << std::setw(17)
1722  << std::setprecision( precision )
1723  << objy[i] << std::endl; )
1724  allzero = false;
1725  }
1726  }
1727 
1728  MSG_INFO1( (*work.spxout), (*work.spxout) << "All " << (allzero ? "" : "other ") << "dual values are zero (within "
1729  << std::setprecision(1) << 0.001*work.opttol() << ")." << std::endl; )
1730 
1731  if( !allzero )
1732  {
1733  if( work.spxSense() == SPxLP::MINIMIZE )
1734  {
1735  MSG_INFO1( (*work.spxout), (*work.spxout) << "Minimizing: a positive/negative value corresponds to left-hand (>=) resp. right-hand (<=) side."
1736  << std::endl; )
1737  }
1738  else
1739  {
1740  MSG_INFO1( (*work.spxout), (*work.spxout) << "Maximizing: a positive/negative value corresponds to right-hand (<=) resp. left-hand (>=) side."
1741  << std::endl; )
1742  }
1743  }
1744  }
1745  }
1746  if ( write_basis )
1747  {
1748  MSG_INFO1( (*work.spxout), (*work.spxout) << "Writing basis of original problem to file " << basisname << std::endl; )
1749  if ( ! work.writeBasisFile( basisname, &rownames, &colnames ) )
1750  {
1751  if ( checkMode )
1752  MSG_INFO1( (*work.spxout), (*work.spxout) << "EEXAMP30 error while writing file \"" << basisname << "\"" << std::endl; )
1753  else
1754  MSG_INFO1( (*work.spxout), (*work.spxout) << "Error while writing file \"" << basisname << "\"" << std::endl; )
1755  }
1756  }
1757  break;
1758  case SPxSolver::UNBOUNDED:
1759  if ( checkMode )
1760  MSG_INFO1( (*work.spxout), (*work.spxout) << "IEXAMP31 LP is unbounded" << std::endl; )
1761  else
1762  MSG_INFO1( (*work.spxout), (*work.spxout) << "LP is unbounded" << std::endl; )
1763 
1764  if ( print_solution )
1765  {
1766  DVector objx(work.nCols());
1767  if( work.getPrimal(objx) != SPxSolver::ERROR )
1768  {
1769  MSG_INFO1( (*work.spxout), (*work.spxout) << std::endl << "Primal solution (name, id, value):" << std::endl; )
1770  for( int i = 0; i < work.nCols(); ++i )
1771  {
1772  if ( isNotZero( objx[i], 0.001 * work.feastol() ) )
1773  MSG_INFO1( (*work.spxout), (*work.spxout) << colnames[ work.cId(i) ] << "\t"
1774  << i << "\t"
1775  << std::setw(17)
1776  << std::setprecision( precision )
1777  << objx[i] << std::endl; )
1778  }
1779  MSG_INFO1( (*work.spxout), (*work.spxout) << "All other variables are zero (within " << std::setprecision(1) << 0.001*work.feastol() << ")." << std::endl; )
1780  }
1781 
1782  DVector objcoef(work.nCols());
1783  DVector ray(work.nCols());
1784  if( work.getPrimalray(ray) != SPxSolver::ERROR )
1785  {
1786  Real rayobjval = 0.0;
1787 
1788  work.getObj(objcoef);
1789 
1790  MSG_INFO1( (*work.spxout), (*work.spxout) << std::endl << "Primal ray (name, id, value):" << std::endl; )
1791  for( int i = 0; i < work.nCols(); ++i )
1792  {
1793  if ( isNotZero( ray[i], 0.001 * work.feastol() ) )
1794  {
1795  rayobjval += ray[i] * objcoef[i];
1796 
1797  MSG_INFO1( (*work.spxout), (*work.spxout) << colnames[ work.cId(i) ] << "\t"
1798  << i << "\t"
1799  << std::setw(17)
1800  << std::setprecision( precision )
1801  << ray[i] << std::endl; )
1802  }
1803  }
1804  MSG_INFO1( (*work.spxout), (*work.spxout) << "All other variables have zero value (within " << std::setprecision(1) << 0.001*work.feastol() << ")." << std::endl; )
1805  MSG_INFO1( (*work.spxout), (*work.spxout) << "Objective change per unit along primal ray is " << rayobjval << "." << std::endl; )
1806  }
1807  }
1808  break;
1809  case SPxSolver::INFEASIBLE:
1810  if ( checkMode )
1811  MSG_INFO1( (*work.spxout), (*work.spxout) << "IEXAMP32 LP is infeasible" << std::endl; )
1812  else
1813  MSG_INFO1( (*work.spxout), (*work.spxout) << "LP is infeasible" << std::endl; )
1814  if ( print_solution )
1815  {
1816  DVector farkasx(work.nRows());
1817 
1818  if( work.getDualfarkas(farkasx) != SPxSolver::ERROR )
1819  {
1820  DVector proofvec(work.nCols());
1821  double lhs;
1822  double rhs;
1823 
1824  lhs = 0.0;
1825  rhs = 0.0;
1826  proofvec.clear();
1827  for( int i = 0; i < work.nRows(); ++i )
1828  {
1829  if ( isNotZero( farkasx[i], 0.001 * work.opttol() ) )
1830  {
1831  MSG_INFO1( (*work.spxout), (*work.spxout) << rownames[ work.rId(i) ] << "\t"
1832  << i << "\t"
1833  << std::setw(16)
1834  << std::setprecision( precision )
1835  << farkasx[i] << "\t"; )
1836  LPRow row;
1837  work.getRow(i, row);
1838  if( row.lhs() > -soplex::infinity )
1839  {
1840  MSG_INFO1( (*work.spxout), (*work.spxout) << row.lhs() << " <= "; );
1841  }
1842  for( int j = 0; j < row.rowVector().size(); ++j )
1843  {
1844  if( row.rowVector().value(j) > 0 )
1845  {
1846  MSG_INFO1( (*work.spxout), (*work.spxout) << "+"; )
1847  }
1848  MSG_INFO1( (*work.spxout), (*work.spxout)
1849  << row.rowVector().value(j) << " "
1850  << colnames[ work.cId(row.rowVector().index(j)) ]
1851  << " "; );
1852  }
1853  if( row.rhs() < soplex::infinity )
1854  {
1855  MSG_INFO1( (*work.spxout), (*work.spxout) << "<= " << row.rhs(); );
1856  }
1857  MSG_INFO1( (*work.spxout), (*work.spxout) << std::endl; )
1858  if( farkasx[i] > 0.0 )
1859  {
1860  lhs += farkasx[i] * row.lhs();
1861  rhs += farkasx[i] * row.rhs();
1862  }
1863  else
1864  {
1865  lhs += farkasx[i] * row.rhs();
1866  rhs += farkasx[i] * row.lhs();
1867  }
1868  SVector vec(row.rowVector());
1869  vec *= farkasx[i];
1870  proofvec += vec;
1871  }
1872  }
1873 
1874  MSG_INFO1( (*work.spxout), (*work.spxout) << "All other row multipliers are zero (within " << std::setprecision(1) << 0.001*work.opttol() << ")." << std::endl; )
1875  MSG_INFO1( (*work.spxout), (*work.spxout) << "Farkas infeasibility proof: \t"; )
1876  MSG_INFO1( (*work.spxout), (*work.spxout) << lhs << " <= "; )
1877 
1878  bool nonzerofound = false;
1879  for( int i = 0; i < work.nCols(); ++i )
1880  {
1881  if ( isNotZero( proofvec[i], 0.001 * work.opttol() ) )
1882  {
1883  if( proofvec[i] > 0 )
1884  {
1885  MSG_INFO1( (*work.spxout), (*work.spxout) << "+"; )
1886  }
1887  MSG_INFO1( (*work.spxout), (*work.spxout) << proofvec[i] << " " << colnames[ work.cId(i) ] << " "; )
1888  nonzerofound = true;
1889  }
1890  }
1891  if( !nonzerofound )
1892  {
1893  MSG_INFO1( (*work.spxout), (*work.spxout) << "0 "; );
1894  }
1895  MSG_INFO1( (*work.spxout), (*work.spxout) << "<= " << rhs << std::endl; );
1896  }
1897  }
1898  if ( print_quality )
1899  work.displayInfeasibility();
1900  if ( write_basis ) // write basis even if we are infeasible
1901  if ( ! work.writeBasisFile( basisname, &rownames, &colnames ) )
1902  {
1903  if ( checkMode )
1904  MSG_INFO1( (*work.spxout), (*work.spxout) << "EEXAMP30 error while writing file \"" << basisname << "\"" << std::endl; )
1905  else
1906  MSG_INFO1( (*work.spxout), (*work.spxout) << "Error while writing file \"" << basisname << "\"" << std::endl; )
1907  }
1908  break;
1910  if ( checkMode )
1911  MSG_INFO1( (*work.spxout), (*work.spxout) << "EEXAMP40 aborted due to cycling" << std::endl; )
1912  else
1913  MSG_INFO1( (*work.spxout), (*work.spxout) << "Aborted due to cycling" << std::endl; )
1914  break;
1915  case SPxSolver::ABORT_TIME:
1916  if ( checkMode )
1917  MSG_INFO1( (*work.spxout), (*work.spxout) << "IEXAMP33 aborted due to time limit" << std::endl; )
1918  else
1919  MSG_INFO1( (*work.spxout), (*work.spxout) << "Aborted due to time limit" << std::endl; )
1920  break;
1921  case SPxSolver::ABORT_ITER:
1922  if ( checkMode )
1923  MSG_INFO1( (*work.spxout), (*work.spxout) << "IEXAMP34 aborted due to iteration limit" << std::endl; )
1924  else
1925  MSG_INFO1( (*work.spxout), (*work.spxout) << "Aborted due to iteration limit" << std::endl; )
1926  break;
1928  if ( checkMode )
1929  MSG_INFO1( (*work.spxout), (*work.spxout) << "IEXAMP35 aborted due to objective value limit" << std::endl; )
1930  else
1931  MSG_INFO1( (*work.spxout), (*work.spxout) << "Aborted due to objective value limit" << std::endl; )
1932  break;
1933  case SPxSolver::SINGULAR:
1934  if ( checkMode )
1935  MSG_INFO1( (*work.spxout), (*work.spxout) << "EEXAMP39 basis is singular" << std::endl; )
1936  else
1937  MSG_INFO1( (*work.spxout), (*work.spxout) << "Basis is singular" << std::endl; )
1938  break;
1939  default:
1940  if ( checkMode )
1941  MSG_INFO1( (*work.spxout), (*work.spxout) << "EEXAMP36 An error occurred during " << "the solution process" << std::endl; )
1942  else
1943  MSG_INFO1( (*work.spxout), (*work.spxout) << "An error occurred during " << "the solution process" << std::endl; )
1944  break;
1945  }
1946  MSG_INFO1( (*work.spxout), (*work.spxout) << std::endl; )
1947 }
1948 
1949 //------------------------------------------------------------------------
1950 static
1951 void clean_up(
1952  SPxScaler*& postscaler,
1953  SPxSimplifier*& simplifier,
1954  SPxStarter*& starter,
1955  SPxPricer*& pricer,
1956  SPxRatioTester*& ratiotester,
1957  char*& basisname
1958  )
1959 {
1960  if ( postscaler != 0 )
1961  {
1962  delete postscaler;
1963  postscaler = 0;
1964  }
1965  if ( simplifier != 0 )
1966  {
1967  delete simplifier;
1968  simplifier = 0;
1969  }
1970  if ( starter != 0 )
1971  {
1972  delete starter;
1973  starter = 0;
1974  }
1975 
1976  assert( pricer != 0 );
1977  delete pricer;
1978  pricer = 0;
1979 
1980  assert( ratiotester != 0 );
1981  delete ratiotester;
1982  ratiotester = 0;
1983 
1984  if ( basisname != 0 )
1985  delete [] basisname;
1986  basisname = 0;
1987 }
1988 
1989 //------------------------------------------------------------------------
1990 // main program
1991 //------------------------------------------------------------------------
1992 
1993 int main(int argc, char* argv[])
1994 {
1995  const char* filename;
1996  char* basisname = 0;
2000  SPxSimplifier* simplifier = 0;
2001  SPxStarter* starter = 0;
2002  SPxPricer* pricer = 0;
2003  SPxRatioTester* ratiotester = 0;
2004  SPxScaler* postscaler = 0;
2005 
2006  SPxOut spxout;
2007 
2008  try {
2009  NameSet rownames;
2010  NameSet colnames;
2011  int starting = 0;
2012  int pricing = 4;
2013  int ratiotest = 3;
2014  int scaling = 2;
2015  int simplifying = 1;
2016  int iterlimit = -1;
2017  Real timelimit = DEFAULT_INFINITY;
2018  Real delta = DEFAULT_BND_VIOL;
2019  Real feastol = DEFAULT_BND_VIOL;
2020  Real opttol = DEFAULT_BND_VIOL;
2021  Real epsilon = DEFAULT_EPS_ZERO;
2022  Real epsilon_factor = DEFAULT_EPS_FACTOR;
2023  Real epsilon_update = DEFAULT_EPS_UPDATE;
2024  int verbose = SPxOut::INFO1;
2025  bool print_solution = false;
2026  bool print_dual = false;
2027  bool print_quality = false;
2028  bool read_basis = false;
2029  bool write_basis = false;
2030  int precision;
2031  int optidx;
2032 
2033  for(optidx = 1; optidx < argc; optidx++)
2034  {
2035  if (*argv[optidx] != '-')
2036  break;
2037 
2038  switch(argv[optidx][1])
2039  {
2040  case 'b' :
2041  check_parameter(argv[optidx][2], argv); // use -b{r,w}, not -b
2042  if (argv[optidx][2] == 'r')
2043  read_basis = true;
2044  if (argv[optidx][2] == 'w')
2045  write_basis = true;
2046  break;
2047  case 'c' :
2048  check_parameter(argv[optidx][2], argv); // use -c[0-3], not -c
2049  starting = atoi(&argv[optidx][2]);
2050  break;
2051  case 'd' :
2052  check_parameter(argv[optidx][2], argv); // use -dx, not -d
2053  delta = atof(&argv[optidx][2]);
2054  break;
2055  case 'f' :
2056  check_parameter(argv[optidx][2], argv); // use -fx, not -f
2057  feastol = atof(&argv[optidx][2]);
2058  break;
2059  case 'o' :
2060  check_parameter(argv[optidx][2], argv); // use -ox, not -o
2061  opttol = atof(&argv[optidx][2]);
2062  break;
2063  case 'e':
2064  type = SPxSolver::ENTER;
2065  break;
2066  case 'g' :
2067  check_parameter(argv[optidx][2], argv); // use -g[0-5], not -g
2068  scaling = atoi(&argv[optidx][2]);
2069  break;
2070  case 'i' :
2071  update = SLUFactor::ETA;
2072  break;
2073  case 'l' :
2074  if (argv[optidx][2] == '\0' ) // use -lx, not -l
2075  print_usage_and_exit( argv );
2076  timelimit = atof(&argv[optidx][2]);
2077  break;
2078  case 'L' :
2079  if (argv[optidx][2] == '\0' ) // use -Lx, not -L
2080  print_usage_and_exit( argv );
2081  iterlimit = atoi(&argv[optidx][2]);
2082  break;
2083  case 'p' :
2084  check_parameter(argv[optidx][2], argv); // use -p[0-5], not -p
2085  pricing = atoi(&argv[optidx][2]);
2086  break;
2087  case 'q' :
2088  print_quality = true;
2089  break;
2090  case 'r' :
2091  representation = SPxSolver::ROW;
2092  break;
2093  case 's' :
2094  check_parameter(argv[optidx][2], argv); // use -s[0-4], not -s
2095  simplifying = atoi(&argv[optidx][2]);
2096  break;
2097  case 't' :
2098  check_parameter(argv[optidx][2], argv); // use -r[0-2], not -r
2099  ratiotest = atoi(&argv[optidx][2]);
2100  break;
2101  case 'v' :
2102  check_parameter(argv[optidx][2], argv); // use -v[0-5], not -v
2103  if (argv[optidx][2] >= '0' && argv[optidx][2] <= '9')
2104  verbose = argv[optidx][2] - '0';
2105  break;
2106  case 'V' :
2107  print_version_info();
2108  exit(0);
2109  case 'x' :
2110  print_solution = true;
2111  break;
2112  case 'y' :
2113  print_dual = true;
2114  break;
2115  case 'z' :
2116  check_parameter(argv[optidx][2], argv); // must not be empty
2117  check_parameter(argv[optidx][3], argv); // must not be empty
2118  switch(argv[optidx][2])
2119  {
2120  case 'z' :
2121  epsilon = atof(&argv[optidx][3]);
2122  break;
2123  case 'f' :
2124  epsilon_factor = atof(&argv[optidx][3]);
2125  break;
2126  case 'u' :
2127  epsilon_update = atof(&argv[optidx][3]);
2128  break;
2129  default :
2130  print_usage_and_exit( argv );
2131  }
2132  break;
2133  case 'C' :
2134  checkMode = true;
2135  break;
2136  case 'h' :
2137  case '?' :
2138  print_version_info();
2139  //lint -fallthrough
2140  default :
2141  print_usage_and_exit( argv );
2142  }
2143  }
2144 
2145  // print version
2146  print_version_info();
2147 
2148  // enough arguments?
2149  if ((argc - optidx) < 1 + (read_basis ? 1 : 0) + (write_basis ? 1 : 0))
2150  print_usage_and_exit( argv );
2151  filename = argv[optidx];
2152 
2153  ++optidx;
2154 
2155  // switch off simplifier when using a starting basis
2156  if ( read_basis )
2157  simplifying = 0;
2158 
2159  if ( read_basis || write_basis )
2160  basisname = strcpy( new char[strlen(argv[optidx]) + 1], argv[optidx] );
2161 
2162  // set some algorithm parameters
2163  Param::setEpsilon ( epsilon );
2164  Param::setEpsilonFactorization( epsilon_factor );
2165  Param::setEpsilonUpdate ( epsilon_update );
2166  spxout.setVerbosity ( (SPxOut::Verbosity) verbose );
2167 
2168  // Set the output precision.
2169  precision = int(-log10(MINIMUM(feastol, opttol))) + 1;
2170 
2171  std::cout.setf( std::ios::scientific | std::ios::showpoint );
2172  std::cerr.setf( std::ios::scientific | std::ios::showpoint );
2173 
2174 #ifdef SEND_ALL_OUTPUT_TO_FILES
2175  // Example of redirecting output to different files.
2176  // Default is cerr for errors and warnings, cout for everything else.
2177  std::ofstream myerrstream ( "errwarn.txt" );
2178  std::ofstream myinfostream( "infos.txt" );
2179  redirect_output(myerrstream, myinfostream);
2180 #endif
2181 
2182  // create an instance of MySoPlex
2183  MySoPlex work( spxout, type, representation );
2184  work.setOutstream ( spxout );
2185  work.setUtype ( update );
2186  work.setFeastol ( MINIMUM(feastol, delta) );
2187  work.setOpttol ( MINIMUM(opttol, delta) );
2188  work.setTerminationTime ( timelimit );
2189  work.setTerminationIter ( iterlimit );
2190  print_algorithm_parameters( work, representation, update );
2191  assert( work.isConsistent() );
2192 
2193  // set pricer, starter, simplifier, and ratio tester
2194  work.setPricer ( pricer = get_pricer (pricing, work.spxout) );
2195  work.setStarter ( starter = get_starter (starting, work.spxout) );
2196  work.setSimplifier( simplifier = get_simplifier (simplifying, work.spxout) );
2197  work.setTester ( ratiotester = get_ratio_tester(ratiotest, work.spxout) );
2198  assert(work.isConsistent());
2199 
2200  // set pre- and postscaler
2201  get_scalers(postscaler, scaling, work.spxout);
2202  work.setPostScaler(postscaler);
2203  assert(work.isConsistent());
2204 
2205  // read the LP from an input file (.lp or .mps)
2206  read_input_file(work, filename, rownames, colnames);
2207 
2208  // read a basis file if specified
2209  if (read_basis)
2210  read_basis_file(work, basisname, &rownames, &colnames);
2211 
2212  // solve the LP
2213  solve_LP(work);
2214 
2215  // print solution, status, infeasibility system,...
2216  print_solution_and_status(work, rownames, colnames, precision, print_quality,
2217  print_solution, print_dual, write_basis, basisname);
2218 
2219  // clean up
2220  clean_up(postscaler, simplifier, starter, pricer, ratiotester, basisname);
2221 
2222  return 0;
2223  }
2224  catch( const SPxException& x )
2225  {
2226  std::cout << "exception caught : " << x.what() << std::endl;
2227  delete [] basisname;
2228  if (simplifier)
2229  delete simplifier;
2230  delete starter;
2231  delete pricer;
2232  delete ratiotester;
2233  delete postscaler;
2234  }
2235 }
2236 #endif
Fast shifting ratio test.
bool isNotZero(Real a, Real eps=Param::epsilon())
returns true iff |a| > eps
Definition: spxdefines.h:417
virtual void setStream(const Verbosity &verbosity, std::ostream &stream)
Sets the stream for the specified verbosity level.
Definition: spxout.h:150
UpdateType
Specifies how to perform change method.
Definition: slufactor.h:49
Bound flipping ratio test ("long step dual") for SoPlex.Class SPxBoundFlippingRT provides an implemen...
#define DEFAULT_EPS_FACTOR
Definition: spxdefines.h:230
void printVersion() const
prints version and compilation options
Definition: soplex.cpp:6835
bool getDualViolationRational(Rational &maxviol, Rational &sumviol)
gets violation of dual multipliers; returns true on success
Definition: soplex.cpp:3554
#define EGlpNumStart()
Definition: soplexmain.cpp:40
int numRowsReal() const
returns number of rows
Definition: soplex.cpp:793
static void setEpsilon(Real eps)
Definition: spxdefines.cpp:50
Devex pricer.The Devex Pricer for SoPlex implements an approximate steepest edge pricing, that does without solving an extra linear system and computing the scalar products.
Definition: spxdevexpr.h:43
#define DEFAULT_BND_VIOL
default allowed bound violation
Definition: spxdefines.h:223
THREADLOCAL const Real infinity
Definition: spxdefines.cpp:26
Type
Algorithmic type.
Definition: spxsolver.h:124
type of ratio test
Definition: soplex.h:980
Steepest edge pricer.Class SPxSteepExPR implements a steepest edge pricer to be used with SoPlex...
Definition: spxsteepexpr.h:40
Geometric mean row/column scaling.This SPxScaler implementation performs geometric mean scaling of th...
Definition: spxgeometsc.h:35
verbosity level
Definition: soplex.h:965
apply standard floating-point algorithm
Definition: soplex.h:1206
Abstract pricer base class.
bool getPrimalReal(VectorReal &vector)
gets the primal solution vector if available; returns true on success
Definition: soplex.cpp:2969
int numRowsRational() const
returns number of rows
Definition: soplex.cpp:1085
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...
Definition: soplex.cpp:5177
bool getDualRational(VectorRational &vector)
gets the dual solution vector if available; returns true on success
Definition: soplex.cpp:3324
Solution vector based start basis.
time limit in seconds (INFTY if unlimited)
Definition: soplex.h:1292
mode for iterative refinement strategy
Definition: soplex.h:989
Representation
LP basis representation.
Definition: spxsolver.h:105
virtual ~SoPlex()
destructor
Definition: soplex.cpp:752
LP geometric mean scaling.
primal feasibility tolerance
Definition: soplex.h:1271
virtual ~Timer()
Definition: timer.h:124
bool writeBasisFile(const char *filename, const NameSet *rowNames=0, const NameSet *colNames=0, const bool cpxFormat=false) const
writes basis information to filename; if rowNames and colNames are NULL, default names are used; retu...
Definition: soplex.cpp:5385
Abstract ratio test base class.
solve() aborted due to iteration limit.
Definition: spxsolver.h:213
#define SOPLEX_VERSION
Definition: spxdefines.h:42
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...
Definition: soplex.cpp:5192
mode for reading LP files
Definition: soplex.h:986
mode for synchronizing real and rational LP
Definition: soplex.h:983
bool getDualFarkasReal(VectorReal &vector)
gets the Farkas proof if available; returns true on success
Definition: soplex.cpp:3044
automatic sync of real and rational LP
Definition: soplex.h:1186
iteration limit (-1 if unlimited)
Definition: soplex.h:953
Implementation of Sparse Linear Solver.
Abstract ratio test base class.Class SPxRatioTester is the virtual base class for computing the ratio...
bool getRowViolationReal(Real &maxviol, Real &sumviol)
gets violation of constraints; returns true on success
Definition: soplex.cpp:3098
bool getRowViolationRational(Rational &maxviol, Rational &sumviol)
gets violation of constraints; returns true on success
Definition: soplex.cpp:3420
#define DEFAULT_INFINITY
Definition: spxdefines.h:238
SoPlex start basis generation base class.SPxStarter is the virtual base class for classes generating ...
Definition: spxstarter.h:41
bool updateExternalSolution(char *solution)
updates the external solution used for validation
Definition: validation.cpp:25
#define DEFAULT_EPS_UPDATE
Definition: spxdefines.h:233
LP has been proven to be primal infeasible.
Definition: spxsolver.h:222
Dantzig pricer.
General methods in LP preprocessing.
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
Definition: soplex.cpp:5114
int intParam(const IntParam param) const
returns integer parameter value
Definition: soplex.cpp:5534
Wrapper for GMP type mpq_class.We wrap mpq_class so that we can replace it by a double type if GMP is...
Definition: rational.h:45
static void disableListMem()
disables list memory
Definition: rational.cpp:3067
Devex pricer.
void printStatistics(std::ostream &os)
prints complete statistics
Definition: soplex.cpp:6742
std::ostream & getStream(const Verbosity &verbosity) const
Returns the stream for the specified verbosity level.
Definition: spxout.h:157
rowwise representation.
Definition: spxsolver.h:107
TimerFactory class.
LP simplification base class.
virtual const std::string what() const
returns exception message
Definition: exceptions.h:57
Partial multiple pricing.Class SPxParMultPr is an implementation class for SPxPricer implementing Dan...
Definition: spxparmultpr.h:47
Wrapper for different output streams and verbosity levels.
SPxSolver::Status optimize()
optimize the given LP
Definition: soplex.cpp:2797
Steepest edge pricer.
virtual void start()=0
start timer, resume accounting user, system and real time.
Entering Simplex.
Definition: spxsolver.h:134
virtual Real stop()=0
stop timer, return accounted user time.
void spx_alloc(T &p, int n=1)
Allocate memory.
Definition: spxalloc.h:48
#define EGlpNumClear()
Definition: soplexmain.cpp:41
Fast shifting ratio test.Class SPxFastRT is an implementation class of SPxRatioTester providing fast ...
Definition: spxfastrt.h:41
Leaving Simplex.
Definition: spxsolver.h:143
standard floating-point parsing
Definition: soplex.h:1196
type of scaler
Definition: soplex.h:971
double Real
Definition: spxdefines.h:215
Weighted pricing.Class SPxWeightPR is an implemantation class of SPxPricer that uses weights for colu...
Definition: spxweightpr.h:41
int main(int argc, char *argv[])
runs SoPlex command line
Definition: soplexmain.cpp:266
bool getPrimalRayReal(VectorReal &vector)
gets the primal ray if available; returns true on success
Definition: soplex.cpp:2999
bool hasPrimal() const
is a primal feasible solution available?
Definition: soplex.cpp:2908
static void printUsage(const char *const argv[], int idx)
Definition: soplexmain.cpp:51
virtual const char * getName() const
get name of simplifier.
void validateSolveReal(SoPlex &soplex)
validates the soplex solution using the external solution
Definition: validation.cpp:63
LP simplification abstract base class.Instances of classes derived from SPxSimplifier may be loaded t...
Definition: spxsimplifier.h:41
LP has been solved to optimality.
Definition: spxsolver.h:220
bool hasBasis() const
is an advanced starting basis available?
Definition: soplex.cpp:3844
#define MSG_ERROR(x)
Prints out message x if the verbosity level is at least SPxOut::ERROR.
Definition: spxdefines.h:111
bool getDualViolationReal(Real &maxviol, Real &sumviol)
gets violation of dual multipliers; returns true on success
Definition: soplex.cpp:3194
Wrapper for several output streams. A verbosity level is used to decide which stream to use and wheth...
Definition: spxout.h:63
virtual Real time() const
Definition: usertimer.cpp:100
solve() aborted due to time limit.
Definition: spxsolver.h:212
main LP solver class
an error occured.
Definition: spxsolver.h:204
#define DEFAULT_EPS_ZERO
default allowed additive zero: 1.0 + EPS_ZERO == 1.0
Definition: spxdefines.h:227
virtual void setVerbosity(const Verbosity &v)
Definition: spxout.h:111
type of simplifier
Definition: soplex.h:968
static Real epsilonUpdate()
Definition: spxdefines.cpp:65
void printUserSettings()
print non-default parameter values
Definition: soplex.cpp:6205
static void checkSolutionRational(SoPlex &soplex)
performs external feasibility check with rational type
Definition: soplexmain.cpp:196
#define MINIMUM(x, y)
Definition: spxdefines.h:244
int numColsRational() const
returns number of columns
Definition: soplex.cpp:1094
Abstract pricer base class.Class SPxPricer is a pure virtual class defining the interface for pricer ...
Definition: spxpricer.h:46
bool getPrimalRational(VectorRational &vector)
gets the primal solution vector if available; returns true on success
Definition: soplex.cpp:3279
Solution vector based start basis.This version of SPxWeightST can be used to construct a starting bas...
Definition: spxvectorst.h:44
virtual Real stop()
stop timer, return accounted user time.
Definition: usertimer.cpp:86
Real realParam(const RealParam param) const
returns real parameter value
Definition: soplex.cpp:5544
virtual Real time() const =0
Simple heuristic SPxStarter.
user sync of real and rational LP
Definition: soplex.h:1189
bool hasDual() const
is a dual feasible solution available?
Definition: soplex.cpp:2932
bool parseSettingsString(char *line)
parses one setting string and returns true on success; note that string is modified ...
Definition: soplex.cpp:6387
SPxOut spxout
Definition: soplex.h:1441
virtual void start()
start timer, resume accounting user, system and real time.
Definition: usertimer.cpp:72
static Timer * createTimer(Timer::TYPE ttype)
create timers and allocate memory for them
Definition: timerfactory.h:43
(In)equality for LPs.Class LPRowBase provides constraints for linear programs in the form where a is...
Definition: lprowbase.h:45
virtual const char * getName() const
get name of ratio tester.
Preconfigured SoPlex LP solver.
Bound flipping ratio test (long step dual) for SoPlex.
Debugging, floating point type and parameter definitions.
static Real epsilon()
Definition: spxdefines.cpp:45
virtual const char * getName() const
get name of scaler
Definition: spxscaler.cpp:100
Set of strings.Class NameSet implements a symbol or name table. It allows to store or remove names (i...
Definition: nameset.h:61
LP least squares scaling.
Hybrid pricer.The hybrid pricer for SoPlex tries to guess the best pricing strategy to use for pricin...
Definition: spxhybridpr.h:43
bool validate
should the soplex solution be validated?
Definition: validation.h:32
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.
bool setRealParam(const RealParam param, const Real value, const bool init=true)
sets real parameter value; returns true on success
Definition: soplex.cpp:5979
Timer class.
returns the current git hash of SoPlex
bool loadSettingsFile(const char *filename)
reads settings file; returns true on success
Definition: soplex.cpp:6338
int numNonzerosReal() const
returns number of nonzeros
Definition: soplex.cpp:811
Dantzig pricer.Class SPxDantzigPR is an implementation class of an SPxPricer implementing Dantzig&#39;s d...
Definition: spxdantzigpr.h:38
bool getRedCostViolationRational(Rational &maxviol, Rational &sumviol)
gets violation of reduced costs; returns true on success
Definition: soplex.cpp:3473
Harris pricing with shifting.
solve() aborted due to detection of cycling.
Definition: spxsolver.h:211
Weighted start basis.
type of pricer
Definition: soplex.h:977
bool getDualReal(VectorReal &vector)
gets the dual solution vector if available; returns true on success
Definition: soplex.cpp:3014
static void checkSolution(SoPlex &soplex)
performs external feasibility check according to check mode
Definition: soplexmain.cpp:249
Steepest edge pricer with exact initialization of weights.
Preconfigured SoPlex LP-solver.
Definition: soplex.h:90
#define MSG_WARNING(spxout, x)
Prints out message x if the verbosity level is at least SPxOut::WARNING.
Definition: spxdefines.h:113
virtual const char * getName() const
get name of pricer.
Definition: spxpricer.h:109
LP scaling base class.
std::streamsize precision() const
Definition: spxout.h:139
static void setEpsilonUpdate(Real eps)
Definition: spxdefines.cpp:70
bool getBoundViolationReal(Real &maxviol, Real &sumviol)
gets violation of bounds; returns true on success
Definition: soplex.cpp:3059
bool writeFileReal(const char *filename, const NameSet *rowNames=0, const NameSet *colNames=0, const DIdxSet *intvars=0, const bool unscale=true) const
writes real LP to file; LP or MPS format is chosen from the extension in filename; if rowNames and co...
Definition: soplex.cpp:5132
Simple heuristic SPxStarter.Testing version of an SPxVectorST using a very simplistic heuristic to bu...
Definition: spxsumst.h:37
Weighted start basis.Class SPxWeightST is an implementation of a SPxStarter for generating a Simplex ...
Definition: spxweightst.h:56
decide according to READMODE
Definition: soplex.h:1222
const char * getGitHash()
Definition: spxgithash.cpp:23
mode for a posteriori feasibility checks
Definition: soplex.h:992
Partial multiple pricing.
Verbosity
Verbosity level.
Definition: spxout.h:72
~Validation()
default destructor
Definition: validation.h:49
Textbook ratio test for SoPlex.Class SPxDefaultRT provides an implementation of the textbook ratio te...
Definition: spxdefaultrt.h:42
void clear()
Set vector to 0.
Definition: vectorbase.h:260
LP scaler abstract base class.Instances of classes derived from SPxScaler may be loaded to SoPlex in ...
Definition: spxscaler.h:75
virtual const char * getName() const
get name of starter.
Definition: spxstarter.h:88
#define MSG_INFO1(spxout, x)
Prints out message x if the verbosity level is at least SPxOut::INFO1.
Definition: spxdefines.h:115
Validation object for soplex solutions.
bool getRedCostViolationReal(Real &maxviol, Real &sumviol)
gets violation of reduced costs; returns true on success
Definition: soplex.cpp:3140
#define SOPLEX_SUBVERSION
Definition: spxdefines.h:43
static void freeStrings(char *&s1, char *&s2, char *&s3, char *&s4, char *&s5)
Definition: soplexmain.cpp:106
static void setEpsilonFactorization(Real eps)
Definition: spxdefines.cpp:60
#define SOPLEX_COPYRIGHT
Definition: spxdefines.h:45
dual feasibility tolerance
Definition: soplex.h:1274
Hybrid pricer.
bool setIntParam(const IntParam param, const int value, const bool init=true)
sets integer parameter value; returns true on success
Definition: soplex.cpp:5628
bool saveSettingsFile(const char *filename, const bool onlyChanged=false) const
writes settings file; returns true on success
Definition: soplex.cpp:6260
static void checkSolutionReal(SoPlex &soplex)
performs external feasibility check with real type
Definition: soplexmain.cpp:138
std::string rationalToString(const Rational &r, const int precision)
convert rational number to string
Definition: rational.cpp:3452
Textbook ratio test for SoPlex.
static Real epsilonFactorization()
Definition: spxdefines.cpp:55
LP equilibrium scaling.
bool updateValidationTolerance(char *tolerance)
updates the tolerance used for validation
Definition: validation.cpp:49
Equilibrium row/column scaling.This SPxScaler implementation performs equilibrium scaling of the LPs ...
Definition: spxequilisc.h:35
int numColsReal() const
returns number of columns
Definition: soplex.cpp:802
Wrapper for the system time query methods.
Definition: timer.h:76
Weighted pricing.
solve() aborted due to objective limit.
Definition: spxsolver.h:214
columnwise representation.
Definition: spxsolver.h:108
void spx_free(T &p)
Release memory.
Definition: spxalloc.h:109
Basis is singular, numerical troubles?
Definition: spxsolver.h:215
Steepest edge pricer.Class SPxSteepPR implements a steepest edge pricer to be used with SoPlex...
Definition: spxsteeppr.h:41
Harris pricing with shifting.Class SPxHarrisRT is a stable implementation of a SPxRatioTester class a...
Definition: spxharrisrt.h:40
bool getBoundViolationRational(Rational &maxviol, Rational &sumviol)
gets violation of bounds; returns true on success
Definition: soplex.cpp:3369
LP simplifier for removing uneccessary row/columns.This SPxSimplifier is mainly based on the paper "P...
Definition: spxmainsm.h:60
LP has been proven to be primal unbounded.
Definition: spxsolver.h:221