source: trunk/Clp/src/CbcOrClpParam.cpp @ 799

Last change on this file since 799 was 799, checked in by andreasw, 14 years ago

undid last commit (patches incorrectly applied)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 82.4 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 "CbcOrClpParam.hpp"
9
10#include <string>
11#include <iostream>
12#include <cassert>
13
14#ifdef COIN_HAS_CBC
15#include "OsiClpSolverInterface.hpp"
16#include "ClpSimplex.hpp"
17#include "CbcModel.hpp"
18#endif
19#ifdef COIN_HAS_CLP
20#ifndef COIN_HAS_CLP
21#define COIN_HAS_CLP
22#endif
23#endif
24#ifdef COIN_HAS_CLP
25#include "ClpSimplex.hpp"
26#include "ClpFactorization.hpp"
27#endif
28#ifdef COIN_HAS_READLINE     
29#include <readline/readline.h>
30#include <readline/history.h>
31#endif
32#ifdef COIN_HAS_OSICLP
33// from CoinSolve
34static char coin_prompt[]="Coin:";
35#else
36static char coin_prompt[]="Clp:";
37#endif
38static bool doPrinting=true;
39std::string afterEquals="";
40void setCbcOrClpPrinting(bool yesNo)
41{
42  doPrinting=yesNo;
43}
44//#############################################################################
45// Constructors / Destructor / Assignment
46//#############################################################################
47
48//-------------------------------------------------------------------
49// Default Constructor
50//-------------------------------------------------------------------
51CbcOrClpParam::CbcOrClpParam () 
52  : type_(INVALID),
53    lowerDoubleValue_(0.0),
54    upperDoubleValue_(0.0),
55    lowerIntValue_(0),
56    upperIntValue_(0),
57    lengthName_(0),
58    lengthMatch_(0),
59    definedKeyWords_(),
60    name_(),
61    shortHelp_(),
62    longHelp_(),
63    action_(INVALID),
64    currentKeyWord_(-1),
65    display_(false),
66    intValue_(-1),
67    doubleValue_(-1.0),
68    stringValue_(""),
69    whereUsed_(7)
70{
71}
72// Other constructors
73CbcOrClpParam::CbcOrClpParam (std::string name, std::string help,
74           double lower, double upper, CbcOrClpParameterType type,
75                    bool display)
76  : type_(type),
77    lowerIntValue_(0),
78    upperIntValue_(0),
79    definedKeyWords_(),
80    name_(name),
81    shortHelp_(help),
82    longHelp_(),
83    action_(type),
84    currentKeyWord_(-1),
85    display_(display),
86    intValue_(-1),
87    doubleValue_(-1.0),
88    stringValue_(""),
89    whereUsed_(7)
90{
91  lowerDoubleValue_ = lower;
92  upperDoubleValue_ = upper;
93  gutsOfConstructor();
94}
95CbcOrClpParam::CbcOrClpParam (std::string name, std::string help,
96           int lower, int upper, CbcOrClpParameterType type,
97                    bool display)
98  : type_(type),
99    lowerDoubleValue_(0.0),
100    upperDoubleValue_(0.0),
101    definedKeyWords_(),
102    name_(name),
103    shortHelp_(help),
104    longHelp_(),
105    action_(type),
106    currentKeyWord_(-1),
107    display_(display),
108    intValue_(-1),
109    doubleValue_(-1.0),
110    stringValue_(""),
111    whereUsed_(7)
112{
113  gutsOfConstructor();
114  lowerIntValue_ = lower;
115  upperIntValue_ = upper;
116}
117// Other strings will be added by append
118CbcOrClpParam::CbcOrClpParam (std::string name, std::string help, 
119                    std::string firstValue,
120                    CbcOrClpParameterType type,int whereUsed,
121                    bool display)
122  : type_(type),
123    lowerDoubleValue_(0.0),
124    upperDoubleValue_(0.0),
125    lowerIntValue_(0),
126    upperIntValue_(0),
127    definedKeyWords_(),
128    name_(name),
129    shortHelp_(help),
130    longHelp_(),
131    action_(type),
132    currentKeyWord_(0),
133    display_(display),
134    intValue_(-1),
135    doubleValue_(-1.0),
136    stringValue_(""),
137    whereUsed_(whereUsed)
138{
139  gutsOfConstructor();
140  definedKeyWords_.push_back(firstValue);
141}
142// Action
143CbcOrClpParam::CbcOrClpParam (std::string name, std::string help,
144                    CbcOrClpParameterType type,int whereUsed,
145                    bool display)
146  : type_(type),
147    lowerDoubleValue_(0.0),
148    upperDoubleValue_(0.0),
149    lowerIntValue_(0),
150    upperIntValue_(0),
151    definedKeyWords_(),
152    name_(name),
153    shortHelp_(help),
154    longHelp_(),
155    action_(type),
156    currentKeyWord_(-1),
157    display_(display),
158    intValue_(-1),
159    doubleValue_(-1.0),
160    stringValue_("")
161{
162  whereUsed_=whereUsed;
163  gutsOfConstructor();
164}
165
166//-------------------------------------------------------------------
167// Copy constructor
168//-------------------------------------------------------------------
169CbcOrClpParam::CbcOrClpParam (const CbcOrClpParam & rhs) 
170{ 
171  type_ = rhs.type_;
172  lowerDoubleValue_ = rhs.lowerDoubleValue_;
173  upperDoubleValue_ = rhs.upperDoubleValue_;
174  lowerIntValue_ = rhs.lowerIntValue_;
175  upperIntValue_ = rhs.upperIntValue_;
176  lengthName_ = rhs.lengthName_;
177  lengthMatch_ = rhs.lengthMatch_;
178  definedKeyWords_ = rhs.definedKeyWords_;
179  name_ = rhs.name_;
180  shortHelp_ = rhs.shortHelp_;
181  longHelp_ = rhs.longHelp_;
182  action_ = rhs.action_;
183  currentKeyWord_ = rhs.currentKeyWord_;
184  display_=rhs.display_;
185  intValue_=rhs.intValue_;
186  doubleValue_=rhs.doubleValue_;
187  stringValue_=rhs.stringValue_;
188  whereUsed_=rhs.whereUsed_;
189}
190
191//-------------------------------------------------------------------
192// Destructor
193//-------------------------------------------------------------------
194CbcOrClpParam::~CbcOrClpParam ()
195{
196}
197
198//----------------------------------------------------------------
199// Assignment operator
200//-------------------------------------------------------------------
201CbcOrClpParam &
202CbcOrClpParam::operator=(const CbcOrClpParam& rhs)
203{
204  if (this != &rhs) {
205    type_ = rhs.type_;
206    lowerDoubleValue_ = rhs.lowerDoubleValue_;
207    upperDoubleValue_ = rhs.upperDoubleValue_;
208    lowerIntValue_ = rhs.lowerIntValue_;
209    upperIntValue_ = rhs.upperIntValue_;
210    lengthName_ = rhs.lengthName_;
211    lengthMatch_ = rhs.lengthMatch_;
212    definedKeyWords_ = rhs.definedKeyWords_;
213    name_ = rhs.name_;
214    shortHelp_ = rhs.shortHelp_;
215    longHelp_ = rhs.longHelp_;
216    action_ = rhs.action_;
217    currentKeyWord_ = rhs.currentKeyWord_;
218    display_=rhs.display_;
219    intValue_=rhs.intValue_;
220    doubleValue_=rhs.doubleValue_;
221    stringValue_=rhs.stringValue_;
222    whereUsed_=rhs.whereUsed_;
223  }
224  return *this;
225}
226void 
227CbcOrClpParam::gutsOfConstructor()
228{
229  std::string::size_type  shriekPos = name_.find('!');
230  lengthName_ = name_.length();
231  if ( shriekPos==std::string::npos ) {
232    //does not contain '!'
233    lengthMatch_= lengthName_;
234  } else {
235    lengthMatch_=shriekPos;
236    name_ = name_.substr(0,shriekPos)+name_.substr(shriekPos+1);
237    lengthName_--;
238  }
239}
240// Insert string (only valid for keywords)
241void 
242CbcOrClpParam::append(std::string keyWord)
243{
244  definedKeyWords_.push_back(keyWord);
245}
246
247int 
248CbcOrClpParam::matches (std::string input) const
249{
250  // look up strings to do more elegantly
251  if (input.length()>lengthName_) {
252    return 0;
253  } else {
254    unsigned int i;
255    for (i=0;i<input.length();i++) {
256      if (tolower(name_[i])!=tolower(input[i])) 
257        break;
258    }
259    if (i<input.length()) {
260      return 0;
261    } else if (i>=lengthMatch_) {
262      return 1;
263    } else {
264      // matched but too short
265      return 2;
266    }
267  }
268}
269// Returns name which could match
270std::string
271CbcOrClpParam::matchName (  ) const
272{ 
273  if (lengthMatch_==lengthName_) 
274    return name_;
275  else
276    return name_.substr(0,lengthMatch_)+"("+name_.substr(lengthMatch_)+")";
277}
278
279// Returns parameter option which matches (-1 if none)
280int 
281CbcOrClpParam::parameterOption ( std::string check ) const
282{
283  int numberItems = definedKeyWords_.size();
284  if (!numberItems) {
285    return -1;
286  } else {
287    int whichItem=0;
288    unsigned int it;
289    for (it=0;it<definedKeyWords_.size();it++) {
290      std::string thisOne = definedKeyWords_[it];
291      std::string::size_type  shriekPos = thisOne.find('!');
292      unsigned int length1 = thisOne.length();
293      unsigned int length2 = length1;
294      if ( shriekPos!=std::string::npos ) {
295        //contains '!'
296        length2 = shriekPos;
297        thisOne = thisOne.substr(0,shriekPos)+
298          thisOne.substr(shriekPos+1);
299        length1 = thisOne.length();
300      }
301      if (check.length()<=length1&&length2<=check.length()) {
302        unsigned int i;
303        for (i=0;i<check.length();i++) {
304          if (tolower(thisOne[i])!=tolower(check[i])) 
305            break;
306        }
307        if (i<check.length()) {
308          whichItem++;
309        } else if (i>=length2) {
310          break;
311        } 
312      } else {
313        whichItem++;
314      }
315    }
316    if (whichItem<numberItems)
317      return whichItem;
318    else
319      return -1;
320  }
321}
322// Prints parameter options
323void 
324CbcOrClpParam::printOptions (  ) const
325{
326  std::cout<<"<Possible options for "<<name_<<" are:";
327  unsigned int it;
328  for (it=0;it<definedKeyWords_.size();it++) {
329    std::string thisOne = definedKeyWords_[it];
330    std::string::size_type  shriekPos = thisOne.find('!');
331    if ( shriekPos!=std::string::npos ) {
332      //contains '!'
333      thisOne = thisOne.substr(0,shriekPos)+
334        "("+thisOne.substr(shriekPos+1)+")";
335    }
336    std::cout<<" "<<thisOne;
337  }
338  assert (currentKeyWord_>=0&&currentKeyWord_<(int)definedKeyWords_.size());
339  std::string current = definedKeyWords_[currentKeyWord_];
340  std::string::size_type  shriekPos = current.find('!');
341  if ( shriekPos!=std::string::npos ) {
342    //contains '!'
343    current = current.substr(0,shriekPos)+
344      "("+current.substr(shriekPos+1)+")";
345  }
346  std::cout<<";\n\tcurrent  "<<current<<">"<<std::endl;
347}
348// Print action and string
349void 
350CbcOrClpParam::printString() const
351{
352  if (name_=="directory")
353    std::cout<<"Current working directory is "<<stringValue_<<std::endl;
354  else if (name_=="printM!ask")
355    std::cout<<"Current value of printMask is "<<stringValue_<<std::endl;
356  else
357    std::cout<<"Current default (if $ as parameter) for "<<name_
358             <<" is "<<stringValue_<<std::endl;
359}
360void CoinReadPrintit(const char * input)
361{
362  int length =strlen(input);
363  char temp[101];
364  int i;
365  int n=0;
366  for (i=0;i<length;i++) {
367    if (input[i]=='\n') {
368      temp[n]='\0';
369      std::cout<<temp<<std::endl;
370      n=0;
371    } else if (n>=65&&input[i]==' ') {
372      temp[n]='\0';
373      std::cout<<temp<<std::endl;
374      n=0;
375    } else if (n||input[i]!=' ') {
376      temp[n++]=input[i];
377    }
378  }
379  if (n) {
380    temp[n]='\0';
381    std::cout<<temp<<std::endl;
382  }
383}
384// Print Long help
385void 
386CbcOrClpParam::printLongHelp() const
387{
388  if (type_>=1&&type_<400) {
389    CoinReadPrintit(longHelp_.c_str());
390    if (type_<SOLVERLOGLEVEL) {
391      printf("<Range of values is %g to %g;\n\tcurrent %g>\n",lowerDoubleValue_,upperDoubleValue_, doubleValue_);
392      assert (upperDoubleValue_>lowerDoubleValue_);
393    } else if (type_<DIRECTION) {
394      printf("<Range of values is %d to %d;\n\tcurrent %d>\n",lowerIntValue_,upperIntValue_,intValue_);
395      assert (upperIntValue_>lowerIntValue_);
396    } else if (type_<DIRECTORY) {
397      printOptions();
398    }
399  }
400}
401#ifdef COIN_HAS_CBC
402int
403CbcOrClpParam::setDoubleParameter (OsiSolverInterface * model,double value) 
404{
405  if (value<lowerDoubleValue_||value>upperDoubleValue_) {
406    std::cout<<value<<" was provided for "<<name_<<
407      " - valid range is "<<lowerDoubleValue_<<" to "<<
408      upperDoubleValue_<<std::endl;
409    return 1;
410  } else {
411    double oldValue=doubleValue_;
412    doubleValue_=value;
413    switch(type_) {
414    case DUALTOLERANCE:
415      model->getDblParam(OsiDualTolerance,oldValue);
416      model->setDblParam(OsiDualTolerance,value);
417      break;
418    case PRIMALTOLERANCE:
419      model->getDblParam(OsiPrimalTolerance,oldValue);
420      model->setDblParam(OsiPrimalTolerance,value);
421      break;
422    default:
423      break;
424    }
425    if (doPrinting)
426      std::cout<<name_<<" was changed from "<<oldValue<<" to "
427               <<value<<std::endl;
428    return 0;
429  }
430}
431#endif
432#ifdef COIN_HAS_CLP
433int
434CbcOrClpParam::setDoubleParameter (ClpSimplex * model,double value) 
435{
436  double oldValue = doubleValue_;
437  if (value<lowerDoubleValue_||value>upperDoubleValue_) {
438    std::cout<<value<<" was provided for "<<name_<<
439      " - valid range is "<<lowerDoubleValue_<<" to "<<
440      upperDoubleValue_<<std::endl;
441    return 1;
442  } else {
443    if (doPrinting)
444      std::cout<<name_<<" was changed from "<<oldValue<<" to "
445               <<value<<std::endl;
446    doubleValue_=value;
447    switch(type_) {
448#ifndef COIN_HAS_CBC
449    case DUALTOLERANCE:
450      model->setDualTolerance(value);
451      break;
452    case PRIMALTOLERANCE:
453      model->setPrimalTolerance(value);
454      break;
455#endif
456    case DUALBOUND:
457      model->setDualBound(value);
458      break;
459    case PRIMALWEIGHT:
460      model->setInfeasibilityCost(value);
461      break;
462#ifndef COIN_HAS_CBC
463    case TIMELIMIT:
464      model->setMaximumSeconds(value);
465      break;
466#endif
467    case OBJSCALE:
468      model->setObjectiveScale(value);
469      break;
470    case RHSSCALE:
471      model->setRhsScale(value);
472      break;
473    case PRESOLVETOLERANCE:
474      model->setDblParam(ClpPresolveTolerance,value);
475      break;
476    default:
477      break;
478    }
479    return 0;
480  }
481}
482double 
483CbcOrClpParam::doubleParameter (ClpSimplex * model) const
484{
485  double value;
486  switch(type_) {
487#ifndef COIN_HAS_CBC
488  case DUALTOLERANCE:
489    value=model->dualTolerance();
490    break;
491  case PRIMALTOLERANCE:
492    value=model->primalTolerance();
493    break;
494#endif
495  case DUALBOUND:
496    value=model->dualBound();
497    break;
498  case PRIMALWEIGHT:
499    value=model->infeasibilityCost();
500    break;
501#ifndef COIN_HAS_CBC
502  case TIMELIMIT:
503    value=model->maximumSeconds();
504    break;
505#endif
506  case OBJSCALE:
507    value=model->objectiveScale();
508    break;
509  case RHSSCALE:
510    value=model->rhsScale();
511    break;
512  default:
513    value=doubleValue_;
514    break;
515  }
516  return value;
517}
518int 
519CbcOrClpParam::setIntParameter (ClpSimplex * model,int value) 
520{
521  int oldValue = intValue_;
522  if (value<lowerIntValue_||value>upperIntValue_) {
523    std::cout<<value<<" was provided for "<<name_<<
524      " - valid range is "<<lowerIntValue_<<" to "<<
525      upperIntValue_<<std::endl;
526    return 1;
527  } else {
528    intValue_=value;
529    if (doPrinting)
530      std::cout<<name_<<" was changed from "<<oldValue<<" to "
531               <<value<<std::endl;
532    switch(type_) {
533    case SOLVERLOGLEVEL:
534      model->setLogLevel(value);
535      if (value>2)
536        model->factorization()->messageLevel(8);
537      else
538        model->factorization()->messageLevel(0);
539      break;
540    case MAXFACTOR:
541      model->factorization()->maximumPivots(value);
542      break;
543    case PERTVALUE:
544      model->setPerturbation(value);
545      break;
546    case MAXITERATION:
547      model->setMaximumIterations(value);
548      break;
549    case SPECIALOPTIONS:
550      model->setSpecialOptions(value);
551    case THREADS:
552      model->setNumberThreads(value);
553      break;
554    default:
555      break;
556    }
557    return 0;
558  }
559}
560int 
561CbcOrClpParam::intParameter (ClpSimplex * model) const
562{
563  int value;
564  switch(type_) {
565#ifndef COIN_HAS_CBC
566  case SOLVERLOGLEVEL:
567    value=model->logLevel();
568    break;
569#endif
570  case MAXFACTOR:
571    value=model->factorization()->maximumPivots();
572    break;
573    break;
574  case PERTVALUE:
575    value=model->perturbation();
576    break;
577  case MAXITERATION:
578    value=model->maximumIterations();
579    break;
580  case SPECIALOPTIONS:
581    value=model->specialOptions();
582    break;
583  case THREADS:
584    value = model->numberThreads();
585  default:
586    value=intValue_;
587    break;
588  }
589  return value;
590}
591#endif
592int
593CbcOrClpParam::checkDoubleParameter (double value) const
594{
595  if (value<lowerDoubleValue_||value>upperDoubleValue_) {
596    std::cout<<value<<" was provided for "<<name_<<
597      " - valid range is "<<lowerDoubleValue_<<" to "<<
598      upperDoubleValue_<<std::endl;
599    return 1;
600  } else {
601    return 0;
602  }
603}
604#ifdef COIN_HAS_CBC
605double 
606CbcOrClpParam::doubleParameter (OsiSolverInterface * model) const
607{
608  double value;
609  switch(type_) {
610  case DUALTOLERANCE:
611    assert(model->getDblParam(OsiDualTolerance,value));
612    break;
613  case PRIMALTOLERANCE:
614    assert(model->getDblParam(OsiPrimalTolerance,value));
615    break;
616  default:
617    return doubleValue_;
618    break;
619  }
620  return value;
621}
622int 
623CbcOrClpParam::setIntParameter (OsiSolverInterface * model,int value) 
624{
625  if (value<lowerIntValue_||value>upperIntValue_) {
626    std::cout<<value<<" was provided for "<<name_<<
627      " - valid range is "<<lowerIntValue_<<" to "<<
628      upperIntValue_<<std::endl;
629    return 1;
630  } else {
631    int oldValue=intValue_;
632    intValue_=oldValue;
633    switch(type_) {
634    case SOLVERLOGLEVEL:
635      model->messageHandler()->setLogLevel(value);
636      break;
637    default:
638      break;
639    }
640    if (doPrinting)
641      std::cout<<name_<<" was changed from "<<oldValue<<" to "
642               <<value<<std::endl;
643    return 0;
644  }
645}
646int 
647CbcOrClpParam::intParameter (OsiSolverInterface * model) const
648{
649  int value=0;
650  switch(type_) {
651  case SOLVERLOGLEVEL:
652    value=model->messageHandler()->logLevel();
653    break;
654  default:
655    value=intValue_;
656    break;
657  }
658  return value;
659}
660int
661CbcOrClpParam::setDoubleParameter (CbcModel &model,double value) 
662{
663  if (value<lowerDoubleValue_||value>upperDoubleValue_) {
664    std::cout<<value<<" was provided for "<<name_<<
665      " - valid range is "<<lowerDoubleValue_<<" to "<<
666      upperDoubleValue_<<std::endl;
667    return 1;
668  } else {
669    double oldValue=doubleValue_;
670    doubleValue_ = value;
671    switch(type_) {
672    case INFEASIBILITYWEIGHT:
673      oldValue=model.getDblParam(CbcModel::CbcInfeasibilityWeight);
674      model.setDblParam(CbcModel::CbcInfeasibilityWeight,value);
675      break;
676    case INTEGERTOLERANCE:
677      oldValue=model.getDblParam(CbcModel::CbcIntegerTolerance);
678      model.setDblParam(CbcModel::CbcIntegerTolerance,value);
679      break;
680    case INCREMENT:
681      oldValue=model.getDblParam(CbcModel::CbcCutoffIncrement);
682      model.setDblParam(CbcModel::CbcCutoffIncrement,value);
683    case ALLOWABLEGAP:
684      oldValue=model.getDblParam(CbcModel::CbcAllowableGap);
685      model.setDblParam(CbcModel::CbcAllowableGap,value);
686      break;
687    case CUTOFF:
688      oldValue=model.getCutoff();
689      model.setCutoff(value);
690      break;
691    case TIMELIMIT_BAB:
692      oldValue = model.getDblParam(CbcModel::CbcMaximumSeconds) ;
693      {
694        //OsiClpSolverInterface * clpSolver = dynamic_cast< OsiClpSolverInterface*> (model.solver());
695        //ClpSimplex * lpSolver = clpSolver->getModelPtr();
696        //lpSolver->setMaximumSeconds(value);
697        model.setDblParam(CbcModel::CbcMaximumSeconds,value) ;
698      }
699      break ;
700    case DUALTOLERANCE:
701    case PRIMALTOLERANCE:
702      setDoubleParameter(model.solver(),value);
703      return 0; // to avoid message
704    default:
705      break;
706    }
707    if (doPrinting)
708      std::cout<<name_<<" was changed from "<<oldValue<<" to "
709               <<value<<std::endl;
710    return 0;
711  }
712}
713double 
714CbcOrClpParam::doubleParameter (CbcModel &model) const
715{
716  double value;
717  switch(type_) {
718  case INFEASIBILITYWEIGHT:
719    value=model.getDblParam(CbcModel::CbcInfeasibilityWeight);
720    break;
721  case INTEGERTOLERANCE:
722    value=model.getDblParam(CbcModel::CbcIntegerTolerance);
723    break;
724  case INCREMENT:
725    value=model.getDblParam(CbcModel::CbcCutoffIncrement);
726  case ALLOWABLEGAP:
727    value=model.getDblParam(CbcModel::CbcAllowableGap);
728    break;
729  case CUTOFF:
730    value=model.getCutoff();
731    break;
732  case TIMELIMIT_BAB:
733    value = model.getDblParam(CbcModel::CbcMaximumSeconds) ;
734    break ;
735  case DUALTOLERANCE:
736  case PRIMALTOLERANCE:
737    value=doubleParameter(model.solver());
738    break;
739  default:
740    value = doubleValue_;
741    break;
742  }
743  return value;
744}
745int 
746CbcOrClpParam::setIntParameter (CbcModel &model,int value) 
747{
748  if (value<lowerIntValue_||value>upperIntValue_) {
749    std::cout<<value<<" was provided for "<<name_<<
750      " - valid range is "<<lowerIntValue_<<" to "<<
751      upperIntValue_<<std::endl;
752    return 1;
753  } else {
754    int oldValue=intValue_;
755    intValue_ = value;
756    switch(type_) {
757    case LOGLEVEL:
758      oldValue = model.messageHandler()->logLevel();
759      model.messageHandler()->setLogLevel(value);
760      break;
761    case SOLVERLOGLEVEL:
762      oldValue = model.solver()->messageHandler()->logLevel();
763      model.solver()->messageHandler()->setLogLevel(value);
764      break;
765    case MAXNODES:
766      oldValue=model.getIntParam(CbcModel::CbcMaxNumNode);
767      model.setIntParam(CbcModel::CbcMaxNumNode,value);
768      break;
769    case STRONGBRANCHING:
770      oldValue=model.numberStrong();
771      model.setNumberStrong(value);
772      break;
773    case NUMBERBEFORE:
774      oldValue=model.numberBeforeTrust();
775      model.setNumberBeforeTrust(value);
776      break;
777    case NUMBERANALYZE:
778      oldValue=model.numberAnalyzeIterations();
779      model.setNumberAnalyzeIterations(value);
780      break;
781    case NUMBERMINI:
782      oldValue=model.sizeMiniTree();
783      model.setSizeMiniTree(value);
784      break;
785    default:
786      break;
787    }
788    if (doPrinting)
789      std::cout<<name_<<" was changed from "<<oldValue<<" to "
790               <<value<<std::endl;
791    return 0;
792  }
793}
794int 
795CbcOrClpParam::intParameter (CbcModel &model) const
796{
797  int value;
798  switch(type_) {
799  case LOGLEVEL:
800    value = model.messageHandler()->logLevel();
801      break;
802  case SOLVERLOGLEVEL:
803    value = model.solver()->messageHandler()->logLevel();
804      break;
805  case MAXNODES:
806    value = model.getIntParam(CbcModel::CbcMaxNumNode);
807    break;
808  case STRONGBRANCHING:
809    value=model.numberStrong();
810    break;
811  case NUMBERBEFORE:
812    value=model.numberBeforeTrust();
813    break;
814  case NUMBERANALYZE:
815    value=model.numberAnalyzeIterations();
816    break;
817  case NUMBERMINI:
818    value=model.sizeMiniTree();
819    break;
820  default:
821    value=intValue_;
822    break;
823  }
824  return value;
825}
826#endif
827// Sets current parameter option using string
828void 
829CbcOrClpParam::setCurrentOption ( const std::string value )
830{
831  int action = parameterOption(value);
832  if (action>=0)
833    currentKeyWord_=action;
834}
835// Sets current parameter option
836void 
837CbcOrClpParam::setCurrentOption ( int value , bool printIt)
838{
839  if (printIt&&value!=currentKeyWord_)
840    std::cout<<"Option for "<<name_<<" changed from "
841             <<definedKeyWords_[currentKeyWord_]<<" to "
842             <<definedKeyWords_[value]<<std::endl;
843
844    currentKeyWord_=value;
845}
846void 
847CbcOrClpParam::setIntValue ( int value )
848{ 
849  if (value<lowerIntValue_||value>upperIntValue_) {
850    std::cout<<value<<" was provided for "<<name_<<
851      " - valid range is "<<lowerIntValue_<<" to "<<
852      upperIntValue_<<std::endl;
853  } else {
854    intValue_=value;
855  }
856}
857void 
858CbcOrClpParam::setDoubleValue ( double value )
859{ 
860  if (value<lowerDoubleValue_||value>upperDoubleValue_) {
861    std::cout<<value<<" was provided for "<<name_<<
862      " - valid range is "<<lowerDoubleValue_<<" to "<<
863      upperDoubleValue_<<std::endl;
864  } else {
865    doubleValue_=value;
866  }
867}
868void 
869CbcOrClpParam::setStringValue ( std::string value )
870{ 
871  stringValue_=value;
872}
873static char line[1000];
874static char * where=NULL;
875extern int CbcOrClpRead_mode;
876extern FILE * CbcOrClpReadCommand;
877// Simple read stuff
878std::string
879CoinReadNextField()
880{
881  std::string field;
882  if (!where) {
883    // need new line
884#ifdef COIN_HAS_READLINE     
885    if (CbcOrClpReadCommand==stdin) {
886      // Get a line from the user.
887      where = readline (coin_prompt);
888     
889      // If the line has any text in it, save it on the history.
890      if (where) {
891        if ( *where)
892          add_history (where);
893        strcpy(line,where);
894        free(where);
895      }
896    } else {
897      where = fgets(line,1000,CbcOrClpReadCommand);
898    }
899#else
900    if (CbcOrClpReadCommand==stdin) {
901      fprintf(stdout,coin_prompt);
902      fflush(stdout);
903    }
904    where = fgets(line,1000,CbcOrClpReadCommand);
905#endif
906    if (!where)
907      return field; // EOF
908    where = line;
909    // clean image
910    char * lastNonBlank = line-1;
911    while ( *where != '\0' ) {
912      if ( *where != '\t' && *where < ' ' ) {
913        break;
914      } else if ( *where != '\t' && *where != ' ') {
915        lastNonBlank = where;
916      }
917      where++;
918    }
919    where=line;
920    *(lastNonBlank+1)='\0';
921  }
922  // munch white space
923  while(*where==' '||*where=='\t')
924    where++;
925  char * saveWhere = where;
926  while (*where!=' '&&*where!='\t'&&*where!='\0')
927    where++;
928  if (where!=saveWhere) {
929    char save = *where;
930    *where='\0';
931    //convert to string
932    field=saveWhere;
933    *where=save;
934  } else {
935    where=NULL;
936    field="EOL";
937  }
938  return field;
939}
940
941std::string
942CoinReadGetCommand(int argc, const char *argv[])
943{
944  std::string field="EOL";
945  // say no =
946  afterEquals="";
947  while (field=="EOL") {
948    if (CbcOrClpRead_mode>0) {
949      if (CbcOrClpRead_mode<argc) {
950        field = argv[CbcOrClpRead_mode++];
951        if (field=="-") {
952          std::cout<<"Switching to line mode"<<std::endl;
953          CbcOrClpRead_mode=-1;
954          field=CoinReadNextField();
955        } else if (field[0]!='-') {
956          if (CbcOrClpRead_mode!=2) {
957            // now allow std::cout<<"skipping non-command "<<field<<std::endl;
958            // field="EOL"; // skip
959          } else {
960            // special dispensation - taken as -import name
961            CbcOrClpRead_mode--;
962            field="import";
963          }
964        } else {
965          if (field!="--") {
966            // take off -
967            field = field.substr(1);
968          } else {
969            // special dispensation - taken as -import --
970            CbcOrClpRead_mode--;
971            field="import";
972          }
973        }
974      } else {
975        field="";
976      }
977    } else {
978      field=CoinReadNextField();
979    }
980  }
981  // if = then modify and save
982  std::string::size_type found = field.find('=');
983  if (found!=std::string::npos) {
984    afterEquals = field.substr(found+1);
985    field = field.substr(0,found);
986  }
987  //std::cout<<field<<std::endl;
988  return field;
989}
990std::string
991CoinReadGetString(int argc, const char *argv[])
992{
993  std::string field="EOL";
994  if (afterEquals=="") {
995    if (CbcOrClpRead_mode>0) {
996      if (CbcOrClpRead_mode<argc) {
997        if (argv[CbcOrClpRead_mode][0]!='-') { 
998          field = argv[CbcOrClpRead_mode++];
999        } else if (!strcmp(argv[CbcOrClpRead_mode],"--")) {
1000          field = argv[CbcOrClpRead_mode++];
1001          // -- means import from stdin
1002          field = "-";
1003        }
1004      }
1005    } else {
1006      field=CoinReadNextField();
1007    }
1008  } else {
1009    field=afterEquals;
1010    afterEquals = "";
1011  }
1012  //std::cout<<field<<std::endl;
1013  return field;
1014}
1015// valid 0 - okay, 1 bad, 2 not there
1016int
1017CoinReadGetIntField(int argc, const char *argv[],int * valid)
1018{
1019  std::string field="EOL";
1020  if (afterEquals=="") {
1021    if (CbcOrClpRead_mode>0) {
1022      if (CbcOrClpRead_mode<argc) {
1023        // may be negative value so do not check for -
1024        field = argv[CbcOrClpRead_mode++];
1025      }
1026    } else {
1027      field=CoinReadNextField();
1028    }
1029  } else {
1030    field=afterEquals;
1031    afterEquals = "";
1032  }
1033  int value=0;
1034  //std::cout<<field<<std::endl;
1035  if (field!="EOL") {
1036    // how do I check valid
1037    value =  atoi(field.c_str());
1038    *valid=0;
1039  } else {
1040    *valid=2;
1041  }
1042  return value;
1043}
1044double
1045CoinReadGetDoubleField(int argc, const char *argv[],int * valid)
1046{
1047  std::string field="EOL";
1048  if (afterEquals=="") {
1049    if (CbcOrClpRead_mode>0) {
1050      if (CbcOrClpRead_mode<argc) {
1051        // may be negative value so do not check for -
1052        field = argv[CbcOrClpRead_mode++];
1053      }
1054    } else {
1055      field=CoinReadNextField();
1056    }
1057  } else {
1058    field=afterEquals;
1059    afterEquals = "";
1060  }
1061  double value=0.0;
1062  //std::cout<<field<<std::endl;
1063  if (field!="EOL") {
1064    // how do I check valid
1065    value = atof(field.c_str());
1066    *valid=0;
1067  } else {
1068    *valid=2;
1069  }
1070  return value;
1071}
1072/*
1073  Subroutine to establish the cbc parameter array. See the description of
1074  class CbcOrClpParam for details. Pulled from C..Main() for clarity.
1075*/
1076void 
1077establishParams (int &numberParameters, CbcOrClpParam *const parameters)
1078{
1079  numberParameters=0;
1080  parameters[numberParameters++]=
1081    CbcOrClpParam("?","For help",GENERALQUERY,7,false);
1082  parameters[numberParameters++]=
1083    CbcOrClpParam("???","For help",FULLGENERALQUERY,7,false);
1084  parameters[numberParameters++]=
1085    CbcOrClpParam("-","From stdin",
1086                  STDIN,3,false);
1087#ifdef COIN_HAS_CBC
1088    parameters[numberParameters++]=
1089      CbcOrClpParam("allow!ableGap","Stop when gap between best possible and \
1090best less than this",
1091              0.0,1.0e20,ALLOWABLEGAP);
1092  parameters[numberParameters-1].setDoubleValue(0.0);
1093  parameters[numberParameters-1].setLonghelp
1094    (
1095     "If the gap between best solution and best possible solution is less than this \
1096then the search will be terminated.  Also see gapRatio."
1097     ); 
1098#endif
1099#ifdef COIN_HAS_CLP
1100  parameters[numberParameters++]=
1101    CbcOrClpParam("allS!lack","Set basis back to all slack and reset solution",
1102                  ALLSLACK,3);
1103  parameters[numberParameters-1].setLonghelp
1104    (
1105     "Mainly useful for tuning purposes.  Normally the first dual or primal will be using an all slack \
1106basis anyway."
1107     ); 
1108  parameters[numberParameters++]=
1109    CbcOrClpParam("auto!Scale","Whether to scale objective, rhs and bounds of problem if they look odd",
1110                  "off",AUTOSCALE,7,false);
1111  parameters[numberParameters-1].append("on");
1112  parameters[numberParameters-1].setLonghelp
1113    (
1114     "If you think you may get odd objective values or large equality rows etc then\
1115 it may be worth setting this true.  It is still experimental and you may prefer\
1116 to use objective!Scale and rhs!Scale"
1117     ); 
1118  parameters[numberParameters++]=
1119    CbcOrClpParam("barr!ier","Solve using primal dual predictor corrector algorithm",
1120                  BARRIER);
1121  parameters[numberParameters-1].setLonghelp
1122    (
1123     "This command solves the current model using the  primal dual predictor \
1124corrector algorithm.  You will probably want to link in and choose a better \
1125ordering and factorization than the default ones provided.  It will also solve models \
1126with quadratic objectives."
1127     
1128     ); 
1129  parameters[numberParameters++]=
1130    CbcOrClpParam("basisI!n","Import basis from bas file",
1131                  BASISIN,3);
1132  parameters[numberParameters-1].setLonghelp
1133    (
1134     "This will read an MPS format basis file from the given file name.  It will use the default\
1135 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
1136 is initialized to '', i.e. it must be set.  If you have libz then it can read compressed\
1137 files 'xxxxxxxx.gz'.."
1138     ); 
1139  parameters[numberParameters++]=
1140    CbcOrClpParam("basisO!ut","Export basis as bas file",
1141                  BASISOUT);
1142  parameters[numberParameters-1].setLonghelp
1143    (
1144     "This will write an MPS format basis file to the given file name.  It will use the default\
1145 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
1146 is initialized to 'default.bas'."
1147     ); 
1148  parameters[numberParameters++]=
1149    CbcOrClpParam("biasLU","Whether factorization biased towards U",
1150                  "UU",BIASLU,2,false);
1151  parameters[numberParameters-1].append("UX");
1152  parameters[numberParameters-1].append("LX");
1153  parameters[numberParameters-1].append("LL");
1154  parameters[numberParameters-1].setCurrentOption("LX");
1155#endif
1156#ifdef COIN_HAS_CBC
1157  parameters[numberParameters++]=
1158    CbcOrClpParam("branch!AndCut","Do Branch and Cut",
1159                  BAB);
1160  parameters[numberParameters-1].setLonghelp
1161    (
1162     "This does branch and cut.  There are many parameters which can affect the performance.  \
1163First just try with default settings and look carefully at the log file.  Did cuts help?  Did they take too long?  \
1164Look at output to see which cuts were effective and then do some tuning.  You will see that the \
1165options for cuts are off, on, root and ifmove.  Off is \
1166obvious, on means that this cut generator will be tried in the branch and cut tree (you can fine tune using \
1167'depth').  Root means just at the root node while 'ifmove' means that cuts will be used in the tree if they \
1168look as if they are doing some good and moving the objective value.  If pre-processing reduced the size of the \
1169problem or strengthened many coefficients then it is probably wise to leave it on.  Switch off heuristics \
1170which did not provide solutions.  The other major area to look at is the search.  Hopefully good solutions \
1171were obtained fairly early in the search so the important point is to select the best variable to branch on.  \
1172See whether strong branching did a good job - or did it just take a lot of iterations.  Adjust the strongBranching \
1173and trustPseudoCosts parameters."
1174     ); 
1175#endif
1176  parameters[numberParameters++]=
1177    CbcOrClpParam("bscale","Whether to scale in barrier",
1178                  "off",BARRIERSCALE,7,false);
1179  parameters[numberParameters-1].append("on");
1180  parameters[numberParameters++]=
1181    CbcOrClpParam("chol!esky","Which cholesky algorithm",
1182                  "native",CHOLESKY,7);
1183  parameters[numberParameters-1].append("dense");
1184  //#ifdef FOREIGN_BARRIER
1185#ifdef WSSMP_BARRIER
1186  parameters[numberParameters-1].append("fudge!Long");
1187  parameters[numberParameters-1].append("wssmp");
1188#define REAL_BARRIER
1189#else
1190  parameters[numberParameters-1].append("fudge!Long_dummy");
1191  parameters[numberParameters-1].append("wssmp_dummy");
1192#endif
1193#ifdef UFL_BARRIER
1194  parameters[numberParameters-1].append("Uni!versityOfFlorida");
1195#define REAL_BARRIER
1196#else
1197  parameters[numberParameters-1].append("Uni!versityOfFlorida_dummy");
1198#endif
1199#ifdef TAUCS_BARRIER
1200  parameters[numberParameters-1].append("Taucs");
1201#define REAL_BARRIER
1202#else
1203  parameters[numberParameters-1].append("Taucs_dummy");
1204#endif
1205  parameters[numberParameters-1].setLonghelp
1206    (
1207     "For a barrier code to be effective it needs a good Cholesky ordering and factorization.  \
1208You will need to link in one from another source.  See Makefile.locations for some \
1209possibilities."
1210     ); 
1211  //#endif
1212#ifdef COIN_HAS_CBC
1213  parameters[numberParameters++]=
1214    CbcOrClpParam("clique!Cuts","Whether to use Clique cuts",
1215                  "off",CLIQUECUTS);
1216  parameters[numberParameters-1].append("on");
1217  parameters[numberParameters-1].append("root");
1218  parameters[numberParameters-1].append("ifmove");
1219  parameters[numberParameters-1].setLonghelp
1220    (
1221     "This switches on clique cuts (either at root or in entire tree) \
1222See branchAndCut for information on options."
1223     ); 
1224  parameters[numberParameters++]=
1225    CbcOrClpParam("combine!Solutions","Whether to use combine solution heuristic",
1226                  "off",COMBINE);
1227  parameters[numberParameters-1].append("on");
1228  parameters[numberParameters-1].setLonghelp
1229    (
1230     "This switches on a heuristic which does branch and cut on the problem given by just \
1231using variables which have appeared in one or more solutions. \
1232It is obviously only tries after two or more solutions."
1233     ); 
1234  parameters[numberParameters++]=
1235    CbcOrClpParam("cost!Strategy","How to use costs as priorities",
1236                  "off",COSTSTRATEGY);
1237  parameters[numberParameters-1].append("pri!orities");
1238  parameters[numberParameters-1].append("pseudo!costs(not implemented yet)");
1239  parameters[numberParameters-1].setLonghelp
1240    (
1241     "This orders the variables in order of their absolute costs - with largest cost ones being branched on \
1242first.  This primitive strategy can be surprsingly effective."
1243     ); 
1244#endif
1245#ifdef COIN_HAS_CLP
1246  parameters[numberParameters++]=
1247    CbcOrClpParam("crash","Whether to create basis for problem",
1248                  "off",CRASH);
1249  parameters[numberParameters-1].append("on");
1250  parameters[numberParameters-1].append("so!low_halim");
1251  parameters[numberParameters-1].append("ha!lim_solow(JJF mods)");
1252  //  parameters[numberParameters-1].append("4");
1253  //  parameters[numberParameters-1].append("5");
1254  parameters[numberParameters-1].setLonghelp
1255    (
1256     "If crash is set on and there is an all slack basis then Clp will flip or put structural\
1257 variables into basis with the aim of getting dual feasible.  On the whole dual seems to be\
1258 better without it and there alernative types of 'crash' for primal e.g. 'idiot' or 'sprint'. \
1259I have also added a variant due to Solow and Halim which is as on but just flip."); 
1260  parameters[numberParameters++]=
1261    CbcOrClpParam("cross!over","Whether to get a basic solution after barrier",
1262                  "on",CROSSOVER);
1263  parameters[numberParameters-1].append("off");
1264  parameters[numberParameters-1].append("maybe");
1265  parameters[numberParameters-1].append("presolve");
1266  parameters[numberParameters-1].setLonghelp
1267    (
1268     "Interior point algorithms do not obtain a basic solution (and \
1269the feasibility criterion is a bit suspect (JJF)).  This option will crossover \
1270to a basic solution suitable for ranging or branch and cut.  With the current state \
1271of quadratic it may be a good idea to switch off crossover for quadratic (and maybe \
1272presolve as well) - the option maybe does this."
1273     );
1274#endif
1275#ifdef COIN_HAS_CBC
1276  parameters[numberParameters++]=
1277    CbcOrClpParam("cutD!epth","Depth in tree at which to do cuts",
1278                  -1,999999,CUTDEPTH);
1279  parameters[numberParameters-1].setLonghelp
1280    (
1281     "Cut generators may be - off, on only at root, on if they look possible \
1282and on.  If they are done every node then that is that, but it may be worth doing them \
1283every so often.  The original method was every so many nodes but it is more logical \
1284to do it whenever depth in tree is a multiple of K.  This option does that and defaults \
1285to -1 (off)."
1286     );
1287  parameters[numberParameters-1].setIntValue(-1);
1288  parameters[numberParameters++]=
1289    CbcOrClpParam("cuto!ff","All solutions must be better than this",
1290                  -1.0e60,1.0e60,CUTOFF);
1291  parameters[numberParameters-1].setDoubleValue(1.0e50);
1292  parameters[numberParameters-1].setLonghelp
1293    (
1294     "All solutions must be better than this value (in a minimization sense).  \
1295This is also set by code whenever it obtains a solution and is set to value of \
1296objective for solution minus cutoff increment."
1297     );
1298  parameters[numberParameters++]=
1299    CbcOrClpParam("cuts!OnOff","Switches all cuts on or off",
1300                  "off",CUTSSTRATEGY);
1301  parameters[numberParameters-1].append("on");
1302  parameters[numberParameters-1].append("root");
1303  parameters[numberParameters-1].append("ifmove");
1304  parameters[numberParameters-1].setLonghelp
1305    (
1306     "This can be used to switch on or off all cuts (apart from Reduce and Split).  Then you can do \
1307individual ones off or on \
1308See branchAndCut for information on options."
1309     ); 
1310  parameters[numberParameters++]=
1311    CbcOrClpParam("debug!In","read valid solution from file",
1312                  DEBUG,7,false);
1313  parameters[numberParameters-1].setLonghelp
1314    (
1315     "This will read a solution file from the given file name.  It will use the default\
1316 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
1317 is initialized to '', i.e. it must be set.\n\n\
1318If set to create it will create a file called debug.file  after search; if set \
1319to createAfterPre it will create one suitable for use after preprocessing.\n\n\
1320The idea is that if you suspect a bad cut generator and you did not use preprocessing \
1321you can do a good run with debug set to 'create' and then switch on the cuts you suspect and \
1322re-run with debug set to 'debug.file'  Similarly if you do use preprocessing but use \
1323createAfterPre.  The create case has same effect as saveSolution."
1324     ); 
1325#endif
1326  parameters[numberParameters++]=
1327    CbcOrClpParam("direction","Minimize or Maximize",
1328                  "min!imize",DIRECTION);
1329  parameters[numberParameters-1].append("max!imize");
1330  parameters[numberParameters-1].append("zero");
1331  parameters[numberParameters-1].setLonghelp
1332    (
1333     "The default is minimize - use 'direction maximize' for maximization.\n\
1334You can also use the parameters 'maximize' or 'minimize'."
1335     ); 
1336  parameters[numberParameters++]=
1337    CbcOrClpParam("directory","Set Default directory for import etc.",
1338                  DIRECTORY);
1339  parameters[numberParameters-1].setLonghelp
1340    (
1341     "This sets the directory which import, export, saveModel, restoreModel etc will use.\
1342  It is initialized to './'"
1343     ); 
1344#ifdef COIN_HAS_CLP
1345  parameters[numberParameters++]=
1346    CbcOrClpParam("dualB!ound","Initially algorithm acts as if no \
1347gap between bounds exceeds this value",
1348                  1.0e-20,1.0e12,DUALBOUND);
1349  parameters[numberParameters-1].setLonghelp
1350    (
1351     "The dual algorithm in Clp is a single phase algorithm as opposed to a two phase\
1352 algorithm where you first get feasible then optimal.  If a problem has both upper and\
1353 lower bounds then it is trivial to get dual feasible by setting non basic variables\
1354 to correct bound.  If the gap between the upper and lower bounds of a variable is more\
1355 than the value of dualBound Clp introduces fake bounds so that it can make the problem\
1356 dual feasible.  This has the same effect as a composite objective function in the\
1357 primal algorithm.  Too high a value may mean more iterations, while too low a bound means\
1358 the code may go all the way and then have to increase the bounds.  OSL had a heuristic to\
1359 adjust bounds, maybe we need that here."
1360     );
1361  parameters[numberParameters++]=
1362    CbcOrClpParam("dualize","Solves dual reformulation",
1363                  0,1,DUALIZE,false);
1364  parameters[numberParameters-1].setLonghelp
1365    (
1366     "Don't even think about it."
1367     ); 
1368  parameters[numberParameters++]=
1369    CbcOrClpParam("dualP!ivot","Dual pivot choice algorithm",
1370                  "auto!matic",DUALPIVOT);
1371  parameters[numberParameters-1].append("dant!zig");
1372  parameters[numberParameters-1].append("partial");
1373  parameters[numberParameters-1].append("steep!est");
1374  parameters[numberParameters-1].setLonghelp
1375    (
1376     "Clp can use any pivot selection algorithm which the user codes as long as it\
1377 implements the features in the abstract pivot base class.  The Dantzig method is implemented\
1378 to show a simple method but its use is deprecated.  Steepest is the method of choice and there\
1379 are two variants which keep all weights updated but only scan a subset each iteration.\
1380 Partial switches this on while automatic decides at each iteration based on information\
1381 about the factorization."
1382     ); 
1383  parameters[numberParameters++]=
1384    CbcOrClpParam("dualS!implex","Do dual simplex algorithm",
1385                  DUALSIMPLEX);
1386  parameters[numberParameters-1].setLonghelp
1387    (
1388     "This command solves the current model using the dual steepest edge algorithm.\
1389The time and iterations may be affected by settings such as presolve, scaling, crash\
1390 and also by dual pivot method, fake bound on variables and dual and primal tolerances."
1391     );
1392#endif
1393  parameters[numberParameters++]=
1394    CbcOrClpParam("dualT!olerance","For an optimal solution \
1395no dual infeasibility may exceed this value",
1396                  1.0e-20,1.0e12,DUALTOLERANCE);
1397  parameters[numberParameters-1].setLonghelp
1398    (
1399     "Normally the default tolerance is fine, but you may want to increase it a\
1400 bit if a dual run seems to be having a hard time.  One method which can be faster is \
1401to use a large tolerance e.g. 1.0e-4 and dual and then clean up problem using primal and the \
1402correct tolerance (remembering to switch off presolve for this final short clean up phase)."
1403     ); 
1404#ifdef COIN_HAS_CLP
1405  parameters[numberParameters++]=
1406    CbcOrClpParam("either!Simplex","Do dual or primal simplex algorithm",
1407                  EITHERSIMPLEX);
1408  parameters[numberParameters-1].setLonghelp
1409    (
1410     "This command solves the current model using the dual or primal algorithm,\
1411 based on a dubious analysis of model."
1412     );
1413#endif
1414  parameters[numberParameters++]=
1415    CbcOrClpParam("end","Stops clp execution",
1416                  EXIT);
1417  parameters[numberParameters-1].setLonghelp
1418    (
1419     "This stops execution ; end, exit, quit and stop are synonyms"
1420     ); 
1421  parameters[numberParameters++]=
1422    CbcOrClpParam("error!sAllowed","Whether to allow import errors",
1423                  "off",ERRORSALLOWED,3);
1424  parameters[numberParameters-1].append("on");
1425  parameters[numberParameters-1].setLonghelp
1426    (
1427     "The default is not to use any model which had errors when reading the mps file.\
1428  Setting this to 'on' will allow all errors from which the code can recover\
1429 simply by ignoring the error.  There are some errors from which the code can not recover \
1430e.g. no ENDATA.  This has to be set before import i.e. -errorsAllowed on -import xxxxxx.mps."
1431     );
1432  parameters[numberParameters++]=
1433    CbcOrClpParam("exit","Stops clp execution",
1434                  EXIT);
1435  parameters[numberParameters-1].setLonghelp
1436    (
1437     "This stops the execution of Clp, end, exit, quit and stop are synonyms"
1438     ); 
1439  parameters[numberParameters++]=
1440    CbcOrClpParam("export","Export model as mps file",
1441                  EXPORT);
1442  parameters[numberParameters-1].setLonghelp
1443    (
1444     "This will write an MPS format file to the given file name.  It will use the default\
1445 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
1446 is initialized to 'default.mps'."
1447     ); 
1448#ifdef COIN_HAS_CLP
1449  parameters[numberParameters++]=
1450    CbcOrClpParam("fakeB!ound","All bounds <= this value - DEBUG",
1451                  1.0,1.0e15,FAKEBOUND,false);
1452#ifdef COIN_HAS_CBC
1453    parameters[numberParameters++]=
1454      CbcOrClpParam("feas!ibilityPump","Whether to try Feasibility Pump",
1455                    "off",FPUMP);
1456    parameters[numberParameters-1].append("on");
1457  parameters[numberParameters-1].setLonghelp
1458    (
1459     "This switches on feasibility pump heuristic at root. This is due to Fischetti and Lodi \
1460and uses a sequence of Lps to try and get an integer feasible solution. \
1461Some fine tuning is available by passFeasibilityPump."
1462     ); 
1463  parameters[numberParameters++]=
1464    CbcOrClpParam("fix!OnDj","Try heuristic based on fixing variables with \
1465reduced costs greater than this",
1466                  -1.0e20,1.0e20,DJFIX,false);
1467  parameters[numberParameters-1].setLonghelp
1468    (
1469     "If this is set integer variables with reduced costs greater than this will be fixed \
1470before branch and bound - use with extreme caution!" 
1471     ); 
1472    parameters[numberParameters++]=
1473      CbcOrClpParam("flow!CoverCuts","Whether to use Flow Cover cuts",
1474                    "off",FLOWCUTS);
1475    parameters[numberParameters-1].append("on");
1476    parameters[numberParameters-1].append("root");
1477    parameters[numberParameters-1].append("ifmove");
1478  parameters[numberParameters-1].setLonghelp
1479    (
1480     "This switches on flow cover cuts (either at root or in entire tree) \
1481See branchAndCut for information on options."
1482     ); 
1483#endif
1484  parameters[numberParameters++]=
1485    CbcOrClpParam("gamma!(Delta)","Whether to regularize barrier",
1486                  "off",GAMMA,7,false);
1487  parameters[numberParameters-1].append("on");
1488  parameters[numberParameters-1].append("gamma");
1489  parameters[numberParameters-1].append("delta");
1490  parameters[numberParameters-1].append("onstrong");
1491  parameters[numberParameters-1].append("gammastrong");
1492  parameters[numberParameters-1].append("deltastrong");
1493#endif
1494#ifdef COIN_HAS_CBC
1495  parameters[numberParameters++]=
1496    CbcOrClpParam("gap!Ratio","Stop when gap between best possible and \
1497best less than this fraction of larger of two",
1498                  0.0,1.0e20,GAPRATIO);
1499  parameters[numberParameters-1].setDoubleValue(0.0);
1500  parameters[numberParameters-1].setLonghelp
1501    (
1502     "If the gap between best solution and best possible solution is less than this fraction \
1503of the objective value at the root node then the search will terminate.  See 'allowableGap' for a \
1504way of using absolute value rather than fraction."
1505     ); 
1506  parameters[numberParameters++]=
1507    CbcOrClpParam("gomory!Cuts","Whether to use Gomory cuts",
1508                  "off",GOMORYCUTS);
1509  parameters[numberParameters-1].append("on");
1510  parameters[numberParameters-1].append("root");
1511  parameters[numberParameters-1].append("ifmove");
1512  parameters[numberParameters-1].setLonghelp
1513    (
1514     "The original cuts - beware of imitations!  Having gone out of favor, they are now more \
1515fashionable as LP solvers are more robust and they interact well with other cuts.  They will almost always \
1516give cuts (although in this executable they are limited as to number of variables in cut).  \
1517However the cuts may be dense so it is worth experimenting. \
1518See branchAndCut for information on options."
1519     ); 
1520  parameters[numberParameters++]=
1521    CbcOrClpParam("greedy!Heuristic","Whether to use a greedy heuristic",
1522                  "off",GREEDY);
1523  parameters[numberParameters-1].append("on");
1524  parameters[numberParameters-1].append("root");
1525  parameters[numberParameters-1].setLonghelp
1526    (
1527     "Switches on a greedy heuristic which will try and obtain a solution.  It may just fix a \
1528percentage of variables and then try a small branch and cut run."
1529     ); 
1530  parameters[numberParameters++]=
1531    CbcOrClpParam("heur!isticsOnOff","Switches most heuristics on or off",
1532                  "off",HEURISTICSTRATEGY);
1533  parameters[numberParameters-1].append("on");
1534  parameters[numberParameters-1].setLonghelp
1535    (
1536     "This can be used to switch on or off all heuristics.  Then you can do \
1537individual ones off or on.  CbcTreeLocal is not included as it dramatically \
1538alters search."
1539     ); 
1540#endif
1541  parameters[numberParameters++]=
1542    CbcOrClpParam("help","Print out version, non-standard options and some help",
1543                  HELP,3);
1544  parameters[numberParameters-1].setLonghelp
1545    (
1546     "This prints out some help to get user started.  If you have printed this then \
1547you should be past that stage:-)"
1548     ); 
1549#ifdef COIN_HAS_CBC
1550  parameters[numberParameters++]=
1551    CbcOrClpParam("hot!StartMaxIts","Maximum iterations on hot start",
1552                  0,INT_MAX,MAXHOTITS,false);
1553#endif
1554#ifdef COIN_HAS_CLP
1555  parameters[numberParameters++]=
1556    CbcOrClpParam("idiot!Crash","Whether to try idiot crash",
1557                  -1,999999,IDIOT);
1558  parameters[numberParameters-1].setLonghelp
1559    (
1560     "This is a type of 'crash' which works well on some homogeneous problems.\
1561 It works best on problems with unit elements and rhs but will do something to any model.  It should only be\
1562 used before primal.  It can be set to -1 when the code decides for itself whether to use it,\
1563 0 to switch off or n > 0 to do n passes."
1564     ); 
1565#endif
1566  parameters[numberParameters++]=
1567    CbcOrClpParam("import","Import model from mps file",
1568                  IMPORT,3);
1569  parameters[numberParameters-1].setLonghelp
1570    (
1571     "This will read an MPS format file from the given file name.  It will use the default\
1572 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
1573 is initialized to '', i.e. it must be set.  If you have libgz then it can read compressed\
1574 files 'xxxxxxxx.gz'.."
1575     );
1576#ifdef COIN_HAS_CBC
1577  parameters[numberParameters++]=
1578    CbcOrClpParam("inc!rement","A valid solution must be at least this \
1579much better than last integer solution",
1580                  -1.0e20,1.0e20,INCREMENT);
1581  parameters[numberParameters-1].setLonghelp
1582    (
1583     "Whenever a solution is found the bound on solutions is set to solution (in a minimization\
1584sense) plus this.  If it is not set then the code will try and work one out e.g. if \
1585all objective coefficients are multiples of 0.01 and only integer variables have entries in \
1586objective then this can be set to 0.01.  Be careful if you set this negative!"
1587     ); 
1588  parameters[numberParameters++]=
1589    CbcOrClpParam("inf!easibilityWeight","Each integer infeasibility is expected \
1590to cost this much",
1591                  0.0,1.0e20,INFEASIBILITYWEIGHT);
1592  parameters[numberParameters-1].setLonghelp
1593    (
1594     "A primitive way of deciding which node to explore next.  Satisfying each integer infeasibility is \
1595expected to cost this much."
1596     ); 
1597  parameters[numberParameters++]=
1598    CbcOrClpParam("initialS!olve","Solve to continuous",
1599                  SOLVECONTINUOUS);
1600  parameters[numberParameters-1].setLonghelp
1601    (
1602     "This just solves the problem to continuous - without adding any cuts"
1603     ); 
1604  parameters[numberParameters++]=
1605    CbcOrClpParam("integerT!olerance","For an optimal solution \
1606no integer variable may be this away from an integer value",
1607              1.0e-20,0.5,INTEGERTOLERANCE);
1608  parameters[numberParameters-1].setLonghelp
1609    (
1610     "Beware of setting this smaller than the primal tolerance."
1611     ); 
1612#endif
1613#ifdef COIN_HAS_CLP
1614  parameters[numberParameters++]=
1615    CbcOrClpParam("keepN!ames","Whether to keep names from import",
1616                  "on",KEEPNAMES);
1617  parameters[numberParameters-1].append("off");
1618  parameters[numberParameters-1].setLonghelp
1619    (
1620     "It saves space to get rid of names so if you need to you can set this to off.  \
1621This needs to be set before the import of model - so -keepnames off -import xxxxx.mps."
1622     ); 
1623  parameters[numberParameters++]=
1624    CbcOrClpParam("KKT","Whether to use KKT factorization",
1625                  "off",KKT,7,false);
1626  parameters[numberParameters-1].append("on");
1627#endif
1628#ifdef COIN_HAS_CBC
1629  parameters[numberParameters++]=
1630    CbcOrClpParam("knapsack!Cuts","Whether to use Knapsack cuts",
1631                  "off",KNAPSACKCUTS);
1632  parameters[numberParameters-1].append("on");
1633  parameters[numberParameters-1].append("root");
1634  parameters[numberParameters-1].append("ifmove");
1635  parameters[numberParameters-1].setLonghelp
1636    (
1637     "This switches on knapsack cuts (either at root or in entire tree) \
1638See branchAndCut for information on options."
1639     ); 
1640  parameters[numberParameters++]=
1641    CbcOrClpParam("local!TreeSearch","Whether to use local treesearch",
1642                  "off",LOCALTREE);
1643  parameters[numberParameters-1].append("on");
1644  parameters[numberParameters-1].setLonghelp
1645    (
1646     "This switches on a local search algorithm when a solution is found.  This is from \
1647Fischetti and Lodi and is not really a heuristic although it can be used as one. \
1648When used from Coin solve it has limited functionality.  It is not switched on when \
1649heuristics are switched on."
1650     ); 
1651#endif
1652#ifndef COIN_HAS_CBC
1653  parameters[numberParameters++]=
1654    CbcOrClpParam("log!Level","Level of detail in Solver output",
1655                  -1,63,SOLVERLOGLEVEL);
1656#else
1657  parameters[numberParameters++]=
1658    CbcOrClpParam("log!Level","Level of detail in Coin branch and Cut output",
1659                  -1,63,LOGLEVEL);
1660  parameters[numberParameters-1].setIntValue(1);
1661#endif
1662  parameters[numberParameters-1].setLonghelp
1663    (
1664     "If 0 then there should be no output in normal circumstances.  1 is probably the best\
1665 value for most uses, while 2 and 3 give more information."
1666     ); 
1667  parameters[numberParameters++]=
1668    CbcOrClpParam("max!imize","Set optimization direction to maximize",
1669                  MAXIMIZE,7);
1670  parameters[numberParameters-1].setLonghelp
1671    (
1672     "The default is minimize - use 'maximize' for maximization.\n\
1673You can also use the parameters 'direction maximize'."
1674     ); 
1675#ifdef COIN_HAS_CLP
1676  parameters[numberParameters++]=
1677    CbcOrClpParam("maxF!actor","Maximum number of iterations between \
1678refactorizations",
1679                  1,999999,MAXFACTOR);
1680  parameters[numberParameters-1].setLonghelp
1681    (
1682     "If this is at its initial value of 200 then in this executable clp will guess at a\
1683 value to use.  Otherwise the user can set a value.  The code may decide to re-factorize\
1684 earlier for accuracy."
1685     ); 
1686  parameters[numberParameters++]=
1687    CbcOrClpParam("maxIt!erations","Maximum number of iterations before \
1688stopping",
1689                  0,2147483647,MAXITERATION);
1690  parameters[numberParameters-1].setLonghelp
1691    (
1692     "This can be used for testing purposes.  The corresponding library call\n\
1693      \tsetMaximumIterations(value)\n can be useful.  If the code stops on\
1694 seconds or by an interrupt this will be treated as stopping on maximum iterations"
1695     ); 
1696#endif
1697#ifdef COIN_HAS_CBC
1698  parameters[numberParameters++]=
1699    CbcOrClpParam("maxN!odes","Maximum number of nodes to do",
1700                  1,2147483647,MAXNODES);
1701  parameters[numberParameters-1].setLonghelp
1702    (
1703     "This is a repeatable way to limit search.  Normally using time is easier \
1704but then the results may not be repeatable."
1705     ); 
1706#endif
1707  parameters[numberParameters++]=
1708    CbcOrClpParam("min!imize","Set optimization direction to minimize",
1709                  MINIMIZE,7);
1710  parameters[numberParameters-1].setLonghelp
1711    (
1712     "The default is minimize - use 'maximize' for maximization.\n\
1713This should only be necessary if you have previously set maximization \
1714You can also use the parameters 'direction minimize'."
1715     );
1716#ifdef COIN_HAS_CBC
1717  parameters[numberParameters++]=
1718    CbcOrClpParam("mipO!ptions","Dubious options for mip",
1719                  0,INT_MAX,MIPOPTIONS,false);
1720  parameters[numberParameters++]=
1721    CbcOrClpParam("more!MipOptions","More dubious options for mip",
1722                  -1,INT_MAX,MOREMIPOPTIONS,false);
1723  parameters[numberParameters++]=
1724    CbcOrClpParam("mixed!IntegerRoundingCuts","Whether to use Mixed Integer Rounding cuts",
1725                  "off",MIXEDCUTS);
1726  parameters[numberParameters-1].append("on");
1727  parameters[numberParameters-1].append("root");
1728  parameters[numberParameters-1].append("ifmove");
1729  parameters[numberParameters-1].setLonghelp
1730    (
1731     "This switches on mixed integer rounding cuts (either at root or in entire tree) \
1732See branchAndCut for information on options."
1733     ); 
1734#endif
1735  parameters[numberParameters++]=
1736    CbcOrClpParam("mess!ages","Controls if Clpnnnn is printed",
1737                  "off",MESSAGES);
1738  parameters[numberParameters-1].append("on");
1739  parameters[numberParameters-1].setLonghelp
1740    ("The default behavior is to put out messages such as:\n\
1741   Clp0005 2261  Objective 109.024 Primal infeas 944413 (758)\n\
1742but this program turns this off to make it look more friendly.  It can be useful\
1743 to turn them back on if you want to be able to 'grep' for particular messages or if\
1744 you intend to override the behavior of a particular message."
1745     );
1746#ifdef COIN_HAS_CBC
1747  parameters[numberParameters++]=
1748    CbcOrClpParam("miniT!ree","Size of fast mini tree",
1749                  0,INT_MAX,NUMBERMINI,false);
1750  parameters[numberParameters-1].setLonghelp
1751    (
1752     "The idea is that I can do a small tree fast. \
1753This is a first try and will hopefully become more sophisticated."
1754     ); 
1755  parameters[numberParameters++]=
1756    CbcOrClpParam("miplib","Do some of miplib test set",
1757                  MIPLIB,3);
1758#endif
1759#ifdef COIN_HAS_CLP
1760  parameters[numberParameters++]=
1761    CbcOrClpParam("netlib","Solve entire netlib test set",
1762                  NETLIB_EITHER,3);
1763  parameters[numberParameters-1].setLonghelp
1764    (
1765     "This exercises the unit test for clp and then solves the netlib test set using dual or primal.\
1766The user can set options before e.g. clp -presolve off -netlib"
1767     ); 
1768#ifdef REAL_BARRIER
1769  parameters[numberParameters++]=
1770    CbcOrClpParam("netlibB!arrier","Solve entire netlib test set with barrier",
1771                  NETLIB_BARRIER,3);
1772  parameters[numberParameters-1].setLonghelp
1773    (
1774     "This exercises the unit test for clp and then solves the netlib test set using barrier.\
1775The user can set options before e.g. clp -kkt on -netlib"
1776     ); 
1777#endif
1778  parameters[numberParameters++]=
1779    CbcOrClpParam("netlibD!ual","Solve entire netlib test set (dual)",
1780                  NETLIB_DUAL,3);
1781  parameters[numberParameters-1].setLonghelp
1782    (
1783     "This exercises the unit test for clp and then solves the netlib test set using dual.\
1784The user can set options before e.g. clp -presolve off -netlib"
1785     ); 
1786  parameters[numberParameters++]=
1787    CbcOrClpParam("netlibP!rimal","Solve entire netlib test set (primal)",
1788                  NETLIB_PRIMAL,3);
1789  parameters[numberParameters-1].setLonghelp
1790    (
1791     "This exercises the unit test for clp and then solves the netlib test set using primal.\
1792The user can set options before e.g. clp -presolve off -netlibp"
1793     ); 
1794  parameters[numberParameters++]=
1795    CbcOrClpParam("netlibT!une","Solve entire netlib test set with 'best' algorithm",
1796                  NETLIB_TUNE,3);
1797  parameters[numberParameters-1].setLonghelp
1798    (
1799     "This exercises the unit test for clp and then solves the netlib test set using whatever \
1800works best.  I know this is cheating but it also stresses the code better by doing a \
1801mixture of stuff.  The best algorithm was chosen on a Linux ThinkPad using native cholesky \
1802with University of Florida ordering."
1803     ); 
1804  parameters[numberParameters++]=
1805    CbcOrClpParam("network","Tries to make network matrix",
1806                  NETWORK,7,false);
1807  parameters[numberParameters-1].setLonghelp
1808    (
1809     "Clp will go faster if the matrix can be converted to a network.  The matrix\
1810 operations may be a bit faster with more efficient storage, but the main advantage\
1811 comes from using a network factorization.  It will probably not be as fast as a \
1812specialized network code."
1813     ); 
1814#ifdef COIN_HAS_CBC
1815  parameters[numberParameters++]=
1816    CbcOrClpParam("numberA!nalyze","Number of analysis iterations",
1817                  -INT_MAX,INT_MAX,NUMBERANALYZE,false);
1818  parameters[numberParameters-1].setLonghelp
1819    (
1820     "This says how many iterations to spend at root node analyzing problem. \
1821This is a first try and will hopefully become more sophisticated."
1822     ); 
1823#endif
1824  parameters[numberParameters++]=
1825    CbcOrClpParam("objective!Scale","Scale factor to apply to objective",
1826                  -1.0e20,1.0e20,OBJSCALE,false);
1827  parameters[numberParameters-1].setLonghelp
1828    (
1829     "If the objective function has some very large values, you may wish to scale them\
1830 internally by this amount.  It can also be set by autoscale.  It is applied after scaling"
1831     ); 
1832  parameters[numberParameters-1].setDoubleValue(1.0);
1833#endif
1834  parameters[numberParameters++]=
1835    CbcOrClpParam("output!Format","Which output format to use",
1836                  1,6,OUTPUTFORMAT);
1837  parameters[numberParameters-1].setLonghelp
1838    (
1839     "Normally export will be done using normal representation for numbers and two values\
1840 per line.  You may want to do just one per line (for grep or suchlike) and you may wish\
1841 to save with absolute accuracy using a coded version of the IEEE value. A value of 2 is normal.\
1842 otherwise odd values gives one value per line, even two.  Values 1,2 give normal format, 3,4\
1843 gives greater precision, while 5,6 give IEEE values.  When used for exporting a basis 1 does not save \
1844values, 2 saves values, 3 with greater accuracy and 4 in IEEE."
1845     );
1846#ifdef COIN_HAS_CBC
1847  parameters[numberParameters++]=
1848    CbcOrClpParam("passC!uts","Number of cut passes at root node",
1849                  -999999,999999,CUTPASS);
1850  parameters[numberParameters-1].setLonghelp
1851    (
1852     "The default is 100 passes if less than 500 columns, 100 passes (but \
1853stop if drop small if less than 5000 columns, 20 otherwise"
1854     ); 
1855  parameters[numberParameters++]=
1856    CbcOrClpParam("passF!easibilityPump","How many passes in feasibility pump",
1857                  0,10000,FPUMPITS);
1858  parameters[numberParameters-1].setLonghelp
1859    (
1860     "This fine tunes Feasibility Pump by doing more or fewer passes."
1861     ); 
1862  parameters[numberParameters-1].setIntValue(20);
1863#endif
1864#ifdef COIN_HAS_CLP
1865  parameters[numberParameters++]=
1866    CbcOrClpParam("passP!resolve","How many passes in presolve",
1867                  -200,100,PRESOLVEPASS,false);
1868  parameters[numberParameters-1].setLonghelp
1869    (
1870     "Normally Presolve does 5 passes but you may want to do less to make it\
1871 more lightweight or do more if improvements are still being made.  As Presolve will return\
1872 if nothing is being taken out, you should not normally need to use this fine tuning."
1873     ); 
1874  parameters[numberParameters++]=
1875    CbcOrClpParam("pertV!alue","Method of perturbation",
1876                  -5000,102,PERTVALUE,false);
1877  parameters[numberParameters++]=
1878    CbcOrClpParam("perturb!ation","Whether to perturb problem",
1879                  "on",PERTURBATION);
1880  parameters[numberParameters-1].append("off");
1881  parameters[numberParameters-1].setLonghelp
1882    (
1883     "Perturbation helps to stop cycling, but Clp uses other measures for this.\
1884  However large problems and especially ones with unit elements and unit rhs or costs\
1885 benefit from perturbation.  Normally Clp tries to be intelligent, but you can switch this off.\
1886  The Clp library has this off by default.  This program has it on by default."
1887     ); 
1888  parameters[numberParameters++]=
1889    CbcOrClpParam("PFI","Whether to use Product Form of Inverse in simplex",
1890                  "off",PFI,7,false);
1891  parameters[numberParameters-1].append("on");
1892  parameters[numberParameters-1].setLonghelp
1893    (
1894     "By default clp uses Forrest-Tomlin L-U update.  If you are masochistic you can switch it off."
1895     ); 
1896  parameters[numberParameters++]=
1897    CbcOrClpParam("plus!Minus","Tries to make +- 1 matrix",
1898                  PLUSMINUS,7,false);
1899  parameters[numberParameters-1].setLonghelp
1900    (
1901     "Clp will go slightly faster if the matrix can be converted so that the elements are\
1902 not stored and are known to be unit.  The main advantage is memory use.  Clp may automatically\
1903 see if it can convert the problem so you should not need to use this."
1904     ); 
1905  parameters[numberParameters++]=
1906    CbcOrClpParam("pO!ptions","Dubious print options",
1907                  0,INT_MAX,PRINTOPTIONS,false);
1908  parameters[numberParameters-1].setIntValue(0);
1909  parameters[numberParameters-1].setLonghelp
1910    (
1911     "If this is > 0 then presolve will give more information and branch and cut will give statistics"
1912     ); 
1913  parameters[numberParameters++]=
1914    CbcOrClpParam("preO!pt","Presolve options",
1915                  0,INT_MAX,PRESOLVEOPTIONS,false);
1916#endif
1917  parameters[numberParameters++]=
1918    CbcOrClpParam("presolve","Whether to presolve problem",
1919                  "on",PRESOLVE);
1920  parameters[numberParameters-1].append("off");
1921  parameters[numberParameters-1].append("more");
1922  parameters[numberParameters-1].append("file");
1923  parameters[numberParameters-1].setLonghelp
1924    (
1925     "Presolve analyzes the model to find such things as redundant equations, equations\
1926 which fix some variables, equations which can be transformed into bounds etc etc.  For the\
1927 initial solve of any problem this is worth doing unless you know that it will have no effect.  \
1928on will normally do 5 passes while using 'more' will do 10.  If the problem is very large you may need \
1929to write the original to file using 'file'."
1930     ); 
1931#ifdef COIN_HAS_CBC
1932  parameters[numberParameters++]=
1933    CbcOrClpParam("preprocess","Whether to use integer preprocessing",
1934                  "off",PREPROCESS);
1935  parameters[numberParameters-1].append("on");
1936  parameters[numberParameters-1].append("save");
1937  parameters[numberParameters-1].append("equal");
1938  parameters[numberParameters-1].append("sos");
1939  parameters[numberParameters-1].append("trysos");
1940  parameters[numberParameters-1].setLonghelp
1941    (
1942     "This tries to reduce size of model in a similar way to presolve and \
1943it also tries to strengthen the model - this can be very useful and is worth trying. \
1944 Save option saves on file presolved.mps.  equal will turn <= cliques into \
1945==.  sos will create sos sets if all 0-1 in sets (well one extra is allowed) \
1946and no overlaps.  trysos is same but allows any number extra."
1947     ); 
1948#endif
1949#ifdef COIN_HAS_CLP
1950  parameters[numberParameters++]=
1951    CbcOrClpParam("preT!olerance","Tolerance to use in presolve",
1952                  1.0e-20,1.0e12,PRESOLVETOLERANCE);
1953  parameters[numberParameters-1].setLonghelp
1954    (
1955     "The default is 1.0e-8 - you may wish to try 1.0e-7 if presolve says the problem is \
1956infeasible and you have awkward numbers and you are sure the problem is really feasible."
1957     ); 
1958  parameters[numberParameters++]=
1959    CbcOrClpParam("primalP!ivot","Primal pivot choice algorithm",
1960                  "auto!matic",PRIMALPIVOT);
1961  parameters[numberParameters-1].append("exa!ct");
1962  parameters[numberParameters-1].append("dant!zig");
1963  parameters[numberParameters-1].append("part!ial");
1964  parameters[numberParameters-1].append("steep!est");
1965  parameters[numberParameters-1].append("change");
1966  parameters[numberParameters-1].append("sprint");
1967  parameters[numberParameters-1].setLonghelp
1968    (
1969     "Clp can use any pivot selection algorithm which the user codes as long as it\
1970 implements the features in the abstract pivot base class.  The Dantzig method is implemented\
1971 to show a simple method but its use is deprecated.  Exact devex is the method of choice and there\
1972 are two variants which keep all weights updated but only scan a subset each iteration.\
1973 Partial switches this on while change initially does dantzig until the factorization\
1974 becomes denser.  This is still a work in progress."
1975     ); 
1976  parameters[numberParameters++]=
1977    CbcOrClpParam("primalS!implex","Do primal simplex algorithm",
1978                  PRIMALSIMPLEX);
1979  parameters[numberParameters-1].setLonghelp
1980    (
1981     "This command solves the current model using the primal algorithm.\
1982  The default is to use exact devex.\
1983 The time and iterations may be affected by settings such as presolve, scaling, crash\
1984 and also by column selection  method, infeasibility weight and dual and primal tolerances."
1985     );
1986#endif
1987  parameters[numberParameters++]=
1988    CbcOrClpParam("primalT!olerance","For an optimal solution \
1989no primal infeasibility may exceed this value",
1990                  1.0e-20,1.0e12,PRIMALTOLERANCE);
1991  parameters[numberParameters-1].setLonghelp
1992    (
1993     "Normally the default tolerance is fine, but you may want to increase it a\
1994 bit if a primal run seems to be having a hard time"
1995     ); 
1996#ifdef COIN_HAS_CLP
1997  parameters[numberParameters++]=
1998    CbcOrClpParam("primalW!eight","Initially algorithm acts as if it \
1999costs this much to be infeasible",
2000                  1.0e-20,1.0e20,PRIMALWEIGHT);
2001  parameters[numberParameters-1].setLonghelp
2002    (
2003     "The primal algorithm in Clp is a single phase algorithm as opposed to a two phase\
2004 algorithm where you first get feasible then optimal.  So Clp is minimizing this weight times\
2005 the sum of primal infeasibilities plus the true objective function (in minimization sense).\
2006  Too high a value may mean more iterations, while too low a bound means\
2007 the code may go all the way and then have to increase the weight in order to get feasible.\
2008  OSL had a heuristic to\
2009 adjust bounds, maybe we need that here."
2010     ); 
2011#endif
2012  parameters[numberParameters++]=
2013    CbcOrClpParam("printi!ngOptions","Print options",
2014                  "normal",INTPRINT,3);
2015  parameters[numberParameters-1].append("integer");
2016  parameters[numberParameters-1].append("special");
2017  parameters[numberParameters-1].append("rows");
2018  parameters[numberParameters-1].append("all");
2019  parameters[numberParameters-1].setLonghelp
2020    (
2021     "This changes the amount and format of printing a solution:\nnormal - nonzero column variables \n\
2022integer - nonzero integer column variables\n\
2023special - in format suitable for OsiRowCutDebugger\n\
2024rows - nonzero column variables and row activities\n\
2025all - all column variables and row activities.\n\
2026\nFor non-integer problems 'integer' and 'special' act like 'normal'.  \
2027Also see printMask for controlling output."
2028     ); 
2029  parameters[numberParameters++]=
2030    CbcOrClpParam("printM!ask","Control printing of solution on a  mask",
2031                  PRINTMASK,3);
2032  parameters[numberParameters-1].setLonghelp
2033    (
2034     "If set then only those names which match mask are printed in a solution. \
2035'*' matches any character.  The default is '' i.e. unset so all variables are printed. \
2036This is only active if model has names."
2037     ); 
2038#ifdef COIN_HAS_CBC
2039  parameters[numberParameters++]=
2040    CbcOrClpParam("prio!rityIn","Import priorities etc from file",
2041                  PRIORITYIN,3);
2042  parameters[numberParameters-1].setLonghelp
2043    (
2044     "This will read a file with priorities from the given file name.  It will use the default\
2045 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
2046 is initialized to '', i.e. it must be set.  This can not read from compressed files. \
2047File is in csv format with allowed headings - name, number, priority, direction.  Exactly one of\
2048 name and number must be given."
2049     ); 
2050  parameters[numberParameters++]=
2051    CbcOrClpParam("probing!Cuts","Whether to use Probing cuts",
2052                  "off",PROBINGCUTS);
2053  parameters[numberParameters-1].append("on");
2054  parameters[numberParameters-1].append("root");
2055  parameters[numberParameters-1].append("ifmove");
2056  parameters[numberParameters-1].setLonghelp
2057    (
2058     "This switches on probing cuts (either at root or in entire tree) \
2059See branchAndCut for information on options."
2060     ); 
2061#endif
2062  parameters[numberParameters++]=
2063    CbcOrClpParam("quit","Stops clp execution",
2064                  EXIT);
2065  parameters[numberParameters-1].setLonghelp
2066    (
2067     "This stops the execution of Clp, end, exit, quit and stop are synonyms"
2068     ); 
2069#ifdef COIN_HAS_CLP
2070  parameters[numberParameters++]=
2071    CbcOrClpParam("reallyO!bjectiveScale","Scale factor to apply to objective in place",
2072                  -1.0e20,1.0e20,OBJSCALE2,false);
2073  parameters[numberParameters-1].setLonghelp
2074    (
2075     "You can set this to -1.0 to test maximization or other to stress code"
2076     ); 
2077  parameters[numberParameters-1].setDoubleValue(1.0);
2078  parameters[numberParameters++]=
2079    CbcOrClpParam("reallyS!cale","Scales model in place",
2080                  REALLY_SCALE,7,false);
2081#endif
2082#ifdef COIN_HAS_CBC
2083    parameters[numberParameters++]=
2084      CbcOrClpParam("reduce!AndSplitCuts","Whether to use Reduce-and-Split cuts",
2085              "off",REDSPLITCUTS);
2086    parameters[numberParameters-1].append("on");
2087    parameters[numberParameters-1].append("root");
2088    parameters[numberParameters-1].append("ifmove");
2089  parameters[numberParameters-1].setLonghelp
2090    (
2091     "This switches on reduce and split  cuts (either at root or in entire tree) \
2092See branchAndCut for information on options."
2093     ); 
2094#endif
2095#ifdef COIN_HAS_CLP
2096  parameters[numberParameters++]=
2097    CbcOrClpParam("restore!Model","Restore model from binary file",
2098                  RESTORE);
2099  parameters[numberParameters-1].setLonghelp
2100    (
2101     "This reads data save by saveModel from the given file.  It will use the default\
2102 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
2103 is initialized to 'default.prob'."
2104     ); 
2105  parameters[numberParameters++]=
2106    CbcOrClpParam("reverse","Reverses sign of objective",
2107                  REVERSE,7,false);
2108  parameters[numberParameters-1].setLonghelp
2109    (
2110     "Useful for testing if maximization works correctly"
2111     ); 
2112  parameters[numberParameters++]=
2113    CbcOrClpParam("rhs!Scale","Scale factor to apply to rhs and bounds",
2114                  -1.0e20,1.0e20,RHSSCALE,false);
2115  parameters[numberParameters-1].setLonghelp
2116    (
2117     "If the rhs or bounds have some very large meaningful values, you may wish to scale them\
2118 internally by this amount.  It can also be set by autoscale"
2119     ); 
2120  parameters[numberParameters-1].setDoubleValue(1.0);
2121#endif
2122#ifdef COIN_HAS_CBC
2123  parameters[numberParameters++]=
2124    CbcOrClpParam("round!ingHeuristic","Whether to use Rounding heuristic",
2125                  "off",ROUNDING);
2126  parameters[numberParameters-1].append("on");
2127  parameters[numberParameters-1].setLonghelp
2128    (
2129     "This switches on a simple (but effective) rounding heuristic at each node of tree."
2130     ); 
2131#endif
2132  parameters[numberParameters++]=
2133    CbcOrClpParam("saveM!odel","Save model to binary file",
2134                  SAVE);
2135  parameters[numberParameters-1].setLonghelp
2136    (
2137     "This will save the problem to the given file name for future use\
2138 by restoreModel.  It will use the default\
2139 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
2140 is initialized to 'default.prob'."
2141     ); 
2142  parameters[numberParameters++]=
2143    CbcOrClpParam("saveS!olution","saves solution to file",
2144                  SAVESOL);
2145  parameters[numberParameters-1].setLonghelp
2146    (
2147     "This will write a binary solution file to the given file name.  It will use the default\
2148 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
2149 is initialized to 'solution.file'.  To read the file use fread(int) twice to pick up number of rows \
2150and columns, then fread(double) to pick up objective value, then pick up row activities, row duals, column \
2151activities and reduced costs - see bottom of CbcOrClpParam.cpp for code that writes file."
2152     ); 
2153  parameters[numberParameters++]=
2154    CbcOrClpParam("scal!ing","Whether to scale problem",
2155                  "off",SCALING);
2156  parameters[numberParameters-1].append("equi!librium");
2157  parameters[numberParameters-1].append("geo!metric");
2158  parameters[numberParameters-1].append("auto!matic");
2159  parameters[numberParameters-1].setLonghelp
2160    (
2161     "Scaling can help in solving problems which might otherwise fail because of lack of\
2162 accuracy.  It can also reduce the number of iterations.  It is not applied if the range\
2163 of elements is small.  When unscaled it is possible that there may be small primal and/or\
2164 infeasibilities."
2165     ); 
2166  parameters[numberParameters-1].setCurrentOption(3); // say auto
2167#ifndef COIN_HAS_CBC
2168  parameters[numberParameters++]=
2169    CbcOrClpParam("sec!onds","Maximum seconds",
2170                  -1.0,1.0e12,TIMELIMIT);
2171  parameters[numberParameters-1].setLonghelp
2172    (
2173     "After this many seconds clp will act as if maximum iterations had been reached \
2174(if value >=0).  \
2175In this program it is really only useful for testing but the library function\n\
2176      \tsetMaximumSeconds(value)\n can be useful."
2177     );
2178#else
2179  parameters[numberParameters++]=
2180    CbcOrClpParam("sec!onds","maximum seconds",
2181                  -1.0,1.0e12,TIMELIMIT_BAB);
2182  parameters[numberParameters-1].setLonghelp
2183    (
2184     "After this many seconds coin solver will act as if maximum nodes had been reached."
2185     );
2186#endif
2187  parameters[numberParameters++]=
2188    CbcOrClpParam("sleep","for debug",
2189                  DUMMY,7,false);
2190  parameters[numberParameters-1].setLonghelp
2191    (
2192     "If passed to solver fom ampl, then ampl will wait so that you can copy .nl file for debug."
2193     ); 
2194#ifdef COIN_HAS_CLP
2195  parameters[numberParameters++]=
2196    CbcOrClpParam("slp!Value","Number of slp passes before primal",
2197                  -1,50000,SLPVALUE,false);
2198  parameters[numberParameters-1].setLonghelp
2199    (
2200     "If you are solving a quadratic problem using primal then it may be helpful to do some \
2201sequential Lps to get a good approximate solution."
2202     ); 
2203#endif
2204  parameters[numberParameters++]=
2205    CbcOrClpParam("solu!tion","Prints solution to file",
2206                  SOLUTION);
2207  parameters[numberParameters-1].setLonghelp
2208    (
2209     "This will write a primitive solution file to the given file name.  It will use the default\
2210 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
2211 is initialized to 'stdout'.  The amount of output can be varied using printi!ngOptions or printMask."
2212     ); 
2213#ifdef COIN_HAS_CLP
2214#ifdef COIN_HAS_CBC
2215  parameters[numberParameters++]=
2216    CbcOrClpParam("solv!e","Solve problem",
2217                  BAB);
2218  parameters[numberParameters-1].setLonghelp
2219    (
2220     "If there are no integer variables then this just solves LP.  If there are integer variables \
2221this does branch and cut."
2222     ); 
2223  parameters[numberParameters++]=
2224    CbcOrClpParam("slog!Level","Level of detail in Solver output",
2225                  -1,63,SOLVERLOGLEVEL);
2226  parameters[numberParameters-1].setLonghelp
2227    (
2228     "If 0 then there should be no output in normal circumstances.  1 is probably the best\
2229 value for most uses, while 2 and 3 give more information."
2230     );
2231#else
2232  // allow solve as synonym for dual
2233  parameters[numberParameters++]=
2234    CbcOrClpParam("solv!e","Solve problem using dual simplex",
2235                  BAB);
2236  parameters[numberParameters-1].setLonghelp
2237    (
2238     "Just so can use solve for clp as well as in cbc"
2239     ); 
2240#endif
2241#endif
2242#ifdef COIN_HAS_CLP
2243  parameters[numberParameters++]=
2244    CbcOrClpParam("spars!eFactor","Whether factorization treated as sparse",
2245                  "on",SPARSEFACTOR,7,false);
2246  parameters[numberParameters-1].append("off");
2247  parameters[numberParameters++]=
2248    CbcOrClpParam("special!Options","Dubious options for Simplex - see ClpSimplex.hpp",
2249                  0,INT_MAX,SPECIALOPTIONS,false);
2250  parameters[numberParameters++]=
2251    CbcOrClpParam("sprint!Crash","Whether to try sprint crash",
2252                  -1,500,SPRINT);
2253  parameters[numberParameters-1].setLonghelp
2254    (
2255     "For long and thin problems this program may solve a series of small problems\
2256 created by taking a subset of the columns.  I introduced the idea as 'Sprint' after\
2257 an LP code of that name of the 60's which tried the same tactic (not totally successfully).\
2258  Cplex calls it 'sifting'.  -1 is automatic choice, 0 is off, n is number of passes"
2259     ); 
2260  parameters[numberParameters++]=
2261    CbcOrClpParam("stat!istics","Print some statistics",
2262                  STATISTICS);
2263  parameters[numberParameters-1].setLonghelp
2264    (
2265     "This command prints some statistics for the current model.\
2266 If log level >1 then more is printed.\
2267 These are for presolved model if presolve on (and unscaled)."
2268     );
2269#endif
2270  parameters[numberParameters++]=
2271    CbcOrClpParam("stop","Stops clp execution",
2272                  EXIT);
2273  parameters[numberParameters-1].setLonghelp
2274    (
2275     "This stops the execution of Clp, end, exit, quit and stop are synonyms"
2276     ); 
2277#ifdef COIN_HAS_CBC
2278  parameters[numberParameters++]=
2279    CbcOrClpParam("strengthen","Create strengthened problem",
2280                  STRENGTHEN,3);
2281  parameters[numberParameters-1].setLonghelp
2282    (
2283     "This creates a new problem by applying the root node cuts.  All tight constraints \
2284will be in resulting problem"
2285     ); 
2286  parameters[numberParameters++]=
2287    CbcOrClpParam("strong!Branching","Number of variables to look at in strong branching",
2288                  0,999999,STRONGBRANCHING);
2289  parameters[numberParameters-1].setLonghelp
2290    (
2291     "In order to decide which variable to branch on, the code will choose up to this number \
2292of unsatisfied variables to do mini up and down branches on.  Then the most effective one is chosen. \
2293If a variable is branched on many times then the previous average up and down costs may be used - \
2294see number before trust."
2295     ); 
2296#endif
2297#ifdef COIN_HAS_CLP
2298  parameters[numberParameters++]=
2299    CbcOrClpParam("subs!titution","How long a column to substitute for in presolve",
2300                  0,10000,SUBSTITUTION,false);
2301  parameters[numberParameters-1].setLonghelp
2302    (
2303     "Normally Presolve gets rid of 'free' variables when there are no more than 3 \
2304 variables in column.  If you increase this the number of rows may decrease but number of \
2305 elements may increase."
2306     ); 
2307  parameters[numberParameters++]=
2308    CbcOrClpParam("thread!s","Number of threads to try and use",
2309                  -2,64,THREADS);
2310#endif
2311#ifdef COIN_HAS_CBC
2312  parameters[numberParameters++]=
2313    CbcOrClpParam("tighten!Factor","Tighten bounds using this times largest \
2314activity at continuous solution",
2315                  1.0,1.0e20,TIGHTENFACTOR,false);
2316  parameters[numberParameters-1].setLonghelp
2317    (
2318     "This sleazy trick can help on some problems."
2319     ); 
2320#endif
2321#ifdef COIN_HAS_CLP
2322  parameters[numberParameters++]=
2323    CbcOrClpParam("tightLP","Poor person's preSolve for now",
2324                  TIGHTEN,7,false);
2325#endif
2326#ifdef COIN_HAS_CBC
2327  parameters[numberParameters++]=
2328    CbcOrClpParam("trust!PseudoCosts","Number of branches before we trust pseudocosts",
2329                  -1,2000000,NUMBERBEFORE);
2330  parameters[numberParameters-1].setLonghelp
2331    (
2332     "Using strong branching computes pseudo-costs.  After this many times for a variable we just \
2333trust the pseudo costs and do not do any more strong branching."
2334     ); 
2335#endif
2336#ifdef COIN_HAS_CBC
2337  parameters[numberParameters++]=
2338    CbcOrClpParam("two!MirCuts","Whether to use Two phase Mixed Integer Rounding cuts",
2339                  "off",TWOMIRCUTS);
2340  parameters[numberParameters-1].append("on");
2341  parameters[numberParameters-1].append("root");
2342  parameters[numberParameters-1].append("ifmove");
2343  parameters[numberParameters-1].setLonghelp
2344    (
2345     "This switches on two phase mixed integer rounding  cuts (either at root or in entire tree) \
2346See branchAndCut for information on options."
2347     ); 
2348#endif
2349  parameters[numberParameters++]=
2350    CbcOrClpParam("unitTest","Do unit test",
2351                  UNITTEST,3);
2352  parameters[numberParameters-1].setLonghelp
2353    (
2354     "This exercises the unit test for clp"
2355     ); 
2356  parameters[numberParameters++]=
2357    CbcOrClpParam("verbose","Switches on longer help on single ?",
2358                  0,7,VERBOSE,false);
2359  parameters[numberParameters-1].setLonghelp
2360    (
2361     "Set to 1 to get short help with ? list, 2 to get long help, 3 for both.  (add 4 to just get ampl ones)."
2362     ); 
2363  parameters[numberParameters-1].setIntValue(0);
2364  assert(numberParameters<CBCMAXPARAMETERS);
2365}
2366// Given a parameter type - returns its number in list
2367int whichParam (CbcOrClpParameterType name, 
2368                int numberParameters, CbcOrClpParam *const parameters)
2369{
2370  int i;
2371  for (i=0;i<numberParameters;i++) {
2372    if (parameters[i].type()==name)
2373      break;
2374  }
2375  assert (i<numberParameters);
2376  return i;
2377}
2378// Dump a solution to file
2379void saveSolution(const ClpSimplex * lpSolver,std::string fileName)
2380{
2381  FILE * fp=fopen(fileName.c_str(),"wb");
2382  if (fp) {
2383    int numberRows=lpSolver->numberRows();
2384    int numberColumns=lpSolver->numberColumns();
2385    double objectiveValue = lpSolver->objectiveValue();
2386    fwrite(&numberRows,sizeof(int),1,fp);
2387    fwrite(&numberColumns,sizeof(int),1,fp);
2388    fwrite(&objectiveValue,sizeof(double),1,fp);
2389    double * dualRowSolution = lpSolver->dualRowSolution();
2390    double * primalRowSolution = lpSolver->primalRowSolution();
2391    fwrite(primalRowSolution,sizeof(double),numberRows,fp);
2392    fwrite(dualRowSolution,sizeof(double),numberRows,fp);
2393    double * dualColumnSolution = lpSolver->dualColumnSolution();
2394    double * primalColumnSolution = lpSolver->primalColumnSolution();
2395    fwrite(primalColumnSolution,sizeof(double),numberColumns,fp);
2396    fwrite(dualColumnSolution,sizeof(double),numberColumns,fp);
2397    fclose(fp);
2398  } else {
2399    std::cout<<"Unable to open file "<<fileName<<std::endl;
2400  }
2401}
2402
Note: See TracBrowser for help on using the repository browser.