source: stable/1.6/Clp/src/CbcOrClpParam.cpp @ 1144

Last change on this file since 1144 was 1144, checked in by forrest, 12 years ago

change meaning of useSolution

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