source: branches/devel/Clp/src/CbcOrClpParam.cpp @ 902

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

allow testosi -1

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