source: trunk/Test/CbcOrClpParam.cpp @ 17

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

start trying for Coinsolver

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 57.9 KB
Line 
1// Copyright (C) 2002, International Business Machines
2// Corporation and others.  All Rights Reserved.
3#if defined(_MSC_VER)
4// Turn off compiler warning about long names
5#  pragma warning(disable:4786)
6#endif
7
8#include <string>
9#include <iostream>
10#include <cassert>
11
12#include "CbcOrClpParam.hpp"
13#ifdef COIN_USE_CBC
14#include "OsiSolverInterface.hpp"
15#include "CbcModel.hpp"
16#endif
17#ifdef COIN_USE_CLP
18#include "ClpSimplex.hpp"
19#include "ClpFactorization.hpp"
20#endif
21#ifdef COIN_USE_READLINE     
22#include <readline/readline.h>
23#include <readline/history.h>
24#endif
25
26//#############################################################################
27// Constructors / Destructor / Assignment
28//#############################################################################
29
30//-------------------------------------------------------------------
31// Default Constructor
32//-------------------------------------------------------------------
33CbcOrClpParam::CbcOrClpParam () 
34  : type_(INVALID),
35    lowerDoubleValue_(0.0),
36    upperDoubleValue_(0.0),
37    lowerIntValue_(0),
38    upperIntValue_(0),
39    lengthName_(0),
40    lengthMatch_(0),
41    definedKeyWords_(),
42    name_(),
43    shortHelp_(),
44    longHelp_(),
45    action_(INVALID),
46    currentKeyWord_(-1),
47    display_(false),
48    intValue_(-1),
49    doubleValue_(-1.0),
50    stringValue_(""),
51    indexNumber_(INVALID)
52{
53}
54// Other constructors
55CbcOrClpParam::CbcOrClpParam (std::string name, std::string help,
56           double lower, double upper, CbcOrClpParameterType type,
57                    bool display)
58  : type_(type),
59    lowerIntValue_(0),
60    upperIntValue_(0),
61    definedKeyWords_(),
62    name_(name),
63    shortHelp_(help),
64    longHelp_(),
65    action_(type),
66    currentKeyWord_(-1),
67    display_(display),
68    intValue_(-1),
69    doubleValue_(-1.0),
70    stringValue_(""),
71    indexNumber_(type)
72{
73  lowerDoubleValue_ = lower;
74  upperDoubleValue_ = upper;
75  gutsOfConstructor();
76}
77CbcOrClpParam::CbcOrClpParam (std::string name, std::string help,
78           int lower, int upper, CbcOrClpParameterType type,
79                    bool display)
80  : type_(type),
81    lowerDoubleValue_(0.0),
82    upperDoubleValue_(0.0),
83    definedKeyWords_(),
84    name_(name),
85    shortHelp_(help),
86    longHelp_(),
87    action_(type),
88    currentKeyWord_(-1),
89    display_(display),
90    intValue_(-1),
91    doubleValue_(-1.0),
92    stringValue_(""),
93    indexNumber_(type)
94{
95  gutsOfConstructor();
96  lowerIntValue_ = lower;
97  upperIntValue_ = upper;
98}
99// Other strings will be added by append
100CbcOrClpParam::CbcOrClpParam (std::string name, std::string help, 
101                    std::string firstValue,
102                    CbcOrClpParameterType type,int defaultIndex,
103                    bool display)
104  : type_(type),
105    lowerDoubleValue_(0.0),
106    upperDoubleValue_(0.0),
107    lowerIntValue_(0),
108    upperIntValue_(0),
109    definedKeyWords_(),
110    name_(name),
111    shortHelp_(help),
112    longHelp_(),
113    action_(type),
114    currentKeyWord_(defaultIndex),
115    display_(display),
116    intValue_(-1),
117    doubleValue_(-1.0),
118    stringValue_(""),
119    indexNumber_(type)
120{
121  gutsOfConstructor();
122  definedKeyWords_.push_back(firstValue);
123}
124// Action
125CbcOrClpParam::CbcOrClpParam (std::string name, std::string help,
126                    CbcOrClpParameterType type,int indexNumber,
127                    bool display)
128  : type_(type),
129    lowerDoubleValue_(0.0),
130    upperDoubleValue_(0.0),
131    lowerIntValue_(0),
132    upperIntValue_(0),
133    definedKeyWords_(),
134    name_(name),
135    shortHelp_(help),
136    longHelp_(),
137    action_(type),
138    currentKeyWord_(-1),
139    display_(display),
140    intValue_(-1),
141    doubleValue_(-1.0),
142    stringValue_("")
143{
144  if (indexNumber<0)
145    indexNumber_=type;
146  else
147    indexNumber_=indexNumber;
148  gutsOfConstructor();
149}
150
151//-------------------------------------------------------------------
152// Copy constructor
153//-------------------------------------------------------------------
154CbcOrClpParam::CbcOrClpParam (const CbcOrClpParam & rhs) 
155{ 
156  type_ = rhs.type_;
157  lowerDoubleValue_ = rhs.lowerDoubleValue_;
158  upperDoubleValue_ = rhs.upperDoubleValue_;
159  lowerIntValue_ = rhs.lowerIntValue_;
160  upperIntValue_ = rhs.upperIntValue_;
161  lengthName_ = rhs.lengthName_;
162  lengthMatch_ = rhs.lengthMatch_;
163  definedKeyWords_ = rhs.definedKeyWords_;
164  name_ = rhs.name_;
165  shortHelp_ = rhs.shortHelp_;
166  longHelp_ = rhs.longHelp_;
167  action_ = rhs.action_;
168  currentKeyWord_ = rhs.currentKeyWord_;
169  display_=rhs.display_;
170  intValue_=rhs.intValue_;
171  doubleValue_=rhs.doubleValue_;
172  stringValue_=rhs.stringValue_;
173  indexNumber_=rhs.indexNumber_;
174}
175
176//-------------------------------------------------------------------
177// Destructor
178//-------------------------------------------------------------------
179CbcOrClpParam::~CbcOrClpParam ()
180{
181}
182
183//----------------------------------------------------------------
184// Assignment operator
185//-------------------------------------------------------------------
186CbcOrClpParam &
187CbcOrClpParam::operator=(const CbcOrClpParam& rhs)
188{
189  if (this != &rhs) {
190    type_ = rhs.type_;
191    lowerDoubleValue_ = rhs.lowerDoubleValue_;
192    upperDoubleValue_ = rhs.upperDoubleValue_;
193    lowerIntValue_ = rhs.lowerIntValue_;
194    upperIntValue_ = rhs.upperIntValue_;
195    lengthName_ = rhs.lengthName_;
196    lengthMatch_ = rhs.lengthMatch_;
197    definedKeyWords_ = rhs.definedKeyWords_;
198    name_ = rhs.name_;
199    shortHelp_ = rhs.shortHelp_;
200    longHelp_ = rhs.longHelp_;
201    action_ = rhs.action_;
202    currentKeyWord_ = rhs.currentKeyWord_;
203    display_=rhs.display_;
204    intValue_=rhs.intValue_;
205    doubleValue_=rhs.doubleValue_;
206    stringValue_=rhs.stringValue_;
207    indexNumber_=rhs.indexNumber_;
208  }
209  return *this;
210}
211void 
212CbcOrClpParam::gutsOfConstructor()
213{
214  std::string::size_type  shriekPos = name_.find('!');
215  lengthName_ = name_.length();
216  if ( shriekPos==std::string::npos ) {
217    //does not contain '!'
218    lengthMatch_= lengthName_;
219  } else {
220    lengthMatch_=shriekPos;
221    name_ = name_.substr(0,shriekPos)+name_.substr(shriekPos+1);
222    lengthName_--;
223  }
224}
225// Insert string (only valid for keywords)
226void 
227CbcOrClpParam::append(std::string keyWord)
228{
229  definedKeyWords_.push_back(keyWord);
230}
231
232int 
233CbcOrClpParam::matches (std::string input) const
234{
235  // look up strings to do more elegantly
236  if (input.length()>lengthName_) {
237    return 0;
238  } else {
239    unsigned int i;
240    for (i=0;i<input.length();i++) {
241      if (tolower(name_[i])!=tolower(input[i])) 
242        break;
243    }
244    if (i<input.length()) {
245      return 0;
246    } else if (i>=lengthMatch_) {
247      return 1;
248    } else {
249      // matched but too short
250      return 2;
251    }
252  }
253}
254// Returns name which could match
255std::string
256CbcOrClpParam::matchName (  ) const
257{ 
258  if (lengthMatch_==lengthName_) 
259    return name_;
260  else
261    return name_.substr(0,lengthMatch_)+"("+name_.substr(lengthMatch_)+")";
262}
263
264// Returns parameter option which matches (-1 if none)
265int 
266CbcOrClpParam::parameterOption ( std::string check ) const
267{
268  int numberItems = definedKeyWords_.size();
269  if (!numberItems) {
270    return -1;
271  } else {
272    int whichItem=0;
273    unsigned int it;
274    for (it=0;it<definedKeyWords_.size();it++) {
275      std::string thisOne = definedKeyWords_[it];
276      std::string::size_type  shriekPos = thisOne.find('!');
277      unsigned int length1 = thisOne.length();
278      unsigned int length2 = length1;
279      if ( shriekPos!=std::string::npos ) {
280        //contains '!'
281        length2 = shriekPos;
282        thisOne = thisOne.substr(0,shriekPos)+
283          thisOne.substr(shriekPos+1);
284        length1 = thisOne.length();
285      }
286      if (check.length()<=length1&&length2<=check.length()) {
287        unsigned int i;
288        for (i=0;i<check.length();i++) {
289          if (tolower(thisOne[i])!=tolower(check[i])) 
290            break;
291        }
292        if (i<check.length()) {
293          whichItem++;
294        } else if (i>=length2) {
295          break;
296        } 
297      } else {
298        whichItem++;
299      }
300    }
301    if (whichItem<numberItems)
302      return whichItem;
303    else
304      return -1;
305  }
306}
307// Prints parameter options
308void 
309CbcOrClpParam::printOptions (  ) const
310{
311  std::cout<<"Possible options for "<<name_<<" are:"<<std::endl;
312  unsigned int it;
313  for (it=0;it<definedKeyWords_.size();it++) {
314    std::string thisOne = definedKeyWords_[it];
315    std::string::size_type  shriekPos = thisOne.find('!');
316    if ( shriekPos!=std::string::npos ) {
317      //contains '!'
318      thisOne = thisOne.substr(0,shriekPos)+
319        "("+thisOne.substr(shriekPos+1)+")";
320    }
321    std::cout<<thisOne<<std::endl;
322  }
323}
324// Print action and string
325void 
326CbcOrClpParam::printString() const
327{
328  if (name_=="directory")
329    std::cout<<"Current working directory is "<<stringValue_<<std::endl;
330  else
331    std::cout<<"Current default (if $ as parameter) for "<<name_
332             <<" is "<<stringValue_<<std::endl;
333}
334void CoinReadPrintit(const char * input)
335{
336  int length =strlen(input);
337  char temp[101];
338  int i;
339  int n=0;
340  for (i=0;i<length;i++) {
341    if (input[i]=='\n') {
342      temp[n]='\0';
343      std::cout<<temp<<std::endl;
344      n=0;
345    } else if (n>=65&&input[i]==' ') {
346      temp[n]='\0';
347      std::cout<<temp<<std::endl;
348      n=0;
349    } else if (n||input[i]!=' ') {
350      temp[n++]=input[i];
351    }
352  }
353  if (n) {
354    temp[n]='\0';
355    std::cout<<temp<<std::endl;
356  }
357}
358// Print Long help
359void 
360CbcOrClpParam::printLongHelp() const
361{
362  if (type_>=1&&type_<400) {
363    if (type_<LOGLEVEL) {
364      printf("Range of values is %g to %g\n",lowerDoubleValue_,upperDoubleValue_);
365    } else if (type_<DIRECTION) {
366      printf("Range of values is %d to %d\n",lowerIntValue_,upperIntValue_);
367    } else if (type_<DIRECTORY) {
368      printOptions();
369    }
370    CoinReadPrintit(longHelp_.c_str());
371  }
372}
373#ifdef COIN_USE_CBC
374int
375CbcOrClpParam::setDoubleParameter (OsiSolverInterface * model,double value) 
376{
377  if (value<lowerDoubleValue_||value>upperDoubleValue_) {
378    std::cout<<value<<" was provided for "<<name_<<
379      " - valid range is "<<lowerDoubleValue_<<" to "<<
380      upperDoubleValue_<<std::endl;
381    return 1;
382  } else {
383    double oldValue;
384    switch(type_) {
385    case DUALTOLERANCE:
386      model->getDblParam(OsiDualTolerance,oldValue);
387      model->setDblParam(OsiDualTolerance,value);
388      break;
389    case PRIMALTOLERANCE:
390      model->getDblParam(OsiPrimalTolerance,oldValue);
391      model->setDblParam(OsiPrimalTolerance,value);
392      break;
393    default:
394      oldValue=0.0; // to avoid compiler message
395      abort();
396    }
397    std::cout<<name_<<" was changed from "<<oldValue<<" to "
398             <<value<<std::endl;
399    return 0;
400  }
401}
402#endif
403#ifdef COIN_USE_CLP
404int
405CbcOrClpParam::setDoubleParameter (ClpSimplex * model,double value) 
406{
407  double oldValue = doubleParameter(model);
408  if (value<lowerDoubleValue_||value>upperDoubleValue_) {
409    std::cout<<value<<" was provided for "<<name_<<
410      " - valid range is "<<lowerDoubleValue_<<" to "<<
411      upperDoubleValue_<<std::endl;
412    return 1;
413  } else {
414    std::cout<<name_<<" was changed from "<<oldValue<<" to "
415             <<value<<std::endl;
416    switch(type_) {
417#ifndef COIN_USE_CBC
418    case DUALTOLERANCE:
419      model->setDualTolerance(value);
420      break;
421    case PRIMALTOLERANCE:
422      model->setPrimalTolerance(value);
423      break;
424#endif
425    case DUALBOUND:
426      model->setDualBound(value);
427      break;
428    case PRIMALWEIGHT:
429      model->setInfeasibilityCost(value);
430      break;
431    case TIMELIMIT:
432      model->setMaximumSeconds(value);
433      break;
434    case OBJSCALE:
435      model->setObjectiveScale(value);
436      break;
437    case RHSSCALE:
438      model->setRhsScale(value);
439      break;
440    default:
441      abort();
442    }
443    return 0;
444  }
445}
446double 
447CbcOrClpParam::doubleParameter (ClpSimplex * model) const
448{
449  double value;
450  switch(type_) {
451#ifndef COIN_USE_CBC
452  case DUALTOLERANCE:
453    value=model->dualTolerance();
454    break;
455  case PRIMALTOLERANCE:
456    value=model->primalTolerance();
457    break;
458#endif
459  case DUALBOUND:
460    value=model->dualBound();
461    break;
462  case PRIMALWEIGHT:
463    value=model->infeasibilityCost();
464    break;
465  case TIMELIMIT:
466    value=model->maximumSeconds();
467    break;
468  case OBJSCALE:
469    value=model->objectiveScale();
470    break;
471  case RHSSCALE:
472    value=model->rhsScale();
473    break;
474  default:
475    abort();
476  }
477  return value;
478}
479int 
480CbcOrClpParam::setIntParameter (ClpSimplex * model,int value) 
481{
482  int oldValue = intParameter(model);
483  if (value<lowerIntValue_||value>upperIntValue_) {
484    std::cout<<value<<" was provided for "<<name_<<
485      " - valid range is "<<lowerIntValue_<<" to "<<
486      upperIntValue_<<std::endl;
487    return 1;
488  } else {
489    std::cout<<name_<<" was changed from "<<oldValue<<" to "
490             <<value<<std::endl;
491    switch(type_) {
492    case SOLVERLOGLEVEL:
493      model->setLogLevel(value);
494      if (value>2)
495        model->factorization()->messageLevel(8);
496      else
497        model->factorization()->messageLevel(0);
498      break;
499    case MAXFACTOR:
500      model->factorization()->maximumPivots(value);
501      break;
502    case PERTVALUE:
503      model->setPerturbation(value);
504      break;
505    case MAXITERATION:
506      model->setMaximumIterations(value);
507      break;
508    case SPECIALOPTIONS:
509      model->setSpecialOptions(value);
510      break;
511    default:
512      abort();
513    }
514    return 0;
515  }
516}
517int 
518CbcOrClpParam::intParameter (ClpSimplex * model) const
519{
520  int value;
521  switch(type_) {
522#ifndef COIN_USE_CBC
523  case SOLVERLOGLEVEL:
524    value=model->logLevel();
525    break;
526#endif
527  case MAXFACTOR:
528    value=model->factorization()->maximumPivots();
529    break;
530    break;
531  case PERTVALUE:
532    value=model->perturbation();
533    break;
534  case MAXITERATION:
535    value=model->maximumIterations();
536    break;
537  case SPECIALOPTIONS:
538    value=model->specialOptions();
539    break;
540  default:
541    value=-1;
542    break;
543  }
544  return value;
545}
546#endif
547int
548CbcOrClpParam::checkDoubleParameter (double value) const
549{
550  if (value<lowerDoubleValue_||value>upperDoubleValue_) {
551    std::cout<<value<<" was provided for "<<name_<<
552      " - valid range is "<<lowerDoubleValue_<<" to "<<
553      upperDoubleValue_<<std::endl;
554    return 1;
555  } else {
556    return 0;
557  }
558}
559#ifdef COIN_USE_CBC
560double 
561CbcOrClpParam::doubleParameter (OsiSolverInterface * model) const
562{
563  double value;
564  switch(type_) {
565  case DUALTOLERANCE:
566    assert(model->getDblParam(OsiDualTolerance,value));
567    break;
568  case PRIMALTOLERANCE:
569    assert(model->getDblParam(OsiPrimalTolerance,value));
570    break;
571  default:
572    abort();
573  }
574  return value;
575}
576int 
577CbcOrClpParam::setIntParameter (OsiSolverInterface * model,int value) 
578{
579  if (value<lowerIntValue_||value>upperIntValue_) {
580    std::cout<<value<<" was provided for "<<name_<<
581      " - valid range is "<<lowerIntValue_<<" to "<<
582      upperIntValue_<<std::endl;
583    return 1;
584  } else {
585    int oldValue;
586    switch(type_) {
587    case SOLVERLOGLEVEL:
588      model->messageHandler()->setLogLevel(value);
589      break;
590    default:
591      oldValue=0; // to avoid compiler message
592      abort();
593    }
594    std::cout<<name_<<" was changed from "<<oldValue<<" to "
595             <<value<<std::endl;
596    return 0;
597  }
598}
599int 
600CbcOrClpParam::intParameter (OsiSolverInterface * model) const
601{
602  int value=0;
603  switch(type_) {
604  case SOLVERLOGLEVEL:
605    value=model->messageHandler()->logLevel();
606    break;
607  default:
608    abort();
609  }
610  return value;
611}
612int
613CbcOrClpParam::setDoubleParameter (CbcModel &model,double value) 
614{
615  if (value<lowerDoubleValue_||value>upperDoubleValue_) {
616    std::cout<<value<<" was provided for "<<name_<<
617      " - valid range is "<<lowerDoubleValue_<<" to "<<
618      upperDoubleValue_<<std::endl;
619    return 1;
620  } else {
621    double oldValue;
622    setDoubleValue(value);
623    switch(type_) {
624    case INFEASIBILITYWEIGHT:
625      oldValue=model.getDblParam(CbcModel::CbcInfeasibilityWeight);
626      model.setDblParam(CbcModel::CbcInfeasibilityWeight,value);
627      break;
628    case INTEGERTOLERANCE:
629      oldValue=model.getDblParam(CbcModel::CbcIntegerTolerance);
630      model.setDblParam(CbcModel::CbcIntegerTolerance,value);
631      break;
632    case INCREMENT:
633      oldValue=model.getDblParam(CbcModel::CbcCutoffIncrement);
634      model.setDblParam(CbcModel::CbcCutoffIncrement,value);
635    case ALLOWABLEGAP:
636      oldValue=model.getDblParam(CbcModel::CbcAllowableGap);
637      model.setDblParam(CbcModel::CbcAllowableGap,value);
638      break;
639    case TIMELIMIT:
640    { oldValue = model.getDblParam(CbcModel::CbcMaximumSeconds) ;
641      model.setDblParam(CbcModel::CbcMaximumSeconds,value) ;
642      break ; }
643    case DUALTOLERANCE:
644    case PRIMALTOLERANCE:
645      setDoubleParameter(model.solver(),value);
646      return 0; // to avoid message
647    default:
648      oldValue=0.0; // to avoid compiler message
649      break;
650    }
651    std::cout<<name_<<" was changed from "<<oldValue<<" to "
652             <<value<<std::endl;
653    return 0;
654  }
655}
656double 
657CbcOrClpParam::doubleParameter (CbcModel &model) const
658{
659  double value;
660  switch(type_) {
661  case INFEASIBILITYWEIGHT:
662    value=model.getDblParam(CbcModel::CbcInfeasibilityWeight);
663    break;
664  case INTEGERTOLERANCE:
665    value=model.getDblParam(CbcModel::CbcIntegerTolerance);
666    break;
667  case INCREMENT:
668    value=model.getDblParam(CbcModel::CbcCutoffIncrement);
669  case ALLOWABLEGAP:
670    value=model.getDblParam(CbcModel::CbcAllowableGap);
671    break;
672  case TIMELIMIT:
673  { value = model.getDblParam(CbcModel::CbcMaximumSeconds) ;
674    break ; }
675  case DUALTOLERANCE:
676  case PRIMALTOLERANCE:
677    value=doubleParameter(model.solver());
678    break;
679  default:
680    abort();
681  }
682  return value;
683}
684int 
685CbcOrClpParam::setIntParameter (CbcModel &model,int value) 
686{
687  if (value<lowerIntValue_||value>upperIntValue_) {
688    std::cout<<value<<" was provided for "<<name_<<
689      " - valid range is "<<lowerIntValue_<<" to "<<
690      upperIntValue_<<std::endl;
691    return 1;
692  } else {
693    setIntValue(value);
694    int oldValue;
695    switch(type_) {
696    case LOGLEVEL:
697      oldValue = model.messageHandler()->logLevel();
698      model.messageHandler()->setLogLevel(value);
699      break;
700    case SOLVERLOGLEVEL:
701      oldValue = model.solver()->messageHandler()->logLevel();
702      model.solver()->messageHandler()->setLogLevel(value);
703      break;
704    case MAXNODES:
705      oldValue=model.getIntParam(CbcModel::CbcMaxNumNode);
706      model.setIntParam(CbcModel::CbcMaxNumNode,value);
707      break;
708    case STRONGBRANCHING:
709      oldValue=model.numberStrong();
710      model.setNumberStrong(value);
711      break;
712    default:
713      oldValue=0; // to avoid compiler message
714      break;
715    }
716    std::cout<<name_<<" was changed from "<<oldValue<<" to "
717             <<value<<std::endl;
718    return 0;
719  }
720}
721int 
722CbcOrClpParam::intParameter (CbcModel &model) const
723{
724  int value;
725  switch(type_) {
726  case LOGLEVEL:
727    value = model.messageHandler()->logLevel();
728      break;
729  case SOLVERLOGLEVEL:
730    value = model.solver()->messageHandler()->logLevel();
731      break;
732  case MAXNODES:
733    value = model.getIntParam(CbcModel::CbcMaxNumNode);
734    break;
735  case STRONGBRANCHING:
736    value=model.numberStrong();
737    break;
738  default:
739    abort();
740  }
741  return value;
742}
743#endif
744void 
745CbcOrClpParam::setIntValue ( int value )
746{ 
747  if (value<lowerIntValue_||value>upperIntValue_) {
748    std::cout<<value<<" was provided for "<<name_<<
749      " - valid range is "<<lowerIntValue_<<" to "<<
750      upperIntValue_<<std::endl;
751  } else {
752    intValue_=value;
753  }
754}
755void 
756CbcOrClpParam::setDoubleValue ( double value )
757{ 
758  if (value<lowerDoubleValue_||value>upperDoubleValue_) {
759    std::cout<<value<<" was provided for "<<name_<<
760      " - valid range is "<<lowerDoubleValue_<<" to "<<
761      upperDoubleValue_<<std::endl;
762  } else {
763    doubleValue_=value;
764  }
765}
766void 
767CbcOrClpParam::setStringValue ( std::string value )
768{ 
769  stringValue_=value;
770}
771static char line[1000];
772static char * where=NULL;
773extern int CbcOrClpRead_mode;
774extern FILE * CbcOrClpReadCommand;
775// Simple read stuff
776std::string
777CoinReadNextField()
778{
779  std::string field;
780  if (!where) {
781    // need new line
782#ifdef COIN_USE_READLINE     
783    if (CbcOrClpReadCommand==stdin) {
784      // Get a line from the user.
785      where = readline ("Clp:");
786     
787      // If the line has any text in it, save it on the history.
788      if (where) {
789        if ( *where)
790          add_history (where);
791        strcpy(line,where);
792        free(where);
793      }
794    } else {
795      where = fgets(line,1000,CbcOrClpReadCommand);
796    }
797#else
798    if (CbcOrClpReadCommand==stdin) {
799      fprintf(stdout,"Clp:");
800      fflush(stdout);
801    }
802    where = fgets(line,1000,CbcOrClpReadCommand);
803#endif
804    if (!where)
805      return field; // EOF
806    where = line;
807    // clean image
808    char * lastNonBlank = line-1;
809    while ( *where != '\0' ) {
810      if ( *where != '\t' && *where < ' ' ) {
811        break;
812      } else if ( *where != '\t' && *where != ' ') {
813        lastNonBlank = where;
814      }
815      where++;
816    }
817    where=line;
818    *(lastNonBlank+1)='\0';
819  }
820  // munch white space
821  while(*where==' '||*where=='\t')
822    where++;
823  char * saveWhere = where;
824  while (*where!=' '&&*where!='\t'&&*where!='\0')
825    where++;
826  if (where!=saveWhere) {
827    char save = *where;
828    *where='\0';
829    //convert to string
830    field=saveWhere;
831    *where=save;
832  } else {
833    where=NULL;
834    field="EOL";
835  }
836  return field;
837}
838
839std::string
840CoinReadGetCommand(int argc, const char *argv[])
841{
842  std::string field="EOL";
843  while (field=="EOL") {
844    if (CbcOrClpRead_mode>0) {
845      if (CbcOrClpRead_mode<argc) {
846        field = argv[CbcOrClpRead_mode++];
847        if (field=="-") {
848          std::cout<<"Switching to line mode"<<std::endl;
849          CbcOrClpRead_mode=-1;
850          field=CoinReadNextField();
851        } else if (field[0]!='-') {
852          if (CbcOrClpRead_mode!=2) {
853            std::cout<<"skipping non-command "<<field<<std::endl;
854            field="EOL"; // skip
855          } else {
856            // special dispensation - taken as -import name
857            CbcOrClpRead_mode--;
858            field="import";
859          }
860        } else {
861          if (field!="--") {
862            // take off -
863            field = field.substr(1);
864          } else {
865            // special dispensation - taken as -import --
866            CbcOrClpRead_mode--;
867            field="import";
868          }
869        }
870      } else {
871        field="";
872      }
873    } else {
874      field=CoinReadNextField();
875    }
876  }
877  //std::cout<<field<<std::endl;
878  return field;
879}
880std::string
881CoinReadGetString(int argc, const char *argv[])
882{
883  std::string field="EOL";
884  if (CbcOrClpRead_mode>0) {
885    if (CbcOrClpRead_mode<argc) {
886      if (argv[CbcOrClpRead_mode][0]!='-') { 
887        field = argv[CbcOrClpRead_mode++];
888      } else if (!strcmp(argv[CbcOrClpRead_mode],"--")) {
889        field = argv[CbcOrClpRead_mode++];
890        // -- means import from stdin
891        field = "-";
892      }
893    }
894  } else {
895    field=CoinReadNextField();
896  }
897  //std::cout<<field<<std::endl;
898  return field;
899}
900// valid 0 - okay, 1 bad, 2 not there
901int
902CoinReadGetIntField(int argc, const char *argv[],int * valid)
903{
904  std::string field="EOL";
905  if (CbcOrClpRead_mode>0) {
906    if (CbcOrClpRead_mode<argc) {
907      // may be negative value so do not check for -
908      field = argv[CbcOrClpRead_mode++];
909    }
910  } else {
911    field=CoinReadNextField();
912  }
913  int value=0;
914  //std::cout<<field<<std::endl;
915  if (field!="EOL") {
916    // how do I check valid
917    value =  atoi(field.c_str());
918    *valid=0;
919  } else {
920    *valid=2;
921  }
922  return value;
923}
924double
925CoinReadGetDoubleField(int argc, const char *argv[],int * valid)
926{
927  std::string field="EOL";
928  if (CbcOrClpRead_mode>0) {
929    if (CbcOrClpRead_mode<argc) {
930      // may be negative value so do not check for -
931      field = argv[CbcOrClpRead_mode++];
932    }
933  } else {
934    field=CoinReadNextField();
935  }
936  double value=0.0;
937  //std::cout<<field<<std::endl;
938  if (field!="EOL") {
939    // how do I check valid
940    value = atof(field.c_str());
941    *valid=0;
942  } else {
943    *valid=2;
944  }
945  return value;
946}
947/*
948  Subroutine to establish the cbc parameter array. See the description of
949  class CbcOrClpParam for details. Pulled from C..Main() for clarity.
950*/
951void 
952establishParams (int &numberParameters, CbcOrClpParam *const parameters)
953{
954  numberParameters=0;
955  parameters[numberParameters++]=
956    CbcOrClpParam("?","For help",GENERALQUERY,-1,false);
957  parameters[numberParameters++]=
958    CbcOrClpParam("???","For help",FULLGENERALQUERY,-1,false);
959  parameters[numberParameters++]=
960    CbcOrClpParam("-","From stdin",
961                  STDIN,299,false);
962#ifdef COIN_USE_CBC
963    parameters[numberParameters++]=
964      CbcOrClpParam("allow!ableGap","Stop when gap between best possible and \
965best less than this",
966              0.0,1.0e20,ALLOWABLEGAP);
967  parameters[numberParameters-1].setLonghelp
968    (
969     "TODO"
970     ); 
971#endif
972#ifdef COIN_USE_CLP
973  parameters[numberParameters++]=
974    CbcOrClpParam("allS!lack","Set basis back to all slack and reset solution",
975                  ALLSLACK,false);
976  parameters[numberParameters-1].setLonghelp
977    (
978     "Useful for playing around"
979     ); 
980  parameters[numberParameters++]=
981    CbcOrClpParam("auto!Scale","Whether to scale objective, rhs and bounds of problem if they look odd",
982                  "off",AUTOSCALE,0,false);
983  parameters[numberParameters-1].append("on");
984  parameters[numberParameters-1].setLonghelp
985    (
986     "If you think you may get odd objective values or large equality rows etc then\
987 it may be worth setting this true.  It is still experimental and you may prefer\
988 to use objective!Scale and rhs!Scale"
989     ); 
990  parameters[numberParameters++]=
991    CbcOrClpParam("barr!ier","Solve using primal dual predictor corrector algorithm",
992                  BARRIER);
993  parameters[numberParameters-1].setLonghelp
994    (
995     "This command solves the current model using the  primal dual predictor \
996corrector algorithm."
997     
998     ); 
999  parameters[numberParameters++]=
1000    CbcOrClpParam("basisI!n","Import basis from bas file",
1001                  BASISIN);
1002  parameters[numberParameters-1].setLonghelp
1003    (
1004     "This will read an MPS format basis file from the given file name.  It will use the default\
1005 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
1006 is initialized to '', i.e. it must be set.  If you have libgz then it can read compressed\
1007 files 'xxxxxxxx.gz'.."
1008     ); 
1009  parameters[numberParameters++]=
1010    CbcOrClpParam("basisO!ut","Export basis as bas file",
1011                  BASISOUT);
1012  parameters[numberParameters-1].setLonghelp
1013    (
1014     "This will write an MPS format basis file to the given file name.  It will use the default\
1015 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
1016 is initialized to 'default.bas'."
1017     ); 
1018  parameters[numberParameters++]=
1019    CbcOrClpParam("biasLU","Whether factorization biased towards U",
1020                  "UU",BIASLU,2,false);
1021  parameters[numberParameters-1].append("UX");
1022  parameters[numberParameters-1].append("LX");
1023  parameters[numberParameters-1].append("LL");
1024#endif
1025#ifdef COIN_USE_CBC
1026  parameters[numberParameters++]=
1027    CbcOrClpParam("branch!AndCut","Do Branch and Cut",
1028                  BAB);
1029  parameters[numberParameters-1].setLonghelp
1030    (
1031     "This does branch and cut.  Far too many parameters apply to give a full description here.  \
1032the main thing is to think about which cuts to apply.  .. expand ..."
1033     ); 
1034#endif
1035  parameters[numberParameters++]=
1036    CbcOrClpParam("bscale","Whether to scale in barrier",
1037                  "off",BARRIERSCALE,0,false);
1038  parameters[numberParameters-1].append("on");
1039  parameters[numberParameters++]=
1040    CbcOrClpParam("chol!esky","Which cholesky algorithm",
1041                  "native",CHOLESKY,false);
1042  parameters[numberParameters-1].append("dense");
1043#ifdef FOREIGN_BARRIER
1044#ifdef WSSMP_BARRIER
1045  parameters[numberParameters-1].append("fudge!Long");
1046  parameters[numberParameters-1].append("wssmp");
1047#else
1048  parameters[numberParameters-1].append("fudge!Long_dummy");
1049  parameters[numberParameters-1].append("wssmp_dummy");
1050#endif
1051#ifdef UFL_BARRIER
1052  parameters[numberParameters-1].append("Uni!versityOfFlorida");
1053#else
1054  parameters[numberParameters-1].append("Uni!versityOfFlorida_dummy");
1055#endif
1056#ifdef TAUCS_BARRIER
1057  parameters[numberParameters-1].append("Taucs");
1058#else
1059  parameters[numberParameters-1].append("Taucs_dummy");
1060#endif
1061#endif
1062#ifdef COIN_USE_CBC
1063  parameters[numberParameters++]=
1064    CbcOrClpParam("clique!Cuts","Whether to use Clique cuts",
1065                  "off",CLIQUECUTS);
1066  parameters[numberParameters-1].append("on");
1067  parameters[numberParameters-1].append("root");
1068  parameters[numberParameters-1].setLonghelp
1069    (
1070     "TODO"
1071     ); 
1072  parameters[numberParameters++]=
1073    CbcOrClpParam("cost!Strategy","How to use costs",
1074                  "off",COSTSTRATEGY);
1075  parameters[numberParameters-1].append("pri!orities");
1076  parameters[numberParameters-1].append("pseudo!costs(not implemented yet)");
1077  parameters[numberParameters-1].setLonghelp
1078    (
1079     "TODO"
1080     ); 
1081#endif
1082#ifdef COIN_USE_CLP
1083  parameters[numberParameters++]=
1084    CbcOrClpParam("crash","Whether to create basis for problem",
1085                  "off",CRASH);
1086  parameters[numberParameters-1].append("on");
1087  parameters[numberParameters-1].append("so!low_halim");
1088  parameters[numberParameters-1].append("ha!lim_solow(JJF mods)");
1089  parameters[numberParameters-1].setLonghelp
1090    (
1091     "If crash is set on and there is an all slack basis then Clp will flip or put structural\
1092 variables into basis with the aim of getting dual feasible.  On the whole dual seems to be\
1093 better without it and there alernative types of 'crash' for primal e.g. 'idiot' or 'sprint'. \
1094I have also added a variant due to Solow and Halim which is as on but just flip."); 
1095  parameters[numberParameters++]=
1096    CbcOrClpParam("cross!over","Whether to get a basic solution after barrier",
1097                  "on",CROSSOVER);
1098  parameters[numberParameters-1].append("off");
1099  parameters[numberParameters-1].append("maybe");
1100  parameters[numberParameters-1].setLonghelp
1101    (
1102     "Interior point algorithms do not obtain a basic solution (and \
1103the feasibility criterion is a bit suspect (JJF)).  This option will crossover \
1104to a basic solution suitable for ranging or branch and cut.  With the current state \
1105of quadratic it may be a good idea to switch off crossover for quadratic (and maybe \
1106presolve as well) - the option maybe does this."
1107     );
1108#endif
1109#ifdef COIN_USE_CBC
1110  parameters[numberParameters++]=
1111    CbcOrClpParam("cutD!epth","Depth in tree at which to do cuts",
1112                  -1,999999,CUTDEPTH);
1113  parameters[numberParameters-1].setLonghelp
1114    (
1115     "Cut generators may be - off, on only at root, on if they look possible \
1116and on.  If they are done every node then that is that, but it may be worth doing them \
1117every so often.  The original method was every so many node but it may be more logical \
1118to do it whenever depth in tree is a multiple of K.  This option does that and defaults \
1119to 5."
1120     );
1121  parameters[numberParameters-1].setIntValue(5);
1122#endif
1123  parameters[numberParameters++]=
1124    CbcOrClpParam("direction","Minimize or Maximize",
1125                  "min!imize",DIRECTION);
1126  parameters[numberParameters-1].append("max!imize");
1127  parameters[numberParameters-1].append("zero");
1128  parameters[numberParameters-1].setLonghelp
1129    (
1130     "The default is minimize - use 'direction maximize' for maximization.\n\
1131You can also use the parameters 'maximize' or 'minimize'."
1132     ); 
1133  parameters[numberParameters++]=
1134    CbcOrClpParam("directory","Set Default directory for import etc.",
1135                  DIRECTORY,299);
1136  parameters[numberParameters-1].setLonghelp
1137    (
1138     "This sets the directory which import, export, saveModel and restoreModel will use.\
1139  It is initialized to './'"
1140     ); 
1141#ifdef COIN_USE_CLP
1142  parameters[numberParameters++]=
1143    CbcOrClpParam("dualB!ound","Initially algorithm acts as if no \
1144gap between bounds exceeds this value",
1145                  1.0e-20,1.0e12,DUALBOUND);
1146  parameters[numberParameters-1].setLonghelp
1147    (
1148     "The dual algorithm in Clp is a single phase algorithm as opposed to a two phase\
1149 algorithm where you first get feasible then optimal.  If a problem has both upper and\
1150 lower bounds then it is trivial to get dual feasible by setting non basic variables\
1151 to correct bound.  If the gap between the upper and lower bounds of a variable is more\
1152 than the value of dualBound Clp introduces fake bounds so that it can make the problem\
1153 dual feasible.  This has the same effect as a composite objective function in the\
1154 primal algorithm.  Too high a value may mean more iterations, while too low a bound means\
1155 the code may go all the way and then have to increase the bounds.  OSL had a heuristic to\
1156 adjust bounds, maybe we need that here."
1157     );
1158  parameters[numberParameters++]=
1159    CbcOrClpParam("dualP!ivot","Dual pivot choice algorithm",
1160                  "auto!matic",DUALPIVOT);
1161  parameters[numberParameters-1].append("dant!zig");
1162  parameters[numberParameters-1].append("partial");
1163  parameters[numberParameters-1].append("steep!est");
1164  parameters[numberParameters-1].setLonghelp
1165    (
1166     "Clp can use any pivot selection algorithm which the user codes as long as it\
1167 implements the features in the abstract pivot base class.  The Dantzig method is implemented\
1168 to show a simple method but its use is deprecated.  Steepest is the method of choice and there\
1169 are two variants which keep all weights updated but only scan a subset each iteration.\
1170 Partial switches this on while automatic decides at each iteration based on information\
1171 about the factorization."
1172     ); 
1173  parameters[numberParameters++]=
1174    CbcOrClpParam("dualS!implex","Do dual simplex algorithm",
1175                  DUALSIMPLEX);
1176  parameters[numberParameters-1].setLonghelp
1177    (
1178     "This command solves the current model using the dual steepest algorithm.\
1179The time and iterations may be affected by settings such as presolve, scaling, crash\
1180 and also by dual pivot method, fake bound on variables and dual and primal tolerances."
1181     );
1182#endif
1183  parameters[numberParameters++]=
1184    CbcOrClpParam("dualT!olerance","For an optimal solution \
1185no dual infeasibility may exceed this value",
1186                  1.0e-20,1.0e12,DUALTOLERANCE);
1187  parameters[numberParameters-1].setLonghelp
1188    (
1189     "Normally the default tolerance is fine, but you may want to increase it a\
1190 bit if a dual run seems to be having a hard time"
1191     ); 
1192  parameters[numberParameters++]=
1193    CbcOrClpParam("end","Stops clp execution",
1194                  EXIT);
1195  parameters[numberParameters-1].setLonghelp
1196    (
1197     "This stops execution ; end, exit, quit and stop are synonyms"
1198     ); 
1199  parameters[numberParameters++]=
1200    CbcOrClpParam("error!sAllowed","Whether to allow import errors",
1201                  "off",ERRORSALLOWED);
1202  parameters[numberParameters-1].append("on");
1203  parameters[numberParameters-1].setLonghelp
1204    (
1205     "The default is not to use any model which had errors when reading the mps file.\
1206  Setting this to 'on' will allow all errors from which the code can recover\
1207 by ignoring the error."
1208     );
1209  parameters[numberParameters++]=
1210    CbcOrClpParam("exit","Stops clp execution",
1211                  EXIT);
1212  parameters[numberParameters-1].setLonghelp
1213    (
1214     "This stops the execution of Clp, end, exit, quit and stop are synonyms"
1215     ); 
1216  parameters[numberParameters++]=
1217    CbcOrClpParam("export","Export model as mps file",
1218                  EXPORT);
1219  parameters[numberParameters-1].setLonghelp
1220    (
1221     "This will write an MPS format file to the given file name.  It will use the default\
1222 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
1223 is initialized to 'default.mps'."
1224     ); 
1225#ifdef COIN_USE_CLP
1226  parameters[numberParameters++]=
1227    CbcOrClpParam("fakeB!ound","All bounds <= this value - DEBUG",
1228                  1.0,1.0e15,FAKEBOUND,false);
1229#ifdef COIN_USE_CBC
1230  parameters[numberParameters++]=
1231    CbcOrClpParam("fix!OnDj","Try heuristic based on fixing variables with \
1232reduced costs greater than this",
1233                  -1.0e20,1.0e20,DJFIX,false);
1234  parameters[numberParameters-1].setLonghelp
1235    (
1236     "TODO"
1237     ); 
1238    parameters[numberParameters++]=
1239      CbcOrClpParam("flow!CoverCuts","Whether to use Flow Cover cuts",
1240                    "off",FLOWCUTS);
1241    parameters[numberParameters-1].append("on");
1242    parameters[numberParameters-1].append("root");
1243  parameters[numberParameters-1].setLonghelp
1244    (
1245     "TODO"
1246     ); 
1247#endif
1248  parameters[numberParameters++]=
1249    CbcOrClpParam("gamma","Whether to regularize barrier",
1250                  "off",GAMMA,0,false);
1251  parameters[numberParameters-1].append("on");
1252#endif
1253#ifdef COIN_USE_CBC
1254  parameters[numberParameters++]=
1255    CbcOrClpParam("gap!Ratio","Stop when gap between best possible and \
1256best less than this fraction of larger of two",
1257                  0.0,1.0e20,GAPRATIO);
1258  parameters[numberParameters-1].setLonghelp
1259    (
1260     "TODO"
1261     ); 
1262  parameters[numberParameters++]=
1263    CbcOrClpParam("gomory!Cuts","Whether to use Gomory cuts",
1264                  "off",GOMORYCUTS);
1265  parameters[numberParameters-1].append("on");
1266  parameters[numberParameters-1].append("root");
1267  parameters[numberParameters-1].setLonghelp
1268    (
1269     "The original cuts - beware of imitations!  Having gone out of favo(u)r, they are now more \
1270fashionable as LP solvers are more robust and they interact well with other cuts.  They will almost always \
1271give cuts (although in this executable they are limited as to number of variables in cut)."
1272     ); 
1273#endif
1274  parameters[numberParameters++]=
1275    CbcOrClpParam("help","Print out version, non-standard options and some help",
1276                  HELP);
1277#ifdef COIN_USE_CLP
1278  parameters[numberParameters++]=
1279    CbcOrClpParam("idiot!Crash","Whether to try idiot crash",
1280                  -1,200,IDIOT);
1281  parameters[numberParameters-1].setLonghelp
1282    (
1283     "This is a type of 'crash' which works well on some homogeneous problems.\
1284 It works best on problems with unit elements and rhs but will do something to any model.  It should only be\
1285 used before primal.  It can be set to -1 when the code decides for itself whether to use it,\
1286 0 to switch off or n > 0 to do n passes."
1287     ); 
1288#endif
1289  parameters[numberParameters++]=
1290    CbcOrClpParam("import","Import model from mps file",
1291                  IMPORT);
1292  parameters[numberParameters-1].setLonghelp
1293    (
1294     "This will read an MPS format file from the given file name.  It will use the default\
1295 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
1296 is initialized to '', i.e. it must be set.  If you have libgz then it can read compressed\
1297 files 'xxxxxxxx.gz'.."
1298     );
1299#ifdef COIN_USE_CBC
1300  parameters[numberParameters++]=
1301    CbcOrClpParam("inc!rement","A valid solution must be at least this \
1302much better than last integer solution",
1303                  -1.0e20,1.0e20,INCREMENT);
1304  parameters[numberParameters-1].setLonghelp
1305    (
1306     "TODO"
1307     ); 
1308  parameters[numberParameters++]=
1309    CbcOrClpParam("inf!easibilityWeight","Each integer infeasibility is expected \
1310to cost this much",
1311                  0.0,1.0e20,INFEASIBILITYWEIGHT);
1312  parameters[numberParameters-1].setLonghelp
1313    (
1314     "TODO"
1315     ); 
1316  parameters[numberParameters++]=
1317    CbcOrClpParam("initialS!olve","Solve to continuous",
1318                  SOLVECONTINUOUS);
1319  parameters[numberParameters-1].setLonghelp
1320    (
1321     "TODO"
1322     ); 
1323  parameters[numberParameters++]=
1324    CbcOrClpParam("integerT!olerance","For an optimal solution \
1325no integer variable may be this away from an integer value",
1326              1.0e-20,0.5,INTEGERTOLERANCE);
1327  parameters[numberParameters-1].setLonghelp
1328    (
1329     "TODO"
1330     ); 
1331#endif
1332#ifdef COIN_USE_CLP
1333  parameters[numberParameters++]=
1334    CbcOrClpParam("keepN!ames","Whether to keep names from import",
1335                  "on",KEEPNAMES);
1336  parameters[numberParameters-1].append("off");
1337  parameters[numberParameters-1].setLonghelp
1338    (
1339     "It saves space to get rid of names so if you need to you can set this to off."
1340     ); 
1341  parameters[numberParameters++]=
1342    CbcOrClpParam("KKT","Whether to use KKT factorization",
1343                  "off",KKT,0,false);
1344  parameters[numberParameters-1].append("on");
1345#endif
1346#ifdef COIN_USE_CBC
1347  parameters[numberParameters++]=
1348    CbcOrClpParam("knapsack!Cuts","Whether to use Knapsack cuts",
1349                  "off",KNAPSACKCUTS);
1350  parameters[numberParameters-1].append("on");
1351  parameters[numberParameters-1].append("root");
1352  parameters[numberParameters-1].setLonghelp
1353    (
1354     "TODO"
1355     ); 
1356#endif
1357#ifndef COIN_USE_CBC
1358  parameters[numberParameters++]=
1359    CbcOrClpParam("log!Level","Level of detail in Solver output",
1360                  -1,63,SOLVERLOGLEVEL);
1361#else
1362  parameters[numberParameters++]=
1363    CbcOrClpParam("log!Level","Level of detail in Coin branch and Cut output",
1364                  -1,63,LOGLEVEL);
1365  parameters[numberParameters-1].setIntValue(1);
1366#endif
1367  parameters[numberParameters-1].setLonghelp
1368    (
1369     "If 0 then there should be no output in normal circumstances.  1 is probably the best\
1370 value for most uses, while 2 and 3 give more information."
1371     ); 
1372  parameters[numberParameters++]=
1373    CbcOrClpParam("max!imize","Set optimization direction to maximize",
1374                  MAXIMIZE,299);
1375  parameters[numberParameters-1].setLonghelp
1376    (
1377     "The default is minimize - use 'maximize' for maximization.\n\
1378You can also use the parameters 'direction maximize'."
1379     ); 
1380#ifdef COIN_USE_CLP
1381  parameters[numberParameters++]=
1382    CbcOrClpParam("maxF!actor","Maximum number of iterations between \
1383refactorizations",
1384                  1,999999,MAXFACTOR);
1385  parameters[numberParameters-1].setLonghelp
1386    (
1387     "If this is at its initial value of 201 then in this executable clp will guess at a\
1388 value to use.  Otherwise the user can set a value.  The code may decide to re-factorize\
1389 earlier."
1390     ); 
1391  parameters[numberParameters++]=
1392    CbcOrClpParam("maxIt!erations","Maximum number of iterations before \
1393stopping",
1394                  0,99999999,MAXITERATION);
1395  parameters[numberParameters-1].setLonghelp
1396    (
1397     "This can be used for testing purposes.  The corresponding library call\n\
1398      \tsetMaximumIterations(value)\n can be useful.  If the code stops on\
1399 seconds or by an interrupt this will be treated as stopping on maximum iterations"
1400     ); 
1401#endif
1402#ifdef COIN_USE_CBC
1403  parameters[numberParameters++]=
1404    CbcOrClpParam("maxN!odes","Maximum number of nodes to do",
1405                  1,999999,MAXNODES);
1406  parameters[numberParameters-1].setLonghelp
1407    (
1408     "TODO"
1409     ); 
1410#endif
1411  parameters[numberParameters++]=
1412    CbcOrClpParam("min!imize","Set optimization direction to minimize",
1413                  MINIMIZE,299);
1414  parameters[numberParameters-1].setLonghelp
1415    (
1416     "The default is minimize - use 'maximize' for maximization.\n\
1417This should only be necessary if you have previously set maximization \
1418You can also use the parameters 'direction minimize'."
1419     );
1420#ifdef COIN_USE_CBC
1421  parameters[numberParameters++]=
1422    CbcOrClpParam("mixed!IntegerRoundingCuts","Whether to use Mixed Integer Rounding cuts",
1423                  "off",MIXEDCUTS);
1424  parameters[numberParameters-1].append("on");
1425  parameters[numberParameters-1].append("root");
1426  parameters[numberParameters-1].setLonghelp
1427    (
1428     "TODO"
1429     ); 
1430#endif
1431  parameters[numberParameters++]=
1432    CbcOrClpParam("mess!ages","Controls if Clpnnnn is printed",
1433                  "off",MESSAGES);
1434  parameters[numberParameters-1].append("on");
1435  parameters[numberParameters-1].setLonghelp
1436    ("The default for the Clp library is to put out messages such as:\n\
1437   Clp0005 2261  Objective 109.024 Primal infeas 944413 (758)\n\
1438but this program turns this off to make it look more friendly.  It can be useful\
1439 to turn them back on if you want to be able 'grep' for particular messages or if\
1440 you intend to override the behavior of a particular message."
1441     );
1442#ifdef COIN_USE_CBC
1443  parameters[numberParameters++]=
1444    CbcOrClpParam("miplib","Do some of miplib test set",
1445                  MIPLIB);
1446#endif
1447#ifdef COIN_USE_CLP
1448  parameters[numberParameters++]=
1449    CbcOrClpParam("netlib","Solve entire netlib test set",
1450                  NETLIB_DUAL);
1451  parameters[numberParameters-1].setLonghelp
1452    (
1453     "This exercises the unit test for clp and then solves the netlib test set using dual.\
1454The user can set options before e.g. clp -presolve off -netlib"
1455     ); 
1456#ifdef REAL_BARRIER
1457  parameters[numberParameters++]=
1458    CbcOrClpParam("netlibB!arrier","Solve entire netlib test set with barrier",
1459                  NETLIB_BARRIER);
1460  parameters[numberParameters-1].setLonghelp
1461    (
1462     "This exercises the unit test for clp and then solves the netlib test set using barrier.\
1463The user can set options before e.g. clp -presolve off -netlib"
1464     ); 
1465#endif
1466  parameters[numberParameters++]=
1467    CbcOrClpParam("netlibP!rimal","Solve entire netlib test set (primal)",
1468                  NETLIB_PRIMAL);
1469  parameters[numberParameters-1].setLonghelp
1470    (
1471     "This exercises the unit test for clp and then solves the netlib test set using primal.\
1472The user can set options before e.g. clp -presolve off -netlibp"
1473     ); 
1474  parameters[numberParameters++]=
1475    CbcOrClpParam("network","Tries to make network matrix",
1476                  NETWORK,-1,false);
1477  parameters[numberParameters-1].setLonghelp
1478    (
1479     "Clp will go faster if the matrix can be converted to a network.  The matrix\
1480 operations may be a bit faster with more efficient storage, but the main advantage\
1481 comes from using a network factorization.  It will probably not be as fast as a \
1482specialized network code."
1483     ); 
1484  parameters[numberParameters++]=
1485    CbcOrClpParam("objective!Scale","Scale factor to apply to objective",
1486                  -1.0e20,1.0e20,OBJSCALE,false);
1487  parameters[numberParameters-1].setLonghelp
1488    (
1489     "If the objective function has some very large values, you may wish to scale them\
1490 internally by this amount.  It can also be set by autoscale.  It is applied after scaling"
1491     ); 
1492  parameters[numberParameters-1].setDoubleValue(1.0);
1493#endif
1494#ifdef COIN_USE_CBC
1495    parameters[numberParameters++]=
1496      CbcOrClpParam("oddhole!Cuts","Whether to use Oddhole cuts",
1497              "off",ODDHOLECUTS);
1498    parameters[numberParameters-1].append("on");
1499    parameters[numberParameters-1].append("root");
1500  parameters[numberParameters-1].setLonghelp
1501    (
1502     "TODO"
1503     ); 
1504#endif
1505  parameters[numberParameters++]=
1506    CbcOrClpParam("output!Format","Which output format to use",
1507                  1,6,OUTPUTFORMAT);
1508  parameters[numberParameters-1].setLonghelp
1509    (
1510     "Normally export will be done using normal representation for numbers and two values\
1511 per line.  You may want to do just one per line (for grep or suchlike) and you may wish\
1512 to save with absolute accuracy using a coded version of the IEEE value. A value of 2 is normal.\
1513 otherwise odd values gives one value per line, even two.  Values 1,2 give normal format, 3,4\
1514 gives greater precision, while 5,6 give IEEE values.  When used for exporting a basis 1 does not save \
1515values, 2 saves values, 3 with greater accuracy and 4 in IEEE."
1516     ); 
1517#ifdef COIN_USE_CLP
1518  parameters[numberParameters++]=
1519    CbcOrClpParam("passP!resolve","How many passes in presolve",
1520                  0,100,PRESOLVEPASS,false);
1521  parameters[numberParameters-1].setLonghelp
1522    (
1523     "Normally Presolve does 5 passes but you may want to do less to make it\
1524 more lightweight or do more if improvements are still being made.  As Presolve will return\
1525 if nothing is being taken out, then you should not need to use this fine tuning."
1526     ); 
1527  parameters[numberParameters++]=
1528    CbcOrClpParam("pertV!alue","Method of perturbation",
1529                  -5000,102,PERTVALUE,false);
1530  parameters[numberParameters++]=
1531    CbcOrClpParam("perturb!ation","Whether to perturb problem",
1532                  "on",PERTURBATION);
1533  parameters[numberParameters-1].append("off");
1534  parameters[numberParameters-1].setLonghelp
1535    (
1536     "Perturbation helps to stop cycling, but Clp uses other measures for this.\
1537  However large problems and especially ones with unit elements and unit rhs or costs\
1538 benefit from perturbation.  Normally Clp tries to be intelligent, but you can switch this off.\
1539  The Clp library has this off by default.  This program has it on."
1540     ); 
1541  parameters[numberParameters++]=
1542    CbcOrClpParam("PFI","Whether to use Product Form of Inverse in simplex",
1543                  "off",PFI,0,false);
1544  parameters[numberParameters-1].append("on");
1545  parameters[numberParameters-1].setLonghelp
1546    (
1547     "By default clp uses Forrest-Tomlin L-U update.  If you are masochistic you can switch it off."
1548     ); 
1549  parameters[numberParameters++]=
1550    CbcOrClpParam("plus!Minus","Tries to make +- 1 matrix",
1551                  PLUSMINUS,-1,false);
1552  parameters[numberParameters-1].setLonghelp
1553    (
1554     "Clp will go slightly faster if the matrix can be converted so that the elements are\
1555 not stored and are known to be unit.  The main advantage is memory use.  Clp may automatically\
1556 see if it can convert the problem so you should not need to use this."
1557     ); 
1558  parameters[numberParameters++]=
1559    CbcOrClpParam("preO!pt","Presolve options",
1560                  0,INT_MAX,PRESOLVEOPTIONS,false);
1561#endif
1562  parameters[numberParameters++]=
1563    CbcOrClpParam("presolve","Whether to presolve problem",
1564                  "on",PRESOLVE);
1565  parameters[numberParameters-1].append("off");
1566  parameters[numberParameters-1].append("more");
1567  parameters[numberParameters-1].append("file");
1568  parameters[numberParameters-1].setLonghelp
1569    (
1570     "Presolve analyzes the model to find such things as redundant equations, equations\
1571 which fix some variables, equations which can be transformed into bounds etc etc.  For the\
1572 initial solve of any problem this is worth doing unless you know that it will have no effect."
1573     ); 
1574#ifdef COIN_USE_CLP
1575  parameters[numberParameters++]=
1576    CbcOrClpParam("primalP!ivot","Primal pivot choice algorithm",
1577                  "auto!matic",PRIMALPIVOT);
1578  parameters[numberParameters-1].append("exa!ct");
1579  parameters[numberParameters-1].append("dant!zig");
1580  parameters[numberParameters-1].append("part!ial");
1581  parameters[numberParameters-1].append("steep!est");
1582  parameters[numberParameters-1].append("change");
1583  parameters[numberParameters-1].append("sprint");
1584  parameters[numberParameters-1].setLonghelp
1585    (
1586     "Clp can use any pivot selection algorithm which the user codes as long as it\
1587 implements the features in the abstract pivot base class.  The Dantzig method is implemented\
1588 to show a simple method but its use is deprecated.  Exact devex is the method of choice and there\
1589 are two variants which keep all weights updated but only scan a subset each iteration.\
1590 Partial switches this on while change initially does dantzig until the factorization\
1591 becomes denser.  This is still a work in progress."
1592     ); 
1593  parameters[numberParameters++]=
1594    CbcOrClpParam("primalS!implex","Do primal simplex algorithm",
1595                  PRIMALSIMPLEX);
1596  parameters[numberParameters-1].setLonghelp
1597    (
1598     "This command solves the current model using the primal algorithm.\
1599  The default is to use exact devex.\
1600 The time and iterations may be affected by settings such as presolve, scaling, crash\
1601 and also by column selection  method, infeasibility weight and dual and primal tolerances."
1602     );
1603#endif
1604  parameters[numberParameters++]=
1605    CbcOrClpParam("primalT!olerance","For an optimal solution \
1606no primal infeasibility may exceed this value",
1607                  1.0e-20,1.0e12,PRIMALTOLERANCE);
1608  parameters[numberParameters-1].setLonghelp
1609    (
1610     "Normally the default tolerance is fine, but you may want to increase it a\
1611 bit if a primal run seems to be having a hard time"
1612     ); 
1613#ifdef COIN_USE_CLP
1614  parameters[numberParameters++]=
1615    CbcOrClpParam("primalW!eight","Initially algorithm acts as if it \
1616costs this much to be infeasible",
1617                  1.0e-20,1.0e20,PRIMALWEIGHT);
1618  parameters[numberParameters-1].setLonghelp
1619    (
1620     "The primal algorithm in Clp is a single phase algorithm as opposed to a two phase\
1621 algorithm where you first get feasible then optimal.  So Clp is minimizing this weight times\
1622 the sum of primal infeasibilities plus the true objective function (in minimization sense).\
1623  Too high a value may mean more iterations, while too low a bound means\
1624 the code may go all the way and then have to increase the weight in order to get feasible.\
1625  OSL had a heuristic to\
1626 adjust bounds, maybe we need that here."
1627     ); 
1628  parameters[numberParameters++]=
1629    CbcOrClpParam("printO!ptions","Print options",
1630                  0,INT_MAX,PRINTOPTIONS,false);
1631#endif
1632#ifdef COIN_USE_CBC
1633  parameters[numberParameters++]=
1634    CbcOrClpParam("probing!Cuts","Whether to use Probing cuts",
1635                  "off",PROBINGCUTS);
1636  parameters[numberParameters-1].append("on");
1637  parameters[numberParameters-1].append("root");
1638  parameters[numberParameters-1].setLonghelp
1639    (
1640     "TODO"
1641     ); 
1642#endif
1643  parameters[numberParameters++]=
1644    CbcOrClpParam("quit","Stops clp execution",
1645                  EXIT);
1646  parameters[numberParameters-1].setLonghelp
1647    (
1648     "This stops the execution of Clp, end, exit, quit and stop are synonyms"
1649     ); 
1650#ifdef COIN_USE_CLP
1651  parameters[numberParameters++]=
1652    CbcOrClpParam("reallyS!cale","Scales model in place",
1653                  REALLY_SCALE,false);
1654  parameters[numberParameters++]=
1655    CbcOrClpParam("restore!Model","Restore model from binary file",
1656                  RESTORE);
1657  parameters[numberParameters-1].setLonghelp
1658    (
1659     "This reads data save by saveModel from the given file.  It will use the default\
1660 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
1661 is initialized to 'default.prob'."
1662     ); 
1663  parameters[numberParameters++]=
1664    CbcOrClpParam("reverse","Reverses sign of objective",
1665                  REVERSE,false);
1666  parameters[numberParameters-1].setLonghelp
1667    (
1668     "Useful for testing if maximization works correctly"
1669     ); 
1670  parameters[numberParameters++]=
1671    CbcOrClpParam("rhs!Scale","Scale factor to apply to rhs and bounds",
1672                  -1.0e20,1.0e20,RHSSCALE,false);
1673  parameters[numberParameters-1].setLonghelp
1674    (
1675     "If the rhs or bounds have some very large meaningful values, you may wish to scale them\
1676 internally by this amount.  It can also be set by autoscale"
1677     ); 
1678  parameters[numberParameters-1].setDoubleValue(1.0);
1679#endif
1680#ifdef COIN_USE_CBC
1681  parameters[numberParameters++]=
1682    CbcOrClpParam("round!ingHeuristic","Whether to use Rounding heuristic",
1683                  "off",ROUNDING);
1684  parameters[numberParameters-1].append("on");
1685  parameters[numberParameters-1].setLonghelp
1686    (
1687     "TODO"
1688     ); 
1689#endif
1690  parameters[numberParameters++]=
1691    CbcOrClpParam("save!Model","Save model to binary file",
1692                  SAVE);
1693  parameters[numberParameters-1].setLonghelp
1694    (
1695     "This will save the problem to the given file name for future use\
1696 by restoreModel.  It will use the default\
1697 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
1698 is initialized to 'default.prob'."
1699     ); 
1700  parameters[numberParameters++]=
1701    CbcOrClpParam("scal!ing","Whether to scale problem",
1702                  "off",SCALING);
1703  parameters[numberParameters-1].append("equi!librium");
1704  parameters[numberParameters-1].append("geo!metric");
1705  parameters[numberParameters-1].append("auto!matic");
1706  parameters[numberParameters-1].setLonghelp
1707    (
1708     "Scaling can help in solving problems which might otherwise fail because of lack of\
1709 accuracy.  It can also reduce the number of iterations.  It is not applied if the range\
1710 of elements is small.  When unscaled it is possible that there may be small primal and/or\
1711 infeasibilities."
1712     ); 
1713  parameters[numberParameters-1].setCurrentOption(3); // say auto
1714#ifndef COIN_USE_CBC
1715  parameters[numberParameters++]=
1716    CbcOrClpParam("sec!onds","maximum seconds",
1717                  -1.0,1.0e12,TIMELIMIT);
1718  parameters[numberParameters-1].setLonghelp
1719    (
1720     "After this many seconds clp will act as if maximum iterations had been reached.\
1721  In this program it is really only useful for testing but the library function\n\
1722      \tsetMaximumSeconds(value)\n can be useful."
1723     ); 
1724#endif
1725#ifdef COIN_USE_CLP
1726  parameters[numberParameters++]=
1727    CbcOrClpParam("slp!Value","Number of slp passes before primal",
1728                  -1,50000,SLPVALUE,false);
1729#endif
1730  parameters[numberParameters++]=
1731    CbcOrClpParam("solu!tion","Prints solution to file",
1732                  SOLUTION);
1733  parameters[numberParameters-1].setLonghelp
1734    (
1735     "This will write a primitive solution file to the given file name.  It will use the default\
1736 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
1737 is initialized to 'stdout'."
1738     ); 
1739#ifdef COIN_USE_CBC
1740#ifdef COIN_USE_CLP
1741  parameters[numberParameters++]=
1742    CbcOrClpParam("solv!e","Solve problem",
1743                  BAB);
1744  parameters[numberParameters-1].setLonghelp
1745    (
1746     "If there are no integer variables then this just solves LP.  If there are integer variables \
1747this does branch and cut.  Far too many parameters apply to give a full description here.  \
1748the main thing is to think about which cuts to apply.  .. expand ..."
1749     ); 
1750  parameters[numberParameters++]=
1751    CbcOrClpParam("slog!Level","Level of detail in Solver output",
1752                  -1,63,SOLVERLOGLEVEL);
1753  parameters[numberParameters-1].setLonghelp
1754    (
1755     "If 0 then there should be no output in normal circumstances.  1 is probably the best\
1756 value for most uses, while 2 and 3 give more information."
1757     ); 
1758#endif
1759#endif
1760#ifdef COIN_USE_CLP
1761  parameters[numberParameters++]=
1762    CbcOrClpParam("spars!eFactor","Whether factorization treated as sparse",
1763                  "on",SPARSEFACTOR,0,false);
1764  parameters[numberParameters-1].append("off");
1765  parameters[numberParameters++]=
1766    CbcOrClpParam("special!Options","Dubious options for Simplex - see Clpsimplex.hpp",
1767                  0,INT_MAX,SPECIALOPTIONS,false);
1768  parameters[numberParameters++]=
1769    CbcOrClpParam("sprint!Crash","Whether to try sprint crash",
1770                  -1,500,SPRINT);
1771  parameters[numberParameters-1].setLonghelp
1772    (
1773     "For long and thin problems this program may solve a series of small problems\
1774 created by taking a subset of the columns.  I introduced the idea as 'Sprint' after\
1775 an LP code of that name of the 60's which tried the same tactic (not totally successfully).\
1776  Cplex calls it 'sifting'.  -1 is automatic choice, 0 is off, n is number of passes"
1777     ); 
1778#endif
1779  CbcOrClpParam("stdin","From stdin",
1780                STDIN,-1,false);
1781  parameters[numberParameters++]=
1782    CbcOrClpParam("stop","Stops clp execution",
1783                  EXIT);
1784  parameters[numberParameters-1].setLonghelp
1785    (
1786     "This stops the execution of Clp, end, exit, quit and stop are synonyms"
1787     ); 
1788#ifdef COIN_USE_CBC
1789  parameters[numberParameters++]=
1790    CbcOrClpParam("strong!Branching","Number of variables to look at in strong branching",
1791                  0,999999,STRONGBRANCHING);
1792  parameters[numberParameters-1].setLonghelp
1793    (
1794     "TODO"
1795     ); 
1796  parameters[numberParameters++]=
1797    CbcOrClpParam("tighten!Factor","Tighten bounds using this times largest \
1798activity at continuous solution",
1799                  1.0,1.0e20,TIGHTENFACTOR,false);
1800  parameters[numberParameters++] =
1801    CbcOrClpParam("time!Limit","Set a time limit for solving this problem",
1802                  -1.0,(double)(60*60*24*365*10),TIMELIMIT) ;
1803  parameters[numberParameters-1].setLonghelp
1804    (
1805     "TODO"
1806     ); 
1807#endif
1808#ifdef COIN_USE_CLP
1809  parameters[numberParameters++]=
1810    CbcOrClpParam("tightLP","Poor person's preSolve for now",
1811                  TIGHTEN,-1,false);
1812#endif
1813#ifdef COIN_USE_CBC
1814  parameters[numberParameters++]=
1815    CbcOrClpParam("two!MirCuts","Whether to use Two phase Mixed Integer Rounding cuts",
1816                  "off",TWOMIRCUTS);
1817  parameters[numberParameters-1].append("on");
1818  parameters[numberParameters-1].append("root");
1819  parameters[numberParameters-1].setLonghelp
1820    (
1821     "TODO"
1822     ); 
1823#endif
1824  parameters[numberParameters++]=
1825    CbcOrClpParam("unitTest","Do unit test",
1826                  UNITTEST);
1827  parameters[numberParameters-1].setLonghelp
1828    (
1829     "This exercises the unit test for clp"
1830     ); 
1831  assert(numberParameters<CBCMAXPARAMETERS);
1832}
1833// Given a parameter type - returns its number in list
1834int whichParam (CbcOrClpParameterType name, 
1835                int numberParameters, CbcOrClpParam *const parameters)
1836{
1837  int i;
1838  for (i=0;i<numberParameters;i++) {
1839    if (parameters[i].type()==name)
1840      break;
1841  }
1842  assert (i<numberParameters);
1843  return i;
1844}
Note: See TracBrowser for help on using the repository browser.