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

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

allow csv format

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 106.3 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 1 then tries to branch to solution given by AMPL or priorities file. \
1786If 0 then just tries to set as best solution \
1787If >0 then also does that many nodes on fixed problem."
1788     ); 
1789#endif
1790  parameters[numberParameters++]=
1791    CbcOrClpParam("gamma!(Delta)","Whether to regularize barrier",
1792                  "off",GAMMA,7,false);
1793  parameters[numberParameters-1].append("on");
1794  parameters[numberParameters-1].append("gamma");
1795  parameters[numberParameters-1].append("delta");
1796  parameters[numberParameters-1].append("onstrong");
1797  parameters[numberParameters-1].append("gammastrong");
1798  parameters[numberParameters-1].append("deltastrong");
1799#endif
1800#ifdef COIN_HAS_CBC
1801  parameters[numberParameters++]=
1802    CbcOrClpParam("gomory!Cuts","Whether to use Gomory cuts",
1803                  "off",GOMORYCUTS);
1804  parameters[numberParameters-1].append("on");
1805  parameters[numberParameters-1].append("root");
1806  parameters[numberParameters-1].append("ifmove");
1807  parameters[numberParameters-1].append("forceOn");
1808  parameters[numberParameters-1].append("forceLongOn");
1809  parameters[numberParameters-1].setLonghelp
1810    (
1811     "The original cuts - beware of imitations!  Having gone out of favor, they are now more \
1812fashionable as LP solvers are more robust and they interact well with other cuts.  They will almost always \
1813give cuts (although in this executable they are limited as to number of variables in cut).  \
1814However the cuts may be dense so it is worth experimenting (Long allows any length). \
1815See branchAndCut for information on options."
1816     ); 
1817  parameters[numberParameters++]=
1818    CbcOrClpParam("greedy!Heuristic","Whether to use a greedy heuristic",
1819                  "off",GREEDY);
1820  parameters[numberParameters-1].append("on");
1821  parameters[numberParameters-1].append("do");
1822  //parameters[numberParameters-1].append("root");
1823  parameters[numberParameters-1].setLonghelp
1824    (
1825     "Switches on a greedy heuristic which will try and obtain a solution.  It may just fix a \
1826percentage of variables and then try a small branch and cut run. \
1827The Do option switches on before preprocessing."
1828     ); 
1829  parameters[numberParameters++]=
1830    CbcOrClpParam("heur!isticsOnOff","Switches most heuristics on or off",
1831                  "off",HEURISTICSTRATEGY);
1832  parameters[numberParameters-1].append("on");
1833  parameters[numberParameters-1].setLonghelp
1834    (
1835     "This can be used to switch on or off all heuristics.  Then you can do \
1836individual ones off or on.  CbcTreeLocal is not included as it dramatically \
1837alters search."
1838     ); 
1839#endif
1840  parameters[numberParameters++]=
1841    CbcOrClpParam("help","Print out version, non-standard options and some help",
1842                  HELP,3);
1843  parameters[numberParameters-1].setLonghelp
1844    (
1845     "This prints out some help to get user started.  If you have printed this then \
1846you should be past that stage:-)"
1847     ); 
1848#ifdef COIN_HAS_CBC
1849  parameters[numberParameters++]=
1850    CbcOrClpParam("hot!StartMaxIts","Maximum iterations on hot start",
1851                  0,COIN_INT_MAX,MAXHOTITS,false);
1852#endif
1853#ifdef COIN_HAS_CLP
1854  parameters[numberParameters++]=
1855    CbcOrClpParam("idiot!Crash","Whether to try idiot crash",
1856                  -1,999999,IDIOT);
1857  parameters[numberParameters-1].setLonghelp
1858    (
1859     "This is a type of 'crash' which works well on some homogeneous problems.\
1860 It works best on problems with unit elements and rhs but will do something to any model.  It should only be\
1861 used before primal.  It can be set to -1 when the code decides for itself whether to use it,\
1862 0 to switch off or n > 0 to do n passes."
1863     ); 
1864#endif
1865  parameters[numberParameters++]=
1866    CbcOrClpParam("import","Import model from mps file",
1867                  IMPORT,3);
1868  parameters[numberParameters-1].setLonghelp
1869    (
1870     "This will read an MPS format file from the given file name.  It will use the default\
1871 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
1872 is initialized to '', i.e. it must be set.  If you have libgz then it can read compressed\
1873 files 'xxxxxxxx.gz'.."
1874     );
1875#ifdef COIN_HAS_CBC
1876  parameters[numberParameters++]=
1877    CbcOrClpParam("inc!rement","A valid solution must be at least this \
1878much better than last integer solution",
1879                  -1.0e20,1.0e20,INCREMENT);
1880  parameters[numberParameters-1].setLonghelp
1881    (
1882     "Whenever a solution is found the bound on solutions is set to solution (in a minimization\
1883sense) plus this.  If it is not set then the code will try and work one out e.g. if \
1884all objective coefficients are multiples of 0.01 and only integer variables have entries in \
1885objective then this can be set to 0.01.  Be careful if you set this negative!"
1886     ); 
1887  parameters[numberParameters++]=
1888    CbcOrClpParam("inf!easibilityWeight","Each integer infeasibility is expected \
1889to cost this much",
1890                  0.0,1.0e20,INFEASIBILITYWEIGHT);
1891  parameters[numberParameters-1].setLonghelp
1892    (
1893     "A primitive way of deciding which node to explore next.  Satisfying each integer infeasibility is \
1894expected to cost this much."
1895     ); 
1896  parameters[numberParameters++]=
1897    CbcOrClpParam("initialS!olve","Solve to continuous",
1898                  SOLVECONTINUOUS);
1899  parameters[numberParameters-1].setLonghelp
1900    (
1901     "This just solves the problem to continuous - without adding any cuts"
1902     ); 
1903  parameters[numberParameters++]=
1904    CbcOrClpParam("integerT!olerance","For an optimal solution \
1905no integer variable may be this away from an integer value",
1906              1.0e-20,0.5,INTEGERTOLERANCE);
1907  parameters[numberParameters-1].setLonghelp
1908    (
1909     "Beware of setting this smaller than the primal tolerance."
1910     ); 
1911#endif
1912#ifdef COIN_HAS_CLP
1913  parameters[numberParameters++]=
1914    CbcOrClpParam("keepN!ames","Whether to keep names from import",
1915                  "on",KEEPNAMES);
1916  parameters[numberParameters-1].append("off");
1917  parameters[numberParameters-1].setLonghelp
1918    (
1919     "It saves space to get rid of names so if you need to you can set this to off.  \
1920This needs to be set before the import of model - so -keepnames off -import xxxxx.mps."
1921     ); 
1922  parameters[numberParameters++]=
1923    CbcOrClpParam("KKT","Whether to use KKT factorization",
1924                  "off",KKT,7,false);
1925  parameters[numberParameters-1].append("on");
1926#endif
1927#ifdef COIN_HAS_CBC
1928  parameters[numberParameters++]=
1929    CbcOrClpParam("knapsack!Cuts","Whether to use Knapsack cuts",
1930                  "off",KNAPSACKCUTS);
1931  parameters[numberParameters-1].append("on");
1932  parameters[numberParameters-1].append("root");
1933  parameters[numberParameters-1].append("ifmove");
1934  parameters[numberParameters-1].append("forceOn");
1935  parameters[numberParameters-1].setLonghelp
1936    (
1937     "This switches on knapsack cuts (either at root or in entire tree) \
1938See branchAndCut for information on options."
1939     ); 
1940  parameters[numberParameters++]=
1941    CbcOrClpParam("lift!AndProjectCuts","Whether to use Lift and Project cuts",
1942                  "off",LANDPCUTS);
1943  parameters[numberParameters-1].append("on");
1944  parameters[numberParameters-1].append("root");
1945  parameters[numberParameters-1].append("ifmove");
1946  parameters[numberParameters-1].append("forceOn");
1947  parameters[numberParameters-1].setLonghelp
1948    (
1949     "Lift and project cuts - may be expensive to compute. \
1950See branchAndCut for information on options."
1951     ); 
1952  parameters[numberParameters++]=
1953    CbcOrClpParam("local!TreeSearch","Whether to use local treesearch",
1954                  "off",LOCALTREE);
1955  parameters[numberParameters-1].append("on");
1956  parameters[numberParameters-1].setLonghelp
1957    (
1958     "This switches on a local search algorithm when a solution is found.  This is from \
1959Fischetti and Lodi and is not really a heuristic although it can be used as one. \
1960When used from Coin solve it has limited functionality.  It is not switched on when \
1961heuristics are switched on."
1962     ); 
1963#endif
1964#ifndef COIN_HAS_CBC
1965  parameters[numberParameters++]=
1966    CbcOrClpParam("log!Level","Level of detail in Solver output",
1967                  -1,63,SOLVERLOGLEVEL);
1968#else
1969  parameters[numberParameters++]=
1970    CbcOrClpParam("log!Level","Level of detail in Coin branch and Cut output",
1971                  -63,63,LOGLEVEL);
1972  parameters[numberParameters-1].setIntValue(1);
1973#endif
1974  parameters[numberParameters-1].setLonghelp
1975    (
1976     "If 0 then there should be no output in normal circumstances.  1 is probably the best\
1977 value for most uses, while 2 and 3 give more information."
1978     ); 
1979  parameters[numberParameters++]=
1980    CbcOrClpParam("max!imize","Set optimization direction to maximize",
1981                  MAXIMIZE,7);
1982  parameters[numberParameters-1].setLonghelp
1983    (
1984     "The default is minimize - use 'maximize' for maximization.\n\
1985You can also use the parameters 'direction maximize'."
1986     ); 
1987#ifdef COIN_HAS_CLP
1988  parameters[numberParameters++]=
1989    CbcOrClpParam("maxF!actor","Maximum number of iterations between \
1990refactorizations",
1991                  1,999999,MAXFACTOR);
1992  parameters[numberParameters-1].setLonghelp
1993    (
1994     "If this is at its initial value of 200 then in this executable clp will guess at a\
1995 value to use.  Otherwise the user can set a value.  The code may decide to re-factorize\
1996 earlier for accuracy."
1997     ); 
1998  parameters[numberParameters++]=
1999    CbcOrClpParam("maxIt!erations","Maximum number of iterations before \
2000stopping",
2001                  0,2147483647,MAXITERATION);
2002  parameters[numberParameters-1].setLonghelp
2003    (
2004     "This can be used for testing purposes.  The corresponding library call\n\
2005      \tsetMaximumIterations(value)\n can be useful.  If the code stops on\
2006 seconds or by an interrupt this will be treated as stopping on maximum iterations"
2007     ); 
2008#endif
2009#ifdef COIN_HAS_CBC
2010  parameters[numberParameters++]=
2011    CbcOrClpParam("maxN!odes","Maximum number of nodes to do",
2012                  -1,2147483647,MAXNODES);
2013  parameters[numberParameters-1].setLonghelp
2014    (
2015     "This is a repeatable way to limit search.  Normally using time is easier \
2016but then the results may not be repeatable."
2017     ); 
2018  parameters[numberParameters++]=
2019    CbcOrClpParam("maxS!olutions","Maximum number of solutions to get",
2020                  1,2147483647,MAXSOLS);
2021  parameters[numberParameters-1].setLonghelp
2022    (
2023     "You may want to stop after (say) two solutions or an hour."
2024     ); 
2025#endif
2026  parameters[numberParameters++]=
2027    CbcOrClpParam("min!imize","Set optimization direction to minimize",
2028                  MINIMIZE,7);
2029  parameters[numberParameters-1].setLonghelp
2030    (
2031     "The default is minimize - use 'maximize' for maximization.\n\
2032This should only be necessary if you have previously set maximization \
2033You can also use the parameters 'direction minimize'."
2034     );
2035#ifdef COIN_HAS_CBC
2036  parameters[numberParameters++]=
2037    CbcOrClpParam("mipO!ptions","Dubious options for mip",
2038                  0,COIN_INT_MAX,MIPOPTIONS,false);
2039  parameters[numberParameters++]=
2040    CbcOrClpParam("more!MipOptions","More dubious options for mip",
2041                  -1,COIN_INT_MAX,MOREMIPOPTIONS,false);
2042  parameters[numberParameters++]=
2043    CbcOrClpParam("mixed!IntegerRoundingCuts","Whether to use Mixed Integer Rounding cuts",
2044                  "off",MIXEDCUTS);
2045  parameters[numberParameters-1].append("on");
2046  parameters[numberParameters-1].append("root");
2047  parameters[numberParameters-1].append("ifmove");
2048  parameters[numberParameters-1].append("forceOn");
2049  parameters[numberParameters-1].setLonghelp
2050    (
2051     "This switches on mixed integer rounding cuts (either at root or in entire tree) \
2052See branchAndCut for information on options."
2053     ); 
2054#endif
2055  parameters[numberParameters++]=
2056    CbcOrClpParam("mess!ages","Controls if Clpnnnn is printed",
2057                  "off",MESSAGES);
2058  parameters[numberParameters-1].append("on");
2059  parameters[numberParameters-1].setLonghelp
2060    ("The default behavior is to put out messages such as:\n\
2061   Clp0005 2261  Objective 109.024 Primal infeas 944413 (758)\n\
2062but this program turns this off to make it look more friendly.  It can be useful\
2063 to turn them back on if you want to be able to 'grep' for particular messages or if\
2064 you intend to override the behavior of a particular message."
2065     );
2066#ifdef COIN_HAS_CBC
2067  parameters[numberParameters++]=
2068    CbcOrClpParam("miniT!ree","Size of fast mini tree",
2069                  0,COIN_INT_MAX,NUMBERMINI,false);
2070  parameters[numberParameters-1].setLonghelp
2071    (
2072     "The idea is that I can do a small tree fast. \
2073This is a first try and will hopefully become more sophisticated."
2074     ); 
2075  parameters[numberParameters++]=
2076    CbcOrClpParam("miplib","Do some of miplib test set",
2077                  MIPLIB,3);
2078#endif
2079#ifdef COIN_HAS_CLP
2080  parameters[numberParameters++]=
2081    CbcOrClpParam("netlib","Solve entire netlib test set",
2082                  NETLIB_EITHER,3);
2083  parameters[numberParameters-1].setLonghelp
2084    (
2085     "This exercises the unit test for clp and then solves the netlib test set using dual or primal.\
2086The user can set options before e.g. clp -presolve off -netlib"
2087     ); 
2088#ifdef REAL_BARRIER
2089  parameters[numberParameters++]=
2090    CbcOrClpParam("netlibB!arrier","Solve entire netlib test set with barrier",
2091                  NETLIB_BARRIER,3);
2092  parameters[numberParameters-1].setLonghelp
2093    (
2094     "This exercises the unit test for clp and then solves the netlib test set using barrier.\
2095The user can set options before e.g. clp -kkt on -netlib"
2096     ); 
2097#endif
2098  parameters[numberParameters++]=
2099    CbcOrClpParam("netlibD!ual","Solve entire netlib test set (dual)",
2100                  NETLIB_DUAL,3);
2101  parameters[numberParameters-1].setLonghelp
2102    (
2103     "This exercises the unit test for clp and then solves the netlib test set using dual.\
2104The user can set options before e.g. clp -presolve off -netlib"
2105     ); 
2106  parameters[numberParameters++]=
2107    CbcOrClpParam("netlibP!rimal","Solve entire netlib test set (primal)",
2108                  NETLIB_PRIMAL,3);
2109  parameters[numberParameters-1].setLonghelp
2110    (
2111     "This exercises the unit test for clp and then solves the netlib test set using primal.\
2112The user can set options before e.g. clp -presolve off -netlibp"
2113     ); 
2114  parameters[numberParameters++]=
2115    CbcOrClpParam("netlibT!une","Solve entire netlib test set with 'best' algorithm",
2116                  NETLIB_TUNE,3);
2117  parameters[numberParameters-1].setLonghelp
2118    (
2119     "This exercises the unit test for clp and then solves the netlib test set using whatever \
2120works best.  I know this is cheating but it also stresses the code better by doing a \
2121mixture of stuff.  The best algorithm was chosen on a Linux ThinkPad using native cholesky \
2122with University of Florida ordering."
2123     ); 
2124  parameters[numberParameters++]=
2125    CbcOrClpParam("network","Tries to make network matrix",
2126                  NETWORK,7,false);
2127  parameters[numberParameters-1].setLonghelp
2128    (
2129     "Clp will go faster if the matrix can be converted to a network.  The matrix\
2130 operations may be a bit faster with more efficient storage, but the main advantage\
2131 comes from using a network factorization.  It will probably not be as fast as a \
2132specialized network code."
2133     ); 
2134#ifdef COIN_HAS_CBC
2135  parameters[numberParameters++]=
2136    CbcOrClpParam("node!Strategy","What strategy to use to select nodes",
2137                  "hybrid",NODESTRATEGY);
2138  parameters[numberParameters-1].append("fewest");
2139  parameters[numberParameters-1].append("depth");
2140  parameters[numberParameters-1].append("upfewest");
2141  parameters[numberParameters-1].append("downfewest");
2142  parameters[numberParameters-1].append("updepth");
2143  parameters[numberParameters-1].append("downdepth");
2144  parameters[numberParameters-1].setLonghelp
2145    (
2146     "Normally before a solution the code will choose node with fewest infeasibilities. \
2147You can choose depth as the criterion.  You can also say if up or down branch must \
2148be done first (the up down choice will carry on after solution). \
2149Default has now been changed to hybrid which is breadth first on small depth nodes then fewest."
2150     ); 
2151  parameters[numberParameters++]=
2152    CbcOrClpParam("numberA!nalyze","Number of analysis iterations",
2153                  -COIN_INT_MAX,COIN_INT_MAX,NUMBERANALYZE,false);
2154  parameters[numberParameters-1].setLonghelp
2155    (
2156     "This says how many iterations to spend at root node analyzing problem. \
2157This is a first try and will hopefully become more sophisticated."
2158     ); 
2159#endif
2160  parameters[numberParameters++]=
2161    CbcOrClpParam("objective!Scale","Scale factor to apply to objective",
2162                  -1.0e20,1.0e20,OBJSCALE,false);
2163  parameters[numberParameters-1].setLonghelp
2164    (
2165     "If the objective function has some very large values, you may wish to scale them\
2166 internally by this amount.  It can also be set by autoscale.  It is applied after scaling"
2167     ); 
2168  parameters[numberParameters-1].setDoubleValue(1.0);
2169#endif
2170#ifdef COIN_HAS_CBC
2171  parameters[numberParameters++]=
2172    CbcOrClpParam("outDup!licates","takes duplicate rows etc out of integer model",
2173                  OUTDUPROWS,7,false);
2174#endif
2175  parameters[numberParameters++]=
2176    CbcOrClpParam("output!Format","Which output format to use",
2177                  1,6,OUTPUTFORMAT);
2178  parameters[numberParameters-1].setLonghelp
2179    (
2180     "Normally export will be done using normal representation for numbers and two values\
2181 per line.  You may want to do just one per line (for grep or suchlike) and you may wish\
2182 to save with absolute accuracy using a coded version of the IEEE value. A value of 2 is normal.\
2183 otherwise odd values gives one value per line, even two.  Values 1,2 give normal format, 3,4\
2184 gives greater precision, while 5,6 give IEEE values.  When used for exporting a basis 1 does not save \
2185values, 2 saves values, 3 with greater accuracy and 4 in IEEE."
2186     );
2187#ifdef COIN_HAS_CBC
2188  parameters[numberParameters++]=
2189    CbcOrClpParam("passC!uts","Number of cut passes at root node",
2190                  -9999999,9999999,CUTPASS);
2191  parameters[numberParameters-1].setLonghelp
2192    (
2193     "The default is 100 passes if less than 500 columns, 100 passes (but \
2194stop if drop small if less than 5000 columns, 20 otherwise"
2195     ); 
2196  parameters[numberParameters++]=
2197    CbcOrClpParam("passF!easibilityPump","How many passes in feasibility pump",
2198                  0,10000,FPUMPITS);
2199  parameters[numberParameters-1].setLonghelp
2200    (
2201     "This fine tunes Feasibility Pump by doing more or fewer passes."
2202     ); 
2203  parameters[numberParameters-1].setIntValue(20);
2204#endif
2205#ifdef COIN_HAS_CLP
2206  parameters[numberParameters++]=
2207    CbcOrClpParam("passP!resolve","How many passes in presolve",
2208                  -200,100,PRESOLVEPASS,false);
2209  parameters[numberParameters-1].setLonghelp
2210    (
2211     "Normally Presolve does 5 passes but you may want to do less to make it\
2212 more lightweight or do more if improvements are still being made.  As Presolve will return\
2213 if nothing is being taken out, you should not normally need to use this fine tuning."
2214     );
2215#endif
2216#ifdef COIN_HAS_CBC
2217  parameters[numberParameters++]=
2218    CbcOrClpParam("passT!reeCuts","Number of cut passes in tree",
2219                  -999999,999999,CUTPASSINTREE);
2220  parameters[numberParameters-1].setLonghelp
2221    (
2222     "The default is one pass"
2223     ); 
2224#endif
2225#ifdef COIN_HAS_CLP
2226  parameters[numberParameters++]=
2227    CbcOrClpParam("pertV!alue","Method of perturbation",
2228                  -5000,102,PERTVALUE,false);
2229  parameters[numberParameters++]=
2230    CbcOrClpParam("perturb!ation","Whether to perturb problem",
2231                  "on",PERTURBATION);
2232  parameters[numberParameters-1].append("off");
2233  parameters[numberParameters-1].setLonghelp
2234    (
2235     "Perturbation helps to stop cycling, but Clp uses other measures for this.\
2236  However large problems and especially ones with unit elements and unit rhs or costs\
2237 benefit from perturbation.  Normally Clp tries to be intelligent, but you can switch this off.\
2238  The Clp library has this off by default.  This program has it on by default."
2239     ); 
2240  parameters[numberParameters++]=
2241    CbcOrClpParam("PFI","Whether to use Product Form of Inverse in simplex",
2242                  "off",PFI,7,false);
2243  parameters[numberParameters-1].append("on");
2244  parameters[numberParameters-1].setLonghelp
2245    (
2246     "By default clp uses Forrest-Tomlin L-U update.  If you are masochistic you can switch it off."
2247     ); 
2248  parameters[numberParameters++]=
2249    CbcOrClpParam("plus!Minus","Tries to make +- 1 matrix",
2250                  PLUSMINUS,7,false);
2251  parameters[numberParameters-1].setLonghelp
2252    (
2253     "Clp will go slightly faster if the matrix can be converted so that the elements are\
2254 not stored and are known to be unit.  The main advantage is memory use.  Clp may automatically\
2255 see if it can convert the problem so you should not need to use this."
2256     ); 
2257  parameters[numberParameters++]=
2258    CbcOrClpParam("pO!ptions","Dubious print options",
2259                  0,COIN_INT_MAX,PRINTOPTIONS,false);
2260  parameters[numberParameters-1].setIntValue(0);
2261  parameters[numberParameters-1].setLonghelp
2262    (
2263     "If this is > 0 then presolve will give more information and branch and cut will give statistics"
2264     ); 
2265  parameters[numberParameters++]=
2266    CbcOrClpParam("preO!pt","Presolve options",
2267                  0,COIN_INT_MAX,PRESOLVEOPTIONS,false);
2268#endif
2269  parameters[numberParameters++]=
2270    CbcOrClpParam("presolve","Whether to presolve problem",
2271                  "on",PRESOLVE);
2272  parameters[numberParameters-1].append("off");
2273  parameters[numberParameters-1].append("more");
2274  parameters[numberParameters-1].append("file");
2275  parameters[numberParameters-1].setLonghelp
2276    (
2277     "Presolve analyzes the model to find such things as redundant equations, equations\
2278 which fix some variables, equations which can be transformed into bounds etc etc.  For the\
2279 initial solve of any problem this is worth doing unless you know that it will have no effect.  \
2280on will normally do 5 passes while using 'more' will do 10.  If the problem is very large you may need \
2281to write the original to file using 'file'."
2282     ); 
2283#ifdef COIN_HAS_CBC
2284  parameters[numberParameters++]=
2285    CbcOrClpParam("preprocess","Whether to use integer preprocessing",
2286                  "off",PREPROCESS);
2287  parameters[numberParameters-1].append("on");
2288  parameters[numberParameters-1].append("save");
2289  parameters[numberParameters-1].append("equal");
2290  parameters[numberParameters-1].append("sos");
2291  parameters[numberParameters-1].append("trysos");
2292  parameters[numberParameters-1].append("equalall");
2293  parameters[numberParameters-1].append("strategy");
2294  parameters[numberParameters-1].append("aggregate");
2295  parameters[numberParameters-1].append("forcesos");
2296  parameters[numberParameters-1].setLonghelp
2297    (
2298     "This tries to reduce size of model in a similar way to presolve and \
2299it also tries to strengthen the model - this can be very useful and is worth trying. \
2300 Save option saves on file presolved.mps.  equal will turn <= cliques into \
2301==.  sos will create sos sets if all 0-1 in sets (well one extra is allowed) \
2302and no overlaps.  trysos is same but allows any number extra.  equalall will turn all \
2303valid inequalities into equalities with integer slacks.  strategy is as \
2304on but uses CbcStrategy."
2305     ); 
2306#endif
2307#ifdef COIN_HAS_CLP
2308  parameters[numberParameters++]=
2309    CbcOrClpParam("preT!olerance","Tolerance to use in presolve",
2310                  1.0e-20,1.0e12,PRESOLVETOLERANCE);
2311  parameters[numberParameters-1].setLonghelp
2312    (
2313     "The default is 1.0e-8 - you may wish to try 1.0e-7 if presolve says the problem is \
2314infeasible and you have awkward numbers and you are sure the problem is really feasible."
2315     ); 
2316  parameters[numberParameters++]=
2317    CbcOrClpParam("primalP!ivot","Primal pivot choice algorithm",
2318                  "auto!matic",PRIMALPIVOT);
2319  parameters[numberParameters-1].append("exa!ct");
2320  parameters[numberParameters-1].append("dant!zig");
2321  parameters[numberParameters-1].append("part!ial");
2322  parameters[numberParameters-1].append("steep!est");
2323  parameters[numberParameters-1].append("change");
2324  parameters[numberParameters-1].append("sprint");
2325  parameters[numberParameters-1].setLonghelp
2326    (
2327     "Clp can use any pivot selection algorithm which the user codes as long as it\
2328 implements the features in the abstract pivot base class.  The Dantzig method is implemented\
2329 to show a simple method but its use is deprecated.  Exact devex is the method of choice and there\
2330 are two variants which keep all weights updated but only scan a subset each iteration.\
2331 Partial switches this on while change initially does dantzig until the factorization\
2332 becomes denser.  This is still a work in progress."
2333     ); 
2334  parameters[numberParameters++]=
2335    CbcOrClpParam("primalS!implex","Do primal simplex algorithm",
2336                  PRIMALSIMPLEX);
2337  parameters[numberParameters-1].setLonghelp
2338    (
2339     "This command solves the current model using the primal algorithm.\
2340  The default is to use exact devex.\
2341 The time and iterations may be affected by settings such as presolve, scaling, crash\
2342 and also by column selection  method, infeasibility weight and dual and primal tolerances."
2343     );
2344#endif
2345  parameters[numberParameters++]=
2346    CbcOrClpParam("primalT!olerance","For an optimal solution \
2347no primal infeasibility may exceed this value",
2348                  1.0e-20,1.0e12,PRIMALTOLERANCE);
2349  parameters[numberParameters-1].setLonghelp
2350    (
2351     "Normally the default tolerance is fine, but you may want to increase it a\
2352 bit if a primal run seems to be having a hard time"
2353     ); 
2354#ifdef COIN_HAS_CLP
2355  parameters[numberParameters++]=
2356    CbcOrClpParam("primalW!eight","Initially algorithm acts as if it \
2357costs this much to be infeasible",
2358                  1.0e-20,1.0e20,PRIMALWEIGHT);
2359  parameters[numberParameters-1].setLonghelp
2360    (
2361     "The primal algorithm in Clp is a single phase algorithm as opposed to a two phase\
2362 algorithm where you first get feasible then optimal.  So Clp is minimizing this weight times\
2363 the sum of primal infeasibilities plus the true objective function (in minimization sense).\
2364  Too high a value may mean more iterations, while too low a bound means\
2365 the code may go all the way and then have to increase the weight in order to get feasible.\
2366  OSL had a heuristic to\
2367 adjust bounds, maybe we need that here."
2368     ); 
2369#endif
2370  parameters[numberParameters++]=
2371    CbcOrClpParam("printi!ngOptions","Print options",
2372                  "normal",INTPRINT,3);
2373  parameters[numberParameters-1].append("integer");
2374  parameters[numberParameters-1].append("special");
2375  parameters[numberParameters-1].append("rows");
2376  parameters[numberParameters-1].append("all");
2377  parameters[numberParameters-1].append("csv");
2378  parameters[numberParameters-1].setLonghelp
2379    (
2380     "This changes the amount and format of printing a solution:\nnormal - nonzero column variables \n\
2381integer - nonzero integer column variables\n\
2382special - in format suitable for OsiRowCutDebugger\n\
2383rows - nonzero column variables and row activities\n\
2384all - all column variables and row activities.\n\
2385\nFor non-integer problems 'integer' and 'special' act like 'normal'.  \
2386Also see printMask for controlling output."
2387     ); 
2388  parameters[numberParameters++]=
2389    CbcOrClpParam("printM!ask","Control printing of solution on a  mask",
2390                  PRINTMASK,3);
2391  parameters[numberParameters-1].setLonghelp
2392    (
2393     "If set then only those names which match mask are printed in a solution. \
2394'?' matches any character and '*' matches any set of characters. \
2395 The default is '' i.e. unset so all variables are printed. \
2396This is only active if model has names."
2397     ); 
2398#ifdef COIN_HAS_CBC
2399  parameters[numberParameters++]=
2400    CbcOrClpParam("prio!rityIn","Import priorities etc from file",
2401                  PRIORITYIN,3);
2402  parameters[numberParameters-1].setLonghelp
2403    (
2404     "This will read a file with priorities from the given file name.  It will use the default\
2405 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
2406 is initialized to '', i.e. it must be set.  This can not read from compressed files. \
2407File is in csv format with allowed headings - name, number, priority, direction, up, down, solution.  Exactly one of\
2408 name and number must be given."
2409     ); 
2410  parameters[numberParameters++]=
2411    CbcOrClpParam("probing!Cuts","Whether to use Probing cuts",
2412                  "off",PROBINGCUTS);
2413  parameters[numberParameters-1].append("on");
2414  parameters[numberParameters-1].append("root");
2415  parameters[numberParameters-1].append("ifmove");
2416  parameters[numberParameters-1].append("forceOn");
2417  parameters[numberParameters-1].append("forceOnBut");
2418  parameters[numberParameters-1].append("forceOnStrong");
2419  parameters[numberParameters-1].append("forceOnButStrong");
2420  parameters[numberParameters-1].append("strongRoot");
2421  parameters[numberParameters-1].setLonghelp
2422    (
2423     "This switches on probing cuts (either at root or in entire tree) \
2424See branchAndCut for information on options. \
2425but strong options do more probing"
2426     ); 
2427  parameters[numberParameters++]=
2428    CbcOrClpParam("pumpT!une","Dubious ideas for feasibility pump",
2429                  0,100000000,FPUMPTUNE);
2430  parameters[numberParameters-1].setLonghelp
2431    (
2432     "This fine tunes Feasibility Pump \n\
2433\t>=1000000 use as accumulate switch\n\
2434\t>=1000 use index+1 as number of large loops\n\
2435\t>=100 use 0.05 objvalue as increment\n\
2436\t>=10 use +0.1 objvalue for cutoff (add)\n\
2437\t1 == fix ints at bounds, 2 fix all integral ints, 3 and continuous at bounds"
2438     ); 
2439  parameters[numberParameters-1].setIntValue(0);
2440#endif
2441  parameters[numberParameters++]=
2442    CbcOrClpParam("quit","Stops clp execution",
2443                  EXIT);
2444  parameters[numberParameters-1].setLonghelp
2445    (
2446     "This stops the execution of Clp, end, exit, quit and stop are synonyms"
2447     ); 
2448#ifdef COIN_HAS_CBC
2449  parameters[numberParameters++]=
2450    CbcOrClpParam("ratio!Gap","Stop when gap between best possible and \
2451best less than this fraction of larger of two",
2452                  0.0,1.0e20,GAPRATIO);
2453  parameters[numberParameters-1].setDoubleValue(0.0);
2454  parameters[numberParameters-1].setLonghelp
2455    (
2456     "If the gap between best solution and best possible solution is less than this fraction \
2457of the objective value at the root node then the search will terminate.  See 'allowableGap' for a \
2458way of using absolute value rather than fraction."
2459     ); 
2460#endif
2461#ifdef COIN_HAS_CLP
2462  parameters[numberParameters++]=
2463    CbcOrClpParam("reallyO!bjectiveScale","Scale factor to apply to objective in place",
2464                  -1.0e20,1.0e20,OBJSCALE2,false);
2465  parameters[numberParameters-1].setLonghelp
2466    (
2467     "You can set this to -1.0 to test maximization or other to stress code"
2468     ); 
2469  parameters[numberParameters-1].setDoubleValue(1.0);
2470  parameters[numberParameters++]=
2471    CbcOrClpParam("reallyS!cale","Scales model in place",
2472                  REALLY_SCALE,7,false);
2473#endif
2474#ifdef COIN_HAS_CBC
2475    parameters[numberParameters++]=
2476      CbcOrClpParam("reduce!AndSplitCuts","Whether to use Reduce-and-Split cuts",
2477              "off",REDSPLITCUTS);
2478    parameters[numberParameters-1].append("on");
2479    parameters[numberParameters-1].append("root");
2480    parameters[numberParameters-1].append("ifmove");
2481    parameters[numberParameters-1].append("forceOn");
2482    parameters[numberParameters-1].setLonghelp
2483    (
2484     "This switches on reduce and split  cuts (either at root or in entire tree) \
2485See branchAndCut for information on options."
2486     ); 
2487  parameters[numberParameters++]=
2488    CbcOrClpParam("residual!CapacityCuts","Whether to use Residual Capacity cuts",
2489                  "off",RESIDCUTS);
2490  parameters[numberParameters-1].append("on");
2491  parameters[numberParameters-1].append("root");
2492  parameters[numberParameters-1].append("ifmove");
2493  parameters[numberParameters-1].append("forceOn");
2494  parameters[numberParameters-1].setLonghelp
2495    (
2496     "Residual capacity cuts. \
2497See branchAndCut for information on options."
2498     ); 
2499#endif
2500#ifdef COIN_HAS_CLP
2501  parameters[numberParameters++]=
2502    CbcOrClpParam("restore!Model","Restore model from binary file",
2503                  RESTORE);
2504  parameters[numberParameters-1].setLonghelp
2505    (
2506     "This reads data save by saveModel from the given file.  It will use the default\
2507 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
2508 is initialized to 'default.prob'."
2509     ); 
2510  parameters[numberParameters++]=
2511    CbcOrClpParam("reverse","Reverses sign of objective",
2512                  REVERSE,7,false);
2513  parameters[numberParameters-1].setLonghelp
2514    (
2515     "Useful for testing if maximization works correctly"
2516     ); 
2517  parameters[numberParameters++]=
2518    CbcOrClpParam("rhs!Scale","Scale factor to apply to rhs and bounds",
2519                  -1.0e20,1.0e20,RHSSCALE,false);
2520  parameters[numberParameters-1].setLonghelp
2521    (
2522     "If the rhs or bounds have some very large meaningful values, you may wish to scale them\
2523 internally by this amount.  It can also be set by autoscale"
2524     ); 
2525  parameters[numberParameters-1].setDoubleValue(1.0);
2526#endif
2527#ifdef COIN_HAS_CBC
2528  parameters[numberParameters++]=
2529      CbcOrClpParam("Rens","Whether to try Relaxation Enforced Neighborhood Search",
2530                    "off",RENS);
2531    parameters[numberParameters-1].append("on");
2532    parameters[numberParameters-1].append("200");
2533    parameters[numberParameters-1].append("1000");
2534    parameters[numberParameters-1].append("10000");
2535  parameters[numberParameters-1].setLonghelp
2536    (
2537     "This switches on Relaxation enforced neighborhood Search. \
2538on just does feasibility pump \
2539200 or 1000 does that many nodes."
2540     ); 
2541  parameters[numberParameters++]=
2542      CbcOrClpParam("Rins","Whether to try Relaxed Induced Neighborhood Search",
2543                    "off",RINS);
2544    parameters[numberParameters-1].append("on");
2545    parameters[numberParameters-1].append("often");
2546  parameters[numberParameters-1].setLonghelp
2547    (
2548     "This switches on Relaxed induced neighborhood Search."
2549     ); 
2550  parameters[numberParameters++]=
2551    CbcOrClpParam("round!ingHeuristic","Whether to use Rounding heuristic",
2552                  "off",ROUNDING);
2553  parameters[numberParameters-1].append("on");
2554  parameters[numberParameters-1].append("do");
2555  parameters[numberParameters-1].setLonghelp
2556    (
2557     "This switches on a simple (but effective) rounding heuristic at each node of tree.  \
2558The Do option switches on before preprocessing."
2559     ); 
2560#endif
2561  parameters[numberParameters++]=
2562    CbcOrClpParam("saveM!odel","Save model to binary file",
2563                  SAVE);
2564  parameters[numberParameters-1].setLonghelp
2565    (
2566     "This will save the problem to the given file name for future use\
2567 by restoreModel.  It will use the default\
2568 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
2569 is initialized to 'default.prob'."
2570     ); 
2571  parameters[numberParameters++]=
2572    CbcOrClpParam("saveS!olution","saves solution to file",
2573                  SAVESOL);
2574  parameters[numberParameters-1].setLonghelp
2575    (
2576     "This will write a binary solution file to the given file name.  It will use the default\
2577 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
2578 is initialized to 'solution.file'.  To read the file use fread(int) twice to pick up number of rows \
2579and columns, then fread(double) to pick up objective value, then pick up row activities, row duals, column \
2580activities and reduced costs - see bottom of CbcOrClpParam.cpp for code that reads or writes file. \
2581If name contains '_fix_read_' then does not write but reads and will fix all variables"
2582     ); 
2583  parameters[numberParameters++]=
2584    CbcOrClpParam("scal!ing","Whether to scale problem",
2585                  "off",SCALING);
2586  parameters[numberParameters-1].append("equi!librium");
2587  parameters[numberParameters-1].append("geo!metric");
2588  parameters[numberParameters-1].append("auto!matic");
2589  parameters[numberParameters-1].setLonghelp
2590    (
2591     "Scaling can help in solving problems which might otherwise fail because of lack of\
2592 accuracy.  It can also reduce the number of iterations.  It is not applied if the range\
2593 of elements is small.  When unscaled it is possible that there may be small primal and/or\
2594 infeasibilities."
2595     ); 
2596  parameters[numberParameters-1].setCurrentOption(3); // say auto
2597#ifndef COIN_HAS_CBC
2598  parameters[numberParameters++]=
2599    CbcOrClpParam("sec!onds","Maximum seconds",
2600                  -1.0,1.0e12,TIMELIMIT);
2601  parameters[numberParameters-1].setLonghelp
2602    (
2603     "After this many seconds clp will act as if maximum iterations had been reached \
2604(if value >=0).  \
2605In this program it is really only useful for testing but the library function\n\
2606      \tsetMaximumSeconds(value)\n can be useful."
2607     );
2608#else
2609  parameters[numberParameters++]=
2610    CbcOrClpParam("sec!onds","maximum seconds",
2611                  -1.0,1.0e12,TIMELIMIT_BAB);
2612  parameters[numberParameters-1].setLonghelp
2613    (
2614     "After this many seconds coin solver will act as if maximum nodes had been reached."
2615     );
2616#endif
2617  parameters[numberParameters++]=
2618    CbcOrClpParam("sleep","for debug",
2619                  DUMMY,7,false);
2620  parameters[numberParameters-1].setLonghelp
2621    (
2622     "If passed to solver fom ampl, then ampl will wait so that you can copy .nl file for debug."
2623     ); 
2624#ifdef COIN_HAS_CLP
2625  parameters[numberParameters++]=
2626    CbcOrClpParam("slp!Value","Number of slp passes before primal",
2627                  -1,50000,SLPVALUE,false);
2628  parameters[numberParameters-1].setLonghelp
2629    (
2630     "If you are solving a quadratic problem using primal then it may be helpful to do some \
2631sequential Lps to get a good approximate solution."
2632     ); 
2633#endif
2634  parameters[numberParameters++]=
2635    CbcOrClpParam("solu!tion","Prints solution to file",
2636                  SOLUTION);
2637  parameters[numberParameters-1].setLonghelp
2638    (
2639     "This will write a primitive solution file to the given file name.  It will use the default\
2640 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
2641 is initialized to 'stdout'.  The amount of output can be varied using printi!ngOptions or printMask."
2642     ); 
2643#ifdef COIN_HAS_CLP
2644#ifdef COIN_HAS_CBC
2645  parameters[numberParameters++]=
2646    CbcOrClpParam("solv!e","Solve problem",
2647                  BAB);
2648  parameters[numberParameters-1].setLonghelp
2649    (
2650     "If there are no integer variables then this just solves LP.  If there are integer variables \
2651this does branch and cut."
2652     ); 
2653  parameters[numberParameters++]=
2654    CbcOrClpParam("sos!Options","Whether to use SOS from AMPL",
2655                  "off",SOS);
2656  parameters[numberParameters-1].append("on");
2657  parameters[numberParameters-1].setCurrentOption("on");
2658  parameters[numberParameters-1].setLonghelp
2659    (
2660     "Normally if AMPL says there are SOS variables they should be used, but sometime sthey should\
2661 be turned off - this does so."
2662     ); 
2663  parameters[numberParameters++]=
2664    CbcOrClpParam("slog!Level","Level of detail in Solver output",
2665                  -1,63,SOLVERLOGLEVEL);
2666  parameters[numberParameters-1].setLonghelp
2667    (
2668     "If 0 then there should be no output in normal circumstances.  1 is probably the best\
2669 value for most uses, while 2 and 3 give more information."
2670     );
2671#else
2672  // allow solve as synonym for dual
2673  parameters[numberParameters++]=
2674    CbcOrClpParam("solv!e","Solve problem using dual simplex",
2675                  BAB);
2676  parameters[numberParameters-1].setLonghelp
2677    (
2678     "Just so can use solve for clp as well as in cbc"
2679     ); 
2680#endif
2681#endif
2682#ifdef COIN_HAS_CLP
2683  parameters[numberParameters++]=
2684    CbcOrClpParam("spars!eFactor","Whether factorization treated as sparse",
2685                  "on",SPARSEFACTOR,7,false);
2686  parameters[numberParameters-1].append("off");
2687  parameters[numberParameters++]=
2688    CbcOrClpParam("special!Options","Dubious options for Simplex - see ClpSimplex.hpp",
2689                  0,COIN_INT_MAX,SPECIALOPTIONS,false);
2690  parameters[numberParameters++]=
2691    CbcOrClpParam("sprint!Crash","Whether to try sprint crash",
2692                  -1,5000000,SPRINT);
2693  parameters[numberParameters-1].setLonghelp
2694    (
2695     "For long and thin problems this program may solve a series of small problems\
2696 created by taking a subset of the columns.  I introduced the idea as 'Sprint' after\
2697 an LP code of that name of the 60's which tried the same tactic (not totally successfully).\
2698  Cplex calls it 'sifting'.  -1 is automatic choice, 0 is off, n is number of passes"
2699     ); 
2700  parameters[numberParameters++]=
2701    CbcOrClpParam("stat!istics","Print some statistics",
2702                  STATISTICS);
2703  parameters[numberParameters-1].setLonghelp
2704    (
2705     "This command prints some statistics for the current model.\
2706 If log level >1 then more is printed.\
2707 These are for presolved model if presolve on (and unscaled)."
2708     );
2709#endif
2710  parameters[numberParameters++]=
2711    CbcOrClpParam("stop","Stops clp execution",
2712                  EXIT);
2713  parameters[numberParameters-1].setLonghelp
2714    (
2715     "This stops the execution of Clp, end, exit, quit and stop are synonyms"
2716     ); 
2717#ifdef COIN_HAS_CBC
2718  parameters[numberParameters++]=
2719    CbcOrClpParam("strengthen","Create strengthened problem",
2720                  STRENGTHEN,3);
2721  parameters[numberParameters-1].setLonghelp
2722    (
2723     "This creates a new problem by applying the root node cuts.  All tight constraints \
2724will be in resulting problem"
2725     ); 
2726  parameters[numberParameters++]=
2727    CbcOrClpParam("strong!Branching","Number of variables to look at in strong branching",
2728                  0,999999,STRONGBRANCHING);
2729  parameters[numberParameters-1].setLonghelp
2730    (
2731     "In order to decide which variable to branch on, the code will choose up to this number \
2732of unsatisfied variables to do mini up and down branches on.  Then the most effective one is chosen. \
2733If a variable is branched on many times then the previous average up and down costs may be used - \
2734see number before trust."
2735     ); 
2736#endif
2737#ifdef COIN_HAS_CLP
2738  parameters[numberParameters++]=
2739    CbcOrClpParam("subs!titution","How long a column to substitute for in presolve",
2740                  0,10000,SUBSTITUTION,false);
2741  parameters[numberParameters-1].setLonghelp
2742    (
2743     "Normally Presolve gets rid of 'free' variables when there are no more than 3 \
2744 variables in column.  If you increase this the number of rows may decrease but number of \
2745 elements may increase."
2746     ); 
2747#endif
2748#ifdef COIN_HAS_CBC
2749  parameters[numberParameters++]=
2750    CbcOrClpParam("testO!si","Test OsiObject stuff",
2751                  -1,COIN_INT_MAX,TESTOSI,false);
2752#endif
2753#ifdef CBC_THREAD
2754  parameters[numberParameters++]=
2755    CbcOrClpParam("thread!s","Number of threads to try and use",
2756                  -100,10000,THREADS,false);
2757  parameters[numberParameters-1].setLonghelp
2758    (
2759     "To use multiple threads, set threads to number wanted.  It may be better \
2760to use one or two more than number of cpus available.  If 100+n then n threads and \
2761threads used in sub-trees, if 200+n use threads for root cuts, 300+n - both."
2762     ); 
2763#endif
2764#ifdef COIN_HAS_CBC
2765  parameters[numberParameters++]=
2766    CbcOrClpParam("tighten!Factor","Tighten bounds using this times largest \
2767activity at continuous solution",
2768                  1.0e-3,1.0e20,TIGHTENFACTOR,false);
2769  parameters[numberParameters-1].setLonghelp
2770    (
2771     "This sleazy trick can help on some problems."
2772     ); 
2773#endif
2774#ifdef COIN_HAS_CLP
2775  parameters[numberParameters++]=
2776    CbcOrClpParam("tightLP","Poor person's preSolve for now",
2777                  TIGHTEN,7,false);
2778#endif
2779#ifdef COIN_HAS_CBC
2780  parameters[numberParameters++]=
2781    CbcOrClpParam("trust!PseudoCosts","Number of branches before we trust pseudocosts",
2782                  -3,2000000,NUMBERBEFORE);
2783  parameters[numberParameters-1].setLonghelp
2784    (
2785     "Using strong branching computes pseudo-costs.  After this many times for a variable we just \
2786trust the pseudo costs and do not do any more strong branching."
2787     ); 
2788#endif
2789#ifdef COIN_HAS_CBC
2790  parameters[numberParameters++]=
2791    CbcOrClpParam("tune!PreProcess","Dubious tuning parameters",
2792                  0,20000000,PROCESSTUNE,false);
2793  parameters[numberParameters-1].setLonghelp
2794    (
2795     "For making equality cliques this is minimumsize.  Also for adding \
2796integer slacks.  May be used for more later \
2797If <1000 that is what it does.  If <1000000 - numberPasses is (value/1000)-1 and tune is tune %1000. \
2798If >= 1000000! - numberPasses is (value/1000000)-1 and tune is tune %1000000.  In this case if tune is now still >=10000 \
2799numberPassesPerInnerLoop is changed from 10 to (tune-10000)-1 and tune becomes tune % 10000!!!!! - happy? - \
2800so to keep normal limit on cliques of 5, do 3 major passes (include presolves) but only doing one tightening pass per major pass - \
2801you would use 3010005 (I think)"
2802     ); 
2803  parameters[numberParameters++]=
2804    CbcOrClpParam("two!MirCuts","Whether to use Two phase Mixed Integer Rounding cuts",
2805                  "off",TWOMIRCUTS);
2806  parameters[numberParameters-1].append("on");
2807  parameters[numberParameters-1].append("root");
2808  parameters[numberParameters-1].append("ifmove");
2809  parameters[numberParameters-1].append("forceOn");
2810  parameters[numberParameters-1].append("forceLongOn");
2811  parameters[numberParameters-1].setLonghelp
2812    (
2813     "This switches on two phase mixed integer rounding  cuts (either at root or in entire tree) \
2814See branchAndCut for information on options."
2815     ); 
2816#endif
2817  parameters[numberParameters++]=
2818    CbcOrClpParam("unitTest","Do unit test",
2819                  UNITTEST,3);
2820  parameters[numberParameters-1].setLonghelp
2821    (
2822     "This exercises the unit test for clp"
2823     ); 
2824  parameters[numberParameters++]=
2825    CbcOrClpParam("userClp","Hand coded Clp stuff",
2826                  USERCLP);
2827  parameters[numberParameters-1].setLonghelp
2828    (
2829     "There are times e.g. when using AMPL interface when you may wish to do something unusual.  \
2830Look for USERCLP in main driver and modify sample code."
2831     ); 
2832#ifdef COIN_HAS_CBC
2833  parameters[numberParameters++]=
2834    CbcOrClpParam("userCbc","Hand coded Cbc stuff",
2835                  USERCBC);
2836  parameters[numberParameters-1].setLonghelp
2837    (
2838     "There are times e.g. when using AMPL interface when you may wish to do something unusual.  \
2839Look for USERCBC in main driver and modify sample code."
2840     ); 
2841#endif
2842  parameters[numberParameters++]=
2843    CbcOrClpParam("vector","Whether to use vector? Form of matrix in simplex",
2844                  "off",VECTOR,7,false);
2845  parameters[numberParameters-1].append("on");
2846  parameters[numberParameters-1].setLonghelp
2847    (
2848     "If this is on and ClpPackedMatrix uses extra column copy in odd format."
2849     ); 
2850  parameters[numberParameters++]=
2851    CbcOrClpParam("verbose","Switches on longer help on single ?",
2852                  0,15,VERBOSE,false);
2853  parameters[numberParameters-1].setLonghelp
2854    (
2855     "Set to 1 to get short help with ? list, 2 to get long help, 3 for both.  (add 4 to just get ampl ones)."
2856     ); 
2857  parameters[numberParameters-1].setIntValue(0);
2858#ifdef COIN_HAS_CBC
2859  parameters[numberParameters++]=
2860    CbcOrClpParam("vub!heuristic","Type of vub heuristic",
2861                  -2,20,VUBTRY,false);
2862  parameters[numberParameters-1].setLonghelp
2863    (
2864     "If set will try and fix some integer variables"
2865     ); 
2866  parameters[numberParameters-1].setIntValue(-1);
2867#endif
2868  assert(numberParameters<CBCMAXPARAMETERS);
2869}
2870// Given a parameter type - returns its number in list
2871int whichParam (CbcOrClpParameterType name, 
2872                int numberParameters, CbcOrClpParam *const parameters)
2873{
2874  int i;
2875  for (i=0;i<numberParameters;i++) {
2876    if (parameters[i].type()==name)
2877      break;
2878  }
2879  assert (i<numberParameters);
2880  return i;
2881}
2882#ifdef COIN_HAS_CLP
2883/* Restore a solution from file.
2884   mode 0 normal, 1 swap rows and columns and primal and dual
2885   if 2 set then also change signs
2886*/
2887void restoreSolution(ClpSimplex * lpSolver,std::string fileName,int mode)
2888{
2889  FILE * fp=fopen(fileName.c_str(),"rb");
2890  if (fp) {
2891    int numberRows=lpSolver->numberRows();
2892    int numberColumns=lpSolver->numberColumns();
2893    int numberRowsFile;
2894    int numberColumnsFile;
2895    double objectiveValue;
2896    fread(&numberRowsFile,sizeof(int),1,fp);
2897    fread(&numberColumnsFile,sizeof(int),1,fp);
2898    fread(&objectiveValue,sizeof(double),1,fp);
2899    double * dualRowSolution = lpSolver->dualRowSolution();
2900    double * primalRowSolution = lpSolver->primalRowSolution();
2901    double * dualColumnSolution = lpSolver->dualColumnSolution();
2902    double * primalColumnSolution = lpSolver->primalColumnSolution();
2903    if (mode) {
2904      // swap
2905      int k=numberRows;
2906      numberRows=numberColumns;
2907      numberColumns=k;
2908      double * temp;
2909      temp = dualRowSolution;
2910      dualRowSolution = primalColumnSolution;
2911      primalColumnSolution=temp;
2912      temp = dualColumnSolution;
2913      dualColumnSolution = primalRowSolution;
2914      primalRowSolution=temp;
2915    }
2916    if (numberRows>numberRowsFile||numberColumns>numberColumnsFile) {
2917      std::cout<<"Mismatch on rows and/or columns - giving up"<<std::endl;
2918    } else {
2919      lpSolver->setObjectiveValue(objectiveValue);
2920      if (numberRows==numberRowsFile&&numberColumns==numberColumnsFile) {
2921        fread(primalRowSolution,sizeof(double),numberRows,fp);
2922        fread(dualRowSolution,sizeof(double),numberRows,fp);
2923        fread(primalColumnSolution,sizeof(double),numberColumns,fp);
2924        fread(dualColumnSolution,sizeof(double),numberColumns,fp);
2925      } else {
2926        std::cout<<"Mismatch on rows and/or columns - truncating"<<std::endl;
2927        double * temp = new double [CoinMax(numberRowsFile,numberColumnsFile)];
2928        fread(temp,sizeof(double),numberRowsFile,fp);
2929 CoinMemcpyN(temp,numberRows,primalRowSolution);
2930        fread(temp,sizeof(double),numberRowsFile,fp);
2931 CoinMemcpyN(temp,numberRows,dualRowSolution);
2932        fread(temp,sizeof(double),numberColumnsFile,fp);
2933 CoinMemcpyN(temp,numberColumns,primalColumnSolution);
2934        fread(temp,sizeof(double),numberColumnsFile,fp);
2935 CoinMemcpyN(temp,numberColumns,dualColumnSolution);
2936        delete [] temp;
2937      }
2938      if (mode==3) {
2939        int i;
2940        for (i=0;i<numberRows;i++) {
2941          primalRowSolution[i] = -primalRowSolution[i];
2942          dualRowSolution[i] = -dualRowSolution[i];
2943        }
2944        for (i=0;i<numberColumns;i++) {
2945          primalColumnSolution[i] = -primalColumnSolution[i];
2946          dualColumnSolution[i] = -dualColumnSolution[i];
2947        }
2948      }
2949    }
2950    fclose(fp);
2951  } else {
2952    std::cout<<"Unable to open file "<<fileName<<std::endl;
2953  }
2954}
2955// Dump a solution to file
2956void saveSolution(const ClpSimplex * lpSolver,std::string fileName)
2957{
2958  if (strstr(fileName.c_str(),"_fix_read_")) {
2959    FILE * fp=fopen(fileName.c_str(),"rb");
2960    if (fp) {
2961      ClpSimplex * solver = const_cast<ClpSimplex *>(lpSolver);
2962      restoreSolution(solver,fileName,0);
2963      // fix all
2964      int logLevel=solver->logLevel();
2965      int iColumn;
2966      int numberColumns=solver->numberColumns();
2967      double * primalColumnSolution = 
2968        solver->primalColumnSolution();
2969      double * columnLower = solver->columnLower();
2970      double * columnUpper = solver->columnUpper();
2971      for (iColumn=0;iColumn<numberColumns;iColumn++) {
2972        double value = primalColumnSolution[iColumn];
2973        if (value>columnUpper[iColumn]) {
2974          if (value >columnUpper[iColumn]+1.0e-6&&logLevel>1)
2975            printf("%d value of %g - bounds %g %g\n",
2976                   iColumn,value,columnLower[iColumn],columnUpper[iColumn]);
2977          value=columnUpper[iColumn];
2978        } else if (value<columnLower[iColumn]) {
2979          if (value <columnLower[iColumn]-1.0e-6&&logLevel>1)
2980            printf("%d value of %g - bounds %g %g\n",
2981                   iColumn,value,columnLower[iColumn],columnUpper[iColumn]);
2982          value=columnLower[iColumn];
2983        }
2984        columnLower[iColumn]=value;
2985        columnUpper[iColumn]=value;
2986      }
2987      return;
2988    }
2989  }
2990  FILE * fp=fopen(fileName.c_str(),"wb");
2991  if (fp) {
2992    int numberRows=lpSolver->numberRows();
2993    int numberColumns=lpSolver->numberColumns();
2994    double objectiveValue = lpSolver->objectiveValue();
2995    fwrite(&numberRows,sizeof(int),1,fp);
2996    fwrite(&numberColumns,sizeof(int),1,fp);
2997    fwrite(&objectiveValue,sizeof(double),1,fp);
2998    double * dualRowSolution = lpSolver->dualRowSolution();
2999    double * primalRowSolution = lpSolver->primalRowSolution();
3000    fwrite(primalRowSolution,sizeof(double),numberRows,fp);
3001    fwrite(dualRowSolution,sizeof(double),numberRows,fp);
3002    double * dualColumnSolution = lpSolver->dualColumnSolution();
3003    double * primalColumnSolution = lpSolver->primalColumnSolution();
3004    fwrite(primalColumnSolution,sizeof(double),numberColumns,fp);
3005    fwrite(dualColumnSolution,sizeof(double),numberColumns,fp);
3006    fclose(fp);
3007  } else {
3008    std::cout<<"Unable to open file "<<fileName<<std::endl;
3009  }
3010}
3011#endif
Note: See TracBrowser for help on using the repository browser.