source: branches/BSP/trunk/Clp/src/CbcOrClpParam.cpp @ 1087

Last change on this file since 1087 was 1087, checked in by ladanyi, 12 years ago

committing merging w/ trunk of Clp, Osi, Cbc

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