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