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

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

for diving heuristics

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