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

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

change dense

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