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

Last change on this file since 1152 was 1152, checked in by forrest, 14 years ago

allow dense factorization

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 101.4 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("csv!Statistics","Create one line of statistics",
1349                  CSVSTATISTICS,2,false);
1350  parameters[numberParameters-1].setLonghelp
1351    (
1352     "This appends statistics to given file name.  It will use the default\
1353 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
1354 is initialized to '', i.e. it must be set.  Adds header if file empty or does not exist."
1355     ); 
1356  parameters[numberParameters++]=
1357    CbcOrClpParam("cutD!epth","Depth in tree at which to do cuts",
1358                  -1,999999,CUTDEPTH);
1359  parameters[numberParameters-1].setLonghelp
1360    (
1361     "Cut generators may be - off, on only at root, on if they look possible \
1362and on.  If they are done every node then that is that, but it may be worth doing them \
1363every so often.  The original method was every so many nodes but it is more logical \
1364to do it whenever depth in tree is a multiple of K.  This option does that and defaults \
1365to -1 (off)."
1366     );
1367  parameters[numberParameters-1].setIntValue(-1);
1368  parameters[numberParameters++]=
1369    CbcOrClpParam("cuto!ff","All solutions must be better than this",
1370                  -1.0e60,1.0e60,CUTOFF);
1371  parameters[numberParameters-1].setDoubleValue(1.0e50);
1372  parameters[numberParameters-1].setLonghelp
1373    (
1374     "All solutions must be better than this value (in a minimization sense).  \
1375This is also set by code whenever it obtains a solution and is set to value of \
1376objective for solution minus cutoff increment."
1377     );
1378  parameters[numberParameters++]=
1379    CbcOrClpParam("cuts!OnOff","Switches all cuts on or off",
1380                  "off",CUTSSTRATEGY);
1381  parameters[numberParameters-1].append("on");
1382  parameters[numberParameters-1].append("root");
1383  parameters[numberParameters-1].append("ifmove");
1384  parameters[numberParameters-1].append("forceOn");
1385  parameters[numberParameters-1].setLonghelp
1386    (
1387     "This can be used to switch on or off all cuts (apart from Reduce and Split).  Then you can do \
1388individual ones off or on \
1389See branchAndCut for information on options."
1390     ); 
1391  parameters[numberParameters++]=
1392    CbcOrClpParam("debug!In","read valid solution from file",
1393                  DEBUG,7,false);
1394  parameters[numberParameters-1].setLonghelp
1395    (
1396     "This will read a solution file from the given file name.  It will use the default\
1397 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
1398 is initialized to '', i.e. it must be set.\n\n\
1399If set to create it will create a file called debug.file  after search; if set \
1400to createAfterPre it will create one suitable for use after preprocessing.\n\n\
1401The idea is that if you suspect a bad cut generator and you did not use preprocessing \
1402you can do a good run with debug set to 'create' and then switch on the cuts you suspect and \
1403re-run with debug set to 'debug.file'  Similarly if you do use preprocessing but use \
1404createAfterPre.  The create case has same effect as saveSolution."
1405     ); 
1406#endif
1407#ifdef COIN_HAS_CBC
1408  parameters[numberParameters++]=
1409    CbcOrClpParam("dense!Threshold","Whether to use dense factorization",
1410                  -1,200,DENSE,false);
1411  parameters[numberParameters-1].setLonghelp
1412    (
1413     "If processed problem <= this use dense factorization (for testing)"
1414     ); 
1415  parameters[numberParameters-1].setIntValue(-1);
1416  parameters[numberParameters++]=
1417    CbcOrClpParam("dextra1","Extra double parameter 1",
1418                  -COIN_DBL_MAX,COIN_DBL_MAX,DEXTRA1,false);
1419  parameters[numberParameters-1].setDoubleValue(0.0);
1420  parameters[numberParameters++]=
1421    CbcOrClpParam("dextra2","Extra double parameter 2",
1422                  -COIN_DBL_MAX,COIN_DBL_MAX,DEXTRA2,false);
1423  parameters[numberParameters-1].setDoubleValue(0.0);
1424  parameters[numberParameters++]=
1425    CbcOrClpParam("dextra3","Extra double parameter 3",
1426                  -COIN_DBL_MAX,COIN_DBL_MAX,DEXTRA3,false);
1427  parameters[numberParameters-1].setDoubleValue(0.0);
1428  parameters[numberParameters++]=
1429    CbcOrClpParam("dextra4","Extra double parameter 4",
1430                  -COIN_DBL_MAX,COIN_DBL_MAX,DEXTRA4,false);
1431  parameters[numberParameters-1].setDoubleValue(0.0);
1432#endif
1433  parameters[numberParameters++]=
1434    CbcOrClpParam("direction","Minimize or Maximize",
1435                  "min!imize",DIRECTION);
1436  parameters[numberParameters-1].append("max!imize");
1437  parameters[numberParameters-1].append("zero");
1438  parameters[numberParameters-1].setLonghelp
1439    (
1440     "The default is minimize - use 'direction maximize' for maximization.\n\
1441You can also use the parameters 'maximize' or 'minimize'."
1442     ); 
1443  parameters[numberParameters++]=
1444    CbcOrClpParam("directory","Set Default directory for import etc.",
1445                  DIRECTORY);
1446  parameters[numberParameters-1].setLonghelp
1447    (
1448     "This sets the directory which import, export, saveModel, restoreModel etc will use.\
1449  It is initialized to './'"
1450     ); 
1451  parameters[numberParameters++]=
1452    CbcOrClpParam("dirSample","Set directory where the COIN-OR sample problems are.",
1453                  DIRSAMPLE);
1454  parameters[numberParameters-1].setLonghelp
1455    (
1456     "This sets the directory where the COIN-OR sample problems reside. It is\
1457 used only when -unitTest is passed to clp. clp will pick up the test problems\
1458 from this directory.\
1459 It is initialized to '../../Data/Sample'"
1460     ); 
1461  parameters[numberParameters++]=
1462    CbcOrClpParam("dirNetlib","Set directory where the netlib problems are.",
1463                  DIRNETLIB);
1464  parameters[numberParameters-1].setLonghelp
1465    (
1466     "This sets the directory where the netlib problems reside. One can get\
1467 the netlib problems from COIN-OR or from the main netlib site. This\
1468 parameter is used only when -netlib is passed to clp. clp will pick up the\
1469 netlib problems from this directory. If clp is built without zlib support\
1470 then the problems must be uncompressed.\
1471 It is initialized to '../../Data/Netlib'"
1472     ); 
1473  parameters[numberParameters++]=
1474    CbcOrClpParam("dirMiplib","Set directory where the miplib 2003 problems are.",
1475                  DIRMIPLIB);
1476  parameters[numberParameters-1].setLonghelp
1477    (
1478     "This sets the directory where the miplib 2003 problems reside. One can\
1479 get the miplib problems from COIN-OR or from the main miplib site. This\
1480 parameter is used only when -miplib is passed to cbc. cbc will pick up the\
1481 miplib problems from this directory. If cbc is built without zlib support\
1482 then the problems must be uncompressed.\
1483 It is initialized to '../../Data/miplib3'"
1484     ); 
1485#ifdef COIN_HAS_CBC
1486  parameters[numberParameters++]=
1487    CbcOrClpParam("doH!euristic","Do heuristics before any preprocessing",
1488                  DOHEURISTIC,3);
1489  parameters[numberParameters-1].setLonghelp
1490    (
1491     "Normally heuristics are done in branch and bound.  It may be useful to do them outside. \
1492Doing this may also set cutoff."
1493     ); 
1494#endif
1495#ifdef COIN_HAS_CLP
1496  parameters[numberParameters++]=
1497    CbcOrClpParam("dualB!ound","Initially algorithm acts as if no \
1498gap between bounds exceeds this value",
1499                  1.0e-20,1.0e12,DUALBOUND);
1500  parameters[numberParameters-1].setLonghelp
1501    (
1502     "The dual algorithm in Clp is a single phase algorithm as opposed to a two phase\
1503 algorithm where you first get feasible then optimal.  If a problem has both upper and\
1504 lower bounds then it is trivial to get dual feasible by setting non basic variables\
1505 to correct bound.  If the gap between the upper and lower bounds of a variable is more\
1506 than the value of dualBound Clp introduces fake bounds so that it can make the problem\
1507 dual feasible.  This has the same effect as a composite objective function in the\
1508 primal algorithm.  Too high a value may mean more iterations, while too low a bound means\
1509 the code may go all the way and then have to increase the bounds.  OSL had a heuristic to\
1510 adjust bounds, maybe we need that here."
1511     );
1512  parameters[numberParameters++]=
1513    CbcOrClpParam("dualize","Solves dual reformulation",
1514                  0,3,DUALIZE,false);
1515  parameters[numberParameters-1].setLonghelp
1516    (
1517     "Don't even think about it."
1518     ); 
1519  parameters[numberParameters++]=
1520    CbcOrClpParam("dualP!ivot","Dual pivot choice algorithm",
1521                  "auto!matic",DUALPIVOT);
1522  parameters[numberParameters-1].append("dant!zig");
1523  parameters[numberParameters-1].append("partial");
1524  parameters[numberParameters-1].append("steep!est");
1525  parameters[numberParameters-1].setLonghelp
1526    (
1527     "Clp can use any pivot selection algorithm which the user codes as long as it\
1528 implements the features in the abstract pivot base class.  The Dantzig method is implemented\
1529 to show a simple method but its use is deprecated.  Steepest is the method of choice and there\
1530 are two variants which keep all weights updated but only scan a subset each iteration.\
1531 Partial switches this on while automatic decides at each iteration based on information\
1532 about the factorization."
1533     ); 
1534  parameters[numberParameters++]=
1535    CbcOrClpParam("dualS!implex","Do dual simplex algorithm",
1536                  DUALSIMPLEX);
1537  parameters[numberParameters-1].setLonghelp
1538    (
1539     "This command solves the current model using the dual steepest edge algorithm.\
1540The time and iterations may be affected by settings such as presolve, scaling, crash\
1541 and also by dual pivot method, fake bound on variables and dual and primal tolerances."
1542     );
1543#endif
1544  parameters[numberParameters++]=
1545    CbcOrClpParam("dualT!olerance","For an optimal solution \
1546no dual infeasibility may exceed this value",
1547                  1.0e-20,1.0e12,DUALTOLERANCE);
1548  parameters[numberParameters-1].setLonghelp
1549    (
1550     "Normally the default tolerance is fine, but you may want to increase it a\
1551 bit if a dual run seems to be having a hard time.  One method which can be faster is \
1552to use a large tolerance e.g. 1.0e-4 and dual and then clean up problem using primal and the \
1553correct tolerance (remembering to switch off presolve for this final short clean up phase)."
1554     ); 
1555#ifdef COIN_HAS_CLP
1556  parameters[numberParameters++]=
1557    CbcOrClpParam("either!Simplex","Do dual or primal simplex algorithm",
1558                  EITHERSIMPLEX);
1559  parameters[numberParameters-1].setLonghelp
1560    (
1561     "This command solves the current model using the dual or primal algorithm,\
1562 based on a dubious analysis of model."
1563     );
1564#endif
1565  parameters[numberParameters++]=
1566    CbcOrClpParam("end","Stops clp execution",
1567                  EXIT);
1568  parameters[numberParameters-1].setLonghelp
1569    (
1570     "This stops execution ; end, exit, quit and stop are synonyms"
1571     ); 
1572  parameters[numberParameters++]=
1573    CbcOrClpParam("error!sAllowed","Whether to allow import errors",
1574                  "off",ERRORSALLOWED,3);
1575  parameters[numberParameters-1].append("on");
1576  parameters[numberParameters-1].setLonghelp
1577    (
1578     "The default is not to use any model which had errors when reading the mps file.\
1579  Setting this to 'on' will allow all errors from which the code can recover\
1580 simply by ignoring the error.  There are some errors from which the code can not recover \
1581e.g. no ENDATA.  This has to be set before import i.e. -errorsAllowed on -import xxxxxx.mps."
1582     );
1583  parameters[numberParameters++]=
1584    CbcOrClpParam("exit","Stops clp execution",
1585                  EXIT);
1586  parameters[numberParameters-1].setLonghelp
1587    (
1588     "This stops the execution of Clp, end, exit, quit and stop are synonyms"
1589     ); 
1590  parameters[numberParameters++]=
1591    CbcOrClpParam("export","Export model as mps file",
1592                  EXPORT);
1593  parameters[numberParameters-1].setLonghelp
1594    (
1595     "This will write an MPS format file to the given file name.  It will use the default\
1596 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
1597 is initialized to 'default.mps'."
1598     ); 
1599#ifdef COIN_HAS_CBC
1600  parameters[numberParameters++]=
1601    CbcOrClpParam("extra1","Extra integer parameter 1",
1602                  -1,COIN_INT_MAX,EXTRA1,false);
1603  parameters[numberParameters-1].setIntValue(-1);
1604  parameters[numberParameters++]=
1605    CbcOrClpParam("extra2","Extra integer parameter 2",
1606                  -1,COIN_INT_MAX,EXTRA2,false);
1607  parameters[numberParameters-1].setIntValue(-1);
1608  parameters[numberParameters++]=
1609    CbcOrClpParam("extra3","Extra integer parameter 3",
1610                  -1,COIN_INT_MAX,EXTRA3,false);
1611  parameters[numberParameters-1].setIntValue(-1);
1612  parameters[numberParameters++]=
1613    CbcOrClpParam("extra4","Extra integer parameter 4",
1614                  -1,COIN_INT_MAX,EXTRA4,false);
1615  parameters[numberParameters-1].setIntValue(-1);
1616#endif
1617#ifdef COIN_HAS_CLP
1618  parameters[numberParameters++]=
1619    CbcOrClpParam("fakeB!ound","All bounds <= this value - DEBUG",
1620                  1.0,1.0e15,FAKEBOUND,false);
1621#ifdef COIN_HAS_CBC
1622    parameters[numberParameters++]=
1623      CbcOrClpParam("feas!ibilityPump","Whether to try Feasibility Pump",
1624                    "off",FPUMP);
1625    parameters[numberParameters-1].append("on");
1626    parameters[numberParameters-1].append("do");
1627  parameters[numberParameters-1].setLonghelp
1628    (
1629     "This switches on feasibility pump heuristic at root. This is due to Fischetti and Lodi \
1630and uses a sequence of Lps to try and get an integer feasible solution. \
1631Some fine tuning is available by passFeasibilityPump. Do options does heuristic before preprocessing"
1632     ); 
1633  parameters[numberParameters++]=
1634    CbcOrClpParam("fix!OnDj","Try heuristic based on fixing variables with \
1635reduced costs greater than this",
1636                  -1.0e20,1.0e20,DJFIX,false);
1637  parameters[numberParameters-1].setLonghelp
1638    (
1639     "If this is set integer variables with reduced costs greater than this will be fixed \
1640before branch and bound - use with extreme caution!" 
1641     ); 
1642    parameters[numberParameters++]=
1643      CbcOrClpParam("flow!CoverCuts","Whether to use Flow Cover cuts",
1644                    "off",FLOWCUTS);
1645    parameters[numberParameters-1].append("on");
1646    parameters[numberParameters-1].append("root");
1647    parameters[numberParameters-1].append("ifmove");
1648    parameters[numberParameters-1].append("forceOn");
1649    parameters[numberParameters-1].setLonghelp
1650    (
1651     "This switches on flow cover cuts (either at root or in entire tree) \
1652See branchAndCut for information on options."
1653     ); 
1654    parameters[numberParameters++]=
1655      CbcOrClpParam("force!Solution","Whether to use given solution as crash for BAB",
1656                    -1,20000000,USESOLUTION);
1657    parameters[numberParameters-1].setIntValue(-1);
1658    parameters[numberParameters-1].setLonghelp
1659    (
1660     "-1 off.  If 0 then tries to branch to solution given by AMPL or priorities file. \
1661If >0 then also does that many nodes on fixed problem."
1662     ); 
1663#endif
1664  parameters[numberParameters++]=
1665    CbcOrClpParam("gamma!(Delta)","Whether to regularize barrier",
1666                  "off",GAMMA,7,false);
1667  parameters[numberParameters-1].append("on");
1668  parameters[numberParameters-1].append("gamma");
1669  parameters[numberParameters-1].append("delta");
1670  parameters[numberParameters-1].append("onstrong");
1671  parameters[numberParameters-1].append("gammastrong");
1672  parameters[numberParameters-1].append("deltastrong");
1673#endif
1674#ifdef COIN_HAS_CBC
1675  parameters[numberParameters++]=
1676    CbcOrClpParam("gomory!Cuts","Whether to use Gomory cuts",
1677                  "off",GOMORYCUTS);
1678  parameters[numberParameters-1].append("on");
1679  parameters[numberParameters-1].append("root");
1680  parameters[numberParameters-1].append("ifmove");
1681  parameters[numberParameters-1].append("forceOn");
1682  parameters[numberParameters-1].append("forceLongOn");
1683  parameters[numberParameters-1].setLonghelp
1684    (
1685     "The original cuts - beware of imitations!  Having gone out of favor, they are now more \
1686fashionable as LP solvers are more robust and they interact well with other cuts.  They will almost always \
1687give cuts (although in this executable they are limited as to number of variables in cut).  \
1688However the cuts may be dense so it is worth experimenting (Long allows any length). \
1689See branchAndCut for information on options."
1690     ); 
1691  parameters[numberParameters++]=
1692    CbcOrClpParam("greedy!Heuristic","Whether to use a greedy heuristic",
1693                  "off",GREEDY);
1694  parameters[numberParameters-1].append("on");
1695  parameters[numberParameters-1].append("do");
1696  //parameters[numberParameters-1].append("root");
1697  parameters[numberParameters-1].setLonghelp
1698    (
1699     "Switches on a greedy heuristic which will try and obtain a solution.  It may just fix a \
1700percentage of variables and then try a small branch and cut run. \
1701The Do option switches on before preprocessing."
1702     ); 
1703  parameters[numberParameters++]=
1704    CbcOrClpParam("heur!isticsOnOff","Switches most heuristics on or off",
1705                  "off",HEURISTICSTRATEGY);
1706  parameters[numberParameters-1].append("on");
1707  parameters[numberParameters-1].setLonghelp
1708    (
1709     "This can be used to switch on or off all heuristics.  Then you can do \
1710individual ones off or on.  CbcTreeLocal is not included as it dramatically \
1711alters search."
1712     ); 
1713#endif
1714  parameters[numberParameters++]=
1715    CbcOrClpParam("help","Print out version, non-standard options and some help",
1716                  HELP,3);
1717  parameters[numberParameters-1].setLonghelp
1718    (
1719     "This prints out some help to get user started.  If you have printed this then \
1720you should be past that stage:-)"
1721     ); 
1722#ifdef COIN_HAS_CBC
1723  parameters[numberParameters++]=
1724    CbcOrClpParam("hot!StartMaxIts","Maximum iterations on hot start",
1725                  0,COIN_INT_MAX,MAXHOTITS,false);
1726#endif
1727#ifdef COIN_HAS_CLP
1728  parameters[numberParameters++]=
1729    CbcOrClpParam("idiot!Crash","Whether to try idiot crash",
1730                  -1,999999,IDIOT);
1731  parameters[numberParameters-1].setLonghelp
1732    (
1733     "This is a type of 'crash' which works well on some homogeneous problems.\
1734 It works best on problems with unit elements and rhs but will do something to any model.  It should only be\
1735 used before primal.  It can be set to -1 when the code decides for itself whether to use it,\
1736 0 to switch off or n > 0 to do n passes."
1737     ); 
1738#endif
1739  parameters[numberParameters++]=
1740    CbcOrClpParam("import","Import model from mps file",
1741                  IMPORT,3);
1742  parameters[numberParameters-1].setLonghelp
1743    (
1744     "This will read an MPS format file from the given file name.  It will use the default\
1745 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
1746 is initialized to '', i.e. it must be set.  If you have libgz then it can read compressed\
1747 files 'xxxxxxxx.gz'.."
1748     );
1749#ifdef COIN_HAS_CBC
1750  parameters[numberParameters++]=
1751    CbcOrClpParam("inc!rement","A valid solution must be at least this \
1752much better than last integer solution",
1753                  -1.0e20,1.0e20,INCREMENT);
1754  parameters[numberParameters-1].setLonghelp
1755    (
1756     "Whenever a solution is found the bound on solutions is set to solution (in a minimization\
1757sense) plus this.  If it is not set then the code will try and work one out e.g. if \
1758all objective coefficients are multiples of 0.01 and only integer variables have entries in \
1759objective then this can be set to 0.01.  Be careful if you set this negative!"
1760     ); 
1761  parameters[numberParameters++]=
1762    CbcOrClpParam("inf!easibilityWeight","Each integer infeasibility is expected \
1763to cost this much",
1764                  0.0,1.0e20,INFEASIBILITYWEIGHT);
1765  parameters[numberParameters-1].setLonghelp
1766    (
1767     "A primitive way of deciding which node to explore next.  Satisfying each integer infeasibility is \
1768expected to cost this much."
1769     ); 
1770  parameters[numberParameters++]=
1771    CbcOrClpParam("initialS!olve","Solve to continuous",
1772                  SOLVECONTINUOUS);
1773  parameters[numberParameters-1].setLonghelp
1774    (
1775     "This just solves the problem to continuous - without adding any cuts"
1776     ); 
1777  parameters[numberParameters++]=
1778    CbcOrClpParam("integerT!olerance","For an optimal solution \
1779no integer variable may be this away from an integer value",
1780              1.0e-20,0.5,INTEGERTOLERANCE);
1781  parameters[numberParameters-1].setLonghelp
1782    (
1783     "Beware of setting this smaller than the primal tolerance."
1784     ); 
1785#endif
1786#ifdef COIN_HAS_CLP
1787  parameters[numberParameters++]=
1788    CbcOrClpParam("keepN!ames","Whether to keep names from import",
1789                  "on",KEEPNAMES);
1790  parameters[numberParameters-1].append("off");
1791  parameters[numberParameters-1].setLonghelp
1792    (
1793     "It saves space to get rid of names so if you need to you can set this to off.  \
1794This needs to be set before the import of model - so -keepnames off -import xxxxx.mps."
1795     ); 
1796  parameters[numberParameters++]=
1797    CbcOrClpParam("KKT","Whether to use KKT factorization",
1798                  "off",KKT,7,false);
1799  parameters[numberParameters-1].append("on");
1800#endif
1801#ifdef COIN_HAS_CBC
1802  parameters[numberParameters++]=
1803    CbcOrClpParam("knapsack!Cuts","Whether to use Knapsack cuts",
1804                  "off",KNAPSACKCUTS);
1805  parameters[numberParameters-1].append("on");
1806  parameters[numberParameters-1].append("root");
1807  parameters[numberParameters-1].append("ifmove");
1808  parameters[numberParameters-1].append("forceOn");
1809  parameters[numberParameters-1].setLonghelp
1810    (
1811     "This switches on knapsack cuts (either at root or in entire tree) \
1812See branchAndCut for information on options."
1813     ); 
1814  parameters[numberParameters++]=
1815    CbcOrClpParam("lift!AndProjectCuts","Whether to use Lift and Project cuts",
1816                  "off",LANDPCUTS);
1817  parameters[numberParameters-1].append("on");
1818  parameters[numberParameters-1].append("root");
1819  parameters[numberParameters-1].append("ifmove");
1820  parameters[numberParameters-1].append("forceOn");
1821  parameters[numberParameters-1].setLonghelp
1822    (
1823     "Lift and project cuts - may be expensive to compute. \
1824See branchAndCut for information on options."
1825     ); 
1826  parameters[numberParameters++]=
1827    CbcOrClpParam("local!TreeSearch","Whether to use local treesearch",
1828                  "off",LOCALTREE);
1829  parameters[numberParameters-1].append("on");
1830  parameters[numberParameters-1].setLonghelp
1831    (
1832     "This switches on a local search algorithm when a solution is found.  This is from \
1833Fischetti and Lodi and is not really a heuristic although it can be used as one. \
1834When used from Coin solve it has limited functionality.  It is not switched on when \
1835heuristics are switched on."
1836     ); 
1837#endif
1838#ifndef COIN_HAS_CBC
1839  parameters[numberParameters++]=
1840    CbcOrClpParam("log!Level","Level of detail in Solver output",
1841                  -1,63,SOLVERLOGLEVEL);
1842#else
1843  parameters[numberParameters++]=
1844    CbcOrClpParam("log!Level","Level of detail in Coin branch and Cut output",
1845                  -63,63,LOGLEVEL);
1846  parameters[numberParameters-1].setIntValue(1);
1847#endif
1848  parameters[numberParameters-1].setLonghelp
1849    (
1850     "If 0 then there should be no output in normal circumstances.  1 is probably the best\
1851 value for most uses, while 2 and 3 give more information."
1852     ); 
1853  parameters[numberParameters++]=
1854    CbcOrClpParam("max!imize","Set optimization direction to maximize",
1855                  MAXIMIZE,7);
1856  parameters[numberParameters-1].setLonghelp
1857    (
1858     "The default is minimize - use 'maximize' for maximization.\n\
1859You can also use the parameters 'direction maximize'."
1860     ); 
1861#ifdef COIN_HAS_CLP
1862  parameters[numberParameters++]=
1863    CbcOrClpParam("maxF!actor","Maximum number of iterations between \
1864refactorizations",
1865                  1,999999,MAXFACTOR);
1866  parameters[numberParameters-1].setLonghelp
1867    (
1868     "If this is at its initial value of 200 then in this executable clp will guess at a\
1869 value to use.  Otherwise the user can set a value.  The code may decide to re-factorize\
1870 earlier for accuracy."
1871     ); 
1872  parameters[numberParameters++]=
1873    CbcOrClpParam("maxIt!erations","Maximum number of iterations before \
1874stopping",
1875                  0,2147483647,MAXITERATION);
1876  parameters[numberParameters-1].setLonghelp
1877    (
1878     "This can be used for testing purposes.  The corresponding library call\n\
1879      \tsetMaximumIterations(value)\n can be useful.  If the code stops on\
1880 seconds or by an interrupt this will be treated as stopping on maximum iterations"
1881     ); 
1882#endif
1883#ifdef COIN_HAS_CBC
1884  parameters[numberParameters++]=
1885    CbcOrClpParam("maxN!odes","Maximum number of nodes to do",
1886                  -1,2147483647,MAXNODES);
1887  parameters[numberParameters-1].setLonghelp
1888    (
1889     "This is a repeatable way to limit search.  Normally using time is easier \
1890but then the results may not be repeatable."
1891     ); 
1892  parameters[numberParameters++]=
1893    CbcOrClpParam("maxS!olutions","Maximum number of solutions to get",
1894                  1,2147483647,MAXSOLS);
1895  parameters[numberParameters-1].setLonghelp
1896    (
1897     "You may want to stop after (say) two solutions or an hour."
1898     ); 
1899#endif
1900  parameters[numberParameters++]=
1901    CbcOrClpParam("min!imize","Set optimization direction to minimize",
1902                  MINIMIZE,7);
1903  parameters[numberParameters-1].setLonghelp
1904    (
1905     "The default is minimize - use 'maximize' for maximization.\n\
1906This should only be necessary if you have previously set maximization \
1907You can also use the parameters 'direction minimize'."
1908     );
1909#ifdef COIN_HAS_CBC
1910  parameters[numberParameters++]=
1911    CbcOrClpParam("mipO!ptions","Dubious options for mip",
1912                  0,COIN_INT_MAX,MIPOPTIONS,false);
1913  parameters[numberParameters++]=
1914    CbcOrClpParam("more!MipOptions","More dubious options for mip",
1915                  -1,COIN_INT_MAX,MOREMIPOPTIONS,false);
1916  parameters[numberParameters++]=
1917    CbcOrClpParam("mixed!IntegerRoundingCuts","Whether to use Mixed Integer Rounding cuts",
1918                  "off",MIXEDCUTS);
1919  parameters[numberParameters-1].append("on");
1920  parameters[numberParameters-1].append("root");
1921  parameters[numberParameters-1].append("ifmove");
1922  parameters[numberParameters-1].append("forceOn");
1923  parameters[numberParameters-1].setLonghelp
1924    (
1925     "This switches on mixed integer rounding cuts (either at root or in entire tree) \
1926See branchAndCut for information on options."
1927     ); 
1928#endif
1929  parameters[numberParameters++]=
1930    CbcOrClpParam("mess!ages","Controls if Clpnnnn is printed",
1931                  "off",MESSAGES);
1932  parameters[numberParameters-1].append("on");
1933  parameters[numberParameters-1].setLonghelp
1934    ("The default behavior is to put out messages such as:\n\
1935   Clp0005 2261  Objective 109.024 Primal infeas 944413 (758)\n\
1936but this program turns this off to make it look more friendly.  It can be useful\
1937 to turn them back on if you want to be able to 'grep' for particular messages or if\
1938 you intend to override the behavior of a particular message."
1939     );
1940#ifdef COIN_HAS_CBC
1941  parameters[numberParameters++]=
1942    CbcOrClpParam("miniT!ree","Size of fast mini tree",
1943                  0,COIN_INT_MAX,NUMBERMINI,false);
1944  parameters[numberParameters-1].setLonghelp
1945    (
1946     "The idea is that I can do a small tree fast. \
1947This is a first try and will hopefully become more sophisticated."
1948     ); 
1949  parameters[numberParameters++]=
1950    CbcOrClpParam("miplib","Do some of miplib test set",
1951                  MIPLIB,3);
1952#endif
1953#ifdef COIN_HAS_CLP
1954  parameters[numberParameters++]=
1955    CbcOrClpParam("netlib","Solve entire netlib test set",
1956                  NETLIB_EITHER,3);
1957  parameters[numberParameters-1].setLonghelp
1958    (
1959     "This exercises the unit test for clp and then solves the netlib test set using dual or primal.\
1960The user can set options before e.g. clp -presolve off -netlib"
1961     ); 
1962#ifdef REAL_BARRIER
1963  parameters[numberParameters++]=
1964    CbcOrClpParam("netlibB!arrier","Solve entire netlib test set with barrier",
1965                  NETLIB_BARRIER,3);
1966  parameters[numberParameters-1].setLonghelp
1967    (
1968     "This exercises the unit test for clp and then solves the netlib test set using barrier.\
1969The user can set options before e.g. clp -kkt on -netlib"
1970     ); 
1971#endif
1972  parameters[numberParameters++]=
1973    CbcOrClpParam("netlibD!ual","Solve entire netlib test set (dual)",
1974                  NETLIB_DUAL,3);
1975  parameters[numberParameters-1].setLonghelp
1976    (
1977     "This exercises the unit test for clp and then solves the netlib test set using dual.\
1978The user can set options before e.g. clp -presolve off -netlib"
1979     ); 
1980  parameters[numberParameters++]=
1981    CbcOrClpParam("netlibP!rimal","Solve entire netlib test set (primal)",
1982                  NETLIB_PRIMAL,3);
1983  parameters[numberParameters-1].setLonghelp
1984    (
1985     "This exercises the unit test for clp and then solves the netlib test set using primal.\
1986The user can set options before e.g. clp -presolve off -netlibp"
1987     ); 
1988  parameters[numberParameters++]=
1989    CbcOrClpParam("netlibT!une","Solve entire netlib test set with 'best' algorithm",
1990                  NETLIB_TUNE,3);
1991  parameters[numberParameters-1].setLonghelp
1992    (
1993     "This exercises the unit test for clp and then solves the netlib test set using whatever \
1994works best.  I know this is cheating but it also stresses the code better by doing a \
1995mixture of stuff.  The best algorithm was chosen on a Linux ThinkPad using native cholesky \
1996with University of Florida ordering."
1997     ); 
1998  parameters[numberParameters++]=
1999    CbcOrClpParam("network","Tries to make network matrix",
2000                  NETWORK,7,false);
2001  parameters[numberParameters-1].setLonghelp
2002    (
2003     "Clp will go faster if the matrix can be converted to a network.  The matrix\
2004 operations may be a bit faster with more efficient storage, but the main advantage\
2005 comes from using a network factorization.  It will probably not be as fast as a \
2006specialized network code."
2007     ); 
2008#ifdef COIN_HAS_CBC
2009  parameters[numberParameters++]=
2010    CbcOrClpParam("node!Strategy","What strategy to use to select nodes",
2011                  "hybrid",NODESTRATEGY);
2012  parameters[numberParameters-1].append("fewest");
2013  parameters[numberParameters-1].append("depth");
2014  parameters[numberParameters-1].append("upfewest");
2015  parameters[numberParameters-1].append("downfewest");
2016  parameters[numberParameters-1].append("updepth");
2017  parameters[numberParameters-1].append("downdepth");
2018  parameters[numberParameters-1].setLonghelp
2019    (
2020     "Normally before a solution the code will choose node with fewest infeasibilities. \
2021You can choose depth as the criterion.  You can also say if up or down branch must \
2022be done first (the up down choice will carry on after solution). \
2023Default has now been changed to hybrid which is breadth first on small depth nodes then fewest."
2024     ); 
2025  parameters[numberParameters++]=
2026    CbcOrClpParam("numberA!nalyze","Number of analysis iterations",
2027                  -COIN_INT_MAX,COIN_INT_MAX,NUMBERANALYZE,false);
2028  parameters[numberParameters-1].setLonghelp
2029    (
2030     "This says how many iterations to spend at root node analyzing problem. \
2031This is a first try and will hopefully become more sophisticated."
2032     ); 
2033#endif
2034  parameters[numberParameters++]=
2035    CbcOrClpParam("objective!Scale","Scale factor to apply to objective",
2036                  -1.0e20,1.0e20,OBJSCALE,false);
2037  parameters[numberParameters-1].setLonghelp
2038    (
2039     "If the objective function has some very large values, you may wish to scale them\
2040 internally by this amount.  It can also be set by autoscale.  It is applied after scaling"
2041     ); 
2042  parameters[numberParameters-1].setDoubleValue(1.0);
2043#endif
2044#ifdef COIN_HAS_CBC
2045  parameters[numberParameters++]=
2046    CbcOrClpParam("outDup!licates","takes duplicate rows etc out of integer model",
2047                  OUTDUPROWS,7,false);
2048#endif
2049  parameters[numberParameters++]=
2050    CbcOrClpParam("output!Format","Which output format to use",
2051                  1,6,OUTPUTFORMAT);
2052  parameters[numberParameters-1].setLonghelp
2053    (
2054     "Normally export will be done using normal representation for numbers and two values\
2055 per line.  You may want to do just one per line (for grep or suchlike) and you may wish\
2056 to save with absolute accuracy using a coded version of the IEEE value. A value of 2 is normal.\
2057 otherwise odd values gives one value per line, even two.  Values 1,2 give normal format, 3,4\
2058 gives greater precision, while 5,6 give IEEE values.  When used for exporting a basis 1 does not save \
2059values, 2 saves values, 3 with greater accuracy and 4 in IEEE."
2060     );
2061#ifdef COIN_HAS_CBC
2062  parameters[numberParameters++]=
2063    CbcOrClpParam("passC!uts","Number of cut passes at root node",
2064                  -9999999,9999999,CUTPASS);
2065  parameters[numberParameters-1].setLonghelp
2066    (
2067     "The default is 100 passes if less than 500 columns, 100 passes (but \
2068stop if drop small if less than 5000 columns, 20 otherwise"
2069     ); 
2070  parameters[numberParameters++]=
2071    CbcOrClpParam("passF!easibilityPump","How many passes in feasibility pump",
2072                  0,10000,FPUMPITS);
2073  parameters[numberParameters-1].setLonghelp
2074    (
2075     "This fine tunes Feasibility Pump by doing more or fewer passes."
2076     ); 
2077  parameters[numberParameters-1].setIntValue(20);
2078#endif
2079#ifdef COIN_HAS_CLP
2080  parameters[numberParameters++]=
2081    CbcOrClpParam("passP!resolve","How many passes in presolve",
2082                  -200,100,PRESOLVEPASS,false);
2083  parameters[numberParameters-1].setLonghelp
2084    (
2085     "Normally Presolve does 5 passes but you may want to do less to make it\
2086 more lightweight or do more if improvements are still being made.  As Presolve will return\
2087 if nothing is being taken out, you should not normally need to use this fine tuning."
2088     );
2089#endif
2090#ifdef COIN_HAS_CBC
2091  parameters[numberParameters++]=
2092    CbcOrClpParam("passT!reeCuts","Number of cut passes in tree",
2093                  -999999,999999,CUTPASSINTREE);
2094  parameters[numberParameters-1].setLonghelp
2095    (
2096     "The default is one pass"
2097     ); 
2098#endif
2099#ifdef COIN_HAS_CLP
2100  parameters[numberParameters++]=
2101    CbcOrClpParam("pertV!alue","Method of perturbation",
2102                  -5000,102,PERTVALUE,false);
2103  parameters[numberParameters++]=
2104    CbcOrClpParam("perturb!ation","Whether to perturb problem",
2105                  "on",PERTURBATION);
2106  parameters[numberParameters-1].append("off");
2107  parameters[numberParameters-1].setLonghelp
2108    (
2109     "Perturbation helps to stop cycling, but Clp uses other measures for this.\
2110  However large problems and especially ones with unit elements and unit rhs or costs\
2111 benefit from perturbation.  Normally Clp tries to be intelligent, but you can switch this off.\
2112  The Clp library has this off by default.  This program has it on by default."
2113     ); 
2114  parameters[numberParameters++]=
2115    CbcOrClpParam("PFI","Whether to use Product Form of Inverse in simplex",
2116                  "off",PFI,7,false);
2117  parameters[numberParameters-1].append("on");
2118  parameters[numberParameters-1].setLonghelp
2119    (
2120     "By default clp uses Forrest-Tomlin L-U update.  If you are masochistic you can switch it off."
2121     ); 
2122  parameters[numberParameters++]=
2123    CbcOrClpParam("plus!Minus","Tries to make +- 1 matrix",
2124                  PLUSMINUS,7,false);
2125  parameters[numberParameters-1].setLonghelp
2126    (
2127     "Clp will go slightly faster if the matrix can be converted so that the elements are\
2128 not stored and are known to be unit.  The main advantage is memory use.  Clp may automatically\
2129 see if it can convert the problem so you should not need to use this."
2130     ); 
2131  parameters[numberParameters++]=
2132    CbcOrClpParam("pO!ptions","Dubious print options",
2133                  0,COIN_INT_MAX,PRINTOPTIONS,false);
2134  parameters[numberParameters-1].setIntValue(0);
2135  parameters[numberParameters-1].setLonghelp
2136    (
2137     "If this is > 0 then presolve will give more information and branch and cut will give statistics"
2138     ); 
2139  parameters[numberParameters++]=
2140    CbcOrClpParam("preO!pt","Presolve options",
2141                  0,COIN_INT_MAX,PRESOLVEOPTIONS,false);
2142#endif
2143  parameters[numberParameters++]=
2144    CbcOrClpParam("presolve","Whether to presolve problem",
2145                  "on",PRESOLVE);
2146  parameters[numberParameters-1].append("off");
2147  parameters[numberParameters-1].append("more");
2148  parameters[numberParameters-1].append("file");
2149  parameters[numberParameters-1].setLonghelp
2150    (
2151     "Presolve analyzes the model to find such things as redundant equations, equations\
2152 which fix some variables, equations which can be transformed into bounds etc etc.  For the\
2153 initial solve of any problem this is worth doing unless you know that it will have no effect.  \
2154on will normally do 5 passes while using 'more' will do 10.  If the problem is very large you may need \
2155to write the original to file using 'file'."
2156     ); 
2157#ifdef COIN_HAS_CBC
2158  parameters[numberParameters++]=
2159    CbcOrClpParam("preprocess","Whether to use integer preprocessing",
2160                  "off",PREPROCESS);
2161  parameters[numberParameters-1].append("on");
2162  parameters[numberParameters-1].append("save");
2163  parameters[numberParameters-1].append("equal");
2164  parameters[numberParameters-1].append("sos");
2165  parameters[numberParameters-1].append("trysos");
2166  parameters[numberParameters-1].append("equalall");
2167  parameters[numberParameters-1].append("strategy");
2168  parameters[numberParameters-1].append("aggregate");
2169  parameters[numberParameters-1].setLonghelp
2170    (
2171     "This tries to reduce size of model in a similar way to presolve and \
2172it also tries to strengthen the model - this can be very useful and is worth trying. \
2173 Save option saves on file presolved.mps.  equal will turn <= cliques into \
2174==.  sos will create sos sets if all 0-1 in sets (well one extra is allowed) \
2175and no overlaps.  trysos is same but allows any number extra.  equalall will turn all \
2176valid inequalities into equalities with integer slacks.  strategy is as \
2177on but uses CbcStrategy."
2178     ); 
2179#endif
2180#ifdef COIN_HAS_CLP
2181  parameters[numberParameters++]=
2182    CbcOrClpParam("preT!olerance","Tolerance to use in presolve",
2183                  1.0e-20,1.0e12,PRESOLVETOLERANCE);
2184  parameters[numberParameters-1].setLonghelp
2185    (
2186     "The default is 1.0e-8 - you may wish to try 1.0e-7 if presolve says the problem is \
2187infeasible and you have awkward numbers and you are sure the problem is really feasible."
2188     ); 
2189  parameters[numberParameters++]=
2190    CbcOrClpParam("primalP!ivot","Primal pivot choice algorithm",
2191                  "auto!matic",PRIMALPIVOT);
2192  parameters[numberParameters-1].append("exa!ct");
2193  parameters[numberParameters-1].append("dant!zig");
2194  parameters[numberParameters-1].append("part!ial");
2195  parameters[numberParameters-1].append("steep!est");
2196  parameters[numberParameters-1].append("change");
2197  parameters[numberParameters-1].append("sprint");
2198  parameters[numberParameters-1].setLonghelp
2199    (
2200     "Clp can use any pivot selection algorithm which the user codes as long as it\
2201 implements the features in the abstract pivot base class.  The Dantzig method is implemented\
2202 to show a simple method but its use is deprecated.  Exact devex is the method of choice and there\
2203 are two variants which keep all weights updated but only scan a subset each iteration.\
2204 Partial switches this on while change initially does dantzig until the factorization\
2205 becomes denser.  This is still a work in progress."
2206     ); 
2207  parameters[numberParameters++]=
2208    CbcOrClpParam("primalS!implex","Do primal simplex algorithm",
2209                  PRIMALSIMPLEX);
2210  parameters[numberParameters-1].setLonghelp
2211    (
2212     "This command solves the current model using the primal algorithm.\
2213  The default is to use exact devex.\
2214 The time and iterations may be affected by settings such as presolve, scaling, crash\
2215 and also by column selection  method, infeasibility weight and dual and primal tolerances."
2216     );
2217#endif
2218  parameters[numberParameters++]=
2219    CbcOrClpParam("primalT!olerance","For an optimal solution \
2220no primal infeasibility may exceed this value",
2221                  1.0e-20,1.0e12,PRIMALTOLERANCE);
2222  parameters[numberParameters-1].setLonghelp
2223    (
2224     "Normally the default tolerance is fine, but you may want to increase it a\
2225 bit if a primal run seems to be having a hard time"
2226     ); 
2227#ifdef COIN_HAS_CLP
2228  parameters[numberParameters++]=
2229    CbcOrClpParam("primalW!eight","Initially algorithm acts as if it \
2230costs this much to be infeasible",
2231                  1.0e-20,1.0e20,PRIMALWEIGHT);
2232  parameters[numberParameters-1].setLonghelp
2233    (
2234     "The primal algorithm in Clp is a single phase algorithm as opposed to a two phase\
2235 algorithm where you first get feasible then optimal.  So Clp is minimizing this weight times\
2236 the sum of primal infeasibilities plus the true objective function (in minimization sense).\
2237  Too high a value may mean more iterations, while too low a bound means\
2238 the code may go all the way and then have to increase the weight in order to get feasible.\
2239  OSL had a heuristic to\
2240 adjust bounds, maybe we need that here."
2241     ); 
2242#endif
2243  parameters[numberParameters++]=
2244    CbcOrClpParam("printi!ngOptions","Print options",
2245                  "normal",INTPRINT,3);
2246  parameters[numberParameters-1].append("integer");
2247  parameters[numberParameters-1].append("special");
2248  parameters[numberParameters-1].append("rows");
2249  parameters[numberParameters-1].append("all");
2250  parameters[numberParameters-1].setLonghelp
2251    (
2252     "This changes the amount and format of printing a solution:\nnormal - nonzero column variables \n\
2253integer - nonzero integer column variables\n\
2254special - in format suitable for OsiRowCutDebugger\n\
2255rows - nonzero column variables and row activities\n\
2256all - all column variables and row activities.\n\
2257\nFor non-integer problems 'integer' and 'special' act like 'normal'.  \
2258Also see printMask for controlling output."
2259     ); 
2260  parameters[numberParameters++]=
2261    CbcOrClpParam("printM!ask","Control printing of solution on a  mask",
2262                  PRINTMASK,3);
2263  parameters[numberParameters-1].setLonghelp
2264    (
2265     "If set then only those names which match mask are printed in a solution. \
2266'?' matches any character and '*' matches any set of characters. \
2267 The default is '' i.e. unset so all variables are printed. \
2268This is only active if model has names."
2269     ); 
2270#ifdef COIN_HAS_CBC
2271  parameters[numberParameters++]=
2272    CbcOrClpParam("prio!rityIn","Import priorities etc from file",
2273                  PRIORITYIN,3);
2274  parameters[numberParameters-1].setLonghelp
2275    (
2276     "This will read a file with priorities from the given file name.  It will use the default\
2277 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
2278 is initialized to '', i.e. it must be set.  This can not read from compressed files. \
2279File is in csv format with allowed headings - name, number, priority, direction, up, down, solution.  Exactly one of\
2280 name and number must be given."
2281     ); 
2282  parameters[numberParameters++]=
2283    CbcOrClpParam("probing!Cuts","Whether to use Probing cuts",
2284                  "off",PROBINGCUTS);
2285  parameters[numberParameters-1].append("on");
2286  parameters[numberParameters-1].append("root");
2287  parameters[numberParameters-1].append("ifmove");
2288  parameters[numberParameters-1].append("forceOn");
2289  parameters[numberParameters-1].append("forceOnBut");
2290  parameters[numberParameters-1].append("forceOnStrong");
2291  parameters[numberParameters-1].append("forceOnButStrong");
2292  parameters[numberParameters-1].append("strongRoot");
2293  parameters[numberParameters-1].setLonghelp
2294    (
2295     "This switches on probing cuts (either at root or in entire tree) \
2296See branchAndCut for information on options. \
2297but strong options do more probing"
2298     ); 
2299  parameters[numberParameters++]=
2300    CbcOrClpParam("pumpT!une","Dubious ideas for feasibility pump",
2301                  0,100000000,FPUMPTUNE);
2302  parameters[numberParameters-1].setLonghelp
2303    (
2304     "This fine tunes Feasibility Pump \n\
2305\t>=1000000 use as accumulate switch\n\
2306\t>=1000 use index+1 as number of large loops\n\
2307\t>=100 use 0.05 objvalue as increment\n\
2308\t>=10 use +0.1 objvalue for cutoff (add)\n\
2309\t1 == fix ints at bounds, 2 fix all integral ints, 3 and continuous at bounds"
2310     ); 
2311  parameters[numberParameters-1].setIntValue(0);
2312#endif
2313  parameters[numberParameters++]=
2314    CbcOrClpParam("quit","Stops clp execution",
2315                  EXIT);
2316  parameters[numberParameters-1].setLonghelp
2317    (
2318     "This stops the execution of Clp, end, exit, quit and stop are synonyms"
2319     ); 
2320#ifdef COIN_HAS_CBC
2321  parameters[numberParameters++]=
2322    CbcOrClpParam("ratio!Gap","Stop when gap between best possible and \
2323best less than this fraction of larger of two",
2324                  0.0,1.0e20,GAPRATIO);
2325  parameters[numberParameters-1].setDoubleValue(0.0);
2326  parameters[numberParameters-1].setLonghelp
2327    (
2328     "If the gap between best solution and best possible solution is less than this fraction \
2329of the objective value at the root node then the search will terminate.  See 'allowableGap' for a \
2330way of using absolute value rather than fraction."
2331     ); 
2332#endif
2333#ifdef COIN_HAS_CLP
2334  parameters[numberParameters++]=
2335    CbcOrClpParam("reallyO!bjectiveScale","Scale factor to apply to objective in place",
2336                  -1.0e20,1.0e20,OBJSCALE2,false);
2337  parameters[numberParameters-1].setLonghelp
2338    (
2339     "You can set this to -1.0 to test maximization or other to stress code"
2340     ); 
2341  parameters[numberParameters-1].setDoubleValue(1.0);
2342  parameters[numberParameters++]=
2343    CbcOrClpParam("reallyS!cale","Scales model in place",
2344                  REALLY_SCALE,7,false);
2345#endif
2346#ifdef COIN_HAS_CBC
2347    parameters[numberParameters++]=
2348      CbcOrClpParam("reduce!AndSplitCuts","Whether to use Reduce-and-Split cuts",
2349              "off",REDSPLITCUTS);
2350    parameters[numberParameters-1].append("on");
2351    parameters[numberParameters-1].append("root");
2352    parameters[numberParameters-1].append("ifmove");
2353    parameters[numberParameters-1].append("forceOn");
2354    parameters[numberParameters-1].setLonghelp
2355    (
2356     "This switches on reduce and split  cuts (either at root or in entire tree) \
2357See branchAndCut for information on options."
2358     ); 
2359  parameters[numberParameters++]=
2360    CbcOrClpParam("residual!CapacityCuts","Whether to use Residual Capacity cuts",
2361                  "off",RESIDCUTS);
2362  parameters[numberParameters-1].append("on");
2363  parameters[numberParameters-1].append("root");
2364  parameters[numberParameters-1].append("ifmove");
2365  parameters[numberParameters-1].append("forceOn");
2366  parameters[numberParameters-1].setLonghelp
2367    (
2368     "Residual capacity cuts. \
2369See branchAndCut for information on options."
2370     ); 
2371#endif
2372#ifdef COIN_HAS_CLP
2373  parameters[numberParameters++]=
2374    CbcOrClpParam("restore!Model","Restore model from binary file",
2375                  RESTORE);
2376  parameters[numberParameters-1].setLonghelp
2377    (
2378     "This reads data save by saveModel from the given file.  It will use the default\
2379 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
2380 is initialized to 'default.prob'."
2381     ); 
2382  parameters[numberParameters++]=
2383    CbcOrClpParam("reverse","Reverses sign of objective",
2384                  REVERSE,7,false);
2385  parameters[numberParameters-1].setLonghelp
2386    (
2387     "Useful for testing if maximization works correctly"
2388     ); 
2389  parameters[numberParameters++]=
2390    CbcOrClpParam("rhs!Scale","Scale factor to apply to rhs and bounds",
2391                  -1.0e20,1.0e20,RHSSCALE,false);
2392  parameters[numberParameters-1].setLonghelp
2393    (
2394     "If the rhs or bounds have some very large meaningful values, you may wish to scale them\
2395 internally by this amount.  It can also be set by autoscale"
2396     ); 
2397  parameters[numberParameters-1].setDoubleValue(1.0);
2398#endif
2399#ifdef COIN_HAS_CBC
2400  parameters[numberParameters++]=
2401      CbcOrClpParam("Rens","Whether to try Relaxation Enforced Neighborhood Search",
2402                    "off",RENS);
2403    parameters[numberParameters-1].append("on");
2404    parameters[numberParameters-1].append("200");
2405    parameters[numberParameters-1].append("1000");
2406  parameters[numberParameters-1].setLonghelp
2407    (
2408     "This switches on Relaxation enforced neighborhood Search. \
2409on just does feasibility pump \
2410200 or 1000 does that many nodes."
2411     ); 
2412  parameters[numberParameters++]=
2413      CbcOrClpParam("Rins","Whether to try Relaxed Induced Neighborhood Search",
2414                    "off",RINS);
2415    parameters[numberParameters-1].append("on");
2416    parameters[numberParameters-1].append("often");
2417  parameters[numberParameters-1].setLonghelp
2418    (
2419     "This switches on Relaxed induced neighborhood Search."
2420     ); 
2421  parameters[numberParameters++]=
2422    CbcOrClpParam("round!ingHeuristic","Whether to use Rounding heuristic",
2423                  "off",ROUNDING);
2424  parameters[numberParameters-1].append("on");
2425  parameters[numberParameters-1].append("do");
2426  parameters[numberParameters-1].setLonghelp
2427    (
2428     "This switches on a simple (but effective) rounding heuristic at each node of tree.  \
2429The Do option switches on before preprocessing."
2430     ); 
2431#endif
2432  parameters[numberParameters++]=
2433    CbcOrClpParam("saveM!odel","Save model to binary file",
2434                  SAVE);
2435  parameters[numberParameters-1].setLonghelp
2436    (
2437     "This will save the problem to the given file name for future use\
2438 by restoreModel.  It will use the default\
2439 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
2440 is initialized to 'default.prob'."
2441     ); 
2442  parameters[numberParameters++]=
2443    CbcOrClpParam("saveS!olution","saves solution to file",
2444                  SAVESOL);
2445  parameters[numberParameters-1].setLonghelp
2446    (
2447     "This will write a binary solution file to the given file name.  It will use the default\
2448 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
2449 is initialized to 'solution.file'.  To read the file use fread(int) twice to pick up number of rows \
2450and columns, then fread(double) to pick up objective value, then pick up row activities, row duals, column \
2451activities and reduced costs - see bottom of CbcOrClpParam.cpp for code that reads or writes file. \
2452If name contains '_fix_read_' then does not write but reads and will fix all variables"
2453     ); 
2454  parameters[numberParameters++]=
2455    CbcOrClpParam("scal!ing","Whether to scale problem",
2456                  "off",SCALING);
2457  parameters[numberParameters-1].append("equi!librium");
2458  parameters[numberParameters-1].append("geo!metric");
2459  parameters[numberParameters-1].append("auto!matic");
2460  parameters[numberParameters-1].setLonghelp
2461    (
2462     "Scaling can help in solving problems which might otherwise fail because of lack of\
2463 accuracy.  It can also reduce the number of iterations.  It is not applied if the range\
2464 of elements is small.  When unscaled it is possible that there may be small primal and/or\
2465 infeasibilities."
2466     ); 
2467  parameters[numberParameters-1].setCurrentOption(3); // say auto
2468#ifndef COIN_HAS_CBC
2469  parameters[numberParameters++]=
2470    CbcOrClpParam("sec!onds","Maximum seconds",
2471                  -1.0,1.0e12,TIMELIMIT);
2472  parameters[numberParameters-1].setLonghelp
2473    (
2474     "After this many seconds clp will act as if maximum iterations had been reached \
2475(if value >=0).  \
2476In this program it is really only useful for testing but the library function\n\
2477      \tsetMaximumSeconds(value)\n can be useful."
2478     );
2479#else
2480  parameters[numberParameters++]=
2481    CbcOrClpParam("sec!onds","maximum seconds",
2482                  -1.0,1.0e12,TIMELIMIT_BAB);
2483  parameters[numberParameters-1].setLonghelp
2484    (
2485     "After this many seconds coin solver will act as if maximum nodes had been reached."
2486     );
2487#endif
2488  parameters[numberParameters++]=
2489    CbcOrClpParam("sleep","for debug",
2490                  DUMMY,7,false);
2491  parameters[numberParameters-1].setLonghelp
2492    (
2493     "If passed to solver fom ampl, then ampl will wait so that you can copy .nl file for debug."
2494     ); 
2495#ifdef COIN_HAS_CLP
2496  parameters[numberParameters++]=
2497    CbcOrClpParam("slp!Value","Number of slp passes before primal",
2498                  -1,50000,SLPVALUE,false);
2499  parameters[numberParameters-1].setLonghelp
2500    (
2501     "If you are solving a quadratic problem using primal then it may be helpful to do some \
2502sequential Lps to get a good approximate solution."
2503     ); 
2504#endif
2505  parameters[numberParameters++]=
2506    CbcOrClpParam("solu!tion","Prints solution to file",
2507                  SOLUTION);
2508  parameters[numberParameters-1].setLonghelp
2509    (
2510     "This will write a primitive solution file to the given file name.  It will use the default\
2511 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
2512 is initialized to 'stdout'.  The amount of output can be varied using printi!ngOptions or printMask."
2513     ); 
2514#ifdef COIN_HAS_CLP
2515#ifdef COIN_HAS_CBC
2516  parameters[numberParameters++]=
2517    CbcOrClpParam("solv!e","Solve problem",
2518                  BAB);
2519  parameters[numberParameters-1].setLonghelp
2520    (
2521     "If there are no integer variables then this just solves LP.  If there are integer variables \
2522this does branch and cut."
2523     ); 
2524  parameters[numberParameters++]=
2525    CbcOrClpParam("sos!Options","Whether to use SOS from AMPL",
2526                  "off",SOS);
2527  parameters[numberParameters-1].append("on");
2528  parameters[numberParameters-1].setCurrentOption("on");
2529  parameters[numberParameters-1].setLonghelp
2530    (
2531     "Normally if AMPL says there are SOS variables they should be used, but sometime sthey should\
2532 be turned off - this does so."
2533     ); 
2534  parameters[numberParameters++]=
2535    CbcOrClpParam("slog!Level","Level of detail in Solver output",
2536                  -1,63,SOLVERLOGLEVEL);
2537  parameters[numberParameters-1].setLonghelp
2538    (
2539     "If 0 then there should be no output in normal circumstances.  1 is probably the best\
2540 value for most uses, while 2 and 3 give more information."
2541     );
2542#else
2543  // allow solve as synonym for dual
2544  parameters[numberParameters++]=
2545    CbcOrClpParam("solv!e","Solve problem using dual simplex",
2546                  BAB);
2547  parameters[numberParameters-1].setLonghelp
2548    (
2549     "Just so can use solve for clp as well as in cbc"
2550     ); 
2551#endif
2552#endif
2553#ifdef COIN_HAS_CLP
2554  parameters[numberParameters++]=
2555    CbcOrClpParam("spars!eFactor","Whether factorization treated as sparse",
2556                  "on",SPARSEFACTOR,7,false);
2557  parameters[numberParameters-1].append("off");
2558  parameters[numberParameters++]=
2559    CbcOrClpParam("special!Options","Dubious options for Simplex - see ClpSimplex.hpp",
2560                  0,COIN_INT_MAX,SPECIALOPTIONS,false);
2561  parameters[numberParameters++]=
2562    CbcOrClpParam("sprint!Crash","Whether to try sprint crash",
2563                  -1,5000000,SPRINT);
2564  parameters[numberParameters-1].setLonghelp
2565    (
2566     "For long and thin problems this program may solve a series of small problems\
2567 created by taking a subset of the columns.  I introduced the idea as 'Sprint' after\
2568 an LP code of that name of the 60's which tried the same tactic (not totally successfully).\
2569  Cplex calls it 'sifting'.  -1 is automatic choice, 0 is off, n is number of passes"
2570     ); 
2571  parameters[numberParameters++]=
2572    CbcOrClpParam("stat!istics","Print some statistics",
2573                  STATISTICS);
2574  parameters[numberParameters-1].setLonghelp
2575    (
2576     "This command prints some statistics for the current model.\
2577 If log level >1 then more is printed.\
2578 These are for presolved model if presolve on (and unscaled)."
2579     );
2580#endif
2581  parameters[numberParameters++]=
2582    CbcOrClpParam("stop","Stops clp execution",
2583                  EXIT);
2584  parameters[numberParameters-1].setLonghelp
2585    (
2586     "This stops the execution of Clp, end, exit, quit and stop are synonyms"
2587     ); 
2588#ifdef COIN_HAS_CBC
2589  parameters[numberParameters++]=
2590    CbcOrClpParam("strengthen","Create strengthened problem",
2591                  STRENGTHEN,3);
2592  parameters[numberParameters-1].setLonghelp
2593    (
2594     "This creates a new problem by applying the root node cuts.  All tight constraints \
2595will be in resulting problem"
2596     ); 
2597  parameters[numberParameters++]=
2598    CbcOrClpParam("strong!Branching","Number of variables to look at in strong branching",
2599                  0,999999,STRONGBRANCHING);
2600  parameters[numberParameters-1].setLonghelp
2601    (
2602     "In order to decide which variable to branch on, the code will choose up to this number \
2603of unsatisfied variables to do mini up and down branches on.  Then the most effective one is chosen. \
2604If a variable is branched on many times then the previous average up and down costs may be used - \
2605see number before trust."
2606     ); 
2607#endif
2608#ifdef COIN_HAS_CLP
2609  parameters[numberParameters++]=
2610    CbcOrClpParam("subs!titution","How long a column to substitute for in presolve",
2611                  0,10000,SUBSTITUTION,false);
2612  parameters[numberParameters-1].setLonghelp
2613    (
2614     "Normally Presolve gets rid of 'free' variables when there are no more than 3 \
2615 variables in column.  If you increase this the number of rows may decrease but number of \
2616 elements may increase."
2617     ); 
2618#endif
2619#ifdef COIN_HAS_CBC
2620  parameters[numberParameters++]=
2621    CbcOrClpParam("testO!si","Test OsiObject stuff",
2622                  -1,COIN_INT_MAX,TESTOSI,false);
2623#endif
2624#ifdef CBC_THREAD
2625  parameters[numberParameters++]=
2626    CbcOrClpParam("thread!s","Number of threads to try and use",
2627                  -100,10000,THREADS,false);
2628  parameters[numberParameters-1].setLonghelp
2629    (
2630     "To use multiple threads, set threads to number wanted.  It may be better \
2631to use one or two more than number of cpus available.  If 100+n then n threads and \
2632threads used in sub-trees, if 200+n use threads for root cuts, 300+n - both."
2633     ); 
2634#endif
2635#ifdef COIN_HAS_CBC
2636  parameters[numberParameters++]=
2637    CbcOrClpParam("tighten!Factor","Tighten bounds using this times largest \
2638activity at continuous solution",
2639                  1.0e-3,1.0e20,TIGHTENFACTOR,false);
2640  parameters[numberParameters-1].setLonghelp
2641    (
2642     "This sleazy trick can help on some problems."
2643     ); 
2644#endif
2645#ifdef COIN_HAS_CLP
2646  parameters[numberParameters++]=
2647    CbcOrClpParam("tightLP","Poor person's preSolve for now",
2648                  TIGHTEN,7,false);
2649#endif
2650#ifdef COIN_HAS_CBC
2651  parameters[numberParameters++]=
2652    CbcOrClpParam("trust!PseudoCosts","Number of branches before we trust pseudocosts",
2653                  -3,2000000,NUMBERBEFORE);
2654  parameters[numberParameters-1].setLonghelp
2655    (
2656     "Using strong branching computes pseudo-costs.  After this many times for a variable we just \
2657trust the pseudo costs and do not do any more strong branching."
2658     ); 
2659#endif
2660#ifdef COIN_HAS_CBC
2661  parameters[numberParameters++]=
2662    CbcOrClpParam("tune!PreProcess","Dubious tuning parameters",
2663                  0,20000000,PROCESSTUNE,false);
2664  parameters[numberParameters-1].setLonghelp
2665    (
2666     "For making equality cliques this is minimumsize.  Also for adding \
2667integer slacks.  May be used for more later \
2668If <1000 that is what it does.  If <1000000 - numberPasses is (value/1000)-1 and tune is tune %1000. \
2669If >= 1000000! - numberPasses is (value/1000000)-1 and tune is tune %1000000.  In this case if tune is now still >=10000 \
2670numberPassesPerInnerLoop is changed from 10 to (tune-10000)-1 and tune becomes tune % 10000!!!!! - happy? - \
2671so to keep normal limit on cliques of 5, do 3 major passes (include presolves) but only doing one tightening pass per major pass - \
2672you would use 3010005 (I think)"
2673     ); 
2674  parameters[numberParameters++]=
2675    CbcOrClpParam("two!MirCuts","Whether to use Two phase Mixed Integer Rounding cuts",
2676                  "off",TWOMIRCUTS);
2677  parameters[numberParameters-1].append("on");
2678  parameters[numberParameters-1].append("root");
2679  parameters[numberParameters-1].append("ifmove");
2680  parameters[numberParameters-1].append("forceOn");
2681  parameters[numberParameters-1].setLonghelp
2682    (
2683     "This switches on two phase mixed integer rounding  cuts (either at root or in entire tree) \
2684See branchAndCut for information on options."
2685     ); 
2686#endif
2687  parameters[numberParameters++]=
2688    CbcOrClpParam("unitTest","Do unit test",
2689                  UNITTEST,3);
2690  parameters[numberParameters-1].setLonghelp
2691    (
2692     "This exercises the unit test for clp"
2693     ); 
2694  parameters[numberParameters++]=
2695    CbcOrClpParam("userClp","Hand coded Clp stuff",
2696                  USERCLP);
2697  parameters[numberParameters-1].setLonghelp
2698    (
2699     "There are times e.g. when using AMPL interface when you may wish to do something unusual.  \
2700Look for USERCLP in main driver and modify sample code."
2701     ); 
2702#ifdef COIN_HAS_CBC
2703  parameters[numberParameters++]=
2704    CbcOrClpParam("userCbc","Hand coded Cbc stuff",
2705                  USERCBC);
2706  parameters[numberParameters-1].setLonghelp
2707    (
2708     "There are times e.g. when using AMPL interface when you may wish to do something unusual.  \
2709Look for USERCBC in main driver and modify sample code."
2710     ); 
2711#endif
2712  parameters[numberParameters++]=
2713    CbcOrClpParam("vector","Whether to use vector? Form of matrix in simplex",
2714                  "off",VECTOR,7,false);
2715  parameters[numberParameters-1].append("on");
2716  parameters[numberParameters-1].setLonghelp
2717    (
2718     "If this is on and ClpPackedMatrix uses extra column copy in odd format."
2719     ); 
2720  parameters[numberParameters++]=
2721    CbcOrClpParam("verbose","Switches on longer help on single ?",
2722                  0,15,VERBOSE,false);
2723  parameters[numberParameters-1].setLonghelp
2724    (
2725     "Set to 1 to get short help with ? list, 2 to get long help, 3 for both.  (add 4 to just get ampl ones)."
2726     ); 
2727  parameters[numberParameters-1].setIntValue(0);
2728#ifdef COIN_HAS_CBC
2729  parameters[numberParameters++]=
2730    CbcOrClpParam("vub!heuristic","Type of vub heuristic",
2731                  -2,20,VUBTRY,false);
2732  parameters[numberParameters-1].setLonghelp
2733    (
2734     "If set will try and fix some integer variables"
2735     ); 
2736  parameters[numberParameters-1].setIntValue(-1);
2737#endif
2738  assert(numberParameters<CBCMAXPARAMETERS);
2739}
2740// Given a parameter type - returns its number in list
2741int whichParam (CbcOrClpParameterType name, 
2742                int numberParameters, CbcOrClpParam *const parameters)
2743{
2744  int i;
2745  for (i=0;i<numberParameters;i++) {
2746    if (parameters[i].type()==name)
2747      break;
2748  }
2749  assert (i<numberParameters);
2750  return i;
2751}
2752#ifdef COIN_HAS_CLP
2753/* Restore a solution from file.
2754   mode 0 normal, 1 swap rows and columns and primal and dual
2755   if 2 set then also change signs
2756*/
2757void restoreSolution(ClpSimplex * lpSolver,std::string fileName,int mode)
2758{
2759  FILE * fp=fopen(fileName.c_str(),"rb");
2760  if (fp) {
2761    int numberRows=lpSolver->numberRows();
2762    int numberColumns=lpSolver->numberColumns();
2763    int numberRowsFile;
2764    int numberColumnsFile;
2765    double objectiveValue;
2766    fread(&numberRowsFile,sizeof(int),1,fp);
2767    fread(&numberColumnsFile,sizeof(int),1,fp);
2768    fread(&objectiveValue,sizeof(double),1,fp);
2769    double * dualRowSolution = lpSolver->dualRowSolution();
2770    double * primalRowSolution = lpSolver->primalRowSolution();
2771    double * dualColumnSolution = lpSolver->dualColumnSolution();
2772    double * primalColumnSolution = lpSolver->primalColumnSolution();
2773    if (mode) {
2774      // swap
2775      int k=numberRows;
2776      numberRows=numberColumns;
2777      numberColumns=k;
2778      double * temp;
2779      temp = dualRowSolution;
2780      dualRowSolution = primalColumnSolution;
2781      primalColumnSolution=temp;
2782      temp = dualColumnSolution;
2783      dualColumnSolution = primalRowSolution;
2784      primalRowSolution=temp;
2785    }
2786    if (numberRows>numberRowsFile||numberColumns>numberColumnsFile) {
2787      std::cout<<"Mismatch on rows and/or columns - giving up"<<std::endl;
2788    } else {
2789      lpSolver->setObjectiveValue(objectiveValue);
2790      if (numberRows==numberRowsFile&&numberColumns==numberColumnsFile) {
2791        fread(primalRowSolution,sizeof(double),numberRows,fp);
2792        fread(dualRowSolution,sizeof(double),numberRows,fp);
2793        fread(primalColumnSolution,sizeof(double),numberColumns,fp);
2794        fread(dualColumnSolution,sizeof(double),numberColumns,fp);
2795      } else {
2796        std::cout<<"Mismatch on rows and/or columns - truncating"<<std::endl;
2797        double * temp = new double [CoinMax(numberRowsFile,numberColumnsFile)];
2798        fread(temp,sizeof(double),numberRowsFile,fp);
2799        memcpy(primalRowSolution,temp,numberRows*sizeof(double));
2800        fread(temp,sizeof(double),numberRowsFile,fp);
2801        memcpy(dualRowSolution,temp,numberRows*sizeof(double));
2802        fread(temp,sizeof(double),numberColumnsFile,fp);
2803        memcpy(primalColumnSolution,temp,numberColumns*sizeof(double));
2804        fread(temp,sizeof(double),numberColumnsFile,fp);
2805        memcpy(dualColumnSolution,temp,numberColumns*sizeof(double));
2806        delete [] temp;
2807      }
2808      if (mode==3) {
2809        int i;
2810        for (i=0;i<numberRows;i++) {
2811          primalRowSolution[i] = -primalRowSolution[i];
2812          dualRowSolution[i] = -dualRowSolution[i];
2813        }
2814        for (i=0;i<numberColumns;i++) {
2815          primalColumnSolution[i] = -primalColumnSolution[i];
2816          dualColumnSolution[i] = -dualColumnSolution[i];
2817        }
2818      }
2819    }
2820    fclose(fp);
2821  } else {
2822    std::cout<<"Unable to open file "<<fileName<<std::endl;
2823  }
2824}
2825// Dump a solution to file
2826void saveSolution(const ClpSimplex * lpSolver,std::string fileName)
2827{
2828  if (strstr(fileName.c_str(),"_fix_read_")) {
2829    FILE * fp=fopen(fileName.c_str(),"rb");
2830    if (fp) {
2831      ClpSimplex * solver = const_cast<ClpSimplex *>(lpSolver);
2832      restoreSolution(solver,fileName,0);
2833      // fix all
2834      int logLevel=solver->logLevel();
2835      int iColumn;
2836      int numberColumns=solver->numberColumns();
2837      double * primalColumnSolution = 
2838        solver->primalColumnSolution();
2839      double * columnLower = solver->columnLower();
2840      double * columnUpper = solver->columnUpper();
2841      for (iColumn=0;iColumn<numberColumns;iColumn++) {
2842        double value = primalColumnSolution[iColumn];
2843        if (value>columnUpper[iColumn]) {
2844          if (value >columnUpper[iColumn]+1.0e-6&&logLevel>1)
2845            printf("%d value of %g - bounds %g %g\n",
2846                   iColumn,value,columnLower[iColumn],columnUpper[iColumn]);
2847          value=columnUpper[iColumn];
2848        } else if (value<columnLower[iColumn]) {
2849          if (value <columnLower[iColumn]-1.0e-6&&logLevel>1)
2850            printf("%d value of %g - bounds %g %g\n",
2851                   iColumn,value,columnLower[iColumn],columnUpper[iColumn]);
2852          value=columnLower[iColumn];
2853        }
2854        columnLower[iColumn]=value;
2855        columnUpper[iColumn]=value;
2856      }
2857      return;
2858    }
2859  }
2860  FILE * fp=fopen(fileName.c_str(),"wb");
2861  if (fp) {
2862    int numberRows=lpSolver->numberRows();
2863    int numberColumns=lpSolver->numberColumns();
2864    double objectiveValue = lpSolver->objectiveValue();
2865    fwrite(&numberRows,sizeof(int),1,fp);
2866    fwrite(&numberColumns,sizeof(int),1,fp);
2867    fwrite(&objectiveValue,sizeof(double),1,fp);
2868    double * dualRowSolution = lpSolver->dualRowSolution();
2869    double * primalRowSolution = lpSolver->primalRowSolution();
2870    fwrite(primalRowSolution,sizeof(double),numberRows,fp);
2871    fwrite(dualRowSolution,sizeof(double),numberRows,fp);
2872    double * dualColumnSolution = lpSolver->dualColumnSolution();
2873    double * primalColumnSolution = lpSolver->primalColumnSolution();
2874    fwrite(primalColumnSolution,sizeof(double),numberColumns,fp);
2875    fwrite(dualColumnSolution,sizeof(double),numberColumns,fp);
2876    fclose(fp);
2877  } else {
2878    std::cout<<"Unable to open file "<<fileName<<std::endl;
2879  }
2880}
2881#endif
Note: See TracBrowser for help on using the repository browser.