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

Last change on this file since 1453 was 1453, checked in by forrest, 10 years ago

second try at changes for seg fault and idiot

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 123.7 KB
Line 
1/* $Id: CbcOrClpParam.cpp 1453 2009-10-28 15:01:57Z 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].setLonghelp
1465    (
1466     "This switches on clique cuts (either at root or in entire tree) \
1467See branchAndCut for information on options."
1468     ); 
1469  parameters[numberParameters++]=
1470    CbcOrClpParam("combine!Solutions","Whether to use combine solution heuristic",
1471                  "off",COMBINE);
1472  parameters[numberParameters-1].append("on");
1473  parameters[numberParameters-1].append("both");
1474  parameters[numberParameters-1].append("before");
1475  parameters[numberParameters-1].setLonghelp
1476    (
1477     "This switches on a heuristic which does branch and cut on the problem given by just \
1478using variables which have appeared in one or more solutions. \
1479It obviously only tries after two or more solutions. \
1480See Rounding for meaning of on,both,before"
1481     ); 
1482  parameters[numberParameters++]=
1483    CbcOrClpParam("combine2!Solutions","Whether to use crossover solution heuristic",
1484                  "off",CROSSOVER2);
1485  parameters[numberParameters-1].append("on");
1486  parameters[numberParameters-1].append("both");
1487  parameters[numberParameters-1].append("before");
1488  parameters[numberParameters-1].setLonghelp
1489    (
1490     "This switches on a heuristic which does branch and cut on the problem given by \
1491fixing variables which have same value in two or more solutions. \
1492It obviously only tries after two or more solutions. \
1493See Rounding for meaning of on,both,before"
1494     ); 
1495  parameters[numberParameters++]=
1496    CbcOrClpParam("cost!Strategy","How to use costs as priorities",
1497                  "off",COSTSTRATEGY);
1498  parameters[numberParameters-1].append("pri!orities");
1499  parameters[numberParameters-1].append("column!Order?");
1500  parameters[numberParameters-1].append("01f!irst?");
1501  parameters[numberParameters-1].append("01l!ast?");
1502  parameters[numberParameters-1].append("length!?");
1503  parameters[numberParameters-1].setLonghelp
1504    (
1505     "This orders the variables in order of their absolute costs - with largest cost ones being branched on \
1506first.  This primitive strategy can be surprsingly effective.  The column order\
1507 option is obviously not on costs but easy to code here."
1508     ); 
1509  parameters[numberParameters++]=
1510    CbcOrClpParam("cplex!Use","Whether to use Cplex!",
1511                  "off",CPX);
1512  parameters[numberParameters-1].append("on");
1513  parameters[numberParameters-1].setLonghelp
1514    (
1515     " If the user has Cplex, but wants to use some of Cbc's heuristics \
1516then you can!  If this is on, then Cbc will get to the root node and then \
1517hand over to Cplex.  If heuristics find a solution this can be significantly \
1518quicker.  You will probably want to switch off Cbc's cuts as Cplex thinks \
1519they are genuine constraints.  It is also probable that you want to switch \
1520off preprocessing, although for difficult problems it is worth trying \
1521both."
1522     ); 
1523#endif
1524  parameters[numberParameters++]=
1525    CbcOrClpParam("cpp!Generate","Generates C++ code",
1526                  -1,50000,CPP,1);
1527  parameters[numberParameters-1].setLonghelp
1528    (
1529     "Once you like what the stand-alone solver does then this allows \
1530you to generate user_driver.cpp which approximates the code.  \
15310 gives simplest driver, 1 generates saves and restores, 2 \
1532generates saves and restores even for variables at default value. \
15334 bit in cbc generates size dependent code rather than computed values.  \
1534This is now deprecated as you can call stand-alone solver - see \
1535Cbc/examples/driver4.cpp."
1536     );
1537#ifdef COIN_HAS_CLP
1538  parameters[numberParameters++]=
1539    CbcOrClpParam("crash","Whether to create basis for problem",
1540                  "off",CRASH);
1541  parameters[numberParameters-1].append("on");
1542  parameters[numberParameters-1].append("so!low_halim");
1543  parameters[numberParameters-1].append("ha!lim_solow(JJF mods)");
1544  //  parameters[numberParameters-1].append("4");
1545  //  parameters[numberParameters-1].append("5");
1546  parameters[numberParameters-1].setLonghelp
1547    (
1548     "If crash is set on and there is an all slack basis then Clp will flip or put structural\
1549 variables into basis with the aim of getting dual feasible.  On the whole dual seems to be\
1550 better without it and there are alternative types of 'crash' for primal e.g. 'idiot' or 'sprint'. \
1551I have also added a variant due to Solow and Halim which is as on but just flip."); 
1552  parameters[numberParameters++]=
1553    CbcOrClpParam("cross!over","Whether to get a basic solution after barrier",
1554                  "on",CROSSOVER);
1555  parameters[numberParameters-1].append("off");
1556  parameters[numberParameters-1].append("maybe");
1557  parameters[numberParameters-1].append("presolve");
1558  parameters[numberParameters-1].setLonghelp
1559    (
1560     "Interior point algorithms do not obtain a basic solution (and \
1561the feasibility criterion is a bit suspect (JJF)).  This option will crossover \
1562to a basic solution suitable for ranging or branch and cut.  With the current state \
1563of quadratic it may be a good idea to switch off crossover for quadratic (and maybe \
1564presolve as well) - the option maybe does this."
1565     );
1566#endif
1567#ifdef COIN_HAS_CBC
1568  parameters[numberParameters++]=
1569    CbcOrClpParam("csv!Statistics","Create one line of statistics",
1570                  CSVSTATISTICS,2,1);
1571  parameters[numberParameters-1].setLonghelp
1572    (
1573     "This appends statistics to given file name.  It will use the default\
1574 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
1575 is initialized to '', i.e. it must be set.  Adds header if file empty or does not exist."
1576     ); 
1577  parameters[numberParameters++]=
1578    CbcOrClpParam("cutD!epth","Depth in tree at which to do cuts",
1579                  -1,999999,CUTDEPTH);
1580  parameters[numberParameters-1].setLonghelp
1581    (
1582     "Cut generators may be - off, on only at root, on if they look possible \
1583and on.  If they are done every node then that is that, but it may be worth doing them \
1584every so often.  The original method was every so many nodes but it is more logical \
1585to do it whenever depth in tree is a multiple of K.  This option does that and defaults \
1586to -1 (off -> code decides)."
1587     );
1588  parameters[numberParameters-1].setIntValue(-1);
1589  parameters[numberParameters++]=
1590    CbcOrClpParam("cutL!ength","Length of a cut",
1591                  -1,COIN_INT_MAX,CUTLENGTH);
1592  parameters[numberParameters-1].setLonghelp
1593    (
1594     "At present this only applies to Gomory cuts. -1 (default) leaves as is. \
1595Any value >0 says that all cuts <= this length can be generated both at \
1596root node and in tree. 0 says to use some dynamic lengths.  If value >=10,000,000 \
1597then the length in tree is value%10000000 - so 10000100 means unlimited length \
1598at root and 100 in tree."
1599     );
1600  parameters[numberParameters-1].setIntValue(-1);
1601  parameters[numberParameters++]=
1602    CbcOrClpParam("cuto!ff","All solutions must be better than this",
1603                  -1.0e60,1.0e60,CUTOFF);
1604  parameters[numberParameters-1].setDoubleValue(1.0e50);
1605  parameters[numberParameters-1].setLonghelp
1606    (
1607     "All solutions must be better than this value (in a minimization sense).  \
1608This is also set by code whenever it obtains a solution and is set to value of \
1609objective for solution minus cutoff increment."
1610     );
1611  parameters[numberParameters++]=
1612    CbcOrClpParam("cuts!OnOff","Switches all cuts on or off",
1613                  "off",CUTSSTRATEGY);
1614  parameters[numberParameters-1].append("on");
1615  parameters[numberParameters-1].append("root");
1616  parameters[numberParameters-1].append("ifmove");
1617  parameters[numberParameters-1].append("forceOn");
1618  parameters[numberParameters-1].setLonghelp
1619    (
1620     "This can be used to switch on or off all cuts (apart from Reduce and Split).  Then you can do \
1621individual ones off or on \
1622See branchAndCut for information on options."
1623     ); 
1624  parameters[numberParameters++]=
1625    CbcOrClpParam("debug!In","read valid solution from file",
1626                  DEBUG,7,1);
1627  parameters[numberParameters-1].setLonghelp
1628    (
1629     "This will read a solution file from the given file name.  It will use the default\
1630 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
1631 is initialized to '', i.e. it must be set.\n\n\
1632If set to create it will create a file called debug.file  after search.\n\n\
1633The idea is that if you suspect a bad cut generator \
1634you can do a good run with debug set to 'create' and then switch on the cuts you suspect and \
1635re-run with debug set to 'debug.file'  The create case has same effect as saveSolution."
1636     ); 
1637#endif
1638#ifdef COIN_HAS_CLP
1639#if CLP_MULTIPLE_FACTORIZATIONS >0
1640  parameters[numberParameters++]=
1641    CbcOrClpParam("dense!Threshold","Whether to use dense factorization",
1642                  -1,10000,DENSE,1);
1643  parameters[numberParameters-1].setLonghelp
1644    (
1645     "If processed problem <= this use dense factorization"
1646     ); 
1647  parameters[numberParameters-1].setIntValue(-1);
1648#endif
1649#endif
1650#ifdef COIN_HAS_CBC
1651  parameters[numberParameters++]=
1652    CbcOrClpParam("depth!MiniBab","Depth at which to try mini BAB",
1653                  -COIN_INT_MAX,COIN_INT_MAX,DEPTHMINIBAB);
1654  parameters[numberParameters-1].setIntValue(-1);
1655  parameters[numberParameters-1].setLonghelp
1656    (
1657     "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 \
1658means 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."
1659     ); 
1660  parameters[numberParameters++]=
1661    CbcOrClpParam("dextra3","Extra double parameter 3",
1662                  -COIN_DBL_MAX,COIN_DBL_MAX,DEXTRA3,0);
1663  parameters[numberParameters-1].setDoubleValue(0.0);
1664  parameters[numberParameters++]=
1665    CbcOrClpParam("dextra4","Extra double parameter 4",
1666                  -COIN_DBL_MAX,COIN_DBL_MAX,DEXTRA4,0);
1667  parameters[numberParameters-1].setDoubleValue(0.0);
1668  parameters[numberParameters++]=
1669    CbcOrClpParam("dextra5","Extra double parameter 5",
1670                  -COIN_DBL_MAX,COIN_DBL_MAX,DEXTRA5,0);
1671  parameters[numberParameters-1].setDoubleValue(0.0);
1672  parameters[numberParameters++]=
1673      CbcOrClpParam("Dins","Whether to try Distance Induced Neighborhood Search",
1674                    "off",DINS);
1675  parameters[numberParameters-1].append("on");
1676  parameters[numberParameters-1].append("both");
1677  parameters[numberParameters-1].append("before");
1678  parameters[numberParameters-1].append("often");
1679  parameters[numberParameters-1].setLonghelp
1680    (
1681     "This switches on Distance induced neighborhood Search. \
1682See Rounding for meaning of on,both,before"
1683     ); 
1684#endif
1685  parameters[numberParameters++]=
1686    CbcOrClpParam("direction","Minimize or Maximize",
1687                  "min!imize",DIRECTION);
1688  parameters[numberParameters-1].append("max!imize");
1689  parameters[numberParameters-1].append("zero");
1690  parameters[numberParameters-1].setLonghelp
1691    (
1692     "The default is minimize - use 'direction maximize' for maximization.\n\
1693You can also use the parameters 'maximize' or 'minimize'."
1694     ); 
1695  parameters[numberParameters++]=
1696    CbcOrClpParam("directory","Set Default directory for import etc.",
1697                  DIRECTORY);
1698  parameters[numberParameters-1].setLonghelp
1699    (
1700     "This sets the directory which import, export, saveModel, restoreModel etc will use.\
1701  It is initialized to './'"
1702     ); 
1703  parameters[numberParameters++]=
1704    CbcOrClpParam("dirSample","Set directory where the COIN-OR sample problems are.",
1705                  DIRSAMPLE,7,1);
1706  parameters[numberParameters-1].setLonghelp
1707    (
1708     "This sets the directory where the COIN-OR sample problems reside. It is\
1709 used only when -unitTest is passed to clp. clp will pick up the test problems\
1710 from this directory.\
1711 It is initialized to '../../Data/Sample'"
1712     ); 
1713  parameters[numberParameters++]=
1714    CbcOrClpParam("dirNetlib","Set directory where the netlib problems are.",
1715                  DIRNETLIB,7,1);
1716  parameters[numberParameters-1].setLonghelp
1717    (
1718     "This sets the directory where the netlib problems reside. One can get\
1719 the netlib problems from COIN-OR or from the main netlib site. This\
1720 parameter is used only when -netlib is passed to clp. clp will pick up the\
1721 netlib problems from this directory. If clp is built without zlib support\
1722 then the problems must be uncompressed.\
1723 It is initialized to '../../Data/Netlib'"
1724     ); 
1725  parameters[numberParameters++]=
1726    CbcOrClpParam("dirMiplib","Set directory where the miplib 2003 problems are.",
1727                  DIRMIPLIB,7,1);
1728  parameters[numberParameters-1].setLonghelp
1729    (
1730     "This sets the directory where the miplib 2003 problems reside. One can\
1731 get the miplib problems from COIN-OR or from the main miplib site. This\
1732 parameter is used only when -miplib is passed to cbc. cbc will pick up the\
1733 miplib problems from this directory. If cbc is built without zlib support\
1734 then the problems must be uncompressed.\
1735 It is initialized to '../../Data/miplib3'"
1736     ); 
1737#ifdef COIN_HAS_CBC
1738  parameters[numberParameters++]=
1739    CbcOrClpParam("diveO!pt","Diving options",
1740                  -1,200000,DIVEOPT,1);
1741  parameters[numberParameters-1].setLonghelp
1742    (
1743     "If >2 && <8 then modify diving options - \
1744         \t3 only at root and if no solution,  \
1745         \t4 only at root and if this heuristic has not got solution, \
1746         \t5 only at depth <4, \
1747         \t6 decay, \
1748         \t7 run up to 2 times if solution found 4 otherwise."
1749     ); 
1750  parameters[numberParameters-1].setIntValue(-1);
1751  parameters[numberParameters++]=
1752      CbcOrClpParam("DivingS!ome","Whether to try Diving heuristics",
1753                    "off",DIVINGS);
1754  parameters[numberParameters-1].append("on");
1755  parameters[numberParameters-1].append("both");
1756  parameters[numberParameters-1].append("before");
1757  parameters[numberParameters-1].setLonghelp
1758    (
1759     "This switches on a random diving heuristic at various times. \
1760C - Coefficient, F - Fractional, G - Guided, L - LineSearch, P - PseudoCost, V - VectorLength. \
1761You may prefer to use individual on/off \
1762See Rounding for meaning of on,both,before"
1763     ); 
1764  parameters[numberParameters++]=
1765      CbcOrClpParam("DivingC!oefficient","Whether to try DiveCoefficient",
1766                    "off",DIVINGC);
1767  parameters[numberParameters-1].append("on");
1768  parameters[numberParameters-1].append("both");
1769  parameters[numberParameters-1].append("before");
1770  parameters[numberParameters++]=
1771      CbcOrClpParam("DivingF!ractional","Whether to try DiveFractional",
1772                    "off",DIVINGF);
1773  parameters[numberParameters-1].append("on");
1774  parameters[numberParameters-1].append("both");
1775  parameters[numberParameters-1].append("before");
1776  parameters[numberParameters++]=
1777      CbcOrClpParam("DivingG!uided","Whether to try DiveGuided",
1778                    "off",DIVINGG);
1779  parameters[numberParameters-1].append("on");
1780  parameters[numberParameters-1].append("both");
1781  parameters[numberParameters-1].append("before");
1782  parameters[numberParameters++]=
1783      CbcOrClpParam("DivingL!ineSearch","Whether to try DiveLineSearch",
1784                    "off",DIVINGL);
1785  parameters[numberParameters-1].append("on");
1786  parameters[numberParameters-1].append("both");
1787  parameters[numberParameters-1].append("before");
1788  parameters[numberParameters++]=
1789      CbcOrClpParam("DivingP!seudoCost","Whether to try DivePseudoCost",
1790                    "off",DIVINGP);
1791  parameters[numberParameters-1].append("on");
1792  parameters[numberParameters-1].append("both");
1793  parameters[numberParameters-1].append("before");
1794  parameters[numberParameters++]=
1795      CbcOrClpParam("DivingV!ectorLength","Whether to try DiveVectorLength",
1796                    "off",DIVINGV);
1797  parameters[numberParameters-1].append("on");
1798  parameters[numberParameters-1].append("both");
1799  parameters[numberParameters-1].append("before");
1800  parameters[numberParameters++]=
1801    CbcOrClpParam("doH!euristic","Do heuristics before any preprocessing",
1802                  DOHEURISTIC,3);
1803  parameters[numberParameters-1].setLonghelp
1804    (
1805     "Normally heuristics are done in branch and bound.  It may be useful to do them outside. \
1806Only those heuristics with 'both' or 'before' set will run.  \
1807Doing this may also set cutoff, which can help with preprocessing."
1808     ); 
1809#endif
1810#ifdef COIN_HAS_CLP
1811  parameters[numberParameters++]=
1812    CbcOrClpParam("dualB!ound","Initially algorithm acts as if no \
1813gap between bounds exceeds this value",
1814                  1.0e-20,1.0e12,DUALBOUND);
1815  parameters[numberParameters-1].setLonghelp
1816    (
1817     "The dual algorithm in Clp is a single phase algorithm as opposed to a two phase\
1818 algorithm where you first get feasible then optimal.  If a problem has both upper and\
1819 lower bounds then it is trivial to get dual feasible by setting non basic variables\
1820 to correct bound.  If the gap between the upper and lower bounds of a variable is more\
1821 than the value of dualBound Clp introduces fake bounds so that it can make the problem\
1822 dual feasible.  This has the same effect as a composite objective function in the\
1823 primal algorithm.  Too high a value may mean more iterations, while too low a bound means\
1824 the code may go all the way and then have to increase the bounds.  OSL had a heuristic to\
1825 adjust bounds, maybe we need that here."
1826     );
1827  parameters[numberParameters++]=
1828    CbcOrClpParam("dualize","Solves dual reformulation",
1829                  0,3,DUALIZE,1);
1830  parameters[numberParameters-1].setLonghelp
1831    (
1832     "Don't even think about it."
1833     ); 
1834  parameters[numberParameters++]=
1835    CbcOrClpParam("dualP!ivot","Dual pivot choice algorithm",
1836                  "auto!matic",DUALPIVOT,7,1);
1837  parameters[numberParameters-1].append("dant!zig");
1838  parameters[numberParameters-1].append("partial");
1839  parameters[numberParameters-1].append("steep!est");
1840  parameters[numberParameters-1].setLonghelp
1841    (
1842     "Clp can use any pivot selection algorithm which the user codes as long as it\
1843 implements the features in the abstract pivot base class.  The Dantzig method is implemented\
1844 to show a simple method but its use is deprecated.  Steepest is the method of choice and there\
1845 are two variants which keep all weights updated but only scan a subset each iteration.\
1846 Partial switches this on while automatic decides at each iteration based on information\
1847 about the factorization."
1848     ); 
1849  parameters[numberParameters++]=
1850    CbcOrClpParam("dualS!implex","Do dual simplex algorithm",
1851                  DUALSIMPLEX);
1852  parameters[numberParameters-1].setLonghelp
1853    (
1854     "This command solves the current model using the dual steepest edge algorithm.\
1855The time and iterations may be affected by settings such as presolve, scaling, crash\
1856 and also by dual pivot method, fake bound on variables and dual and primal tolerances."
1857     );
1858#endif
1859  parameters[numberParameters++]=
1860    CbcOrClpParam("dualT!olerance","For an optimal solution \
1861no dual infeasibility may exceed this value",
1862                  1.0e-20,1.0e12,DUALTOLERANCE);
1863  parameters[numberParameters-1].setLonghelp
1864    (
1865     "Normally the default tolerance is fine, but you may want to increase it a\
1866 bit if a dual run seems to be having a hard time.  One method which can be faster is \
1867to use a large tolerance e.g. 1.0e-4 and dual and then clean up problem using primal and the \
1868correct tolerance (remembering to switch off presolve for this final short clean up phase)."
1869     ); 
1870#ifdef COIN_HAS_CLP
1871  parameters[numberParameters++]=
1872    CbcOrClpParam("either!Simplex","Do dual or primal simplex algorithm",
1873                  EITHERSIMPLEX);
1874  parameters[numberParameters-1].setLonghelp
1875    (
1876     "This command solves the current model using the dual or primal algorithm,\
1877 based on a dubious analysis of model."
1878     );
1879#endif
1880  parameters[numberParameters++]=
1881    CbcOrClpParam("end","Stops clp execution",
1882                  EXIT);
1883  parameters[numberParameters-1].setLonghelp
1884    (
1885     "This stops execution ; end, exit, quit and stop are synonyms"
1886     ); 
1887  parameters[numberParameters++]=
1888    CbcOrClpParam("environ!ment","Read commands from environment",
1889                  ENVIRONMENT,7,0);
1890  parameters[numberParameters-1].setLonghelp
1891    (
1892     "This starts reading from environment variable CBC_CLP_ENVIRONMENT."
1893     );
1894  parameters[numberParameters++]=
1895    CbcOrClpParam("error!sAllowed","Whether to allow import errors",
1896                  "off",ERRORSALLOWED,3);
1897  parameters[numberParameters-1].append("on");
1898  parameters[numberParameters-1].setLonghelp
1899    (
1900     "The default is not to use any model which had errors when reading the mps file.\
1901  Setting this to 'on' will allow all errors from which the code can recover\
1902 simply by ignoring the error.  There are some errors from which the code can not recover \
1903e.g. no ENDATA.  This has to be set before import i.e. -errorsAllowed on -import xxxxxx.mps."
1904     );
1905  parameters[numberParameters++]=
1906    CbcOrClpParam("exit","Stops clp execution",
1907                  EXIT);
1908  parameters[numberParameters-1].setLonghelp
1909    (
1910     "This stops the execution of Clp, end, exit, quit and stop are synonyms"
1911     ); 
1912#ifdef COIN_HAS_CBC
1913  parameters[numberParameters++]=
1914    CbcOrClpParam("exp!eriment","Whether to use testing features",
1915                  -1,200,EXPERIMENT,0);
1916  parameters[numberParameters-1].setLonghelp
1917    (
1918     "Defines how adventurous you want to be in using new ideas. \
19190 then no new ideas, 1 fairly sensible, 2 a bit dubious, 3 you are on your own!"
1920     ); 
1921  parameters[numberParameters-1].setIntValue(0);
1922#endif
1923  parameters[numberParameters++]=
1924    CbcOrClpParam("export","Export model as mps file",
1925                  EXPORT);
1926  parameters[numberParameters-1].setLonghelp
1927    (
1928     "This will write an MPS format file to the given file name.  It will use the default\
1929 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
1930 is initialized to 'default.mps'.  \
1931It 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."
1932     ); 
1933#ifdef COIN_HAS_CBC
1934  parameters[numberParameters++]=
1935    CbcOrClpParam("extra1","Extra integer parameter 1",
1936                  -COIN_INT_MAX,COIN_INT_MAX,EXTRA1,0);
1937  parameters[numberParameters-1].setIntValue(-1);
1938  parameters[numberParameters++]=
1939    CbcOrClpParam("extra2","Extra integer parameter 2",
1940                  -100,COIN_INT_MAX,EXTRA2,0);
1941  parameters[numberParameters-1].setIntValue(-1);
1942  parameters[numberParameters++]=
1943    CbcOrClpParam("extra3","Extra integer parameter 3",
1944                  -1,COIN_INT_MAX,EXTRA3,0);
1945  parameters[numberParameters-1].setIntValue(-1);
1946  parameters[numberParameters++]=
1947    CbcOrClpParam("extra4","Extra integer parameter 4",
1948                  -1,COIN_INT_MAX,EXTRA4,0);
1949  parameters[numberParameters-1].setIntValue(-1);
1950  parameters[numberParameters-1].setLonghelp
1951    (
1952     "This switches on yet more special options!! \
1953The bottom digit is a strategy when to used shadow price stuff e.g. 3 \
1954means use until a solution is found.  The next two digits say what sort \
1955of dual information to use.  After that it goes back to powers of 2 so -\n\
1956\t1000 - switches on experimental hotstart\n\
1957\t2,4,6000 - switches on experimental methods of stopping cuts\n\
1958\t8000 - increase minimum drop gradually\n\
1959\t16000 - switches on alternate gomory criterion"
1960     ); 
1961#endif
1962#ifdef COIN_HAS_CLP
1963  parameters[numberParameters++]=
1964    CbcOrClpParam("fact!orization","Which factorization to use",
1965                  "normal",FACTORIZATION);
1966  parameters[numberParameters-1].append("dense");
1967  parameters[numberParameters-1].append("simple");
1968  parameters[numberParameters-1].append("osl");
1969  parameters[numberParameters-1].setLonghelp
1970    (
1971     "The default is to use the normal CoinFactorization, but \
1972other choices are a dense one, osl's or one designed for small problems."
1973     ); 
1974  parameters[numberParameters++]=
1975    CbcOrClpParam("fakeB!ound","All bounds <= this value - DEBUG",
1976                  1.0,1.0e15,FAKEBOUND,0);
1977#ifdef COIN_HAS_CBC
1978  parameters[numberParameters++]=
1979    CbcOrClpParam("feas!ibilityPump","Whether to try Feasibility Pump",
1980                  "off",FPUMP);
1981  parameters[numberParameters-1].append("on");
1982  parameters[numberParameters-1].append("both");
1983  parameters[numberParameters-1].append("before");
1984  parameters[numberParameters-1].setLonghelp
1985    (
1986     "This switches on feasibility pump heuristic at root. This is due to Fischetti, Lodi and Glover \
1987and uses a sequence of Lps to try and get an integer feasible solution. \
1988Some fine tuning is available by passFeasibilityPump and also pumpTune. \
1989See Rounding for meaning of on,both,before"
1990     ); 
1991  parameters[numberParameters++]=
1992    CbcOrClpParam("fix!OnDj","Try heuristic based on fixing variables with \
1993reduced costs greater than this",
1994                  -1.0e20,1.0e20,DJFIX,1);
1995  parameters[numberParameters-1].setLonghelp
1996    (
1997     "If this is set integer variables with reduced costs greater than this will be fixed \
1998before branch and bound - use with extreme caution!" 
1999     ); 
2000    parameters[numberParameters++]=
2001      CbcOrClpParam("flow!CoverCuts","Whether to use Flow Cover cuts",
2002                    "off",FLOWCUTS);
2003    parameters[numberParameters-1].append("on");
2004    parameters[numberParameters-1].append("root");
2005    parameters[numberParameters-1].append("ifmove");
2006    parameters[numberParameters-1].append("forceOn");
2007    parameters[numberParameters-1].append("onglobal");
2008    parameters[numberParameters-1].setLonghelp
2009    (
2010     "This switches on flow cover cuts (either at root or in entire tree) \
2011See branchAndCut for information on options."
2012     ); 
2013    parameters[numberParameters++]=
2014      CbcOrClpParam("force!Solution","Whether to use given solution as crash for BAB",
2015                    -1,20000000,USESOLUTION);
2016    parameters[numberParameters-1].setIntValue(-1);
2017    parameters[numberParameters-1].setLonghelp
2018    (
2019     "-1 off.  If 1 then tries to branch to solution given by AMPL or priorities file. \
2020If 0 then just tries to set as best solution \
2021If >1 then also does that many nodes on fixed problem."
2022     ); 
2023  parameters[numberParameters++]=
2024    CbcOrClpParam("fraction!forBAB","Fraction in feasibility pump",
2025                  1.0e-5,1.1,SMALLBAB,1);
2026  parameters[numberParameters-1].setDoubleValue(0.5);
2027  parameters[numberParameters-1].setLonghelp
2028    (
2029     "After a pass in feasibility pump, variables which have not moved \
2030about are fixed and if the preprocessed model is small enough a few nodes \
2031of branch and bound are done on reduced problem.  Small problem has to be less than this fraction of original."
2032     ); 
2033#endif
2034  parameters[numberParameters++]=
2035    CbcOrClpParam("gamma!(Delta)","Whether to regularize barrier",
2036                  "off",GAMMA,7,1);
2037  parameters[numberParameters-1].append("on");
2038  parameters[numberParameters-1].append("gamma");
2039  parameters[numberParameters-1].append("delta");
2040  parameters[numberParameters-1].append("onstrong");
2041  parameters[numberParameters-1].append("gammastrong");
2042  parameters[numberParameters-1].append("deltastrong");
2043#endif
2044#ifdef COIN_HAS_CBC
2045  parameters[numberParameters++]=
2046    CbcOrClpParam("gomory!Cuts","Whether to use Gomory cuts",
2047                  "off",GOMORYCUTS);
2048  parameters[numberParameters-1].append("on");
2049  parameters[numberParameters-1].append("root");
2050  parameters[numberParameters-1].append("ifmove");
2051  parameters[numberParameters-1].append("forceOn");
2052  parameters[numberParameters-1].append("onglobal");
2053  parameters[numberParameters-1].append("forceandglobal");
2054  parameters[numberParameters-1].append("forceLongOn");
2055  parameters[numberParameters-1].append("long");
2056  parameters[numberParameters-1].setLonghelp
2057    (
2058     "The original cuts - beware of imitations!  Having gone out of favor, they are now more \
2059fashionable as LP solvers are more robust and they interact well with other cuts.  They will almost always \
2060give cuts (although in this executable they are limited as to number of variables in cut).  \
2061However the cuts may be dense so it is worth experimenting (Long allows any length). \
2062See branchAndCut for information on options."
2063     ); 
2064  parameters[numberParameters++]=
2065    CbcOrClpParam("greedy!Heuristic","Whether to use a greedy heuristic",
2066                  "off",GREEDY);
2067  parameters[numberParameters-1].append("on");
2068  parameters[numberParameters-1].append("both");
2069  parameters[numberParameters-1].append("before");
2070  //parameters[numberParameters-1].append("root");
2071  parameters[numberParameters-1].setLonghelp
2072    (
2073     "Switches on a greedy heuristic which will try and obtain a solution.  It may just fix a \
2074percentage of variables and then try a small branch and cut run. \
2075See Rounding for meaning of on,both,before"
2076     ); 
2077  parameters[numberParameters++]=
2078    CbcOrClpParam("heur!isticsOnOff","Switches most heuristics on or off",
2079                  "off",HEURISTICSTRATEGY);
2080  parameters[numberParameters-1].append("on");
2081  parameters[numberParameters-1].setLonghelp
2082    (
2083     "This can be used to switch on or off all heuristics.  Then you can do \
2084individual ones off or on.  CbcTreeLocal is not included as it dramatically \
2085alters search."
2086     ); 
2087#endif
2088  parameters[numberParameters++]=
2089    CbcOrClpParam("help","Print out version, non-standard options and some help",
2090                  HELP,3);
2091  parameters[numberParameters-1].setLonghelp
2092    (
2093     "This prints out some help to get user started.  If you have printed this then \
2094you should be past that stage:-)"
2095     ); 
2096#ifdef COIN_HAS_CBC
2097  parameters[numberParameters++]=
2098    CbcOrClpParam("hOp!tions","Heuristic options",
2099                  -9999999,9999999,HOPTIONS,1);
2100  parameters[numberParameters-1].setLonghelp
2101    (
2102     "1 says stop heuristic immediately allowable gap reached. \
2103Others are for feasibility pump - \
21042 says do exact number of passes given, \
21054 only applies if initial cutoff given and says relax after 50 passes, \
2106while 8 will adapt cutoff rhs after first solution if it looks as if code is stalling."
2107     ); 
2108  parameters[numberParameters-1].setIntValue(0);
2109  parameters[numberParameters++]=
2110    CbcOrClpParam("hot!StartMaxIts","Maximum iterations on hot start",
2111                  0,COIN_INT_MAX,MAXHOTITS);
2112#endif
2113#ifdef COIN_HAS_CLP
2114  parameters[numberParameters++]=
2115    CbcOrClpParam("idiot!Crash","Whether to try idiot crash",
2116                  -1,99999999,IDIOT);
2117  parameters[numberParameters-1].setLonghelp
2118    (
2119     "This is a type of 'crash' which works well on some homogeneous problems.\
2120 It works best on problems with unit elements and rhs but will do something to any model.  It should only be\
2121 used before primal.  It can be set to -1 when the code decides for itself whether to use it,\
2122 0 to switch off or n > 0 to do n passes."
2123     ); 
2124#endif
2125  parameters[numberParameters++]=
2126    CbcOrClpParam("import","Import model from mps file",
2127                  IMPORT,3);
2128  parameters[numberParameters-1].setLonghelp
2129    (
2130     "This will read an MPS format file from the given file name.  It will use the default\
2131 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
2132 is initialized to '', i.e. it must be set.  If you have libgz then it can read compressed\
2133 files 'xxxxxxxx.gz' or 'xxxxxxxx.bz2'.  \
2134If 'keepnames' is off, then names are dropped -> Rnnnnnnn and Cnnnnnnn."
2135     );
2136#ifdef COIN_HAS_CBC
2137  parameters[numberParameters++]=
2138    CbcOrClpParam("inc!rement","A valid solution must be at least this \
2139much better than last integer solution",
2140                  -1.0e20,1.0e20,INCREMENT);
2141  parameters[numberParameters-1].setLonghelp
2142    (
2143     "Whenever a solution is found the bound on solutions is set to solution (in a minimization\
2144sense) plus this.  If it is not set then the code will try and work one out e.g. if \
2145all objective coefficients are multiples of 0.01 and only integer variables have entries in \
2146objective then this can be set to 0.01.  Be careful if you set this negative!"
2147     ); 
2148  parameters[numberParameters++]=
2149    CbcOrClpParam("inf!easibilityWeight","Each integer infeasibility is expected \
2150to cost this much",
2151                  0.0,1.0e20,INFEASIBILITYWEIGHT,1);
2152  parameters[numberParameters-1].setLonghelp
2153    (
2154     "A primitive way of deciding which node to explore next.  Satisfying each integer infeasibility is \
2155expected to cost this much."
2156     ); 
2157  parameters[numberParameters++]=
2158    CbcOrClpParam("initialS!olve","Solve to continuous",
2159                  SOLVECONTINUOUS);
2160  parameters[numberParameters-1].setLonghelp
2161    (
2162     "This just solves the problem to continuous - without adding any cuts"
2163     ); 
2164  parameters[numberParameters++]=
2165    CbcOrClpParam("integerT!olerance","For an optimal solution \
2166no integer variable may be this away from an integer value",
2167              1.0e-20,0.5,INTEGERTOLERANCE);
2168  parameters[numberParameters-1].setLonghelp
2169    (
2170     "Beware of setting this smaller than the primal tolerance."
2171     ); 
2172#endif
2173#ifdef COIN_HAS_CLP
2174  parameters[numberParameters++]=
2175    CbcOrClpParam("keepN!ames","Whether to keep names from import",
2176                  "on",KEEPNAMES);
2177  parameters[numberParameters-1].append("off");
2178  parameters[numberParameters-1].setLonghelp
2179    (
2180     "It saves space to get rid of names so if you need to you can set this to off.  \
2181This needs to be set before the import of model - so -keepnames off -import xxxxx.mps."
2182     ); 
2183  parameters[numberParameters++]=
2184    CbcOrClpParam("KKT","Whether to use KKT factorization",
2185                  "off",KKT,7,1);
2186  parameters[numberParameters-1].append("on");
2187#endif
2188#ifdef COIN_HAS_CBC
2189  parameters[numberParameters++]=
2190    CbcOrClpParam("knapsack!Cuts","Whether to use Knapsack cuts",
2191                  "off",KNAPSACKCUTS);
2192  parameters[numberParameters-1].append("on");
2193  parameters[numberParameters-1].append("root");
2194  parameters[numberParameters-1].append("ifmove");
2195  parameters[numberParameters-1].append("forceOn");
2196  parameters[numberParameters-1].append("onglobal");
2197  parameters[numberParameters-1].append("forceandglobal");
2198  parameters[numberParameters-1].setLonghelp
2199    (
2200     "This switches on knapsack cuts (either at root or in entire tree) \
2201See branchAndCut for information on options."
2202     ); 
2203  parameters[numberParameters++]=
2204    CbcOrClpParam("lift!AndProjectCuts","Whether to use Lift and Project cuts",
2205                  "off",LANDPCUTS);
2206  parameters[numberParameters-1].append("on");
2207  parameters[numberParameters-1].append("root");
2208  parameters[numberParameters-1].append("ifmove");
2209  parameters[numberParameters-1].append("forceOn");
2210  parameters[numberParameters-1].setLonghelp
2211    (
2212     "Lift and project cuts - may be expensive to compute. \
2213See branchAndCut for information on options."
2214     ); 
2215  parameters[numberParameters++]=
2216    CbcOrClpParam("local!TreeSearch","Whether to use local treesearch",
2217                  "off",LOCALTREE);
2218  parameters[numberParameters-1].append("on");
2219  parameters[numberParameters-1].setLonghelp
2220    (
2221     "This switches on a local search algorithm when a solution is found.  This is from \
2222Fischetti and Lodi and is not really a heuristic although it can be used as one. \
2223When used from Coin solve it has limited functionality.  It is not switched on when \
2224heuristics are switched on."
2225     ); 
2226#endif
2227#ifndef COIN_HAS_CBC
2228  parameters[numberParameters++]=
2229    CbcOrClpParam("log!Level","Level of detail in Solver output",
2230                  -1,63,SOLVERLOGLEVEL);
2231#else
2232  parameters[numberParameters++]=
2233    CbcOrClpParam("log!Level","Level of detail in Coin branch and Cut output",
2234                  -63,63,LOGLEVEL);
2235  parameters[numberParameters-1].setIntValue(1);
2236#endif
2237  parameters[numberParameters-1].setLonghelp
2238    (
2239     "If 0 then there should be no output in normal circumstances.  1 is probably the best\
2240 value for most uses, while 2 and 3 give more information."
2241     ); 
2242  parameters[numberParameters++]=
2243    CbcOrClpParam("max!imize","Set optimization direction to maximize",
2244                  MAXIMIZE,7);
2245  parameters[numberParameters-1].setLonghelp
2246    (
2247     "The default is minimize - use 'maximize' for maximization.\n\
2248You can also use the parameters 'direction maximize'."
2249     ); 
2250#ifdef COIN_HAS_CLP
2251  parameters[numberParameters++]=
2252    CbcOrClpParam("maxF!actor","Maximum number of iterations between \
2253refactorizations",
2254                  1,999999,MAXFACTOR);
2255  parameters[numberParameters-1].setLonghelp
2256    (
2257     "If this is at its initial value of 200 then in this executable clp will guess at a\
2258 value to use.  Otherwise the user can set a value.  The code may decide to re-factorize\
2259 earlier for accuracy."
2260     ); 
2261  parameters[numberParameters++]=
2262    CbcOrClpParam("maxIt!erations","Maximum number of iterations before \
2263stopping",
2264                  0,2147483647,MAXITERATION);
2265  parameters[numberParameters-1].setLonghelp
2266    (
2267     "This can be used for testing purposes.  The corresponding library call\n\
2268      \tsetMaximumIterations(value)\n can be useful.  If the code stops on\
2269 seconds or by an interrupt this will be treated as stopping on maximum iterations.  This is ignored in branchAndCut - use maxN!odes."
2270     ); 
2271#endif
2272#ifdef COIN_HAS_CBC
2273  parameters[numberParameters++]=
2274    CbcOrClpParam("maxN!odes","Maximum number of nodes to do",
2275                  -1,2147483647,MAXNODES);
2276  parameters[numberParameters-1].setLonghelp
2277    (
2278     "This is a repeatable way to limit search.  Normally using time is easier \
2279but then the results may not be repeatable."
2280     ); 
2281  parameters[numberParameters++]=
2282    CbcOrClpParam("maxS!olutions","Maximum number of solutions to get",
2283                  1,2147483647,MAXSOLS);
2284  parameters[numberParameters-1].setLonghelp
2285    (
2286     "You may want to stop after (say) two solutions or an hour.  \
2287This is checked every node in tree, so it is possible to get more solutions from heuristics." 
2288     ); 
2289#endif
2290  parameters[numberParameters++]=
2291    CbcOrClpParam("min!imize","Set optimization direction to minimize",
2292                  MINIMIZE,7);
2293  parameters[numberParameters-1].setLonghelp
2294    (
2295     "The default is minimize - use 'maximize' for maximization.\n\
2296This should only be necessary if you have previously set maximization \
2297You can also use the parameters 'direction minimize'."
2298     );
2299#ifdef COIN_HAS_CBC
2300  parameters[numberParameters++]=
2301    CbcOrClpParam("mipO!ptions","Dubious options for mip",
2302                  0,COIN_INT_MAX,MIPOPTIONS,0);
2303  parameters[numberParameters++]=
2304    CbcOrClpParam("more!MipOptions","More dubious options for mip",
2305                  -1,COIN_INT_MAX,MOREMIPOPTIONS,0);
2306  parameters[numberParameters++]=
2307    CbcOrClpParam("mixed!IntegerRoundingCuts","Whether to use Mixed Integer Rounding cuts",
2308                  "off",MIXEDCUTS);
2309  parameters[numberParameters-1].append("on");
2310  parameters[numberParameters-1].append("root");
2311  parameters[numberParameters-1].append("ifmove");
2312  parameters[numberParameters-1].append("forceOn");
2313  parameters[numberParameters-1].append("onglobal");
2314  parameters[numberParameters-1].setLonghelp
2315    (
2316     "This switches on mixed integer rounding cuts (either at root or in entire tree) \
2317See branchAndCut for information on options."
2318     ); 
2319#endif
2320  parameters[numberParameters++]=
2321    CbcOrClpParam("mess!ages","Controls if Clpnnnn is printed",
2322                  "off",MESSAGES);
2323  parameters[numberParameters-1].append("on");
2324  parameters[numberParameters-1].setLonghelp
2325    ("The default behavior is to put out messages such as:\n\
2326   Clp0005 2261  Objective 109.024 Primal infeas 944413 (758)\n\
2327but this program turns this off to make it look more friendly.  It can be useful\
2328 to turn them back on if you want to be able to 'grep' for particular messages or if\
2329 you intend to override the behavior of a particular message.  This only affects Clp not Cbc."
2330     );
2331#ifdef COIN_HAS_CBC
2332  parameters[numberParameters++]=
2333    CbcOrClpParam("moreT!une","Yet more dubious ideas for feasibility pump",
2334                  0,100000000,FPUMPTUNE2,0);
2335  parameters[numberParameters-1].setLonghelp
2336    (
2337     "Yet more ideas for Feasibility Pump \n\
2338\t/100000 == 1 use box constraints and original obj in cleanup\n\
2339\t/1000 == 1 Pump will run twice if no solution found\n\
2340\t/1000 == 2 Pump will only run after root cuts if no solution found\n\
2341\t/1000 >10 as above but even if solution found\n\
2342\t/100 == 1,3.. exact 1.0 for objective values\n\
2343\t/100 == 2,3.. allow more iterations per pass\n\
2344\t n fix if value of variable same for last n iterations."
2345     ); 
2346  parameters[numberParameters-1].setIntValue(0);
2347  parameters[numberParameters++]=
2348    CbcOrClpParam("miplib","Do some of miplib test set",
2349                  MIPLIB,3,1);
2350  parameters[numberParameters++]=
2351      CbcOrClpParam("naive!Heuristics","Whether to try some stupid heuristic",
2352                    "off",NAIVE,7,1);
2353  parameters[numberParameters-1].append("on");
2354  parameters[numberParameters-1].append("both");
2355  parameters[numberParameters-1].append("before");
2356  parameters[numberParameters-1].setLonghelp
2357    (
2358     "Really silly stuff e.g. fix all integers with costs to zero!. \
2359Doh option does heuristic before preprocessing"     ); 
2360#endif
2361#ifdef COIN_HAS_CLP
2362  parameters[numberParameters++]=
2363    CbcOrClpParam("netlib","Solve entire netlib test set",
2364                  NETLIB_EITHER,3,1);
2365  parameters[numberParameters-1].setLonghelp
2366    (
2367     "This exercises the unit test for clp and then solves the netlib test set using dual or primal.\
2368The user can set options before e.g. clp -presolve off -netlib"
2369     ); 
2370  parameters[numberParameters++]=
2371    CbcOrClpParam("netlibB!arrier","Solve entire netlib test set with barrier",
2372                  NETLIB_BARRIER,3,1);
2373  parameters[numberParameters-1].setLonghelp
2374    (
2375     "This exercises the unit test for clp and then solves the netlib test set using barrier.\
2376The user can set options before e.g. clp -kkt on -netlib"
2377     ); 
2378  parameters[numberParameters++]=
2379    CbcOrClpParam("netlibD!ual","Solve entire netlib test set (dual)",
2380                  NETLIB_DUAL,3,1);
2381  parameters[numberParameters-1].setLonghelp
2382    (
2383     "This exercises the unit test for clp and then solves the netlib test set using dual.\
2384The user can set options before e.g. clp -presolve off -netlib"
2385     ); 
2386  parameters[numberParameters++]=
2387    CbcOrClpParam("netlibP!rimal","Solve entire netlib test set (primal)",
2388                  NETLIB_PRIMAL,3,1);
2389  parameters[numberParameters-1].setLonghelp
2390    (
2391     "This exercises the unit test for clp and then solves the netlib test set using primal.\
2392The user can set options before e.g. clp -presolve off -netlibp"
2393     ); 
2394  parameters[numberParameters++]=
2395    CbcOrClpParam("netlibT!une","Solve entire netlib test set with 'best' algorithm",
2396                  NETLIB_TUNE,3,1);
2397  parameters[numberParameters-1].setLonghelp
2398    (
2399     "This exercises the unit test for clp and then solves the netlib test set using whatever \
2400works best.  I know this is cheating but it also stresses the code better by doing a \
2401mixture of stuff.  The best algorithm was chosen on a Linux ThinkPad using native cholesky \
2402with University of Florida ordering."
2403     ); 
2404  parameters[numberParameters++]=
2405    CbcOrClpParam("network","Tries to make network matrix",
2406                  NETWORK,7,0);
2407  parameters[numberParameters-1].setLonghelp
2408    (
2409     "Clp will go faster if the matrix can be converted to a network.  The matrix\
2410 operations may be a bit faster with more efficient storage, but the main advantage\
2411 comes from using a network factorization.  It will probably not be as fast as a \
2412specialized network code."
2413     ); 
2414#ifdef COIN_HAS_CBC
2415  parameters[numberParameters++]=
2416    CbcOrClpParam("node!Strategy","What strategy to use to select nodes",
2417                  "hybrid",NODESTRATEGY);
2418  parameters[numberParameters-1].append("fewest");
2419  parameters[numberParameters-1].append("depth");
2420  parameters[numberParameters-1].append("upfewest");
2421  parameters[numberParameters-1].append("downfewest");
2422  parameters[numberParameters-1].append("updepth");
2423  parameters[numberParameters-1].append("downdepth");
2424  parameters[numberParameters-1].setLonghelp
2425    (
2426     "Normally before a solution the code will choose node with fewest infeasibilities. \
2427You can choose depth as the criterion.  You can also say if up or down branch must \
2428be done first (the up down choice will carry on after solution). \
2429Default has now been changed to hybrid which is breadth first on small depth nodes then fewest."
2430     ); 
2431  parameters[numberParameters++]=
2432    CbcOrClpParam("numberA!nalyze","Number of analysis iterations",
2433                  -COIN_INT_MAX,COIN_INT_MAX,NUMBERANALYZE,0);
2434  parameters[numberParameters-1].setLonghelp
2435    (
2436     "This says how many iterations to spend at root node analyzing problem. \
2437This is a first try and will hopefully become more sophisticated."
2438     ); 
2439#endif
2440  parameters[numberParameters++]=
2441    CbcOrClpParam("objective!Scale","Scale factor to apply to objective",
2442                  -1.0e20,1.0e20,OBJSCALE,1);
2443  parameters[numberParameters-1].setLonghelp
2444    (
2445     "If the objective function has some very large values, you may wish to scale them\
2446 internally by this amount.  It can also be set by autoscale.  It is applied after scaling.  You are unlikely to need this."
2447     ); 
2448  parameters[numberParameters-1].setDoubleValue(1.0);
2449#endif
2450#ifdef COIN_HAS_CBC
2451  parameters[numberParameters++]=
2452    CbcOrClpParam("outDup!licates","takes duplicate rows etc out of integer model",
2453                  OUTDUPROWS,7,0);
2454#endif
2455  parameters[numberParameters++]=
2456    CbcOrClpParam("output!Format","Which output format to use",
2457                  1,6,OUTPUTFORMAT);
2458  parameters[numberParameters-1].setLonghelp
2459    (
2460     "Normally export will be done using normal representation for numbers and two values\
2461 per line.  You may want to do just one per line (for grep or suchlike) and you may wish\
2462 to save with absolute accuracy using a coded version of the IEEE value. A value of 2 is normal.\
2463 otherwise odd values gives one value per line, even two.  Values 1,2 give normal format, 3,4\
2464 gives greater precision, while 5,6 give IEEE values.  When used for exporting a basis 1 does not save \
2465values, 2 saves values, 3 with greater accuracy and 4 in IEEE."
2466     );
2467#ifdef COIN_HAS_CBC
2468  parameters[numberParameters++]=
2469    CbcOrClpParam("passC!uts","Number of cut passes at root node",
2470                  -9999999,9999999,CUTPASS);
2471  parameters[numberParameters-1].setLonghelp
2472    (
2473     "The default is 100 passes if less than 500 columns, 100 passes (but \
2474stop if drop small if less than 5000 columns, 20 otherwise"
2475     ); 
2476  parameters[numberParameters++]=
2477    CbcOrClpParam("passF!easibilityPump","How many passes in feasibility pump",
2478                  0,10000,FPUMPITS);
2479  parameters[numberParameters-1].setLonghelp
2480    (
2481     "This fine tunes Feasibility Pump by doing more or fewer passes."
2482     ); 
2483  parameters[numberParameters-1].setIntValue(20);
2484#endif
2485#ifdef COIN_HAS_CLP
2486  parameters[numberParameters++]=
2487    CbcOrClpParam("passP!resolve","How many passes in presolve",
2488                  -200,100,PRESOLVEPASS,1);
2489  parameters[numberParameters-1].setLonghelp
2490    (
2491     "Normally Presolve does 5 passes but you may want to do less to make it\
2492 more lightweight or do more if improvements are still being made.  As Presolve will return\
2493 if nothing is being taken out, you should not normally need to use this fine tuning."
2494     );
2495#endif
2496#ifdef COIN_HAS_CBC
2497  parameters[numberParameters++]=
2498    CbcOrClpParam("passT!reeCuts","Number of cut passes in tree",
2499                  -9999999,9999999,CUTPASSINTREE);
2500  parameters[numberParameters-1].setLonghelp
2501    (
2502     "The default is one pass"
2503     ); 
2504#endif
2505#ifdef COIN_HAS_CLP
2506  parameters[numberParameters++]=
2507    CbcOrClpParam("pertV!alue","Method of perturbation",
2508                  -5000,102,PERTVALUE,1);
2509  parameters[numberParameters++]=
2510    CbcOrClpParam("perturb!ation","Whether to perturb problem",
2511                  "on",PERTURBATION);
2512  parameters[numberParameters-1].append("off");
2513  parameters[numberParameters-1].setLonghelp
2514    (
2515     "Perturbation helps to stop cycling, but Clp uses other measures for this.\
2516  However large problems and especially ones with unit elements and unit rhs or costs\
2517 benefit from perturbation.  Normally Clp tries to be intelligent, but you can switch this off.\
2518  The Clp library has this off by default.  This program has it on by default."
2519     ); 
2520  parameters[numberParameters++]=
2521    CbcOrClpParam("PFI","Whether to use Product Form of Inverse in simplex",
2522                  "off",PFI,7,0);
2523  parameters[numberParameters-1].append("on");
2524  parameters[numberParameters-1].setLonghelp
2525    (
2526     "By default clp uses Forrest-Tomlin L-U update.  If you are masochistic you can switch it off."
2527     ); 
2528#endif
2529#ifdef COIN_HAS_CBC
2530  parameters[numberParameters++]=
2531      CbcOrClpParam("pivotAndC!omplement","Whether to try Pivot and Complement heuristic",
2532                    "off",PIVOTANDCOMPLEMENT);
2533  parameters[numberParameters-1].append("on");
2534  parameters[numberParameters-1].append("both");
2535  parameters[numberParameters-1].append("before");
2536  parameters[numberParameters-1].setLonghelp
2537    (
2538     "stuff needed. \
2539Doh option does heuristic before preprocessing"     ); 
2540  parameters[numberParameters++]=
2541      CbcOrClpParam("pivotAndF!ix","Whether to try Pivot and Fix heuristic",
2542                    "off",PIVOTANDFIX);
2543  parameters[numberParameters-1].append("on");
2544  parameters[numberParameters-1].append("both");
2545  parameters[numberParameters-1].append("before");
2546  parameters[numberParameters-1].setLonghelp
2547    (
2548     "stuff needed. \
2549Doh option does heuristic before preprocessing"     ); 
2550#endif
2551#ifdef COIN_HAS_CLP
2552  parameters[numberParameters++]=
2553    CbcOrClpParam("plus!Minus","Tries to make +- 1 matrix",
2554                  PLUSMINUS,7,0);
2555  parameters[numberParameters-1].setLonghelp
2556    (
2557     "Clp will go slightly faster if the matrix can be converted so that the elements are\
2558 not stored and are known to be unit.  The main advantage is memory use.  Clp may automatically\
2559 see if it can convert the problem so you should not need to use this."
2560     ); 
2561  parameters[numberParameters++]=
2562    CbcOrClpParam("pO!ptions","Dubious print options",
2563                  0,COIN_INT_MAX,PRINTOPTIONS,1);
2564  parameters[numberParameters-1].setIntValue(0);
2565  parameters[numberParameters-1].setLonghelp
2566    (
2567     "If this is > 0 then presolve will give more information and branch and cut will give statistics"
2568     ); 
2569  parameters[numberParameters++]=
2570    CbcOrClpParam("preO!pt","Presolve options",
2571                  0,COIN_INT_MAX,PRESOLVEOPTIONS,0);
2572#endif
2573  parameters[numberParameters++]=
2574    CbcOrClpParam("presolve","Whether to presolve problem",
2575                  "on",PRESOLVE);
2576  parameters[numberParameters-1].append("off");
2577  parameters[numberParameters-1].append("more");
2578  parameters[numberParameters-1].append("file");
2579  parameters[numberParameters-1].setLonghelp
2580    (
2581     "Presolve analyzes the model to find such things as redundant equations, equations\
2582 which fix some variables, equations which can be transformed into bounds etc etc.  For the\
2583 initial solve of any problem this is worth doing unless you know that it will have no effect.  \
2584on will normally do 5 passes while using 'more' will do 10.  If the problem is very large you may need \
2585to write the original to file using 'file'."
2586     ); 
2587#ifdef COIN_HAS_CBC
2588  parameters[numberParameters++]=
2589    CbcOrClpParam("preprocess","Whether to use integer preprocessing",
2590                  "off",PREPROCESS);
2591  parameters[numberParameters-1].append("on");
2592  parameters[numberParameters-1].append("save");
2593  parameters[numberParameters-1].append("equal");
2594  parameters[numberParameters-1].append("sos");
2595  parameters[numberParameters-1].append("trysos");
2596  parameters[numberParameters-1].append("equalall");
2597  parameters[numberParameters-1].append("strategy");
2598  parameters[numberParameters-1].append("aggregate");
2599  parameters[numberParameters-1].append("forcesos");
2600  parameters[numberParameters-1].setLonghelp
2601    (
2602     "This tries to reduce size of model in a similar way to presolve and \
2603it also tries to strengthen the model - this can be very useful and is worth trying. \
2604 Save option saves on file presolved.mps.  equal will turn <= cliques into \
2605==.  sos will create sos sets if all 0-1 in sets (well one extra is allowed) \
2606and no overlaps.  trysos is same but allows any number extra.  equalall will turn all \
2607valid inequalities into equalities with integer slacks.  strategy is as \
2608on but uses CbcStrategy."
2609     ); 
2610#endif
2611#ifdef COIN_HAS_CLP
2612  parameters[numberParameters++]=
2613    CbcOrClpParam("preT!olerance","Tolerance to use in presolve",
2614                  1.0e-20,1.0e12,PRESOLVETOLERANCE);
2615  parameters[numberParameters-1].setLonghelp
2616    (
2617     "The default is 1.0e-8 - you may wish to try 1.0e-7 if presolve says the problem is \
2618infeasible and you have awkward numbers and you are sure the problem is really feasible."
2619     ); 
2620  parameters[numberParameters++]=
2621    CbcOrClpParam("primalP!ivot","Primal pivot choice algorithm",
2622                  "auto!matic",PRIMALPIVOT,7,1);
2623  parameters[numberParameters-1].append("exa!ct");
2624  parameters[numberParameters-1].append("dant!zig");
2625  parameters[numberParameters-1].append("part!ial");
2626  parameters[numberParameters-1].append("steep!est");
2627  parameters[numberParameters-1].append("change");
2628  parameters[numberParameters-1].append("sprint");
2629  parameters[numberParameters-1].setLonghelp
2630    (
2631     "Clp can use any pivot selection algorithm which the user codes as long as it\
2632 implements the features in the abstract pivot base class.  The Dantzig method is implemented\
2633 to show a simple method but its use is deprecated.  Exact devex is the method of choice and there\
2634 are two variants which keep all weights updated but only scan a subset each iteration.\
2635 Partial switches this on while change initially does dantzig until the factorization\
2636 becomes denser.  This is still a work in progress."
2637     ); 
2638  parameters[numberParameters++]=
2639    CbcOrClpParam("primalS!implex","Do primal simplex algorithm",
2640                  PRIMALSIMPLEX);
2641  parameters[numberParameters-1].setLonghelp
2642    (
2643     "This command solves the current model using the primal algorithm.\
2644  The default is to use exact devex.\
2645 The time and iterations may be affected by settings such as presolve, scaling, crash\
2646 and also by column selection  method, infeasibility weight and dual and primal tolerances."
2647     );
2648#endif
2649  parameters[numberParameters++]=
2650    CbcOrClpParam("primalT!olerance","For an optimal solution \
2651no primal infeasibility may exceed this value",
2652                  1.0e-20,1.0e12,PRIMALTOLERANCE);
2653  parameters[numberParameters-1].setLonghelp
2654    (
2655     "Normally the default tolerance is fine, but you may want to increase it a\
2656 bit if a primal run seems to be having a hard time"
2657     ); 
2658#ifdef COIN_HAS_CLP
2659  parameters[numberParameters++]=
2660    CbcOrClpParam("primalW!eight","Initially algorithm acts as if it \
2661costs this much to be infeasible",
2662                  1.0e-20,1.0e20,PRIMALWEIGHT);
2663  parameters[numberParameters-1].setLonghelp
2664    (
2665     "The primal algorithm in Clp is a single phase algorithm as opposed to a two phase\
2666 algorithm where you first get feasible then optimal.  So Clp is minimizing this weight times\
2667 the sum of primal infeasibilities plus the true objective function (in minimization sense).\
2668  Too high a value may mean more iterations, while too low a bound means\
2669 the code may go all the way and then have to increase the weight in order to get feasible.\
2670  OSL had a heuristic to\
2671 adjust bounds, maybe we need that here."
2672     ); 
2673#endif
2674  parameters[numberParameters++]=
2675    CbcOrClpParam("printi!ngOptions","Print options",
2676                  "normal",INTPRINT,3);
2677  parameters[numberParameters-1].append("integer");
2678  parameters[numberParameters-1].append("special");
2679  parameters[numberParameters-1].append("rows");
2680  parameters[numberParameters-1].append("all");
2681  parameters[numberParameters-1].append("csv");
2682  parameters[numberParameters-1].setLonghelp
2683    (
2684     "This changes the amount and format of printing a solution:\nnormal - nonzero column variables \n\
2685integer - nonzero integer column variables\n\
2686special - in format suitable for OsiRowCutDebugger\n\
2687rows - nonzero column variables and row activities\n\
2688all - all column variables and row activities.\n\
2689\nFor non-integer problems 'integer' and 'special' act like 'normal'.  \
2690Also see printMask for controlling output."
2691     ); 
2692  parameters[numberParameters++]=
2693    CbcOrClpParam("printM!ask","Control printing of solution on a  mask",
2694                  PRINTMASK,3);
2695  parameters[numberParameters-1].setLonghelp
2696    (
2697     "If set then only those names which match mask are printed in a solution. \
2698'?' matches any character and '*' matches any set of characters. \
2699 The default is '' i.e. unset so all variables are printed. \
2700This is only active if model has names."
2701     ); 
2702#ifdef COIN_HAS_CBC
2703  parameters[numberParameters++]=
2704    CbcOrClpParam("prio!rityIn","Import priorities etc from file",
2705                  PRIORITYIN,3);
2706  parameters[numberParameters-1].setLonghelp
2707    (
2708     "This will read a file with priorities from the given file name.  It will use the default\
2709 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
2710 is initialized to '', i.e. it must be set.  This can not read from compressed files. \
2711File is in csv format with allowed headings - name, number, priority, direction, up, down, solution.  Exactly one of\
2712 name and number must be given."
2713     ); 
2714  parameters[numberParameters++]=
2715    CbcOrClpParam("probing!Cuts","Whether to use Probing cuts",
2716                  "off",PROBINGCUTS);
2717  parameters[numberParameters-1].append("on");
2718  parameters[numberParameters-1].append("root");
2719  parameters[numberParameters-1].append("ifmove");
2720  parameters[numberParameters-1].append("forceOn");
2721  parameters[numberParameters-1].append("onglobal");
2722  parameters[numberParameters-1].append("forceonglobal");
2723  parameters[numberParameters-1].append("forceOnBut");
2724  parameters[numberParameters-1].append("forceOnStrong");
2725  parameters[numberParameters-1].append("forceOnButStrong");
2726  parameters[numberParameters-1].append("strongRoot");
2727  parameters[numberParameters-1].setLonghelp
2728    (
2729     "This switches on probing cuts (either at root or in entire tree) \
2730See branchAndCut for information on options. \
2731but strong options do more probing"
2732     ); 
2733  parameters[numberParameters++]=
2734    CbcOrClpParam("pumpC!utoff","Fake cutoff for use in feasibility pump",
2735                  -COIN_DBL_MAX,COIN_DBL_MAX,FAKECUTOFF);
2736  parameters[numberParameters-1].setDoubleValue(0.0);
2737  parameters[numberParameters-1].setLonghelp
2738    (
2739     "0.0 off - otherwise add a constraint forcing objective below this value\
2740 in feasibility pump"
2741     ); 
2742  parameters[numberParameters++]=
2743    CbcOrClpParam("pumpI!ncrement","Fake increment for use in feasibility pump",
2744                  -COIN_DBL_MAX,COIN_DBL_MAX,FAKEINCREMENT,1);
2745  parameters[numberParameters-1].setDoubleValue(0.0);
2746  parameters[numberParameters-1].setLonghelp
2747    (
2748     "0.0 off - otherwise use as absolute increment to cutoff \
2749when solution found in feasibility pump"
2750     ); 
2751  parameters[numberParameters++]=
2752    CbcOrClpParam("pumpT!une","Dubious ideas for feasibility pump",
2753                  0,100000000,FPUMPTUNE);
2754  parameters[numberParameters-1].setLonghelp
2755    (
2756     "This fine tunes Feasibility Pump \n\
2757\t>=10000000 use as objective weight switch\n\
2758\t>=1000000 use as accumulate switch\n\
2759\t>=1000 use index+1 as number of large loops\n\
2760\t==100 use objvalue +0.05*fabs(objvalue) as cutoff OR fakeCutoff if set\n\
2761\t%100 == 10,20 affects how each solve is done\n\
2762\t1 == fix ints at bounds, 2 fix all integral ints, 3 and continuous at bounds. \
2763If accumulate is on then after a major pass, variables which have not moved \
2764are fixed and a small branch and bound is tried."
2765     ); 
2766  parameters[numberParameters-1].setIntValue(0);
2767#endif
2768  parameters[numberParameters++]=
2769    CbcOrClpParam("quit","Stops clp execution",
2770                  EXIT);
2771  parameters[numberParameters-1].setLonghelp
2772    (
2773     "This stops the execution of Clp, end, exit, quit and stop are synonyms"
2774     ); 
2775#ifdef COIN_HAS_CBC
2776  parameters[numberParameters++]=
2777      CbcOrClpParam("rand!omizedRounding","Whether to try randomized rounding heuristic",
2778                    "off",RANDROUND);
2779  parameters[numberParameters-1].append("on");
2780  parameters[numberParameters-1].append("both");
2781  parameters[numberParameters-1].append("before");
2782  parameters[numberParameters-1].setLonghelp
2783    (
2784     "stuff needed. \
2785Doh option does heuristic before preprocessing"     ); 
2786  parameters[numberParameters++]=
2787    CbcOrClpParam("ratio!Gap","Stop when gap between best possible and \
2788best less than this fraction of larger of two",
2789                  0.0,1.0e20,GAPRATIO);
2790  parameters[numberParameters-1].setDoubleValue(0.0);
2791  parameters[numberParameters-1].setLonghelp
2792    (
2793     "If the gap between best solution and best possible solution is less than this fraction \
2794of the objective value at the root node then the search will terminate.  See 'allowableGap' for a \
2795way of using absolute value rather than fraction."
2796     ); 
2797  parameters[numberParameters++]=
2798    CbcOrClpParam("readS!tored","Import stored cuts from file",
2799                  STOREDFILE,3,0);
2800#endif
2801#ifdef COIN_HAS_CLP
2802  parameters[numberParameters++]=
2803    CbcOrClpParam("reallyO!bjectiveScale","Scale factor to apply to objective in place",
2804                  -1.0e20,1.0e20,OBJSCALE2,0);
2805  parameters[numberParameters-1].setLonghelp
2806    (
2807     "You can set this to -1.0 to test maximization or other to stress code"
2808     ); 
2809  parameters[numberParameters-1].setDoubleValue(1.0);
2810  parameters[numberParameters++]=
2811    CbcOrClpParam("reallyS!cale","Scales model in place",
2812                  REALLY_SCALE,7,0);
2813#endif
2814#ifdef COIN_HAS_CBC
2815    parameters[numberParameters++]=
2816      CbcOrClpParam("reduce!AndSplitCuts","Whether to use Reduce-and-Split cuts",
2817              "off",REDSPLITCUTS);
2818    parameters[numberParameters-1].append("on");
2819    parameters[numberParameters-1].append("root");
2820    parameters[numberParameters-1].append("ifmove");
2821    parameters[numberParameters-1].append("forceOn");
2822    parameters[numberParameters-1].setLonghelp
2823    (
2824     "This switches on reduce and split  cuts (either at root or in entire tree) \
2825See branchAndCut for information on options."
2826     ); 
2827  parameters[numberParameters++]=
2828    CbcOrClpParam("residual!CapacityCuts","Whether to use Residual Capacity cuts",
2829                  "off",RESIDCUTS);
2830  parameters[numberParameters-1].append("on");
2831  parameters[numberParameters-1].append("root");
2832  parameters[numberParameters-1].append("ifmove");
2833  parameters[numberParameters-1].append("forceOn");
2834  parameters[numberParameters-1].setLonghelp
2835    (
2836     "Residual capacity cuts. \
2837See branchAndCut for information on options."
2838     ); 
2839#endif
2840#ifdef COIN_HAS_CLP
2841  parameters[numberParameters++]=
2842    CbcOrClpParam("restore!Model","Restore model from binary file",
2843                  RESTORE,7,1);
2844  parameters[numberParameters-1].setLonghelp
2845    (
2846     "This reads data save by saveModel from the given file.  It will use the default\
2847 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
2848 is initialized to 'default.prob'."
2849     ); 
2850  parameters[numberParameters++]=
2851    CbcOrClpParam("reverse","Reverses sign of objective",
2852                  REVERSE,7,0);
2853  parameters[numberParameters-1].setLonghelp
2854    (
2855     "Useful for testing if maximization works correctly"
2856     ); 
2857  parameters[numberParameters++]=
2858    CbcOrClpParam("rhs!Scale","Scale factor to apply to rhs and bounds",
2859                  -1.0e20,1.0e20,RHSSCALE,0);
2860  parameters[numberParameters-1].setLonghelp
2861    (
2862     "If the rhs or bounds have some very large meaningful values, you may wish to scale them\
2863 internally by this amount.  It can also be set by autoscale.  This should not be needed."
2864     ); 
2865  parameters[numberParameters-1].setDoubleValue(1.0);
2866#endif
2867#ifdef COIN_HAS_CBC
2868  parameters[numberParameters++]=
2869      CbcOrClpParam("Rens","Whether to try Relaxation Enforced Neighborhood Search",
2870                    "off",RENS);
2871    parameters[numberParameters-1].append("on");
2872    parameters[numberParameters-1].append("both");
2873    parameters[numberParameters-1].append("before");
2874    parameters[numberParameters-1].append("200");
2875    parameters[numberParameters-1].append("1000");
2876    parameters[numberParameters-1].append("10000");
2877  parameters[numberParameters-1].setLonghelp
2878    (
2879     "This switches on Relaxation enforced neighborhood Search. \
2880on just does 50 nodes \
2881200 or 1000 does that many nodes. \
2882Doh option does heuristic before preprocessing"     ); 
2883  parameters[numberParameters++]=
2884      CbcOrClpParam("Rins","Whether to try Relaxed Induced Neighborhood Search",
2885                    "off",RINS);
2886    parameters[numberParameters-1].append("on");
2887    parameters[numberParameters-1].append("both");
2888    parameters[numberParameters-1].append("before");
2889    parameters[numberParameters-1].append("often");
2890  parameters[numberParameters-1].setLonghelp
2891    (
2892     "This switches on Relaxed induced neighborhood Search. \
2893Doh option does heuristic before preprocessing"     ); 
2894  parameters[numberParameters++]=
2895    CbcOrClpParam("round!ingHeuristic","Whether to use Rounding heuristic",
2896                  "off",ROUNDING);
2897  parameters[numberParameters-1].append("on");
2898  parameters[numberParameters-1].append("both");
2899  parameters[numberParameters-1].append("before");
2900  parameters[numberParameters-1].setLonghelp
2901    (
2902     "This switches on a simple (but effective) rounding heuristic at each node of tree.  \
2903On means do in solve i.e. after preprocessing, \
2904Before means do if doHeuristics used, off otherwise, \
2905and both means do if doHeuristics and in solve."
2906     );
2907
2908#endif
2909  parameters[numberParameters++]=
2910    CbcOrClpParam("saveM!odel","Save model to binary file",
2911                  SAVE,7,1);
2912  parameters[numberParameters-1].setLonghelp
2913    (
2914     "This will save the problem to the given file name for future use\
2915 by restoreModel.  It will use the default\
2916 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
2917 is initialized to 'default.prob'."
2918     ); 
2919  parameters[numberParameters++]=
2920    CbcOrClpParam("saveS!olution","saves solution to file",
2921                  SAVESOL);
2922  parameters[numberParameters-1].setLonghelp
2923    (
2924     "This will write a binary solution file to the given file name.  It will use the default\
2925 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
2926 is initialized to 'solution.file'.  To read the file use fread(int) twice to pick up number of rows \
2927and columns, then fread(double) to pick up objective value, then pick up row activities, row duals, column \
2928activities and reduced costs - see bottom of CbcOrClpParam.cpp for code that reads or writes file. \
2929If name contains '_fix_read_' then does not write but reads and will fix all variables"
2930     ); 
2931  parameters[numberParameters++]=
2932    CbcOrClpParam("scal!ing","Whether to scale problem",
2933                  "off",SCALING);
2934  parameters[numberParameters-1].append("equi!librium");
2935  parameters[numberParameters-1].append("geo!metric");
2936  parameters[numberParameters-1].append("auto!matic");
2937  parameters[numberParameters-1].append("dynamic");
2938  parameters[numberParameters-1].append("rows!only");
2939  parameters[numberParameters-1].setLonghelp
2940    (
2941     "Scaling can help in solving problems which might otherwise fail because of lack of\
2942 accuracy.  It can also reduce the number of iterations.  It is not applied if the range\
2943 of elements is small.  When unscaled it is possible that there may be small primal and/or\
2944 infeasibilities."
2945     ); 
2946  parameters[numberParameters-1].setCurrentOption(3); // say auto
2947#ifndef COIN_HAS_CBC
2948  parameters[numberParameters++]=
2949    CbcOrClpParam("sec!onds","Maximum seconds",
2950                  -1.0,1.0e12,TIMELIMIT);
2951  parameters[numberParameters-1].setLonghelp
2952    (
2953     "After this many seconds clp will act as if maximum iterations had been reached \
2954(if value >=0)."
2955     );
2956#else
2957  parameters[numberParameters++]=
2958    CbcOrClpParam("sec!onds","maximum seconds",
2959                  -1.0,1.0e12,TIMELIMIT_BAB);
2960  parameters[numberParameters-1].setLonghelp
2961    (
2962     "After this many seconds coin solver will act as if maximum nodes had been reached."
2963     );
2964#endif
2965  parameters[numberParameters++]=
2966    CbcOrClpParam("sleep","for debug",
2967                  DUMMY,7,0);
2968  parameters[numberParameters-1].setLonghelp
2969    (
2970     "If passed to solver fom ampl, then ampl will wait so that you can copy .nl file for debug."
2971     ); 
2972#ifdef COIN_HAS_CLP
2973  parameters[numberParameters++]=
2974    CbcOrClpParam("slp!Value","Number of slp passes before primal",
2975                  -1,50000,SLPVALUE,1);
2976  parameters[numberParameters-1].setLonghelp
2977    (
2978     "If you are solving a quadratic problem using primal then it may be helpful to do some \
2979sequential Lps to get a good approximate solution."
2980     ); 
2981#if CLP_MULTIPLE_FACTORIZATIONS > 0
2982  parameters[numberParameters++]=
2983    CbcOrClpParam("small!Factorization","Whether to use small factorization",
2984                  -1,10000,SMALLFACT,1);
2985  parameters[numberParameters-1].setLonghelp
2986    (
2987     "If processed problem <= this use small factorization"
2988     ); 
2989  parameters[numberParameters-1].setIntValue(-1);
2990#endif
2991#endif
2992  parameters[numberParameters++]=
2993    CbcOrClpParam("solu!tion","Prints solution to file",
2994                  SOLUTION);
2995  parameters[numberParameters-1].setLonghelp
2996    (
2997     "This will write a primitive solution file to the given file name.  It will use the default\
2998 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
2999 is initialized to 'stdout'.  The amount of output can be varied using printi!ngOptions or printMask."
3000     ); 
3001#ifdef COIN_HAS_CLP
3002#ifdef COIN_HAS_CBC
3003  parameters[numberParameters++]=
3004    CbcOrClpParam("solv!e","Solve problem",
3005                  BAB);
3006  parameters[numberParameters-1].setLonghelp
3007    (
3008     "If there are no integer variables then this just solves LP.  If there are integer variables \
3009this does branch and cut."
3010     ); 
3011  parameters[numberParameters++]=
3012    CbcOrClpParam("sos!Options","Whether to use SOS from AMPL",
3013                  "off",SOS);
3014  parameters[numberParameters-1].append("on");
3015  parameters[numberParameters-1].setCurrentOption("on");
3016  parameters[numberParameters-1].setLonghelp
3017    (
3018     "Normally if AMPL says there are SOS variables they should be used, but sometime sthey should\
3019 be turned off - this does so."
3020     ); 
3021  parameters[numberParameters++]=
3022    CbcOrClpParam("slog!Level","Level of detail in (LP) Solver output",
3023                  -1,63,SOLVERLOGLEVEL);
3024  parameters[numberParameters-1].setLonghelp
3025    (
3026     "If 0 then there should be no output in normal circumstances.  1 is probably the best\
3027 value for most uses, while 2 and 3 give more information.  This parameter is only used inside MIP - for Clp use 'log'"
3028     );
3029#else
3030  // allow solve as synonym for dual
3031  parameters[numberParameters++]=
3032    CbcOrClpParam("solv!e","Solve problem using dual simplex",
3033                  BAB);
3034  parameters[numberParameters-1].setLonghelp
3035    (
3036     "Just so can use solve for clp as well as in cbc"
3037     ); 
3038#endif
3039#endif
3040#ifdef COIN_HAS_CLP
3041  parameters[numberParameters++]=
3042    CbcOrClpParam("spars!eFactor","Whether factorization treated as sparse",
3043                  "on",SPARSEFACTOR,7,0);
3044  parameters[numberParameters-1].append("off");
3045  parameters[numberParameters++]=
3046    CbcOrClpParam("special!Options","Dubious options for Simplex - see ClpSimplex.hpp",
3047                  0,COIN_INT_MAX,SPECIALOPTIONS,0);
3048  parameters[numberParameters++]=
3049    CbcOrClpParam("sprint!Crash","Whether to try sprint crash",
3050                  -1,5000000,SPRINT);
3051  parameters[numberParameters-1].setLonghelp
3052    (
3053     "For long and thin problems this program may solve a series of small problems\
3054 created by taking a subset of the columns.  I introduced the idea as 'Sprint' after\
3055 an LP code of that name of the 60's which tried the same tactic (not totally successfully).\
3056  Cplex calls it 'sifting'.  -1 is automatic choice, 0 is off, n is number of passes"
3057     ); 
3058  parameters[numberParameters++]=
3059    CbcOrClpParam("stat!istics","Print some statistics",
3060                  STATISTICS);
3061  parameters[numberParameters-1].setLonghelp
3062    (
3063     "This command prints some statistics for the current model.\
3064 If log level >1 then more is printed.\
3065 These are for presolved model if presolve on (and unscaled)."
3066     );
3067#endif
3068  parameters[numberParameters++]=
3069    CbcOrClpParam("stop","Stops clp execution",
3070                  EXIT);
3071  parameters[numberParameters-1].setLonghelp
3072    (
3073     "This stops the execution of Clp, end, exit, quit and stop are synonyms"
3074     ); 
3075#ifdef COIN_HAS_CBC
3076  parameters[numberParameters++]=
3077    CbcOrClpParam("strat!egy","Switches on groups of features",
3078                  0,2,STRATEGY);
3079  parameters[numberParameters-1].setLonghelp
3080    (
3081     "This turns on newer features. \
3082Use 0 for easy problems, 1 is default, 2 is aggressive. \
30831 uses Gomory cuts using tolerance of 0.01 at root, \
3084does a possible restart after 100 nodes if can fix many \
3085and activates a diving and RINS heuristic and makes feasibility pump \
3086more aggressive. \
3087This does not apply to unit tests (where 'experiment' may have similar effects)."
3088     ); 
3089  parameters[numberParameters-1].setIntValue(1);
3090#ifdef CBC_KEEP_DEPRECATED
3091  parameters[numberParameters++]=
3092    CbcOrClpParam("strengthen","Create strengthened problem",
3093                  STRENGTHEN,3);
3094  parameters[numberParameters-1].setLonghelp
3095    (
3096     "This creates a new problem by applying the root node cuts.  All tight constraints \
3097will be in resulting problem"
3098     );
3099#endif
3100  parameters[numberParameters++]=
3101    CbcOrClpParam("strong!Branching","Number of variables to look at in strong branching",
3102                  0,999999,STRONGBRANCHING);
3103  parameters[numberParameters-1].setLonghelp
3104    (
3105     "In order to decide which variable to branch on, the code will choose up to this number \
3106of unsatisfied variables to do mini up and down branches on.  Then the most effective one is chosen. \
3107If a variable is branched on many times then the previous average up and down costs may be used - \
3108see number before trust."
3109     ); 
3110#endif
3111#ifdef COIN_HAS_CLP
3112  parameters[numberParameters++]=
3113    CbcOrClpParam("subs!titution","How long a column to substitute for in presolve",
3114                  0,10000,SUBSTITUTION,0);
3115  parameters[numberParameters-1].setLonghelp
3116    (
3117     "Normally Presolve gets rid of 'free' variables when there are no more than 3 \
3118 variables in column.  If you increase this the number of rows may decrease but number of \
3119 elements may increase."
3120     ); 
3121#endif
3122#ifdef COIN_HAS_CBC
3123  parameters[numberParameters++]=
3124    CbcOrClpParam("testO!si","Test OsiObject stuff",
3125                  -1,COIN_INT_MAX,TESTOSI,0);
3126#endif
3127#ifdef CBC_THREAD
3128  parameters[numberParameters++]=
3129    CbcOrClpParam("thread!s","Number of threads to try and use",
3130                  -100,100000,THREADS,1);
3131  parameters[numberParameters-1].setLonghelp
3132    (
3133     "To use multiple threads, set threads to number wanted.  It may be better \
3134to use one or two more than number of cpus available.  If 100+n then n threads and \
3135search is repeatable (maybe be somewhat slower), \
3136if 200+n use threads for root cuts, 400+n threads used in sub-trees."
3137     ); 
3138#endif
3139#ifdef COIN_HAS_CBC
3140  parameters[numberParameters++]=
3141    CbcOrClpParam("tighten!Factor","Tighten bounds using this times largest \
3142activity at continuous solution",
3143                  1.0e-3,1.0e20,TIGHTENFACTOR,0);
3144  parameters[numberParameters-1].setLonghelp
3145    (
3146     "This sleazy trick can help on some problems."
3147     ); 
3148#endif
3149#ifdef COIN_HAS_CLP
3150  parameters[numberParameters++]=
3151    CbcOrClpParam("tightLP","Poor person's preSolve for now",
3152                  TIGHTEN,7,0);
3153#endif
3154#ifdef COIN_HAS_CBC
3155  parameters[numberParameters++]=
3156    CbcOrClpParam("trust!PseudoCosts","Number of branches before we trust pseudocosts",
3157                  -3,2000000,NUMBERBEFORE);
3158  parameters[numberParameters-1].setLonghelp
3159    (
3160     "Using strong branching computes pseudo-costs.  After this many times for a variable we just \
3161trust the pseudo costs and do not do any more strong branching."
3162     ); 
3163#endif
3164#ifdef COIN_HAS_CBC
3165  parameters[numberParameters++]=
3166    CbcOrClpParam("tune!PreProcess","Dubious tuning parameters",
3167                  0,20000000,PROCESSTUNE,1);
3168  parameters[numberParameters-1].setLonghelp
3169    (
3170     "For making equality cliques this is minimumsize.  Also for adding \
3171integer slacks.  May be used for more later \
3172If <1000 that is what it does.  If <1000000 - numberPasses is (value/1000)-1 and tune is tune %1000. \
3173If >= 1000000! - numberPasses is (value/1000000)-1 and tune is tune %1000000.  In this case if tune is now still >=10000 \
3174numberPassesPerInnerLoop is changed from 10 to (tune-10000)-1 and tune becomes tune % 10000!!!!! - happy? - \
3175so to keep normal limit on cliques of 5, do 3 major passes (include presolves) but only doing one tightening pass per major pass - \
3176you would use 3010005 (I think)"
3177     ); 
3178  parameters[numberParameters++]=
3179    CbcOrClpParam("two!MirCuts","Whether to use Two phase Mixed Integer Rounding cuts",
3180                  "off",TWOMIRCUTS);
3181  parameters[numberParameters-1].append("on");
3182  parameters[numberParameters-1].append("root");
3183  parameters[numberParameters-1].append("ifmove");
3184  parameters[numberParameters-1].append("forceOn");
3185  parameters[numberParameters-1].append("onglobal");
3186  parameters[numberParameters-1].append("forceandglobal");
3187  parameters[numberParameters-1].append("forceLongOn");
3188  parameters[numberParameters-1].setLonghelp
3189    (
3190     "This switches on two phase mixed integer rounding  cuts (either at root or in entire tree) \
3191See branchAndCut for information on options."
3192     ); 
3193#endif
3194  parameters[numberParameters++]=
3195    CbcOrClpParam("unitTest","Do unit test",
3196                  UNITTEST,3,1);
3197  parameters[numberParameters-1].setLonghelp
3198    (
3199     "This exercises the unit test for clp"
3200     ); 
3201  parameters[numberParameters++]=
3202    CbcOrClpParam("userClp","Hand coded Clp stuff",
3203                  USERCLP,0,0);
3204  parameters[numberParameters-1].setLonghelp
3205    (
3206     "There are times e.g. when using AMPL interface when you may wish to do something unusual.  \
3207Look for USERCLP in main driver and modify sample code."
3208     ); 
3209#ifdef COIN_HAS_CBC
3210  parameters[numberParameters++]=
3211    CbcOrClpParam("userCbc","Hand coded Cbc stuff",
3212                  USERCBC,0,0);
3213  parameters[numberParameters-1].setLonghelp
3214    (
3215     "There are times e.g. when using AMPL interface when you may wish to do something unusual.  \
3216Look for USERCBC in main driver and modify sample code. \
3217It is possible you can get same effect by using example driver4.cpp."
3218     ); 
3219  parameters[numberParameters++]=
3220      CbcOrClpParam("Vnd!VariableNeighborhoodSearch","Whether to try Variable Neighborhood Search",
3221                    "off",VND);
3222    parameters[numberParameters-1].append("on");
3223    parameters[numberParameters-1].append("both");
3224    parameters[numberParameters-1].append("before");
3225    parameters[numberParameters-1].append("intree");
3226  parameters[numberParameters-1].setLonghelp
3227    (
3228     "This switches on variable neighborhood Search. \
3229Doh option does heuristic before preprocessing"     ); 
3230#endif
3231  parameters[numberParameters++]=
3232    CbcOrClpParam("vector","Whether to use vector? Form of matrix in simplex",
3233                  "off",VECTOR,7,0);
3234  parameters[numberParameters-1].append("on");
3235  parameters[numberParameters-1].setLonghelp
3236    (
3237     "If this is on ClpPackedMatrix uses extra column copy in odd format."
3238     ); 
3239  parameters[numberParameters++]=
3240    CbcOrClpParam("verbose","Switches on longer help on single ?",
3241                  0,31,VERBOSE,0);
3242  parameters[numberParameters-1].setLonghelp
3243    (
3244     "Set to 1 to get short help with ? list, 2 to get long help, 3 for both.  (add 4 to just get ampl ones)."
3245     ); 
3246  parameters[numberParameters-1].setIntValue(0);
3247#ifdef COIN_HAS_CBC
3248  parameters[numberParameters++]=
3249    CbcOrClpParam("vub!heuristic","Type of vub heuristic",
3250                  -2,20,VUBTRY,0);
3251  parameters[numberParameters-1].setLonghelp
3252    (
3253     "If set will try and fix some integer variables"
3254     ); 
3255  parameters[numberParameters-1].setIntValue(-1);
3256#ifdef ZERO_HALF_CUTS
3257  parameters[numberParameters++]=
3258    CbcOrClpParam("zero!HalfCuts","Whether to use zero half cuts",
3259                  "off",ZEROHALFCUTS);
3260  parameters[numberParameters-1].append("on");
3261  parameters[numberParameters-1].append("root");
3262  parameters[numberParameters-1].append("ifmove");
3263  parameters[numberParameters-1].append("forceOn");
3264  parameters[numberParameters-1].append("onglobal");
3265  parameters[numberParameters-1].setLonghelp
3266    (
3267     "This switches on zero-half cuts (either at root or in entire tree) \
3268See branchAndCut for information on options."
3269     );
3270#endif
3271#endif
3272  assert(numberParameters<CBCMAXPARAMETERS);
3273}
3274// Given a parameter type - returns its number in list
3275int whichParam (CbcOrClpParameterType name, 
3276                int numberParameters, CbcOrClpParam *const parameters)
3277{
3278  int i;
3279  for (i=0;i<numberParameters;i++) {
3280    if (parameters[i].type()==name)
3281      break;
3282  }
3283  assert (i<numberParameters);
3284  return i;
3285}
3286#ifdef COIN_HAS_CLP
3287/* Restore a solution from file.
3288   mode 0 normal, 1 swap rows and columns and primal and dual
3289   if 2 set then also change signs
3290*/
3291void restoreSolution(ClpSimplex * lpSolver,std::string fileName,int mode)
3292{
3293  FILE * fp=fopen(fileName.c_str(),"rb");
3294  if (fp) {
3295    int numberRows=lpSolver->numberRows();
3296    int numberColumns=lpSolver->numberColumns();
3297    int numberRowsFile;
3298    int numberColumnsFile;
3299    double objectiveValue;
3300    int nRead;
3301    nRead=fread(&numberRowsFile,sizeof(int),1,fp);
3302    if (nRead!=1)
3303      throw("Error in fread");
3304    nRead=fread(&numberColumnsFile,sizeof(int),1,fp);
3305    if (nRead!=1)
3306      throw("Error in fread");
3307    nRead=fread(&objectiveValue,sizeof(double),1,fp);
3308    if (nRead!=1)
3309      throw("Error in fread");
3310    double * dualRowSolution = lpSolver->dualRowSolution();
3311    double * primalRowSolution = lpSolver->primalRowSolution();
3312    double * dualColumnSolution = lpSolver->dualColumnSolution();
3313    double * primalColumnSolution = lpSolver->primalColumnSolution();
3314    if (mode) {
3315      // swap
3316      int k=numberRows;
3317      numberRows=numberColumns;
3318      numberColumns=k;
3319      double * temp;
3320      temp = dualRowSolution;
3321      dualRowSolution = primalColumnSolution;
3322      primalColumnSolution=temp;
3323      temp = dualColumnSolution;
3324      dualColumnSolution = primalRowSolution;
3325      primalRowSolution=temp;
3326    }
3327    if (numberRows>numberRowsFile||numberColumns>numberColumnsFile) {
3328      std::cout<<"Mismatch on rows and/or columns - giving up"<<std::endl;
3329    } else {
3330      lpSolver->setObjectiveValue(objectiveValue);
3331      if (numberRows==numberRowsFile&&numberColumns==numberColumnsFile) {
3332        nRead=fread(primalRowSolution,sizeof(double),numberRows,fp);
3333        if (nRead!=numberRows)
3334          throw("Error in fread");
3335        nRead=fread(dualRowSolution,sizeof(double),numberRows,fp);
3336        if (nRead!=numberRows)
3337          throw("Error in fread");
3338        nRead=fread(primalColumnSolution,sizeof(double),numberColumns,fp);
3339        if (nRead!=numberColumns)
3340          throw("Error in fread");
3341        nRead=fread(dualColumnSolution,sizeof(double),numberColumns,fp);
3342        if (nRead!=numberColumns)
3343          throw("Error in fread");
3344      } else {
3345        std::cout<<"Mismatch on rows and/or columns - truncating"<<std::endl;
3346        double * temp = new double [CoinMax(numberRowsFile,numberColumnsFile)];
3347        nRead=fread(temp,sizeof(double),numberRowsFile,fp);
3348        if (nRead!=numberRowsFile)
3349          throw("Error in fread");
3350        CoinMemcpyN(temp,numberRows,primalRowSolution);
3351        nRead=fread(temp,sizeof(double),numberRowsFile,fp);
3352        if (nRead!=numberRowsFile)
3353          throw("Error in fread");
3354        CoinMemcpyN(temp,numberRows,dualRowSolution);
3355        nRead=fread(temp,sizeof(double),numberColumnsFile,fp);
3356        if (nRead!=numberColumnsFile)
3357          throw("Error in fread");
3358        CoinMemcpyN(temp,numberColumns,primalColumnSolution);
3359        nRead=fread(temp,sizeof(double),numberColumnsFile,fp);
3360        if (nRead!=numberColumnsFile)
3361          throw("Error in fread");
3362        CoinMemcpyN(temp,numberColumns,dualColumnSolution);
3363        delete [] temp;
3364      }
3365      if (mode==3) {
3366        int i;
3367        for (i=0;i<numberRows;i++) {
3368          primalRowSolution[i] = -primalRowSolution[i];
3369          dualRowSolution[i] = -dualRowSolution[i];
3370        }
3371        for (i=0;i<numberColumns;i++) {
3372          primalColumnSolution[i] = -primalColumnSolution[i];
3373          dualColumnSolution[i] = -dualColumnSolution[i];
3374        }
3375      }
3376    }
3377    fclose(fp);
3378  } else {
3379    std::cout<<"Unable to open file "<<fileName<<std::endl;
3380  }
3381}
3382// Dump a solution to file
3383void saveSolution(const ClpSimplex * lpSolver,std::string fileName)
3384{
3385  if (strstr(fileName.c_str(),"_fix_read_")) {
3386    FILE * fp=fopen(fileName.c_str(),"rb");
3387    if (fp) {
3388      ClpSimplex * solver = const_cast<ClpSimplex *>(lpSolver);
3389      restoreSolution(solver,fileName,0);
3390      // fix all
3391      int logLevel=solver->logLevel();
3392      int iColumn;
3393      int numberColumns=solver->numberColumns();
3394      double * primalColumnSolution = 
3395        solver->primalColumnSolution();
3396      double * columnLower = solver->columnLower();
3397      double * columnUpper = solver->columnUpper();
3398      for (iColumn=0;iColumn<numberColumns;iColumn++) {
3399        double value = primalColumnSolution[iColumn];
3400        if (value>columnUpper[iColumn]) {
3401          if (value >columnUpper[iColumn]+1.0e-6&&logLevel>1)
3402            printf("%d value of %g - bounds %g %g\n",
3403                   iColumn,value,columnLower[iColumn],columnUpper[iColumn]);
3404          value=columnUpper[iColumn];
3405        } else if (value<columnLower[iColumn]) {
3406          if (value <columnLower[iColumn]-1.0e-6&&logLevel>1)
3407            printf("%d value of %g - bounds %g %g\n",
3408                   iColumn,value,columnLower[iColumn],columnUpper[iColumn]);
3409          value=columnLower[iColumn];
3410        }
3411        columnLower[iColumn]=value;
3412        columnUpper[iColumn]=value;
3413      }
3414      return;
3415    }
3416  }
3417  FILE * fp=fopen(fileName.c_str(),"wb");
3418  if (fp) {
3419    int numberRows=lpSolver->numberRows();
3420    int numberColumns=lpSolver->numberColumns();
3421    double objectiveValue = lpSolver->objectiveValue();
3422    int nWrite;
3423    nWrite=fwrite(&numberRows,sizeof(int),1,fp);
3424    if (nWrite!=1)
3425      throw("Error in fwrite");
3426    nWrite=fwrite(&numberColumns,sizeof(int),1,fp);
3427    if (nWrite!=1)
3428      throw("Error in fwrite");
3429    nWrite=fwrite(&objectiveValue,sizeof(double),1,fp);
3430    if (nWrite!=1)
3431      throw("Error in fwrite");
3432    double * dualRowSolution = lpSolver->dualRowSolution();
3433    double * primalRowSolution = lpSolver->primalRowSolution();
3434    nWrite=fwrite(primalRowSolution,sizeof(double),numberRows,fp);
3435    if (nWrite!=numberRows)
3436      throw("Error in fwrite");
3437    nWrite=fwrite(dualRowSolution,sizeof(double),numberRows,fp);
3438    if (nWrite!=numberRows)
3439      throw("Error in fwrite");
3440    double * dualColumnSolution = lpSolver->dualColumnSolution();
3441    double * primalColumnSolution = lpSolver->primalColumnSolution();
3442    nWrite=fwrite(primalColumnSolution,sizeof(double),numberColumns,fp);
3443    if (nWrite!=numberColumns)
3444      throw("Error in fwrite");
3445    nWrite=fwrite(dualColumnSolution,sizeof(double),numberColumns,fp);
3446    if (nWrite!=numberColumns)
3447      throw("Error in fwrite");
3448    fclose(fp);
3449  } else {
3450    std::cout<<"Unable to open file "<<fileName<<std::endl;
3451  }
3452}
3453#endif
Note: See TracBrowser for help on using the repository browser.