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

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

add keyword for naive heuristic

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