source: stable/1.8/Clp/src/CbcOrClpParam.cpp @ 1249

Last change on this file since 1249 was 1249, checked in by ladanyi, 12 years ago

Updated stable/1.8 to match trunk

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