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

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

changes to simplex and lots of stuff and start Mumps cholesky

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