source: stable/1.11/Clp/src/CbcOrClpParam.cpp @ 1830

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

to keep compiler happy

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