source: branches/pre/Test/ClpMain.cpp @ 210

Last change on this file since 210 was 210, checked in by forrest, 17 years ago

Trying

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 56.5 KB
Line 
1// Copyright (C) 2002, International Business Machines
2// Corporation and others.  All Rights Reserved.
3
4#include "CoinPragma.hpp"
5
6#include <cassert>
7#include <cstdio>
8#include <cmath>
9#include <cfloat>
10#include <string>
11#include <iostream>
12
13
14#include "CoinPragma.hpp"
15#include "CoinHelperFunctions.hpp"
16#define CLPVERSION "0.98.5"
17
18#include "CoinMpsIO.hpp"
19
20#include "ClpFactorization.hpp"
21#include "CoinTime.hpp"
22#include "ClpSimplex.hpp"
23#include "ClpSolve.hpp"
24#include "ClpPackedMatrix.hpp"
25#include "ClpPlusMinusOneMatrix.hpp"
26#include "ClpNetworkMatrix.hpp"
27#include "ClpDualRowSteepest.hpp"
28#include "ClpDualRowDantzig.hpp"
29#include "ClpPrimalColumnSteepest.hpp"
30#include "ClpPrimalColumnDantzig.hpp"
31#include "ClpPresolve.hpp"
32
33// For Branch and bound
34//  #include "OsiClpSolverInterface.hpp"
35//  #include "OsiCuts.hpp"
36//  #include "OsiRowCut.hpp"
37//  #include "OsiColCut.hpp"
38
39#ifdef DMALLOC
40#include "dmalloc.h"
41#endif
42
43static double totalTime=0.0;
44
45//#############################################################################
46
47#ifdef NDEBUG
48#undef NDEBUG
49#endif
50
51int mainTest (int argc, const char *argv[],bool doDual,
52              ClpSimplex empty, bool doPresolve,int doIdiot);
53enum ClpParameterType {
54  GENERALQUERY=-100,
55 
56  DUALTOLERANCE=1,PRIMALTOLERANCE,DUALBOUND,PRIMALWEIGHT,MAXTIME,OBJSCALE,
57
58  LOGLEVEL=101,MAXFACTOR,PERTVALUE,MAXITERATION,PRESOLVEPASS,IDIOT,SPRINT,
59 
60  DIRECTION=201,DUALPIVOT,SCALING,ERRORSALLOWED,KEEPNAMES,SPARSEFACTOR,
61  PRIMALPIVOT,PRESOLVE,CRASH,BIASLU,PERTURBATION,MESSAGES,
62 
63  DIRECTORY=301,IMPORT,EXPORT,RESTORE,SAVE,DUALSIMPLEX,PRIMALSIMPLEX,
64  MAXIMIZE,MINIMIZE,EXIT,STDIN,UNITTEST,NETLIB_DUAL,NETLIB_PRIMAL,SOLUTION,
65  TIGHTEN,FAKEBOUND,HELP,PLUSMINUS,NETWORK,ALLSLACK,
66
67  INVALID=1000
68};
69static void printit(const char * input)
70{
71  int length =strlen(input);
72  char temp[101];
73  int i;
74  int n=0;
75  for (i=0;i<length;i++) {
76    if (input[i]=='\n') {
77      temp[n]='\0';
78      std::cout<<temp<<std::endl;
79      n=0;
80    } else if (n>=65&&input[i]==' ') {
81      temp[n]='\0';
82      std::cout<<temp<<std::endl;
83      n=0;
84    } else if (n||input[i]!=' ') {
85      temp[n++]=input[i];
86    }
87  }
88  if (n) {
89    temp[n]='\0';
90    std::cout<<temp<<std::endl;
91  }
92}
93/// Very simple class for setting parameters
94class ClpItem {
95
96public:
97
98  /**@name Constructor and destructor */
99  //@{
100  /// Constructors
101  ClpItem (  );
102  ClpItem (std::string name, std::string help,
103           double lower, double upper, ClpParameterType type,bool display=true);
104  ClpItem (std::string name, std::string help,
105           int lower, int upper, ClpParameterType type,bool display=true);
106  // Other strings will be added by insert
107  ClpItem (std::string name, std::string help, std::string firstValue,
108           ClpParameterType type,int defaultIndex=0,bool display=true);
109  // Action
110  ClpItem (std::string name, std::string help,
111           ClpParameterType type,int indexNumber=-1,bool display=true);
112  /// Copy constructor.
113  ClpItem(const ClpItem &);
114  /// Assignment operator. This copies the data
115    ClpItem & operator=(const ClpItem & rhs);
116  /// Destructor
117  ~ClpItem (  );
118  //@}
119
120  /**@name stuff */
121  //@{
122  /// Insert string (only valid for keywords)
123  void append(std::string keyWord);
124  /// Adds one help line
125  void addHelp(std::string keyWord);
126  /// Returns name
127  inline std::string  name(  ) const {
128    return name_;
129  };
130  /// Returns short help
131  inline std::string  shortHelp(  ) const {
132    return shortHelp_;
133  };
134  /// Sets a double parameter (nonzero code if error)
135  int setDoubleParameter(ClpSimplex * model, double value) const;
136  /// Gets a double parameter
137  double doubleParameter(ClpSimplex * model) const;
138  /// Sets a int parameter (nonzero code if error)
139  int setIntParameter(ClpSimplex * model, int value) const;
140  /// Gets a int parameter
141  int intParameter(ClpSimplex * model) const;
142  /// Returns name which could match
143  std::string matchName (  ) const;
144  /// Returns parameter option which matches (-1 if none)
145  int parameterOption ( std::string check ) const;
146  /// Prints parameter options
147  void printOptions (  ) const;
148  /// Returns current parameter option
149  inline std::string currentOption (  ) const
150  { return definedKeyWords_[currentKeyWord_]; };
151  /// Sets current parameter option
152  inline void setCurrentOption ( int value )
153  { currentKeyWord_=value; };
154  /// Sets int value
155  inline void setIntValue ( int value )
156  { intValue_=value; };
157  inline int intValue () const
158  { return intValue_; };
159  /// Sets double value
160  inline void setDoubleValue ( double value )
161  { doubleValue_=value; };
162  inline double doubleValue () const
163  { return doubleValue_; };
164  /// Sets string value
165  inline void setStringValue ( std::string value )
166  { stringValue_=value; };
167  inline std::string stringValue () const
168  { return stringValue_; };
169  /// Returns 1 if matches minimum, 2 if matches less, 0 if not matched
170  int matches (std::string input) const;
171  /// type
172  inline ClpParameterType type() const
173  { return type_;};
174  /// whether to display
175  inline bool displayThis() const
176  { return display_;};
177  /// Set Long help
178  inline void setLonghelp(const std::string help) 
179  {longHelp_=help;};
180  /// Print Long help
181  void printLongHelp() const;
182  /// Print action and string
183  void printString() const;
184  /// type for classification
185  inline int indexNumber() const
186  { return indexNumber_;};
187private:
188  /// gutsOfConstructor
189  void gutsOfConstructor();
190  //@}
191////////////////// data //////////////////
192private:
193
194  /**@name data
195   We might as well throw all type data in - could derive?
196  */
197  //@{
198  // Type see ClpParameterType
199  ClpParameterType type_;
200  /// If double == okay
201  double lowerDoubleValue_;
202  double upperDoubleValue_;
203  /// If int == okay
204  int lowerIntValue_;
205  int upperIntValue_;
206  // Length of name
207  unsigned int lengthName_;
208  // Minimum match
209  unsigned int lengthMatch_;
210  /// set of valid strings
211  std::vector<std::string> definedKeyWords_;
212  /// Name
213  std::string name_;
214  /// Short help
215  std::string shortHelp_;
216  /// Long help
217  std::string longHelp_;
218  /// Action
219  ClpParameterType action_;
220  /// Current keyWord (if a keyword parameter)
221  int currentKeyWord_;
222  /// Display on ?
223  bool display_;
224  /// Integer parameter - current value
225  int intValue_;
226  /// Double parameter - current value
227  double doubleValue_;
228  /// String parameter - current value
229  std::string stringValue_;
230  /// index number to use for display purposes
231  int indexNumber_;
232  //@}
233};
234//#############################################################################
235// Constructors / Destructor / Assignment
236//#############################################################################
237
238//-------------------------------------------------------------------
239// Default Constructor
240//-------------------------------------------------------------------
241ClpItem::ClpItem () 
242  : type_(INVALID),
243    lowerDoubleValue_(0.0),
244    upperDoubleValue_(0.0),
245    lowerIntValue_(0),
246    upperIntValue_(0),
247    lengthName_(0),
248    lengthMatch_(0),
249    definedKeyWords_(),
250    name_(),
251    shortHelp_(),
252    longHelp_(),
253    action_(INVALID),
254    currentKeyWord_(-1),
255    display_(false),
256    intValue_(-1),
257    doubleValue_(-1.0),
258    stringValue_(""),
259    indexNumber_(INVALID)
260{
261}
262// Other constructors
263ClpItem::ClpItem (std::string name, std::string help,
264           double lower, double upper, ClpParameterType type,bool display)
265  : type_(type),
266    lowerIntValue_(0),
267    upperIntValue_(0),
268    definedKeyWords_(),
269    name_(name),
270    shortHelp_(help),
271    longHelp_(),
272    action_(type),
273    currentKeyWord_(-1),
274    display_(display),
275    intValue_(-1),
276    doubleValue_(-1.0),
277    stringValue_(""),
278    indexNumber_(type)
279{
280  lowerDoubleValue_ = lower;
281  upperDoubleValue_ = upper;
282  gutsOfConstructor();
283}
284ClpItem::ClpItem (std::string name, std::string help,
285           int lower, int upper, ClpParameterType type,bool display)
286  : type_(type),
287    lowerDoubleValue_(0.0),
288    upperDoubleValue_(0.0),
289    definedKeyWords_(),
290    name_(name),
291    shortHelp_(help),
292    longHelp_(),
293    action_(type),
294    currentKeyWord_(-1),
295    display_(display),
296    intValue_(-1),
297    doubleValue_(-1.0),
298    stringValue_(""),
299    indexNumber_(type)
300{
301  gutsOfConstructor();
302  lowerIntValue_ = lower;
303  upperIntValue_ = upper;
304}
305// Other strings will be added by append
306ClpItem::ClpItem (std::string name, std::string help, 
307                  std::string firstValue,
308                  ClpParameterType type,
309                  int defaultIndex,bool display)
310  : type_(type),
311    lowerDoubleValue_(0.0),
312    upperDoubleValue_(0.0),
313    lowerIntValue_(0),
314    upperIntValue_(0),
315    definedKeyWords_(),
316    name_(name),
317    shortHelp_(help),
318    longHelp_(),
319    action_(type),
320    currentKeyWord_(defaultIndex),
321    display_(display),
322    intValue_(-1),
323    doubleValue_(-1.0),
324    stringValue_(""),
325    indexNumber_(type)
326{
327  gutsOfConstructor();
328  definedKeyWords_.push_back(firstValue);
329}
330// Action
331ClpItem::ClpItem (std::string name, std::string help,
332           ClpParameterType type,int indexNumber,bool display)
333  : type_(type),
334    lowerDoubleValue_(0.0),
335    upperDoubleValue_(0.0),
336    lowerIntValue_(0),
337    upperIntValue_(0),
338    definedKeyWords_(),
339    name_(name),
340    shortHelp_(help),
341    longHelp_(),
342    action_(type),
343    currentKeyWord_(-1),
344    display_(display),
345    intValue_(-1),
346    doubleValue_(-1.0),
347    stringValue_("")
348{
349  if (indexNumber<0)
350    indexNumber_=type;
351  else
352    indexNumber_=indexNumber;
353  gutsOfConstructor();
354}
355
356//-------------------------------------------------------------------
357// Copy constructor
358//-------------------------------------------------------------------
359ClpItem::ClpItem (const ClpItem & rhs) 
360{ 
361  type_ = rhs.type_;
362  lowerDoubleValue_ = rhs.lowerDoubleValue_;
363  upperDoubleValue_ = rhs.upperDoubleValue_;
364  lowerIntValue_ = rhs.lowerIntValue_;
365  upperIntValue_ = rhs.upperIntValue_;
366  lengthName_ = rhs.lengthName_;
367  lengthMatch_ = rhs.lengthMatch_;
368  definedKeyWords_ = rhs.definedKeyWords_;
369  name_ = rhs.name_;
370  shortHelp_ = rhs.shortHelp_;
371  longHelp_ = rhs.longHelp_;
372  action_ = rhs.action_;
373  currentKeyWord_ = rhs.currentKeyWord_;
374  display_=rhs.display_;
375  intValue_=rhs.intValue_;
376  doubleValue_=rhs.doubleValue_;
377  stringValue_=rhs.stringValue_;
378  indexNumber_=rhs.indexNumber_;
379}
380
381//-------------------------------------------------------------------
382// Destructor
383//-------------------------------------------------------------------
384ClpItem::~ClpItem ()
385{
386}
387
388//----------------------------------------------------------------
389// Assignment operator
390//-------------------------------------------------------------------
391ClpItem &
392ClpItem::operator=(const ClpItem& rhs)
393{
394  if (this != &rhs) {
395    type_ = rhs.type_;
396    lowerDoubleValue_ = rhs.lowerDoubleValue_;
397    upperDoubleValue_ = rhs.upperDoubleValue_;
398    lowerIntValue_ = rhs.lowerIntValue_;
399    upperIntValue_ = rhs.upperIntValue_;
400    lengthName_ = rhs.lengthName_;
401    lengthMatch_ = rhs.lengthMatch_;
402    definedKeyWords_ = rhs.definedKeyWords_;
403    name_ = rhs.name_;
404    shortHelp_ = rhs.shortHelp_;
405    longHelp_ = rhs.longHelp_;
406    action_ = rhs.action_;
407    currentKeyWord_ = rhs.currentKeyWord_;
408    display_=rhs.display_;
409    intValue_=rhs.intValue_;
410    doubleValue_=rhs.doubleValue_;
411    stringValue_=rhs.stringValue_;
412    indexNumber_=rhs.indexNumber_;
413  }
414  return *this;
415}
416void 
417ClpItem::gutsOfConstructor()
418{
419  unsigned int  shriekPos = name_.find('!');
420  lengthName_ = name_.length();
421  if ( shriekPos==std::string::npos ) {
422    //does not contain '!'
423    lengthMatch_= lengthName_;
424  } else {
425    lengthMatch_=shriekPos;
426    name_ = name_.substr(0,shriekPos)+name_.substr(shriekPos+1);
427    lengthName_--;
428  }
429}
430// Insert string (only valid for keywords)
431void 
432ClpItem::append(std::string keyWord)
433{
434  definedKeyWords_.push_back(keyWord);
435}
436
437int 
438ClpItem::matches (std::string input) const
439{
440  // look up strings to do more elegantly
441  if (input.length()>lengthName_) {
442    return 0;
443  } else {
444    unsigned int i;
445    for (i=0;i<input.length();i++) {
446      if (tolower(name_[i])!=tolower(input[i])) 
447        break;
448    }
449    if (i<input.length()) {
450      return 0;
451    } else if (i>=lengthMatch_) {
452      return 1;
453    } else {
454      // matched but too short
455      return 2;
456    }
457  }
458}
459// Returns name which could match
460std::string
461ClpItem::matchName (  ) const
462{ 
463  if (lengthMatch_==lengthName_) 
464    return name_;
465  else
466    return name_.substr(0,lengthMatch_)+"("+name_.substr(lengthMatch_)+")";
467}
468
469// Returns parameter option which matches (-1 if none)
470int 
471ClpItem::parameterOption ( std::string check ) const
472{
473  int numberItems = definedKeyWords_.size();
474  if (!numberItems) {
475    return -1;
476  } else {
477    int whichItem=0;
478    unsigned int it;
479    for (it=0;it<definedKeyWords_.size();it++) {
480      std::string thisOne = definedKeyWords_[it];
481      unsigned int  shriekPos = thisOne.find('!');
482      unsigned int length1 = thisOne.length();
483      unsigned int length2 = length1;
484      if ( shriekPos!=std::string::npos ) {
485        //contains '!'
486        length2 = shriekPos;
487        thisOne = thisOne.substr(0,shriekPos)+
488          thisOne.substr(shriekPos+1);
489        length1 = thisOne.length();
490      }
491      if (check.length()<=length1) {
492        unsigned int i;
493        for (i=0;i<check.length();i++) {
494          if (tolower(thisOne[i])!=tolower(check[i])) 
495            break;
496        }
497        if (i<check.length()) {
498          whichItem++;
499        } else if (i>=length2) {
500          break;
501        } 
502      } else {
503        whichItem++;
504      }
505    }
506    if (whichItem<numberItems)
507      return whichItem;
508    else
509      return -1;
510  }
511}
512// Prints parameter options
513void 
514ClpItem::printOptions (  ) const
515{
516  std::cout<<"Possible options for "<<name_<<" are:"<<std::endl;
517  unsigned int it;
518  for (it=0;it<definedKeyWords_.size();it++) {
519    std::string thisOne = definedKeyWords_[it];
520    unsigned int  shriekPos = thisOne.find('!');
521    if ( shriekPos!=std::string::npos ) {
522      //contains '!'
523      thisOne = thisOne.substr(0,shriekPos)+
524        "("+thisOne.substr(shriekPos+1)+")";
525    }
526    std::cout<<thisOne<<std::endl;
527  }
528}
529// Print action and string
530void 
531ClpItem::printString() const
532{
533  if (name_=="directory")
534    std::cout<<"Current working directory is "<<stringValue_<<std::endl;
535  else
536    std::cout<<"Current default (if $ as parameter) for "<<name_
537             <<" is "<<stringValue_<<std::endl;
538}
539int
540ClpItem::setDoubleParameter (ClpSimplex * model,double value) const
541{
542  double oldValue = doubleParameter(model);
543  if (value<lowerDoubleValue_||value>upperDoubleValue_) {
544    std::cout<<value<<" was provided for "<<name_<<
545      " - valid range is "<<lowerDoubleValue_<<" to "<<
546      upperDoubleValue_<<std::endl;
547    return 1;
548  } else {
549    std::cout<<name_<<" was changed from "<<oldValue<<" to "
550             <<value<<std::endl;
551    switch(type_) {
552    case DUALTOLERANCE:
553      model->setDualTolerance(value);
554      break;
555    case PRIMALTOLERANCE:
556      model->setPrimalTolerance(value);
557      break;
558    case DUALBOUND:
559      model->setDualBound(value);
560      break;
561    case PRIMALWEIGHT:
562      model->setInfeasibilityCost(value);
563      break;
564    case MAXTIME:
565      model->setMaximumSeconds(value);
566      break;
567    case OBJSCALE:
568      model->setOptimizationDirection(value);
569      break;
570    default:
571      abort();
572    }
573    return 0;
574  }
575}
576double 
577ClpItem::doubleParameter (ClpSimplex * model) const
578{
579  double value;
580  switch(type_) {
581  case DUALTOLERANCE:
582    value=model->dualTolerance();
583    break;
584  case PRIMALTOLERANCE:
585    value=model->primalTolerance();
586    break;
587  case DUALBOUND:
588    value=model->dualBound();
589    break;
590  case PRIMALWEIGHT:
591    value=model->infeasibilityCost();
592    break;
593  case MAXTIME:
594    value=model->maximumSeconds();
595    break;
596  case OBJSCALE:
597    value=model->optimizationDirection();
598    break;
599  default:
600    abort();
601  }
602  return value;
603}
604int 
605ClpItem::setIntParameter (ClpSimplex * model,int value) const
606{
607  int oldValue = intParameter(model);
608  if (value<lowerIntValue_||value>upperIntValue_) {
609    std::cout<<value<<" was provided for "<<name_<<
610      " - valid range is "<<lowerIntValue_<<" to "<<
611      upperIntValue_<<std::endl;
612    return 1;
613  } else {
614    std::cout<<name_<<" was changed from "<<oldValue<<" to "
615             <<value<<std::endl;
616    switch(type_) {
617    case LOGLEVEL:
618      model->setLogLevel(value);
619      break;
620    case MAXFACTOR:
621      model->factorization()->maximumPivots(value);
622      break;
623    case PERTVALUE:
624      model->setPerturbation(value);
625      break;
626    case MAXITERATION:
627      model->setMaximumIterations(value);
628      break;
629    default:
630      abort();
631    }
632    return 0;
633  }
634}
635int 
636ClpItem::intParameter (ClpSimplex * model) const
637{
638  int value;
639  switch(type_) {
640  case LOGLEVEL:
641    value=model->logLevel();
642    break;
643  case MAXFACTOR:
644    value=model->factorization()->maximumPivots();
645    break;
646    break;
647  case PERTVALUE:
648    value=model->perturbation();
649    break;
650  case MAXITERATION:
651    value=model->maximumIterations();
652    break;
653  default:
654    value=-1;
655    break;
656  }
657  return value;
658}
659// Print Long help
660void 
661ClpItem::printLongHelp() const
662{
663  if (type_>=1&&type_<400) {
664    if (type_<LOGLEVEL) {
665      printf("Range of values is %g to %g\n",lowerDoubleValue_,upperDoubleValue_);
666    } else if (type_<DIRECTION) {
667      printf("Range of values is %d to %d\n",lowerIntValue_,upperIntValue_);
668    } else if (type_<DIRECTORY) {
669      printOptions();
670    }
671    printit(longHelp_.c_str());
672  }
673}
674#ifdef READLINE     
675#include <readline/readline.h>
676#include <readline/history.h>
677#endif
678// Returns next valid field
679static int read_mode=1;
680static char line[1000];
681static char * where=NULL;
682
683std::string
684nextField()
685{
686  std::string field;
687  if (!where) {
688    // need new line
689#ifdef READLINE     
690    // Get a line from the user.
691    where = readline ("Clp:");
692     
693    // If the line has any text in it, save it on the history.
694    if (where) {
695      if ( *where)
696        add_history (where);
697      strcpy(line,where);
698    }
699#else
700    fprintf(stdout,"Clp:");
701    fflush(stdout);
702    where = fgets(line,1000,stdin);
703#endif
704    if (!where)
705      return field; // EOF
706    where = line;
707    // clean image
708    char * lastNonBlank = line-1;
709    while ( *where != '\0' ) {
710      if ( *where != '\t' && *where < ' ' ) {
711        break;
712      } else if ( *where != '\t' && *where != ' ') {
713        lastNonBlank = where;
714      }
715      where++;
716    }
717    where=line;
718    *(lastNonBlank+1)='\0';
719  }
720  // munch white space
721  while(*where==' '||*where=='\t')
722    where++;
723  char * saveWhere = where;
724  while (*where!=' '&&*where!='\t'&&*where!='\0')
725    where++;
726  if (where!=saveWhere) {
727    char save = *where;
728    *where='\0';
729    //convert to string
730    field=saveWhere;
731    *where=save;
732  } else {
733    where=NULL;
734    field="EOL";
735  }
736  return field;
737}
738
739std::string
740getCommand(int argc, const char *argv[])
741{
742  std::string field="EOL";
743  while (field=="EOL") {
744    if (read_mode>0) {
745      if (read_mode<argc) {
746        field = argv[read_mode++];
747        if (field=="-") {
748          std::cout<<"Switching to line mode"<<std::endl;
749          read_mode=-1;
750          field=nextField();
751        } else if (field[0]!='-') {
752          if (read_mode!=2) {
753            std::cout<<"skipping non-command "<<field<<std::endl;
754            field="EOL"; // skip
755          } else {
756            // special dispensation - taken as -import name
757            read_mode--;
758            field="import";
759          }
760        } else {
761          if (field!="--") {
762            // take off -
763            field = field.substr(1);
764          } else {
765            // special dispensation - taken as -import --
766            read_mode--;
767            field="import";
768          }
769        }
770      } else {
771        field="";
772      }
773    } else {
774      field=nextField();
775    }
776  }
777  //std::cout<<field<<std::endl;
778  return field;
779}
780std::string
781getString(int argc, const char *argv[])
782{
783  std::string field="EOL";
784  if (read_mode>0) {
785    if (read_mode<argc) {
786      if (argv[read_mode][0]!='-') { 
787        field = argv[read_mode++];
788      } else if (!strcmp(argv[read_mode],"--")) {
789        field = argv[read_mode++];
790        // -- means import from stdin
791        field = "-";
792      }
793    }
794  } else {
795    field=nextField();
796  }
797  //std::cout<<field<<std::endl;
798  return field;
799}
800// valid 0 - okay, 1 bad, 2 not there
801int
802getIntField(int argc, const char *argv[],int * valid)
803{
804  std::string field="EOL";
805  if (read_mode>0) {
806    if (read_mode<argc) {
807      // may be negative value so do not check for -
808      field = argv[read_mode++];
809    }
810  } else {
811    field=nextField();
812  }
813  int value=0;
814  //std::cout<<field<<std::endl;
815  if (field!="EOL") {
816    // how do I check valid
817    value =  atoi(field.c_str());
818    *valid=0;
819  } else {
820    *valid=2;
821  }
822  return value;
823}
824double
825getDoubleField(int argc, const char *argv[],int * valid)
826{
827  std::string field="EOL";
828  if (read_mode>0) {
829    if (read_mode<argc) {
830      // may be negative value so do not check for -
831      field = argv[read_mode++];
832    }
833  } else {
834    field=nextField();
835  }
836  double value=0.0;
837  //std::cout<<field<<std::endl;
838  if (field!="EOL") {
839    // how do I check valid
840    value = atof(field.c_str());
841    *valid=0;
842  } else {
843    *valid=2;
844  }
845  return value;
846}
847int main (int argc, const char *argv[])
848{
849  // next {} is just to make sure all memory should be freed - for debug
850  {
851    double time1 = CoinCpuTime(),time2;
852    // Set up all non-standard stuff
853    //int numberModels=1;
854    ClpSimplex * models = new ClpSimplex[1];
855   
856    // default action on import
857    int allowImportErrors=0;
858    int keepImportNames=1;
859    int doIdiot=-2;
860    int doCrash=0;
861    int doSprint=-1;
862    // set reasonable defaults
863    int preSolve=5;
864    models->setPerturbation(50);
865    models->messageHandler()->setPrefix(false);
866    std::string directory ="./";
867    std::string importFile ="";
868    std::string exportFile ="default.mps";
869    std::string saveFile ="default.prob";
870    std::string restoreFile ="default.prob";
871    std::string solutionFile ="default.sol";
872#define MAXPARAMETERS 100
873    ClpItem parameters[MAXPARAMETERS];
874    int numberParameters=0;
875    parameters[numberParameters++]=
876      ClpItem("?","For help",GENERALQUERY,-1,false);
877    parameters[numberParameters++]=
878      ClpItem("-","From stdin",
879              STDIN,299,false);
880    parameters[numberParameters++]=
881      ClpItem("allS!lack","Set basis back to all slack",
882              ALLSLACK);
883    parameters[numberParameters-1].setLonghelp
884      (
885       ""
886       ); 
887    parameters[numberParameters++]=
888      ClpItem("biasLU","Whether factorization biased towards U",
889              "UU",BIASLU,2,false);
890    parameters[numberParameters-1].append("UX");
891    parameters[numberParameters-1].append("LX");
892    parameters[numberParameters-1].append("LL");
893    parameters[numberParameters++]=
894      ClpItem("crash","Whether to create basis for problem",
895              "off",CRASH);
896    parameters[numberParameters-1].append("on");
897    parameters[numberParameters-1].setLonghelp
898      (
899       "If crash is set on and there is an all slack basis then Clp will put structural\
900variables into basis with the aim of getting dual feasible.  On the whole dual seems to be\
901better without it and there alernative types of 'crash' for primal e.g. 'idiot' or 'sprint'."
902       ); 
903    parameters[numberParameters++]=
904      ClpItem("direction","Minimize or Maximize",
905              "min!imize",DIRECTION);
906    parameters[numberParameters-1].append("max!imize");
907    parameters[numberParameters-1].append("zero");
908    parameters[numberParameters-1].setLonghelp
909      (
910       "The default is minimize - use 'direction maximize' for maximization.\n\
911You can also use the parameters 'maximize' or 'minimize'."
912       ); 
913    parameters[numberParameters++]=
914      ClpItem("directory","Set Default directory for import etc.",
915              DIRECTORY,299);
916    parameters[numberParameters-1].setLonghelp
917      (
918       "This sets the directory which import, export, saveModel and restoreModel will use"
919       ); 
920    parameters[numberParameters-1].setStringValue(directory);
921    parameters[numberParameters++]=
922      ClpItem("dualB!ound","Initially algorithm acts as if no \
923gap between bounds exceeds this value",
924              1.0e-20,1.0e12,DUALBOUND);
925    parameters[numberParameters-1].setLonghelp
926      (
927       ""
928       );
929    parameters[numberParameters-1].setDoubleValue(models->dualBound());
930    parameters[numberParameters++]=
931      ClpItem("dualP!ivot","Dual pivot choice algorithm",
932              "auto!matic",DUALPIVOT);
933    parameters[numberParameters-1].append("dant!zig");
934    parameters[numberParameters-1].append("partial");
935    parameters[numberParameters-1].append("steep!est");
936    parameters[numberParameters-1].setLonghelp
937      (
938       ""
939       ); 
940    parameters[numberParameters++]=
941      ClpItem("dualS!implex","Do dual simplex algorithm",
942              DUALSIMPLEX);
943    parameters[numberParameters-1].setLonghelp
944      (
945       ""
946       ); 
947    parameters[numberParameters++]=
948      ClpItem("dualT!olerance","For an optimal solution \
949no dual infeasibility may exceed this value",
950              1.0e-20,1.0e12,DUALTOLERANCE);
951    parameters[numberParameters-1].setLonghelp
952      (
953       ""
954       ); 
955    parameters[numberParameters-1].setDoubleValue(models->dualTolerance());
956    parameters[numberParameters++]=
957      ClpItem("end","Stops clp execution",
958              EXIT);
959    parameters[numberParameters-1].setLonghelp
960      (
961       ""
962       ); 
963    parameters[numberParameters++]=
964      ClpItem("error!sAllowed","Whether to allow import errors",
965              "off",ERRORSALLOWED);
966    parameters[numberParameters-1].setLonghelp
967      (
968       ""
969       );
970    parameters[numberParameters++]=
971      ClpItem("exit","Stops clp execution",
972              EXIT);
973    parameters[numberParameters-1].setLonghelp
974      (
975       ""
976       ); 
977    parameters[numberParameters++]=
978      ClpItem("export","Export model as mps file",
979              EXPORT);
980    parameters[numberParameters-1].setLonghelp
981      (
982       ""
983       ); 
984    parameters[numberParameters-1].setStringValue(exportFile);
985    parameters[numberParameters++]=
986      ClpItem("fakeB!ound","All bounds <= this value - DEBUG",
987              1.0,1.0e15,FAKEBOUND,false);
988    parameters[numberParameters++]=
989      ClpItem("help","Print out version, non-standard options and some help",
990              HELP);
991    parameters[numberParameters++]=
992      ClpItem("idiot!Crash","Whether to try idiot crash",
993              -2,200,IDIOT);
994    parameters[numberParameters-1].setLonghelp
995      (
996       ""
997       ); 
998    parameters[numberParameters-1].setIntValue(doIdiot);
999    parameters[numberParameters++]=
1000      ClpItem("import","Import model from mps file",
1001              IMPORT);
1002    parameters[numberParameters-1].setLonghelp
1003      (
1004       ""
1005       ); 
1006    parameters[numberParameters-1].setStringValue(importFile);
1007    parameters[numberParameters++]=
1008      ClpItem("keepN!ames","Whether to keep names from import",
1009              "on",KEEPNAMES);
1010    parameters[numberParameters-1].append("off");
1011    parameters[numberParameters-1].setLonghelp
1012      (
1013       ""
1014       ); 
1015    parameters[numberParameters++]=
1016      ClpItem("log!Level","Level of detail in output",
1017              0,63,LOGLEVEL);
1018    parameters[numberParameters-1].setLonghelp
1019      (
1020       ""
1021       ); 
1022    parameters[numberParameters-1].setIntValue(models->logLevel());
1023    parameters[numberParameters++]=
1024      ClpItem("max!imize","Set optimization direction to maximize",
1025              MAXIMIZE,299);
1026    parameters[numberParameters-1].setLonghelp
1027      (
1028       ""
1029       ); 
1030    parameters[numberParameters++]=
1031      ClpItem("maxF!actor","Maximum number of iterations between \
1032refactorizations",
1033              1,999999,MAXFACTOR);
1034    parameters[numberParameters-1].setLonghelp
1035      (
1036       ""
1037       ); 
1038    parameters[numberParameters-1].setIntValue(models->factorizationFrequency());
1039    parameters[numberParameters++]=
1040      ClpItem("maxIt!erations","Maximum number of iterations before \
1041stopping",
1042              0,99999999,MAXITERATION);
1043    parameters[numberParameters-1].setLonghelp
1044      (
1045       ""
1046       ); 
1047    parameters[numberParameters-1].setIntValue(models->maximumIterations());
1048    parameters[numberParameters++]=
1049      ClpItem("min!imize","Set optimization direction to minimize",
1050              MINIMIZE,299);
1051    parameters[numberParameters-1].setLonghelp
1052      (
1053       ""
1054       ); 
1055    parameters[numberParameters++]=
1056      ClpItem("mess!ages","Controls if Clpnnnn is printed",
1057              "off",MESSAGES);
1058    parameters[numberParameters-1].append("on");
1059    parameters[numberParameters-1].setLonghelp
1060      (""
1061       ); 
1062    parameters[numberParameters++]=
1063      ClpItem("netlib","Solve entire netlib test set",
1064              NETLIB_DUAL,-1,false);
1065    parameters[numberParameters++]=
1066      ClpItem("netlibP!rimal","Solve entire netlib test set (primal)",
1067              NETLIB_PRIMAL,-1,false);
1068    parameters[numberParameters++]=
1069      ClpItem("network","Tries to make network matrix",
1070              NETWORK,-1,false);
1071    parameters[numberParameters-1].setLonghelp
1072      (
1073       ""
1074       ); 
1075    parameters[numberParameters++]=
1076      ClpItem("objective!Scale","Scale factor to apply to objective",
1077              -1.0e20,1.0e20,OBJSCALE,false);
1078    parameters[numberParameters-1].setDoubleValue(models->optimizationDirection());
1079    parameters[numberParameters++]=
1080      ClpItem("passP!resolve","How many passes in presolve",
1081              0,100,PRESOLVEPASS);
1082    parameters[numberParameters-1].setLonghelp
1083      (
1084       ""
1085       ); 
1086    parameters[numberParameters-1].setIntValue(preSolve);
1087    parameters[numberParameters++]=
1088      ClpItem("pertV!alue","Method of perturbation",
1089              -5000,102,PERTVALUE,false);
1090    parameters[numberParameters-1].setIntValue(models->perturbation());
1091    parameters[numberParameters++]=
1092      ClpItem("perturb!ation","Whether to perturb problem",
1093              "on",PERTURBATION);
1094    parameters[numberParameters-1].append("off");
1095    parameters[numberParameters-1].setLonghelp
1096      (
1097       ""
1098       ); 
1099    parameters[numberParameters++]=
1100      ClpItem("plus!Minus","Tries to make +- 1 matrix",
1101              PLUSMINUS,-1,false);
1102    parameters[numberParameters-1].setLonghelp
1103      (
1104       ""
1105       ); 
1106    parameters[numberParameters++]=
1107      ClpItem("presolve","Whether to presolve problem",
1108              "on",PRESOLVE);
1109    parameters[numberParameters-1].append("off");
1110    parameters[numberParameters-1].append("more");
1111    parameters[numberParameters-1].setLonghelp
1112      (
1113       ""
1114       ); 
1115    parameters[numberParameters++]=
1116      ClpItem("primalP!ivot","Primal pivot choice algorithm",
1117              "auto!matic",PRIMALPIVOT);
1118    parameters[numberParameters-1].append("exa!ct");
1119    parameters[numberParameters-1].append("dant!zig");
1120    parameters[numberParameters-1].append("part!ial");
1121    parameters[numberParameters-1].append("steep!est");
1122    //parameters[numberParameters-1].append("change");
1123    parameters[numberParameters-1].setLonghelp
1124      (
1125       ""
1126       ); 
1127    parameters[numberParameters++]=
1128      ClpItem("primalS!implex","Do primal simplex algorithm",
1129              PRIMALSIMPLEX);
1130    parameters[numberParameters-1].setLonghelp
1131      (
1132       ""
1133       ); 
1134    parameters[numberParameters++]=
1135      ClpItem("primalT!olerance","For an optimal solution \
1136no primal infeasibility may exceed this value",
1137              1.0e-20,1.0e12,PRIMALTOLERANCE);
1138    parameters[numberParameters-1].setLonghelp
1139      (
1140       ""
1141       ); 
1142    parameters[numberParameters-1].setDoubleValue(models->primalTolerance());
1143    parameters[numberParameters++]=
1144      ClpItem("primalW!eight","Initially algorithm acts as if it \
1145costs this much to be infeasible",
1146              1.0e-20,1.0e12,PRIMALWEIGHT);
1147    parameters[numberParameters-1].setLonghelp
1148      (
1149       ""
1150       ); 
1151    parameters[numberParameters-1].setDoubleValue(models->infeasibilityCost());
1152    parameters[numberParameters++]=
1153      ClpItem("quit","Stops clp execution",
1154              EXIT);
1155    parameters[numberParameters-1].setLonghelp
1156      (
1157       ""
1158       ); 
1159    parameters[numberParameters++]=
1160      ClpItem("restore!Model","Restore model from binary file",
1161              RESTORE);
1162    parameters[numberParameters-1].setLonghelp
1163      (
1164       ""
1165       ); 
1166    parameters[numberParameters-1].setStringValue(restoreFile);
1167    parameters[numberParameters++]=
1168      ClpItem("save!Model","Save model to binary file",
1169              SAVE);
1170    parameters[numberParameters-1].setLonghelp
1171      (
1172       ""
1173       ); 
1174    parameters[numberParameters-1].setStringValue(saveFile);
1175    parameters[numberParameters++]=
1176      ClpItem("scal!ing","Whether to scale problem",
1177              "on",SCALING);
1178    parameters[numberParameters-1].append("off");
1179    parameters[numberParameters-1].setLonghelp
1180      (
1181       ""
1182       ); 
1183    parameters[numberParameters++]=
1184      ClpItem("sec!onds","maximum seconds",
1185              0.0,1.0e12,MAXTIME);
1186    parameters[numberParameters-1].setLonghelp
1187      (
1188       ""
1189       ); 
1190    parameters[numberParameters-1].setDoubleValue(models->maximumSeconds());
1191    parameters[numberParameters++]=
1192      ClpItem("sol!ution","Prints solution to file",
1193              SOLUTION);
1194    parameters[numberParameters-1].setLonghelp
1195      (
1196       ""
1197       ); 
1198    parameters[numberParameters-1].setStringValue(solutionFile);
1199    parameters[numberParameters++]=
1200      ClpItem("spars!eFactor","Whether factorization treated as sparse",
1201              "on",SPARSEFACTOR,0,false);
1202    parameters[numberParameters-1].append("off");
1203    parameters[numberParameters-1].append("on");
1204    parameters[numberParameters++]=
1205      ClpItem("sprint!Crash","Whether to try sprint crash",
1206              0,200,SPRINT);
1207    parameters[numberParameters-1].setLonghelp
1208      (
1209       ""
1210       ); 
1211    parameters[numberParameters-1].setIntValue(doSprint);
1212      ClpItem("stdin","From stdin",
1213              STDIN,-1,false);
1214    parameters[numberParameters++]=
1215      ClpItem("stop","Stops clp execution",
1216              EXIT);
1217    parameters[numberParameters-1].setLonghelp
1218      (
1219       ""
1220       ); 
1221    parameters[numberParameters++]=
1222      ClpItem("tight!en","Poor person's preSolve for now",
1223              TIGHTEN,-1,false);
1224    parameters[numberParameters++]=
1225      ClpItem("unitTest","Do unit test",
1226              UNITTEST,-1,false);
1227    assert(numberParameters<MAXPARAMETERS);
1228   
1229    // total number of commands read
1230    int numberGoodCommands=0;
1231    bool * goodModels = new bool[1];
1232    int getNewMatrix=0;
1233   
1234   
1235    int iModel=0;
1236    goodModels[0]=false;
1237    //models[0].scaling(1);
1238    //models[0].setDualBound(1.0e6);
1239    //models[0].setDualTolerance(1.0e-7);
1240    //ClpDualRowSteepest steep;
1241    //models[0].setDualRowPivotAlgorithm(steep);
1242    //models[0].setPrimalTolerance(1.0e-7);
1243    //ClpPrimalColumnSteepest steepP;
1244    //models[0].setPrimalColumnPivotAlgorithm(steepP);
1245    std::string field;
1246    std::cout<<"Coin LP version "<<CLPVERSION
1247             <<", build "<<__DATE__<<std::endl;
1248   
1249    while (1) {
1250      // next command
1251      field=getCommand(argc,argv);
1252     
1253      // exit if null or similar
1254      if (!field.length()) {
1255        if (numberGoodCommands==1&&goodModels[0]) {
1256          // we just had file name - do dual
1257          field="duals";
1258        } else if (!numberGoodCommands) {
1259          // let's give the sucker a hint
1260          std::cout
1261            <<"Clp takes input from arguments ( - switches to stdin)"
1262            <<std::endl
1263            <<"Enter ? for list of commands or help"<<std::endl;
1264          field="-";
1265        } else {
1266          break;
1267        }
1268      }
1269     
1270      // see if ? at end
1271      int numberQuery=0;
1272      if (field!="?") {
1273        int length = field.length();
1274        int i;
1275        for (i=length-1;i>0;i--) {
1276          if (field[i]=='?') 
1277            numberQuery++;
1278          else
1279            break;
1280        }
1281        field=field.substr(0,length-numberQuery);
1282      }
1283      // find out if valid command
1284      int iParam;
1285      int numberMatches=0;
1286      int firstMatch=-1;
1287      for ( iParam=0; iParam<numberParameters; iParam++ ) {
1288        int match = parameters[iParam].matches(field);
1289        if (match==1) {
1290          numberMatches = 1;
1291          firstMatch=iParam;
1292          break;
1293        } else {
1294          if (match&&firstMatch<0)
1295            firstMatch=iParam;
1296          numberMatches += match>>1;
1297        }
1298      }
1299      if (iParam<numberParameters&&!numberQuery) {
1300        // found
1301        ClpItem found = parameters[iParam];
1302        ClpParameterType type = found.type();
1303        int valid;
1304        numberGoodCommands++;
1305        if (type==GENERALQUERY) {
1306          std::cout<<"In argument list keywords have leading - "
1307            ", -stdin or just - switches to stdin"<<std::endl;
1308          std::cout<<"One command per line (and no -)"<<std::endl;
1309          std::cout<<"abcd? gives list of possibilities, if only one + explanation"<<std::endl;
1310          std::cout<<"abcd?? adds explanation, if only one fuller help(LATER)"<<std::endl;
1311          std::cout<<"abcd without value (where expected) gives current value"<<std::endl;
1312          std::cout<<"abcd value sets value"<<std::endl;
1313          std::cout<<"Commands are:"<<std::endl;
1314          int maxAcross=5;
1315          int limits[]={1,101,201,301,401};
1316          std::vector<std::string> types;
1317          types.push_back("Double parameters:");
1318          types.push_back("Int parameters:");
1319          types.push_back("Keyword parameters and others:");
1320          types.push_back("Actions:");
1321          int iType;
1322          for (iType=0;iType<4;iType++) {
1323            int across=0;
1324            std::cout<<types[iType]<<std::endl;
1325            for ( iParam=0; iParam<numberParameters; iParam++ ) {
1326              int type = parameters[iParam].indexNumber();
1327              if (parameters[iParam].displayThis()&&type>=limits[iType]
1328                  &&type<limits[iType+1]) {
1329                if (!across)
1330                  std::cout<<"  ";
1331                std::cout<<parameters[iParam].matchName()<<"  ";
1332                across++;
1333                if (across==maxAcross) {
1334                  std::cout<<std::endl;
1335                  across=0;
1336                }
1337              }
1338            }
1339            if (across)
1340              std::cout<<std::endl;
1341          }
1342        } else if (type<101) {
1343          // get next field as double
1344          double value = getDoubleField(argc,argv,&valid);
1345          if (!valid) {
1346            parameters[iParam].setDoubleValue(value);
1347            parameters[iParam].setDoubleParameter(models+iModel,value);
1348          } else if (valid==1) {
1349            abort();
1350          } else {
1351            std::cout<<parameters[iParam].name()<<" has value "<<
1352              parameters[iParam].doubleValue()<<std::endl;
1353          }
1354        } else if (type<201) {
1355          // get next field as int
1356          int value = getIntField(argc,argv,&valid);
1357          if (!valid) {
1358            parameters[iParam].setIntValue(value);
1359            if (parameters[iParam].type()==PRESOLVEPASS)
1360              preSolve = value;
1361            else if (parameters[iParam].type()==IDIOT)
1362              doIdiot = value;
1363            else if (parameters[iParam].type()==SPRINT)
1364              doSprint = value;
1365            else
1366              parameters[iParam].setIntParameter(models+iModel,value);
1367          } else if (valid==1) {
1368            abort();
1369          } else {
1370            std::cout<<parameters[iParam].name()<<" has value "<<
1371              parameters[iParam].intValue()<<std::endl;
1372          }
1373        } else if (type<301) {
1374          // one of several strings
1375          std::string value = getString(argc,argv);
1376          int action = parameters[iParam].parameterOption(value);
1377          if (action<0) {
1378            if (value!="EOL") {
1379              // no match
1380              parameters[iParam].printOptions();
1381            } else {
1382              // print current value
1383              std::cout<<parameters[iParam].name()<<" has value "<<
1384                parameters[iParam].currentOption()<<std::endl;
1385            }
1386          } else {
1387            parameters[iParam].setCurrentOption(action);
1388            // for now hard wired
1389            switch (type) {
1390            case DIRECTION:
1391              if (action==0)
1392                models[iModel].setOptimizationDirection(1);
1393              else if (action==1)
1394                models[iModel].setOptimizationDirection(-1);
1395              else
1396                models[iModel].setOptimizationDirection(0);
1397              break;
1398            case DUALPIVOT:
1399              if (action==0) {
1400                ClpDualRowSteepest steep(3);
1401                models[iModel].setDualRowPivotAlgorithm(steep);
1402              } else if (action==1) {
1403                ClpDualRowDantzig dantzig;
1404                models[iModel].setDualRowPivotAlgorithm(dantzig);
1405              } else if (action==2) {
1406                // partial steep
1407                ClpDualRowSteepest steep(2);
1408                models[iModel].setDualRowPivotAlgorithm(steep);
1409              } else {
1410                ClpDualRowSteepest steep;
1411                models[iModel].setDualRowPivotAlgorithm(steep);
1412              }
1413              break;
1414            case PRIMALPIVOT:
1415              if (action==0) {
1416                ClpPrimalColumnSteepest steep(3);
1417                models[iModel].setPrimalColumnPivotAlgorithm(steep);
1418              } else if (action==1) {
1419                ClpPrimalColumnSteepest steep(0);
1420                models[iModel].setPrimalColumnPivotAlgorithm(steep);
1421              } else if (action==2) {
1422                ClpPrimalColumnDantzig dantzig;
1423                models[iModel].setPrimalColumnPivotAlgorithm(dantzig);
1424              } else if (action==3) {
1425                ClpPrimalColumnSteepest steep(2);
1426                models[iModel].setPrimalColumnPivotAlgorithm(steep);
1427              } else if (action==4) {
1428                ClpPrimalColumnSteepest steep(0);
1429                models[iModel].setPrimalColumnPivotAlgorithm(steep);
1430              } else if (action==5) {
1431                ClpPrimalColumnSteepest steep(4);
1432                models[iModel].setPrimalColumnPivotAlgorithm(steep);
1433              }
1434              break;
1435            case SCALING:
1436              models[iModel].scaling(1-action);
1437              break;
1438            case SPARSEFACTOR:
1439              models[iModel].setSparseFactorization((1-action)!=0);
1440              break;
1441            case BIASLU:
1442              models[iModel].factorization()->setBiasLU(action);
1443              break;
1444            case PERTURBATION:
1445              if (action==0)
1446                models[iModel].setPerturbation(50);
1447              else
1448                models[iModel].setPerturbation(100);
1449              break;
1450            case ERRORSALLOWED:
1451              allowImportErrors = action;
1452              break;
1453            case KEEPNAMES:
1454              keepImportNames = 1-action;
1455              break;
1456            case PRESOLVE:
1457              if (action==0)
1458                preSolve = 5;
1459              else if (action==1)
1460                preSolve=0;
1461              else
1462                preSolve=10;
1463              break;
1464            case CRASH:
1465              doCrash=-action;
1466              break;
1467            case MESSAGES:
1468              models[iModel].messageHandler()->setPrefix(action!=0);
1469              break;
1470            default:
1471              abort();
1472            }
1473          }
1474        } else {
1475          // action
1476          if (type==EXIT)
1477            break; // stop all
1478          switch (type) {
1479          case DUALSIMPLEX:
1480          case PRIMALSIMPLEX:
1481            if (goodModels[iModel]) {
1482              ClpSolve::SolveType method;
1483              ClpSolve::PresolveType presolveType;
1484              ClpSimplex * model2 = models+iModel;
1485              ClpSolve solveOptions;
1486              if (preSolve!=5&&preSolve)
1487                presolveType=ClpSolve::presolveNumber;
1488              else if (preSolve)
1489                presolveType=ClpSolve::presolveOn;
1490              else
1491                presolveType=ClpSolve::presolveOff;
1492              solveOptions.setPresolveType(presolveType,preSolve);
1493              if (type==DUALSIMPLEX)
1494                method=ClpSolve::useDual;
1495              else
1496                method=ClpSolve::usePrimalorSprint;
1497              solveOptions.setSolveType(method);
1498              if (method==ClpSolve::useDual) {
1499                // dual
1500                if (doCrash)
1501                  solveOptions.setSpecialOption(0,1); // crash
1502              } else {
1503                // primal
1504                if (doCrash) {
1505                  solveOptions.setSpecialOption(0,1); // crash
1506                } else if (doSprint>0) {
1507                  // sprint overrides idiot
1508                  solveOptions.setSpecialOption(1,3,doSprint); // sprint
1509                } else if (doIdiot>0) {
1510                  solveOptions.setSpecialOption(1,2,doIdiot); // idiot
1511                } else {
1512                  if (doIdiot==0) {
1513                    if (doSprint==0)
1514                      solveOptions.setSpecialOption(1,4); // all slack
1515                    else
1516                      solveOptions.setSpecialOption(1,9); // all slack or sprint
1517                  } else {
1518                    if (doSprint==0)
1519                      solveOptions.setSpecialOption(1,8); // all slack or idiot
1520                    else
1521                      solveOptions.setSpecialOption(1,7); // initiative
1522                  }
1523                }
1524              }
1525              model2->initialSolve(solveOptions);
1526            } else {
1527              std::cout<<"** Current model not valid"<<std::endl;
1528            }
1529            break;
1530          case TIGHTEN:
1531            if (goodModels[iModel]) {
1532              int numberInfeasibilities = models[iModel].tightenPrimalBounds();
1533              if (numberInfeasibilities)
1534                std::cout<<"** Analysis indicates model infeasible"<<std::endl;
1535            } else {
1536              std::cout<<"** Current model not valid"<<std::endl;
1537            }
1538            break;
1539          case PLUSMINUS:
1540            getNewMatrix=1;
1541            break;
1542          case NETWORK:
1543            getNewMatrix=2;
1544            break;
1545          case IMPORT:
1546            {
1547              // get next field
1548              field = getString(argc,argv);
1549              if (field=="$") {
1550                field = parameters[iParam].stringValue();
1551              } else if (field=="EOL") {
1552                parameters[iParam].printString();
1553                break;
1554              } else {
1555                parameters[iParam].setStringValue(field);
1556              }
1557              std::string fileName;
1558              bool canOpen=false;
1559              if (field=="-") {
1560                // stdin
1561                canOpen=true;
1562                fileName = "-";
1563              } else {
1564                if (field[0]=='/'||field[0]=='~')
1565                  fileName = field;
1566                else
1567                  fileName = directory+field;
1568                FILE *fp=fopen(fileName.c_str(),"r");
1569                if (fp) {
1570                  // can open - lets go for it
1571                  fclose(fp);
1572                  canOpen=true;
1573                } else {
1574                  std::cout<<"Unable to open file "<<fileName<<std::endl;
1575                }
1576              }
1577              if (canOpen) {
1578                int status =models[iModel].readMps(fileName.c_str(),
1579                                                   keepImportNames!=0,
1580                                                   allowImportErrors!=0);
1581                if (!status||(status>0&&allowImportErrors)) {
1582                  goodModels[iModel]=true;
1583                  // sets to all slack (not necessary?)
1584                  models[iModel].createStatus();
1585                  time2 = CoinCpuTime();
1586                  totalTime += time2-time1;
1587                  time1=time2;
1588                } else {
1589                  // errors
1590                  std::cout<<"There were "<<status<<
1591                    " errors on input"<<std::endl;
1592                }
1593              }
1594            }
1595            break;
1596          case EXPORT:
1597            {
1598              // get next field
1599              field = getString(argc,argv);
1600              if (field=="$") {
1601                field = parameters[iParam].stringValue();
1602              } else if (field=="EOL") {
1603                parameters[iParam].printString();
1604                break;
1605              } else {
1606                parameters[iParam].setStringValue(field);
1607              }
1608              std::string fileName;
1609              bool canOpen=false;
1610              if (field[0]=='/'||field[0]=='~')
1611                fileName = field;
1612              else
1613                fileName = directory+field;
1614              FILE *fp=fopen(fileName.c_str(),"w");
1615              if (fp) {
1616                // can open - lets go for it
1617                fclose(fp);
1618                canOpen=true;
1619              } else {
1620                std::cout<<"Unable to open file "<<fileName<<std::endl;
1621              }
1622              if (canOpen) {
1623                // If presolve on then save presolved
1624                bool deleteModel2=false;
1625                ClpSimplex * model2 = models+iModel;
1626#ifdef USE_PRESOLVE
1627                if (preSolve) {
1628                  ClpPresolve pinfo;
1629                  model2 = 
1630                    pinfo.presolvedModel(models[iModel],1.0e-8,
1631                                         false,preSolve);
1632                  if (model2) {
1633                    printf("Saving presolved model on %s\n",
1634                           fileName.c_str());
1635                    deleteModel2=true;
1636                  } else {
1637                    printf("Presolved model looks infeasible - saving original on %s\n",
1638                           fileName.c_str());
1639                    deleteModel2=false;
1640                    model2 = models+iModel;
1641
1642                  }
1643                } else {
1644#endif
1645                  printf("Saving model on %s\n",
1646                           fileName.c_str());
1647#ifdef USE_PRESOLVE
1648                }
1649#endif
1650                // Convert names
1651                int iRow;
1652                int numberRows=model2->numberRows();
1653                int iColumn;
1654                int numberColumns=model2->numberColumns();
1655
1656                char ** rowNames = NULL;
1657                char ** columnNames = NULL;
1658                if (model2->lengthNames()) {
1659                  rowNames = new char * [numberRows];
1660                  for (iRow=0;iRow<numberRows;iRow++) {
1661                    rowNames[iRow] = 
1662                      strdup(model2->rowName(iRow).c_str());
1663#ifdef STRIPBLANKS
1664                    char * xx = rowNames[iRow];
1665                    int i;
1666                    int length = strlen(xx);
1667                    int n=0;
1668                    for (i=0;i<length;i++) {
1669                      if (xx[i]!=' ')
1670                        xx[n++]=xx[i];
1671                    }
1672                    xx[n]='\0';
1673#endif
1674                  }
1675                 
1676                  columnNames = new char * [numberColumns];
1677                  for (iColumn=0;iColumn<numberColumns;iColumn++) {
1678                    columnNames[iColumn] = 
1679                      strdup(model2->columnName(iColumn).c_str());
1680#ifdef STRIPBLANKS
1681                    char * xx = columnNames[iColumn];
1682                    int i;
1683                    int length = strlen(xx);
1684                    int n=0;
1685                    for (i=0;i<length;i++) {
1686                      if (xx[i]!=' ')
1687                        xx[n++]=xx[i];
1688                    }
1689                    xx[n]='\0';
1690#endif
1691                  }
1692                }
1693
1694                CoinMpsIO writer;
1695                writer.setMpsData(*model2->matrix(), COIN_DBL_MAX,
1696                                  model2->getColLower(), model2->getColUpper(),
1697                                  model2->getObjCoefficients(),
1698                                  (const char*) 0 /*integrality*/,
1699                                  model2->getRowLower(), model2->getRowUpper(),
1700                                  columnNames, rowNames);
1701                // Pass in array saying if each variable integer
1702                writer.copyInIntegerInformation(model2->integerInformation());
1703                writer.writeMps(fileName.c_str());
1704                if (rowNames) {
1705                  for (iRow=0;iRow<numberRows;iRow++) {
1706                    free(rowNames[iRow]);
1707                  }
1708                  delete [] rowNames;
1709                  for (iColumn=0;iColumn<numberColumns;iColumn++) {
1710                    free(columnNames[iColumn]);
1711                  }
1712                  delete [] columnNames;
1713                }
1714                if (deleteModel2)
1715                  delete model2;
1716                time2 = CoinCpuTime();
1717                totalTime += time2-time1;
1718                time1=time2;
1719              }
1720            }
1721            break;
1722          case SAVE:
1723            {
1724              // get next field
1725              field = getString(argc,argv);
1726              if (field=="$") {
1727                field = parameters[iParam].stringValue();
1728              } else if (field=="EOL") {
1729                parameters[iParam].printString();
1730                break;
1731              } else {
1732                parameters[iParam].setStringValue(field);
1733              }
1734              std::string fileName;
1735              bool canOpen=false;
1736              if (field[0]=='/'||field[0]=='~')
1737                fileName = field;
1738              else
1739                fileName = directory+field;
1740              FILE *fp=fopen(fileName.c_str(),"wb");
1741              if (fp) {
1742                // can open - lets go for it
1743                fclose(fp);
1744                canOpen=true;
1745              } else {
1746                std::cout<<"Unable to open file "<<fileName<<std::endl;
1747              }
1748              if (canOpen) {
1749                int status;
1750                // If presolve on then save presolved
1751                bool deleteModel2=false;
1752                ClpSimplex * model2 = models+iModel;
1753#ifdef USE_PRESOLVE
1754                if (preSolve) {
1755                  ClpPresolve pinfo;
1756                  model2 = 
1757                    pinfo.presolvedModel(models[iModel],1.0e-8,
1758                                         false,preSolve);
1759                  if (model2) {
1760                    printf("Saving presolved model on %s\n",
1761                           fileName.c_str());
1762                    deleteModel2=true;
1763                  } else {
1764                    printf("Presolved model looks infeasible - saving original on %s\n",
1765                           fileName.c_str());
1766                    deleteModel2=false;
1767                    model2 = models+iModel;
1768
1769                  }
1770                } else {
1771#endif
1772                  printf("Saving model on %s\n",
1773                           fileName.c_str());
1774#ifdef USE_PRESOLVE
1775                }
1776#endif
1777                status =model2->saveModel(fileName.c_str());
1778                if (deleteModel2)
1779                  delete model2;
1780                if (!status) {
1781                  goodModels[iModel]=true;
1782                  time2 = CoinCpuTime();
1783                  totalTime += time2-time1;
1784                  time1=time2;
1785                } else {
1786                  // errors
1787                  std::cout<<"There were errors on output"<<std::endl;
1788                }
1789              }
1790            }
1791            break;
1792          case RESTORE:
1793            {
1794              // get next field
1795              field = getString(argc,argv);
1796              if (field=="$") {
1797                field = parameters[iParam].stringValue();
1798              } else if (field=="EOL") {
1799                parameters[iParam].printString();
1800                break;
1801              } else {
1802                parameters[iParam].setStringValue(field);
1803              }
1804              std::string fileName;
1805              bool canOpen=false;
1806              if (field[0]=='/'||field[0]=='~')
1807                fileName = field;
1808              else
1809                fileName = directory+field;
1810              FILE *fp=fopen(fileName.c_str(),"rb");
1811              if (fp) {
1812                // can open - lets go for it
1813                fclose(fp);
1814                canOpen=true;
1815              } else {
1816                std::cout<<"Unable to open file "<<fileName<<std::endl;
1817              }
1818              if (canOpen) {
1819                int status =models[iModel].restoreModel(fileName.c_str());
1820                if (!status) {
1821                  goodModels[iModel]=true;
1822                  time2 = CoinCpuTime();
1823                  totalTime += time2-time1;
1824                  time1=time2;
1825                } else {
1826                  // errors
1827                  std::cout<<"There were errors on input"<<std::endl;
1828                }
1829              }
1830            }
1831            break;
1832          case MAXIMIZE:
1833            models[iModel].setOptimizationDirection(-1);
1834            break;
1835          case MINIMIZE:
1836            models[iModel].setOptimizationDirection(1);
1837            break;
1838          case ALLSLACK:
1839            models[iModel].createStatus();
1840            break;
1841          case DIRECTORY:
1842            {
1843              std::string name = getString(argc,argv);
1844              if (name!="EOL") {
1845                int length=name.length();
1846                if (name[length-1]=='/')
1847                  directory=name;
1848                else
1849                  directory = name+"/";
1850                parameters[iParam].setStringValue(directory);
1851              } else {
1852                parameters[iParam].printString();
1853              }
1854            }
1855            break;
1856          case STDIN:
1857            read_mode=-1;
1858            break;
1859          case NETLIB_DUAL:
1860          case NETLIB_PRIMAL:
1861            {
1862              // create fields for unitTest
1863              const char * fields[4];
1864              int nFields=2;
1865              fields[0]="fake main from unitTest";
1866              fields[1]="-netlib";
1867              if (directory!="./") {
1868                fields[2]="-netlibDir";
1869                fields[3]=directory.c_str();
1870                nFields=4;
1871              }
1872              if (type==NETLIB_DUAL)
1873                std::cerr<<"Doing netlib with dual agorithm"<<std::endl;
1874              else
1875                std::cerr<<"Doing netlib with primal agorithm"<<std::endl;
1876              mainTest(nFields,fields,(type==NETLIB_DUAL),models[iModel],
1877                       (preSolve!=0),doIdiot);
1878            }
1879            break;
1880          case UNITTEST:
1881            {
1882              // create fields for unitTest
1883              const char * fields[3];
1884              int nFields=1;
1885              fields[0]="fake main from unitTest";
1886              if (directory!="./") {
1887                fields[1]="-mpsDir";
1888                fields[2]=directory.c_str();
1889                nFields=3;
1890              }
1891              mainTest(nFields,fields,false,models[iModel],(preSolve!=0),
1892                       false);
1893            }
1894            break;
1895          case FAKEBOUND:
1896            if (goodModels[iModel]) {
1897              // get bound
1898              double value = getDoubleField(argc,argv,&valid);
1899              if (!valid) {
1900                std::cout<<"Setting "<<parameters[iParam].name()<<
1901                  " to DEBUG "<<value<<std::endl;
1902                int iRow;
1903                int numberRows=models[iModel].numberRows();
1904                double * rowLower = models[iModel].rowLower();
1905                double * rowUpper = models[iModel].rowUpper();
1906                for (iRow=0;iRow<numberRows;iRow++) {
1907                  // leave free ones for now
1908                  if (rowLower[iRow]>-1.0e20||rowUpper[iRow]<1.0e20) {
1909                    rowLower[iRow]=max(rowLower[iRow],-value);
1910                    rowUpper[iRow]=min(rowUpper[iRow],value);
1911                  }
1912                }
1913                int iColumn;
1914                int numberColumns=models[iModel].numberColumns();
1915                double * columnLower = models[iModel].columnLower();
1916                double * columnUpper = models[iModel].columnUpper();
1917                for (iColumn=0;iColumn<numberColumns;iColumn++) {
1918                  // leave free ones for now
1919                  if (columnLower[iColumn]>-1.0e20||
1920                      columnUpper[iColumn]<1.0e20) {
1921                    columnLower[iColumn]=max(columnLower[iColumn],-value);
1922                    columnUpper[iColumn]=min(columnUpper[iColumn],value);
1923                  }
1924                }
1925              } else if (valid==1) {
1926                abort();
1927              } else {
1928                std::cout<<"enter value for "<<parameters[iParam].name()<<
1929                  std::endl;
1930              }
1931            }
1932            break;
1933          case HELP:
1934            std::cout<<"Coin LP version "<<CLPVERSION
1935                     <<", build "<<__DATE__<<std::endl;
1936            std::cout<<"Non default values:-"<<std::endl;
1937            std::cout<<"Perturbation "<<models[0].perturbation()<<" (default 100)"
1938                     <<std::endl;
1939            printit(
1940                    "Presolve being done with 5 passes\n\
1941Dual steepest edge steep/partial on matrix shape and factorization density\n\
1942Clpnnnn taken out of messages\n\
1943If Factorization frequency default then done on size of matrix\n\n\
1944(-)unitTest, (-)netlib or (-)netlibp will do standard tests\n\n\
1945You can switch to interactive mode at any time so\n\
1946clp watson.mps -scaling off -primalsimplex\nis the same as\n\
1947clp watson.mps -\nscaling off\nprimalsimplex"
1948                    );
1949            break;
1950          case SOLUTION:
1951            if (goodModels[iModel]) {
1952              // get next field
1953              field = getString(argc,argv);
1954              if (field=="$") {
1955                field = parameters[iParam].stringValue();
1956              } else if (field=="EOL") {
1957                parameters[iParam].printString();
1958                break;
1959              } else {
1960                parameters[iParam].setStringValue(field);
1961              }
1962              std::string fileName;
1963              FILE *fp=NULL;
1964              if (field=="-"||field=="EOL") {
1965                // stdout
1966                fp=stdout;
1967              } else {
1968                if (field[0]=='/'||field[0]=='~')
1969                  fileName = field;
1970                else
1971                  fileName = directory+field;
1972                fp=fopen(fileName.c_str(),"w");
1973              }
1974              if (fp) {
1975                // make fancy later on
1976                int iRow;
1977                int numberRows=models[iModel].numberRows();
1978                int lengthName = models[iModel].lengthNames(); // 0 if no names
1979                // in general I don't want to pass around massive
1980                // amounts of data but seems simpler here
1981                std::vector<std::string> rowNames =
1982                  *(models[iModel].rowNames());
1983                std::vector<std::string> columnNames =
1984                  *(models[iModel].columnNames());
1985
1986                double * dualRowSolution = models[iModel].dualRowSolution();
1987                double * primalRowSolution = 
1988                  models[iModel].primalRowSolution();
1989                double * rowLower = models[iModel].rowLower();
1990                double * rowUpper = models[iModel].rowUpper();
1991                double primalTolerance = models[iModel].primalTolerance();
1992                char format[6];
1993                sprintf(format,"%%-%ds",max(lengthName,8));
1994                for (iRow=0;iRow<numberRows;iRow++) {
1995                  if (primalRowSolution[iRow]>rowUpper[iRow]+primalTolerance||
1996                      primalRowSolution[iRow]<rowLower[iRow]-primalTolerance)
1997                    fprintf(fp,"** ");
1998                  fprintf(fp,"%7d ",iRow);
1999                  if (lengthName)
2000                    fprintf(fp,format,rowNames[iRow].c_str());
2001                  fprintf(fp,"%15.8g        %15.8g\n",primalRowSolution[iRow],
2002                          dualRowSolution[iRow]);
2003                }
2004                int iColumn;
2005                int numberColumns=models[iModel].numberColumns();
2006                double * dualColumnSolution = 
2007                  models[iModel].dualColumnSolution();
2008                double * primalColumnSolution = 
2009                  models[iModel].primalColumnSolution();
2010                double * columnLower = models[iModel].columnLower();
2011                double * columnUpper = models[iModel].columnUpper();
2012                for (iColumn=0;iColumn<numberColumns;iColumn++) {
2013                  if (primalColumnSolution[iColumn]>columnUpper[iColumn]+primalTolerance||
2014                      primalColumnSolution[iColumn]<columnLower[iColumn]-primalTolerance)
2015                    fprintf(fp,"** ");
2016                  fprintf(fp,"%7d ",iColumn);
2017                  if (lengthName)
2018                    fprintf(fp,format,columnNames[iColumn].c_str());
2019                  fprintf(fp,"%15.8g        %15.8g\n",
2020                          primalColumnSolution[iColumn],
2021                          dualColumnSolution[iColumn]);
2022                }
2023                if (fp!=stdout)
2024                  fclose(fp);
2025              } else {
2026                std::cout<<"Unable to open file "<<fileName<<std::endl;
2027              }
2028            } else {
2029              std::cout<<"** Current model not valid"<<std::endl;
2030             
2031            }
2032            break;
2033          default:
2034            abort();
2035          }
2036        } 
2037      } else if (!numberMatches) {
2038        std::cout<<"No match for "<<field<<" - ? for list of commands"
2039                 <<std::endl;
2040      } else if (numberMatches==1) {
2041        if (!numberQuery) {
2042          std::cout<<"Short match for "<<field<<" - completion: ";
2043          std::cout<<parameters[firstMatch].matchName()<<std::endl;
2044        } else if (numberQuery) {
2045          std::cout<<parameters[firstMatch].matchName()<<" : ";
2046          std::cout<<parameters[firstMatch].shortHelp()<<std::endl;
2047          if (numberQuery>=2) 
2048            parameters[firstMatch].printLongHelp();
2049        }
2050      } else {
2051        if (!numberQuery) 
2052          std::cout<<"Multiple matches for "<<field<<" - possible completions:"
2053                   <<std::endl;
2054        else
2055          std::cout<<"Completions of "<<field<<":"<<std::endl;
2056        for ( iParam=0; iParam<numberParameters; iParam++ ) {
2057          int match = parameters[iParam].matches(field);
2058          if (match&&parameters[iParam].displayThis()) {
2059            std::cout<<parameters[iParam].matchName();
2060            if (numberQuery>=2) 
2061              std::cout<<" : "<<parameters[iParam].shortHelp();
2062            std::cout<<std::endl;
2063          }
2064        }
2065      }
2066    }
2067    delete [] models;
2068    delete [] goodModels;
2069  }
2070  // By now all memory should be freed
2071#ifdef DMALLOC
2072  dmalloc_log_unfreed();
2073  dmalloc_shutdown();
2074#endif
2075  return 0;
2076}   
Note: See TracBrowser for help on using the repository browser.