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

Last change on this file since 1115 was 1115, checked in by forrest, 13 years ago

mainly fix isFixed bug when reusing factorization

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