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

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

forgot this

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