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

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

fixes etc

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