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

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

change message for slog

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