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

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

try and improve stability

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