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

Last change on this file since 1206 was 1206, checked in by forrest, 13 years ago

new diving and fix ClpSimplex? bug

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