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

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

allow use of dense factorization

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 105.7 KB
Line 
1// Copyright (C) 2002, International Business Machines
2// Corporation and others.  All Rights Reserved.
3#if defined(_MSC_VER)
4// Turn off compiler warning about long names
5#  pragma warning(disable:4786)
6#endif
7
8#include "CbcOrClpParam.hpp"
9
10#include <string>
11#include <iostream>
12#include <cassert>
13
14#ifdef COIN_HAS_CBC
15#ifdef COIN_HAS_CLP
16#include "OsiClpSolverInterface.hpp"
17#include "ClpSimplex.hpp"
18#endif
19#include "CbcModel.hpp"
20#endif
21#include "CoinHelperFunctions.hpp"
22#ifdef COIN_HAS_CLP
23#include "ClpSimplex.hpp"
24#include "ClpFactorization.hpp"
25#endif
26#ifdef COIN_HAS_READLINE     
27#include <readline/readline.h>
28#include <readline/history.h>
29#endif
30#ifdef COIN_HAS_CBC
31// from CoinSolve
32static char coin_prompt[]="Coin:";
33#else
34static char coin_prompt[]="Clp:";
35#endif
36static bool doPrinting=true;
37std::string afterEquals="";
38static char printArray[200];
39void setCbcOrClpPrinting(bool yesNo)
40{
41  doPrinting=yesNo;
42}
43//#############################################################################
44// Constructors / Destructor / Assignment
45//#############################################################################
46
47//-------------------------------------------------------------------
48// Default Constructor
49//-------------------------------------------------------------------
50CbcOrClpParam::CbcOrClpParam () 
51  : type_(INVALID),
52    lowerDoubleValue_(0.0),
53    upperDoubleValue_(0.0),
54    lowerIntValue_(0),
55    upperIntValue_(0),
56    lengthName_(0),
57    lengthMatch_(0),
58    definedKeyWords_(),
59    name_(),
60    shortHelp_(),
61    longHelp_(),
62    action_(INVALID),
63    currentKeyWord_(-1),
64    display_(false),
65    intValue_(-1),
66    doubleValue_(-1.0),
67    stringValue_(""),
68    whereUsed_(7)
69{
70}
71// Other constructors
72CbcOrClpParam::CbcOrClpParam (std::string name, std::string help,
73           double lower, double upper, CbcOrClpParameterType type,
74                    bool display)
75  : type_(type),
76    lowerIntValue_(0),
77    upperIntValue_(0),
78    definedKeyWords_(),
79    name_(name),
80    shortHelp_(help),
81    longHelp_(),
82    action_(type),
83    currentKeyWord_(-1),
84    display_(display),
85    intValue_(-1),
86    doubleValue_(-1.0),
87    stringValue_(""),
88    whereUsed_(7)
89{
90  lowerDoubleValue_ = lower;
91  upperDoubleValue_ = upper;
92  gutsOfConstructor();
93}
94CbcOrClpParam::CbcOrClpParam (std::string name, std::string help,
95           int lower, int upper, CbcOrClpParameterType type,
96                    bool display)
97  : type_(type),
98    lowerDoubleValue_(0.0),
99    upperDoubleValue_(0.0),
100    definedKeyWords_(),
101    name_(name),
102    shortHelp_(help),
103    longHelp_(),
104    action_(type),
105    currentKeyWord_(-1),
106    display_(display),
107    intValue_(-1),
108    doubleValue_(-1.0),
109    stringValue_(""),
110    whereUsed_(7)
111{
112  gutsOfConstructor();
113  lowerIntValue_ = lower;
114  upperIntValue_ = upper;
115}
116// Other strings will be added by append
117CbcOrClpParam::CbcOrClpParam (std::string name, std::string help, 
118                    std::string firstValue,
119                    CbcOrClpParameterType type,int whereUsed,
120                    bool display)
121  : type_(type),
122    lowerDoubleValue_(0.0),
123    upperDoubleValue_(0.0),
124    lowerIntValue_(0),
125    upperIntValue_(0),
126    definedKeyWords_(),
127    name_(name),
128    shortHelp_(help),
129    longHelp_(),
130    action_(type),
131    currentKeyWord_(0),
132    display_(display),
133    intValue_(-1),
134    doubleValue_(-1.0),
135    stringValue_(""),
136    whereUsed_(whereUsed)
137{
138  gutsOfConstructor();
139  definedKeyWords_.push_back(firstValue);
140}
141// Action
142CbcOrClpParam::CbcOrClpParam (std::string name, std::string help,
143                    CbcOrClpParameterType type,int whereUsed,
144                    bool display)
145  : type_(type),
146    lowerDoubleValue_(0.0),
147    upperDoubleValue_(0.0),
148    lowerIntValue_(0),
149    upperIntValue_(0),
150    definedKeyWords_(),
151    name_(name),
152    shortHelp_(help),
153    longHelp_(),
154    action_(type),
155    currentKeyWord_(-1),
156    display_(display),
157    intValue_(-1),
158    doubleValue_(-1.0),
159    stringValue_("")
160{
161  whereUsed_=whereUsed;
162  gutsOfConstructor();
163}
164
165//-------------------------------------------------------------------
166// Copy constructor
167//-------------------------------------------------------------------
168CbcOrClpParam::CbcOrClpParam (const CbcOrClpParam & rhs) 
169{ 
170  type_ = rhs.type_;
171  lowerDoubleValue_ = rhs.lowerDoubleValue_;
172  upperDoubleValue_ = rhs.upperDoubleValue_;
173  lowerIntValue_ = rhs.lowerIntValue_;
174  upperIntValue_ = rhs.upperIntValue_;
175  lengthName_ = rhs.lengthName_;
176  lengthMatch_ = rhs.lengthMatch_;
177  definedKeyWords_ = rhs.definedKeyWords_;
178  name_ = rhs.name_;
179  shortHelp_ = rhs.shortHelp_;
180  longHelp_ = rhs.longHelp_;
181  action_ = rhs.action_;
182  currentKeyWord_ = rhs.currentKeyWord_;
183  display_=rhs.display_;
184  intValue_=rhs.intValue_;
185  doubleValue_=rhs.doubleValue_;
186  stringValue_=rhs.stringValue_;
187  whereUsed_=rhs.whereUsed_;
188}
189
190//-------------------------------------------------------------------
191// Destructor
192//-------------------------------------------------------------------
193CbcOrClpParam::~CbcOrClpParam ()
194{
195}
196
197//----------------------------------------------------------------
198// Assignment operator
199//-------------------------------------------------------------------
200CbcOrClpParam &
201CbcOrClpParam::operator=(const CbcOrClpParam& rhs)
202{
203  if (this != &rhs) {
204    type_ = rhs.type_;
205    lowerDoubleValue_ = rhs.lowerDoubleValue_;
206    upperDoubleValue_ = rhs.upperDoubleValue_;
207    lowerIntValue_ = rhs.lowerIntValue_;
208    upperIntValue_ = rhs.upperIntValue_;
209    lengthName_ = rhs.lengthName_;
210    lengthMatch_ = rhs.lengthMatch_;
211    definedKeyWords_ = rhs.definedKeyWords_;
212    name_ = rhs.name_;
213    shortHelp_ = rhs.shortHelp_;
214    longHelp_ = rhs.longHelp_;
215    action_ = rhs.action_;
216    currentKeyWord_ = rhs.currentKeyWord_;
217    display_=rhs.display_;
218    intValue_=rhs.intValue_;
219    doubleValue_=rhs.doubleValue_;
220    stringValue_=rhs.stringValue_;
221    whereUsed_=rhs.whereUsed_;
222  }
223  return *this;
224}
225void 
226CbcOrClpParam::gutsOfConstructor()
227{
228  std::string::size_type  shriekPos = name_.find('!');
229  lengthName_ = name_.length();
230  if ( shriekPos==std::string::npos ) {
231    //does not contain '!'
232    lengthMatch_= lengthName_;
233  } else {
234    lengthMatch_=shriekPos;
235    name_ = name_.substr(0,shriekPos)+name_.substr(shriekPos+1);
236    lengthName_--;
237  }
238}
239// Insert string (only valid for keywords)
240void 
241CbcOrClpParam::append(std::string keyWord)
242{
243  definedKeyWords_.push_back(keyWord);
244}
245
246int 
247CbcOrClpParam::matches (std::string input) const
248{
249  // look up strings to do more elegantly
250  if (input.length()>lengthName_) {
251    return 0;
252  } else {
253    unsigned int i;
254    for (i=0;i<input.length();i++) {
255      if (tolower(name_[i])!=tolower(input[i])) 
256        break;
257    }
258    if (i<input.length()) {
259      return 0;
260    } else if (i>=lengthMatch_) {
261      return 1;
262    } else {
263      // matched but too short
264      return 2;
265    }
266  }
267}
268// Returns name which could match
269std::string
270CbcOrClpParam::matchName (  ) const
271{ 
272  if (lengthMatch_==lengthName_) 
273    return name_;
274  else
275    return name_.substr(0,lengthMatch_)+"("+name_.substr(lengthMatch_)+")";
276}
277
278// Returns parameter option which matches (-1 if none)
279int 
280CbcOrClpParam::parameterOption ( std::string check ) const
281{
282  int numberItems = definedKeyWords_.size();
283  if (!numberItems) {
284    return -1;
285  } else {
286    int whichItem=0;
287    unsigned int it;
288    for (it=0;it<definedKeyWords_.size();it++) {
289      std::string thisOne = definedKeyWords_[it];
290      std::string::size_type  shriekPos = thisOne.find('!');
291      unsigned int length1 = thisOne.length();
292      unsigned int length2 = length1;
293      if ( shriekPos!=std::string::npos ) {
294        //contains '!'
295        length2 = shriekPos;
296        thisOne = thisOne.substr(0,shriekPos)+
297          thisOne.substr(shriekPos+1);
298        length1 = thisOne.length();
299      }
300      if (check.length()<=length1&&length2<=check.length()) {
301        unsigned int i;
302        for (i=0;i<check.length();i++) {
303          if (tolower(thisOne[i])!=tolower(check[i])) 
304            break;
305        }
306        if (i<check.length()) {
307          whichItem++;
308        } else if (i>=length2) {
309          break;
310        } 
311      } else {
312        whichItem++;
313      }
314    }
315    if (whichItem<numberItems)
316      return whichItem;
317    else
318      return -1;
319  }
320}
321// Prints parameter options
322void 
323CbcOrClpParam::printOptions (  ) const
324{
325  std::cout<<"<Possible options for "<<name_<<" are:";
326  unsigned int it;
327  for (it=0;it<definedKeyWords_.size();it++) {
328    std::string thisOne = definedKeyWords_[it];
329    std::string::size_type  shriekPos = thisOne.find('!');
330    if ( shriekPos!=std::string::npos ) {
331      //contains '!'
332      thisOne = thisOne.substr(0,shriekPos)+
333        "("+thisOne.substr(shriekPos+1)+")";
334    }
335    std::cout<<" "<<thisOne;
336  }
337  assert (currentKeyWord_>=0&&currentKeyWord_<(int)definedKeyWords_.size());
338  std::string current = definedKeyWords_[currentKeyWord_];
339  std::string::size_type  shriekPos = current.find('!');
340  if ( shriekPos!=std::string::npos ) {
341    //contains '!'
342    current = current.substr(0,shriekPos)+
343      "("+current.substr(shriekPos+1)+")";
344  }
345  std::cout<<";\n\tcurrent  "<<current<<">"<<std::endl;
346}
347// Print action and string
348void 
349CbcOrClpParam::printString() const
350{
351  if (name_=="directory")
352    std::cout<<"Current working directory is "<<stringValue_<<std::endl;
353  else if (name_.substr(0,6)=="printM")
354    std::cout<<"Current value of printMask is "<<stringValue_<<std::endl;
355  else
356    std::cout<<"Current default (if $ as parameter) for "<<name_
357             <<" is "<<stringValue_<<std::endl;
358}
359void CoinReadPrintit(const char * input)
360{
361  int length =strlen(input);
362  char temp[101];
363  int i;
364  int n=0;
365  for (i=0;i<length;i++) {
366    if (input[i]=='\n') {
367      temp[n]='\0';
368      std::cout<<temp<<std::endl;
369      n=0;
370    } else if (n>=65&&input[i]==' ') {
371      temp[n]='\0';
372      std::cout<<temp<<std::endl;
373      n=0;
374    } else if (n||input[i]!=' ') {
375      temp[n++]=input[i];
376    }
377  }
378  if (n) {
379    temp[n]='\0';
380    std::cout<<temp<<std::endl;
381  }
382}
383// Print Long help
384void 
385CbcOrClpParam::printLongHelp() const
386{
387  if (type_>=1&&type_<400) {
388    CoinReadPrintit(longHelp_.c_str());
389    if (type_<SOLVERLOGLEVEL) {
390      printf("<Range of values is %g to %g;\n\tcurrent %g>\n",lowerDoubleValue_,upperDoubleValue_, doubleValue_);
391      assert (upperDoubleValue_>lowerDoubleValue_);
392    } else if (type_<DIRECTION) {
393      printf("<Range of values is %d to %d;\n\tcurrent %d>\n",lowerIntValue_,upperIntValue_,intValue_);
394      assert (upperIntValue_>lowerIntValue_);
395    } else if (type_<DIRECTORY) {
396      printOptions();
397    }
398  }
399}
400#ifdef COIN_HAS_CBC
401int
402CbcOrClpParam::setDoubleParameter (OsiSolverInterface * model,double value) 
403{
404  int returnCode;
405  setDoubleParameterWithMessage(model,value,returnCode);
406  if (doPrinting&&strlen(printArray))
407    std::cout<<printArray<<std::endl;
408  return returnCode;
409}
410// Sets double parameter and returns printable string and error code
411const char * 
412CbcOrClpParam::setDoubleParameterWithMessage ( OsiSolverInterface * model, double  value ,int & returnCode)
413{
414  if (value<lowerDoubleValue_||value>upperDoubleValue_) {
415    sprintf(printArray,"%g was provided for %s - valid range is %g to %g",
416            value,name_.c_str(),lowerDoubleValue_,upperDoubleValue_);
417    std::cout<<value<<" was provided for "<<name_<<
418      " - valid range is "<<lowerDoubleValue_<<" to "<<
419      upperDoubleValue_<<std::endl;
420    returnCode = 1;
421  } else {
422    double oldValue=doubleValue_;
423    doubleValue_=value;
424    switch(type_) {
425    case DUALTOLERANCE:
426      model->getDblParam(OsiDualTolerance,oldValue);
427      model->setDblParam(OsiDualTolerance,value);
428      break;
429    case PRIMALTOLERANCE:
430      model->getDblParam(OsiPrimalTolerance,oldValue);
431      model->setDblParam(OsiPrimalTolerance,value);
432      break;
433    default:
434      break;
435    }
436    sprintf(printArray,"%s was changed from %g to %g",
437            name_.c_str(),oldValue,value);
438    returnCode = 0;
439  }
440  return printArray;
441}
442#endif
443#ifdef COIN_HAS_CLP
444int
445CbcOrClpParam::setDoubleParameter (ClpSimplex * model,double value) 
446{
447  int returnCode;
448  setDoubleParameterWithMessage(model,value,returnCode);
449  if (doPrinting&&strlen(printArray))
450    std::cout<<printArray<<std::endl;
451  return returnCode;
452}
453// Sets int parameter and returns printable string and error code
454const char * 
455CbcOrClpParam::setDoubleParameterWithMessage ( ClpSimplex * model, double value ,int & returnCode)
456{
457  double oldValue = doubleValue_;
458  if (value<lowerDoubleValue_||value>upperDoubleValue_) {
459    sprintf(printArray,"%g was provided for %s - valid range is %g to %g",
460            value,name_.c_str(),lowerDoubleValue_,upperDoubleValue_);
461    returnCode = 1;
462  } else {
463    sprintf(printArray,"%s was changed from %g to %g",
464            name_.c_str(),oldValue,value);
465    returnCode = 0;
466    doubleValue_=value;
467    switch(type_) {
468#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("Diving","Whether to try Diving heuristics",
1571                    "off",DIVING);
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."
1591     ); 
1592  parameters[numberParameters++]=
1593    CbcOrClpParam("doH!euristic","Do heuristics before any preprocessing",
1594                  DOHEURISTIC,3);
1595  parameters[numberParameters-1].setLonghelp
1596    (
1597     "Normally heuristics are done in branch and bound.  It may be useful to do them outside. \
1598Doing this may also set cutoff."
1599     ); 
1600#endif
1601#ifdef COIN_HAS_CLP
1602  parameters[numberParameters++]=
1603    CbcOrClpParam("dualB!ound","Initially algorithm acts as if no \
1604gap between bounds exceeds this value",
1605                  1.0e-20,1.0e12,DUALBOUND);
1606  parameters[numberParameters-1].setLonghelp
1607    (
1608     "The dual algorithm in Clp is a single phase algorithm as opposed to a two phase\
1609 algorithm where you first get feasible then optimal.  If a problem has both upper and\
1610 lower bounds then it is trivial to get dual feasible by setting non basic variables\
1611 to correct bound.  If the gap between the upper and lower bounds of a variable is more\
1612 than the value of dualBound Clp introduces fake bounds so that it can make the problem\
1613 dual feasible.  This has the same effect as a composite objective function in the\
1614 primal algorithm.  Too high a value may mean more iterations, while too low a bound means\
1615 the code may go all the way and then have to increase the bounds.  OSL had a heuristic to\
1616 adjust bounds, maybe we need that here."
1617     );
1618  parameters[numberParameters++]=
1619    CbcOrClpParam("dualize","Solves dual reformulation",
1620                  0,3,DUALIZE,false);
1621  parameters[numberParameters-1].setLonghelp
1622    (
1623     "Don't even think about it."
1624     ); 
1625  parameters[numberParameters++]=
1626    CbcOrClpParam("dualP!ivot","Dual pivot choice algorithm",
1627                  "auto!matic",DUALPIVOT);
1628  parameters[numberParameters-1].append("dant!zig");
1629  parameters[numberParameters-1].append("partial");
1630  parameters[numberParameters-1].append("steep!est");
1631  parameters[numberParameters-1].setLonghelp
1632    (
1633     "Clp can use any pivot selection algorithm which the user codes as long as it\
1634 implements the features in the abstract pivot base class.  The Dantzig method is implemented\
1635 to show a simple method but its use is deprecated.  Steepest is the method of choice and there\
1636 are two variants which keep all weights updated but only scan a subset each iteration.\
1637 Partial switches this on while automatic decides at each iteration based on information\
1638 about the factorization."
1639     ); 
1640  parameters[numberParameters++]=
1641    CbcOrClpParam("dualS!implex","Do dual simplex algorithm",
1642                  DUALSIMPLEX);
1643  parameters[numberParameters-1].setLonghelp
1644    (
1645     "This command solves the current model using the dual steepest edge algorithm.\
1646The time and iterations may be affected by settings such as presolve, scaling, crash\
1647 and also by dual pivot method, fake bound on variables and dual and primal tolerances."
1648     );
1649#endif
1650  parameters[numberParameters++]=
1651    CbcOrClpParam("dualT!olerance","For an optimal solution \
1652no dual infeasibility may exceed this value",
1653                  1.0e-20,1.0e12,DUALTOLERANCE);
1654  parameters[numberParameters-1].setLonghelp
1655    (
1656     "Normally the default tolerance is fine, but you may want to increase it a\
1657 bit if a dual run seems to be having a hard time.  One method which can be faster is \
1658to use a large tolerance e.g. 1.0e-4 and dual and then clean up problem using primal and the \
1659correct tolerance (remembering to switch off presolve for this final short clean up phase)."
1660     ); 
1661#ifdef COIN_HAS_CLP
1662  parameters[numberParameters++]=
1663    CbcOrClpParam("either!Simplex","Do dual or primal simplex algorithm",
1664                  EITHERSIMPLEX);
1665  parameters[numberParameters-1].setLonghelp
1666    (
1667     "This command solves the current model using the dual or primal algorithm,\
1668 based on a dubious analysis of model."
1669     );
1670#endif
1671  parameters[numberParameters++]=
1672    CbcOrClpParam("end","Stops clp execution",
1673                  EXIT);
1674  parameters[numberParameters-1].setLonghelp
1675    (
1676     "This stops execution ; end, exit, quit and stop are synonyms"
1677     ); 
1678  parameters[numberParameters++]=
1679    CbcOrClpParam("error!sAllowed","Whether to allow import errors",
1680                  "off",ERRORSALLOWED,3);
1681  parameters[numberParameters-1].append("on");
1682  parameters[numberParameters-1].setLonghelp
1683    (
1684     "The default is not to use any model which had errors when reading the mps file.\
1685  Setting this to 'on' will allow all errors from which the code can recover\
1686 simply by ignoring the error.  There are some errors from which the code can not recover \
1687e.g. no ENDATA.  This has to be set before import i.e. -errorsAllowed on -import xxxxxx.mps."
1688     );
1689  parameters[numberParameters++]=
1690    CbcOrClpParam("exit","Stops clp execution",
1691                  EXIT);
1692  parameters[numberParameters-1].setLonghelp
1693    (
1694     "This stops the execution of Clp, end, exit, quit and stop are synonyms"
1695     ); 
1696#ifdef COIN_HAS_CBC
1697  parameters[numberParameters++]=
1698    CbcOrClpParam("exp!eriment","Whether to use testing features",
1699                  -1,200,EXPERIMENT,false);
1700  parameters[numberParameters-1].setLonghelp
1701    (
1702     "If >0 then use some dubious scheme (for testing)"
1703     ); 
1704  parameters[numberParameters-1].setIntValue(-1);
1705#endif
1706  parameters[numberParameters++]=
1707    CbcOrClpParam("export","Export model as mps file",
1708                  EXPORT);
1709  parameters[numberParameters-1].setLonghelp
1710    (
1711     "This will write an MPS format file to the given file name.  It will use the default\
1712 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
1713 is initialized to 'default.mps'."
1714     ); 
1715#ifdef COIN_HAS_CBC
1716  parameters[numberParameters++]=
1717    CbcOrClpParam("extra1","Extra integer parameter 1",
1718                  -1,COIN_INT_MAX,EXTRA1,false);
1719  parameters[numberParameters-1].setIntValue(-1);
1720  parameters[numberParameters++]=
1721    CbcOrClpParam("extra2","Extra integer parameter 2",
1722                  -1,COIN_INT_MAX,EXTRA2,false);
1723  parameters[numberParameters-1].setIntValue(-1);
1724  parameters[numberParameters++]=
1725    CbcOrClpParam("extra3","Extra integer parameter 3",
1726                  -1,COIN_INT_MAX,EXTRA3,false);
1727  parameters[numberParameters-1].setIntValue(-1);
1728  parameters[numberParameters++]=
1729    CbcOrClpParam("extra4","Extra integer parameter 4",
1730                  -COIN_INT_MAX,COIN_INT_MAX,EXTRA4,false);
1731  parameters[numberParameters-1].setIntValue(-1);
1732#endif
1733#ifdef COIN_HAS_CLP
1734  parameters[numberParameters++]=
1735    CbcOrClpParam("fakeB!ound","All bounds <= this value - DEBUG",
1736                  1.0,1.0e15,FAKEBOUND,false);
1737#ifdef COIN_HAS_CBC
1738    parameters[numberParameters++]=
1739      CbcOrClpParam("feas!ibilityPump","Whether to try Feasibility Pump",
1740                    "off",FPUMP);
1741    parameters[numberParameters-1].append("on");
1742    parameters[numberParameters-1].append("do");
1743  parameters[numberParameters-1].setLonghelp
1744    (
1745     "This switches on feasibility pump heuristic at root. This is due to Fischetti and Lodi \
1746and uses a sequence of Lps to try and get an integer feasible solution. \
1747Some fine tuning is available by passFeasibilityPump. Do options does heuristic before preprocessing"
1748     ); 
1749  parameters[numberParameters++]=
1750    CbcOrClpParam("fix!OnDj","Try heuristic based on fixing variables with \
1751reduced costs greater than this",
1752                  -1.0e20,1.0e20,DJFIX,false);
1753  parameters[numberParameters-1].setLonghelp
1754    (
1755     "If this is set integer variables with reduced costs greater than this will be fixed \
1756before branch and bound - use with extreme caution!" 
1757     ); 
1758    parameters[numberParameters++]=
1759      CbcOrClpParam("flow!CoverCuts","Whether to use Flow Cover cuts",
1760                    "off",FLOWCUTS);
1761    parameters[numberParameters-1].append("on");
1762    parameters[numberParameters-1].append("root");
1763    parameters[numberParameters-1].append("ifmove");
1764    parameters[numberParameters-1].append("forceOn");
1765    parameters[numberParameters-1].setLonghelp
1766    (
1767     "This switches on flow cover cuts (either at root or in entire tree) \
1768See branchAndCut for information on options."
1769     ); 
1770    parameters[numberParameters++]=
1771      CbcOrClpParam("force!Solution","Whether to use given solution as crash for BAB",
1772                    -1,20000000,USESOLUTION);
1773    parameters[numberParameters-1].setIntValue(-1);
1774    parameters[numberParameters-1].setLonghelp
1775    (
1776     "-1 off.  If 0 then tries to branch to solution given by AMPL or priorities file. \
1777If >0 then also does that many nodes on fixed problem."
1778     ); 
1779#endif
1780  parameters[numberParameters++]=
1781    CbcOrClpParam("gamma!(Delta)","Whether to regularize barrier",
1782                  "off",GAMMA,7,false);
1783  parameters[numberParameters-1].append("on");
1784  parameters[numberParameters-1].append("gamma");
1785  parameters[numberParameters-1].append("delta");
1786  parameters[numberParameters-1].append("onstrong");
1787  parameters[numberParameters-1].append("gammastrong");
1788  parameters[numberParameters-1].append("deltastrong");
1789#endif
1790#ifdef COIN_HAS_CBC
1791  parameters[numberParameters++]=
1792    CbcOrClpParam("gomory!Cuts","Whether to use Gomory cuts",
1793                  "off",GOMORYCUTS);
1794  parameters[numberParameters-1].append("on");
1795  parameters[numberParameters-1].append("root");
1796  parameters[numberParameters-1].append("ifmove");
1797  parameters[numberParameters-1].append("forceOn");
1798  parameters[numberParameters-1].append("forceLongOn");
1799  parameters[numberParameters-1].setLonghelp
1800    (
1801     "The original cuts - beware of imitations!  Having gone out of favor, they are now more \
1802fashionable as LP solvers are more robust and they interact well with other cuts.  They will almost always \
1803give cuts (although in this executable they are limited as to number of variables in cut).  \
1804However the cuts may be dense so it is worth experimenting (Long allows any length). \
1805See branchAndCut for information on options."
1806     ); 
1807  parameters[numberParameters++]=
1808    CbcOrClpParam("greedy!Heuristic","Whether to use a greedy heuristic",
1809                  "off",GREEDY);
1810  parameters[numberParameters-1].append("on");
1811  parameters[numberParameters-1].append("do");
1812  //parameters[numberParameters-1].append("root");
1813  parameters[numberParameters-1].setLonghelp
1814    (
1815     "Switches on a greedy heuristic which will try and obtain a solution.  It may just fix a \
1816percentage of variables and then try a small branch and cut run. \
1817The Do option switches on before preprocessing."
1818     ); 
1819  parameters[numberParameters++]=
1820    CbcOrClpParam("heur!isticsOnOff","Switches most heuristics on or off",
1821                  "off",HEURISTICSTRATEGY);
1822  parameters[numberParameters-1].append("on");
1823  parameters[numberParameters-1].setLonghelp
1824    (
1825     "This can be used to switch on or off all heuristics.  Then you can do \
1826individual ones off or on.  CbcTreeLocal is not included as it dramatically \
1827alters search."
1828     ); 
1829#endif
1830  parameters[numberParameters++]=
1831    CbcOrClpParam("help","Print out version, non-standard options and some help",
1832                  HELP,3);
1833  parameters[numberParameters-1].setLonghelp
1834    (
1835     "This prints out some help to get user started.  If you have printed this then \
1836you should be past that stage:-)"
1837     ); 
1838#ifdef COIN_HAS_CBC
1839  parameters[numberParameters++]=
1840    CbcOrClpParam("hot!StartMaxIts","Maximum iterations on hot start",
1841                  0,COIN_INT_MAX,MAXHOTITS,false);
1842#endif
1843#ifdef COIN_HAS_CLP
1844  parameters[numberParameters++]=
1845    CbcOrClpParam("idiot!Crash","Whether to try idiot crash",
1846                  -1,999999,IDIOT);
1847  parameters[numberParameters-1].setLonghelp
1848    (
1849     "This is a type of 'crash' which works well on some homogeneous problems.\
1850 It works best on problems with unit elements and rhs but will do something to any model.  It should only be\
1851 used before primal.  It can be set to -1 when the code decides for itself whether to use it,\
1852 0 to switch off or n > 0 to do n passes."
1853     ); 
1854#endif
1855  parameters[numberParameters++]=
1856    CbcOrClpParam("import","Import model from mps file",
1857                  IMPORT,3);
1858  parameters[numberParameters-1].setLonghelp
1859    (
1860     "This will read an MPS format file from the given file name.  It will use the default\
1861 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
1862 is initialized to '', i.e. it must be set.  If you have libgz then it can read compressed\
1863 files 'xxxxxxxx.gz'.."
1864     );
1865#ifdef COIN_HAS_CBC
1866  parameters[numberParameters++]=
1867    CbcOrClpParam("inc!rement","A valid solution must be at least this \
1868much better than last integer solution",
1869                  -1.0e20,1.0e20,INCREMENT);
1870  parameters[numberParameters-1].setLonghelp
1871    (
1872     "Whenever a solution is found the bound on solutions is set to solution (in a minimization\
1873sense) plus this.  If it is not set then the code will try and work one out e.g. if \
1874all objective coefficients are multiples of 0.01 and only integer variables have entries in \
1875objective then this can be set to 0.01.  Be careful if you set this negative!"
1876     ); 
1877  parameters[numberParameters++]=
1878    CbcOrClpParam("inf!easibilityWeight","Each integer infeasibility is expected \
1879to cost this much",
1880                  0.0,1.0e20,INFEASIBILITYWEIGHT);
1881  parameters[numberParameters-1].setLonghelp
1882    (
1883     "A primitive way of deciding which node to explore next.  Satisfying each integer infeasibility is \
1884expected to cost this much."
1885     ); 
1886  parameters[numberParameters++]=
1887    CbcOrClpParam("initialS!olve","Solve to continuous",
1888                  SOLVECONTINUOUS);
1889  parameters[numberParameters-1].setLonghelp
1890    (
1891     "This just solves the problem to continuous - without adding any cuts"
1892     ); 
1893  parameters[numberParameters++]=
1894    CbcOrClpParam("integerT!olerance","For an optimal solution \
1895no integer variable may be this away from an integer value",
1896              1.0e-20,0.5,INTEGERTOLERANCE);
1897  parameters[numberParameters-1].setLonghelp
1898    (
1899     "Beware of setting this smaller than the primal tolerance."
1900     ); 
1901#endif
1902#ifdef COIN_HAS_CLP
1903  parameters[numberParameters++]=
1904    CbcOrClpParam("keepN!ames","Whether to keep names from import",
1905                  "on",KEEPNAMES);
1906  parameters[numberParameters-1].append("off");
1907  parameters[numberParameters-1].setLonghelp
1908    (
1909     "It saves space to get rid of names so if you need to you can set this to off.  \
1910This needs to be set before the import of model - so -keepnames off -import xxxxx.mps."
1911     ); 
1912  parameters[numberParameters++]=
1913    CbcOrClpParam("KKT","Whether to use KKT factorization",
1914                  "off",KKT,7,false);
1915  parameters[numberParameters-1].append("on");
1916#endif
1917#ifdef COIN_HAS_CBC
1918  parameters[numberParameters++]=
1919    CbcOrClpParam("knapsack!Cuts","Whether to use Knapsack cuts",
1920                  "off",KNAPSACKCUTS);
1921  parameters[numberParameters-1].append("on");
1922  parameters[numberParameters-1].append("root");
1923  parameters[numberParameters-1].append("ifmove");
1924  parameters[numberParameters-1].append("forceOn");
1925  parameters[numberParameters-1].setLonghelp
1926    (
1927     "This switches on knapsack cuts (either at root or in entire tree) \
1928See branchAndCut for information on options."
1929     ); 
1930  parameters[numberParameters++]=
1931    CbcOrClpParam("lift!AndProjectCuts","Whether to use Lift and Project cuts",
1932                  "off",LANDPCUTS);
1933  parameters[numberParameters-1].append("on");
1934  parameters[numberParameters-1].append("root");
1935  parameters[numberParameters-1].append("ifmove");
1936  parameters[numberParameters-1].append("forceOn");
1937  parameters[numberParameters-1].setLonghelp
1938    (
1939     "Lift and project cuts - may be expensive to compute. \
1940See branchAndCut for information on options."
1941     ); 
1942  parameters[numberParameters++]=
1943    CbcOrClpParam("local!TreeSearch","Whether to use local treesearch",
1944                  "off",LOCALTREE);
1945  parameters[numberParameters-1].append("on");
1946  parameters[numberParameters-1].setLonghelp
1947    (
1948     "This switches on a local search algorithm when a solution is found.  This is from \
1949Fischetti and Lodi and is not really a heuristic although it can be used as one. \
1950When used from Coin solve it has limited functionality.  It is not switched on when \
1951heuristics are switched on."
1952     ); 
1953#endif
1954#ifndef COIN_HAS_CBC
1955  parameters[numberParameters++]=
1956    CbcOrClpParam("log!Level","Level of detail in Solver output",
1957                  -1,63,SOLVERLOGLEVEL);
1958#else
1959  parameters[numberParameters++]=
1960    CbcOrClpParam("log!Level","Level of detail in Coin branch and Cut output",
1961                  -63,63,LOGLEVEL);
1962  parameters[numberParameters-1].setIntValue(1);
1963#endif
1964  parameters[numberParameters-1].setLonghelp
1965    (
1966     "If 0 then there should be no output in normal circumstances.  1 is probably the best\
1967 value for most uses, while 2 and 3 give more information."
1968     ); 
1969  parameters[numberParameters++]=
1970    CbcOrClpParam("max!imize","Set optimization direction to maximize",
1971                  MAXIMIZE,7);
1972  parameters[numberParameters-1].setLonghelp
1973    (
1974     "The default is minimize - use 'maximize' for maximization.\n\
1975You can also use the parameters 'direction maximize'."
1976     ); 
1977#ifdef COIN_HAS_CLP
1978  parameters[numberParameters++]=
1979    CbcOrClpParam("maxF!actor","Maximum number of iterations between \
1980refactorizations",
1981                  1,999999,MAXFACTOR);
1982  parameters[numberParameters-1].setLonghelp
1983    (
1984     "If this is at its initial value of 200 then in this executable clp will guess at a\
1985 value to use.  Otherwise the user can set a value.  The code may decide to re-factorize\
1986 earlier for accuracy."
1987     ); 
1988  parameters[numberParameters++]=
1989    CbcOrClpParam("maxIt!erations","Maximum number of iterations before \
1990stopping",
1991                  0,2147483647,MAXITERATION);
1992  parameters[numberParameters-1].setLonghelp
1993    (
1994     "This can be used for testing purposes.  The corresponding library call\n\
1995      \tsetMaximumIterations(value)\n can be useful.  If the code stops on\
1996 seconds or by an interrupt this will be treated as stopping on maximum iterations"
1997     ); 
1998#endif
1999#ifdef COIN_HAS_CBC
2000  parameters[numberParameters++]=
2001    CbcOrClpParam("maxN!odes","Maximum number of nodes to do",
2002                  -1,2147483647,MAXNODES);
2003  parameters[numberParameters-1].setLonghelp
2004    (
2005     "This is a repeatable way to limit search.  Normally using time is easier \
2006but then the results may not be repeatable."
2007     ); 
2008  parameters[numberParameters++]=
2009    CbcOrClpParam("maxS!olutions","Maximum number of solutions to get",
2010                  1,2147483647,MAXSOLS);
2011  parameters[numberParameters-1].setLonghelp
2012    (
2013     "You may want to stop after (say) two solutions or an hour."
2014     ); 
2015#endif
2016  parameters[numberParameters++]=
2017    CbcOrClpParam("min!imize","Set optimization direction to minimize",
2018                  MINIMIZE,7);
2019  parameters[numberParameters-1].setLonghelp
2020    (
2021     "The default is minimize - use 'maximize' for maximization.\n\
2022This should only be necessary if you have previously set maximization \
2023You can also use the parameters 'direction minimize'."
2024     );
2025#ifdef COIN_HAS_CBC
2026  parameters[numberParameters++]=
2027    CbcOrClpParam("mipO!ptions","Dubious options for mip",
2028                  0,COIN_INT_MAX,MIPOPTIONS,false);
2029  parameters[numberParameters++]=
2030    CbcOrClpParam("more!MipOptions","More dubious options for mip",
2031                  -1,COIN_INT_MAX,MOREMIPOPTIONS,false);
2032  parameters[numberParameters++]=
2033    CbcOrClpParam("mixed!IntegerRoundingCuts","Whether to use Mixed Integer Rounding cuts",
2034                  "off",MIXEDCUTS);
2035  parameters[numberParameters-1].append("on");
2036  parameters[numberParameters-1].append("root");
2037  parameters[numberParameters-1].append("ifmove");
2038  parameters[numberParameters-1].append("forceOn");
2039  parameters[numberParameters-1].setLonghelp
2040    (
2041     "This switches on mixed integer rounding cuts (either at root or in entire tree) \
2042See branchAndCut for information on options."
2043     ); 
2044#endif
2045  parameters[numberParameters++]=
2046    CbcOrClpParam("mess!ages","Controls if Clpnnnn is printed",
2047                  "off",MESSAGES);
2048  parameters[numberParameters-1].append("on");
2049  parameters[numberParameters-1].setLonghelp
2050    ("The default behavior is to put out messages such as:\n\
2051   Clp0005 2261  Objective 109.024 Primal infeas 944413 (758)\n\
2052but this program turns this off to make it look more friendly.  It can be useful\
2053 to turn them back on if you want to be able to 'grep' for particular messages or if\
2054 you intend to override the behavior of a particular message."
2055     );
2056#ifdef COIN_HAS_CBC
2057  parameters[numberParameters++]=
2058    CbcOrClpParam("miniT!ree","Size of fast mini tree",
2059                  0,COIN_INT_MAX,NUMBERMINI,false);
2060  parameters[numberParameters-1].setLonghelp
2061    (
2062     "The idea is that I can do a small tree fast. \
2063This is a first try and will hopefully become more sophisticated."
2064     ); 
2065  parameters[numberParameters++]=
2066    CbcOrClpParam("miplib","Do some of miplib test set",
2067                  MIPLIB,3);
2068#endif
2069#ifdef COIN_HAS_CLP
2070  parameters[numberParameters++]=
2071    CbcOrClpParam("netlib","Solve entire netlib test set",
2072                  NETLIB_EITHER,3);
2073  parameters[numberParameters-1].setLonghelp
2074    (
2075     "This exercises the unit test for clp and then solves the netlib test set using dual or primal.\
2076The user can set options before e.g. clp -presolve off -netlib"
2077     ); 
2078#ifdef REAL_BARRIER
2079  parameters[numberParameters++]=
2080    CbcOrClpParam("netlibB!arrier","Solve entire netlib test set with barrier",
2081                  NETLIB_BARRIER,3);
2082  parameters[numberParameters-1].setLonghelp
2083    (
2084     "This exercises the unit test for clp and then solves the netlib test set using barrier.\
2085The user can set options before e.g. clp -kkt on -netlib"
2086     ); 
2087#endif
2088  parameters[numberParameters++]=
2089    CbcOrClpParam("netlibD!ual","Solve entire netlib test set (dual)",
2090                  NETLIB_DUAL,3);
2091  parameters[numberParameters-1].setLonghelp
2092    (
2093     "This exercises the unit test for clp and then solves the netlib test set using dual.\
2094The user can set options before e.g. clp -presolve off -netlib"
2095     ); 
2096  parameters[numberParameters++]=
2097    CbcOrClpParam("netlibP!rimal","Solve entire netlib test set (primal)",
2098                  NETLIB_PRIMAL,3);
2099  parameters[numberParameters-1].setLonghelp
2100    (
2101     "This exercises the unit test for clp and then solves the netlib test set using primal.\
2102The user can set options before e.g. clp -presolve off -netlibp"
2103     ); 
2104  parameters[numberParameters++]=
2105    CbcOrClpParam("netlibT!une","Solve entire netlib test set with 'best' algorithm",
2106                  NETLIB_TUNE,3);
2107  parameters[numberParameters-1].setLonghelp
2108    (
2109     "This exercises the unit test for clp and then solves the netlib test set using whatever \
2110works best.  I know this is cheating but it also stresses the code better by doing a \
2111mixture of stuff.  The best algorithm was chosen on a Linux ThinkPad using native cholesky \
2112with University of Florida ordering."
2113     ); 
2114  parameters[numberParameters++]=
2115    CbcOrClpParam("network","Tries to make network matrix",
2116                  NETWORK,7,false);
2117  parameters[numberParameters-1].setLonghelp
2118    (
2119     "Clp will go faster if the matrix can be converted to a network.  The matrix\
2120 operations may be a bit faster with more efficient storage, but the main advantage\
2121 comes from using a network factorization.  It will probably not be as fast as a \
2122specialized network code."
2123     ); 
2124#ifdef COIN_HAS_CBC
2125  parameters[numberParameters++]=
2126    CbcOrClpParam("node!Strategy","What strategy to use to select nodes",
2127                  "hybrid",NODESTRATEGY);
2128  parameters[numberParameters-1].append("fewest");
2129  parameters[numberParameters-1].append("depth");
2130  parameters[numberParameters-1].append("upfewest");
2131  parameters[numberParameters-1].append("downfewest");
2132  parameters[numberParameters-1].append("updepth");
2133  parameters[numberParameters-1].append("downdepth");
2134  parameters[numberParameters-1].setLonghelp
2135    (
2136     "Normally before a solution the code will choose node with fewest infeasibilities. \
2137You can choose depth as the criterion.  You can also say if up or down branch must \
2138be done first (the up down choice will carry on after solution). \
2139Default has now been changed to hybrid which is breadth first on small depth nodes then fewest."
2140     ); 
2141  parameters[numberParameters++]=
2142    CbcOrClpParam("numberA!nalyze","Number of analysis iterations",
2143                  -COIN_INT_MAX,COIN_INT_MAX,NUMBERANALYZE,false);
2144  parameters[numberParameters-1].setLonghelp
2145    (
2146     "This says how many iterations to spend at root node analyzing problem. \
2147This is a first try and will hopefully become more sophisticated."
2148     ); 
2149#endif
2150  parameters[numberParameters++]=
2151    CbcOrClpParam("objective!Scale","Scale factor to apply to objective",
2152                  -1.0e20,1.0e20,OBJSCALE,false);
2153  parameters[numberParameters-1].setLonghelp
2154    (
2155     "If the objective function has some very large values, you may wish to scale them\
2156 internally by this amount.  It can also be set by autoscale.  It is applied after scaling"
2157     ); 
2158  parameters[numberParameters-1].setDoubleValue(1.0);
2159#endif
2160#ifdef COIN_HAS_CBC
2161  parameters[numberParameters++]=
2162    CbcOrClpParam("outDup!licates","takes duplicate rows etc out of integer model",
2163                  OUTDUPROWS,7,false);
2164#endif
2165  parameters[numberParameters++]=
2166    CbcOrClpParam("output!Format","Which output format to use",
2167                  1,6,OUTPUTFORMAT);
2168  parameters[numberParameters-1].setLonghelp
2169    (
2170     "Normally export will be done using normal representation for numbers and two values\
2171 per line.  You may want to do just one per line (for grep or suchlike) and you may wish\
2172 to save with absolute accuracy using a coded version of the IEEE value. A value of 2 is normal.\
2173 otherwise odd values gives one value per line, even two.  Values 1,2 give normal format, 3,4\
2174 gives greater precision, while 5,6 give IEEE values.  When used for exporting a basis 1 does not save \
2175values, 2 saves values, 3 with greater accuracy and 4 in IEEE."
2176     );
2177#ifdef COIN_HAS_CBC
2178  parameters[numberParameters++]=
2179    CbcOrClpParam("passC!uts","Number of cut passes at root node",
2180                  -9999999,9999999,CUTPASS);
2181  parameters[numberParameters-1].setLonghelp
2182    (
2183     "The default is 100 passes if less than 500 columns, 100 passes (but \
2184stop if drop small if less than 5000 columns, 20 otherwise"
2185     ); 
2186  parameters[numberParameters++]=
2187    CbcOrClpParam("passF!easibilityPump","How many passes in feasibility pump",
2188                  0,10000,FPUMPITS);
2189  parameters[numberParameters-1].setLonghelp
2190    (
2191     "This fine tunes Feasibility Pump by doing more or fewer passes."
2192     ); 
2193  parameters[numberParameters-1].setIntValue(20);
2194#endif
2195#ifdef COIN_HAS_CLP
2196  parameters[numberParameters++]=
2197    CbcOrClpParam("passP!resolve","How many passes in presolve",
2198                  -200,100,PRESOLVEPASS,false);
2199  parameters[numberParameters-1].setLonghelp
2200    (
2201     "Normally Presolve does 5 passes but you may want to do less to make it\
2202 more lightweight or do more if improvements are still being made.  As Presolve will return\
2203 if nothing is being taken out, you should not normally need to use this fine tuning."
2204     );
2205#endif
2206#ifdef COIN_HAS_CBC
2207  parameters[numberParameters++]=
2208    CbcOrClpParam("passT!reeCuts","Number of cut passes in tree",
2209                  -999999,999999,CUTPASSINTREE);
2210  parameters[numberParameters-1].setLonghelp
2211    (
2212     "The default is one pass"
2213     ); 
2214#endif
2215#ifdef COIN_HAS_CLP
2216  parameters[numberParameters++]=
2217    CbcOrClpParam("pertV!alue","Method of perturbation",
2218                  -5000,102,PERTVALUE,false);
2219  parameters[numberParameters++]=
2220    CbcOrClpParam("perturb!ation","Whether to perturb problem",
2221                  "on",PERTURBATION);
2222  parameters[numberParameters-1].append("off");
2223  parameters[numberParameters-1].setLonghelp
2224    (
2225     "Perturbation helps to stop cycling, but Clp uses other measures for this.\
2226  However large problems and especially ones with unit elements and unit rhs or costs\
2227 benefit from perturbation.  Normally Clp tries to be intelligent, but you can switch this off.\
2228  The Clp library has this off by default.  This program has it on by default."
2229     ); 
2230  parameters[numberParameters++]=
2231    CbcOrClpParam("PFI","Whether to use Product Form of Inverse in simplex",
2232                  "off",PFI,7,false);
2233  parameters[numberParameters-1].append("on");
2234  parameters[numberParameters-1].setLonghelp
2235    (
2236     "By default clp uses Forrest-Tomlin L-U update.  If you are masochistic you can switch it off."
2237     ); 
2238  parameters[numberParameters++]=
2239    CbcOrClpParam("plus!Minus","Tries to make +- 1 matrix",
2240                  PLUSMINUS,7,false);
2241  parameters[numberParameters-1].setLonghelp
2242    (
2243     "Clp will go slightly faster if the matrix can be converted so that the elements are\
2244 not stored and are known to be unit.  The main advantage is memory use.  Clp may automatically\
2245 see if it can convert the problem so you should not need to use this."
2246     ); 
2247  parameters[numberParameters++]=
2248    CbcOrClpParam("pO!ptions","Dubious print options",
2249                  0,COIN_INT_MAX,PRINTOPTIONS,false);
2250  parameters[numberParameters-1].setIntValue(0);
2251  parameters[numberParameters-1].setLonghelp
2252    (
2253     "If this is > 0 then presolve will give more information and branch and cut will give statistics"
2254     ); 
2255  parameters[numberParameters++]=
2256    CbcOrClpParam("preO!pt","Presolve options",
2257                  0,COIN_INT_MAX,PRESOLVEOPTIONS,false);
2258#endif
2259  parameters[numberParameters++]=
2260    CbcOrClpParam("presolve","Whether to presolve problem",
2261                  "on",PRESOLVE);
2262  parameters[numberParameters-1].append("off");
2263  parameters[numberParameters-1].append("more");
2264  parameters[numberParameters-1].append("file");
2265  parameters[numberParameters-1].setLonghelp
2266    (
2267     "Presolve analyzes the model to find such things as redundant equations, equations\
2268 which fix some variables, equations which can be transformed into bounds etc etc.  For the\
2269 initial solve of any problem this is worth doing unless you know that it will have no effect.  \
2270on will normally do 5 passes while using 'more' will do 10.  If the problem is very large you may need \
2271to write the original to file using 'file'."
2272     ); 
2273#ifdef COIN_HAS_CBC
2274  parameters[numberParameters++]=
2275    CbcOrClpParam("preprocess","Whether to use integer preprocessing",
2276                  "off",PREPROCESS);
2277  parameters[numberParameters-1].append("on");
2278  parameters[numberParameters-1].append("save");
2279  parameters[numberParameters-1].append("equal");
2280  parameters[numberParameters-1].append("sos");
2281  parameters[numberParameters-1].append("trysos");
2282  parameters[numberParameters-1].append("equalall");
2283  parameters[numberParameters-1].append("strategy");
2284  parameters[numberParameters-1].append("aggregate");
2285  parameters[numberParameters-1].append("forcesos");
2286  parameters[numberParameters-1].setLonghelp
2287    (
2288     "This tries to reduce size of model in a similar way to presolve and \
2289it also tries to strengthen the model - this can be very useful and is worth trying. \
2290 Save option saves on file presolved.mps.  equal will turn <= cliques into \
2291==.  sos will create sos sets if all 0-1 in sets (well one extra is allowed) \
2292and no overlaps.  trysos is same but allows any number extra.  equalall will turn all \
2293valid inequalities into equalities with integer slacks.  strategy is as \
2294on but uses CbcStrategy."
2295     ); 
2296#endif
2297#ifdef COIN_HAS_CLP
2298  parameters[numberParameters++]=
2299    CbcOrClpParam("preT!olerance","Tolerance to use in presolve",
2300                  1.0e-20,1.0e12,PRESOLVETOLERANCE);
2301  parameters[numberParameters-1].setLonghelp
2302    (
2303     "The default is 1.0e-8 - you may wish to try 1.0e-7 if presolve says the problem is \
2304infeasible and you have awkward numbers and you are sure the problem is really feasible."
2305     ); 
2306  parameters[numberParameters++]=
2307    CbcOrClpParam("primalP!ivot","Primal pivot choice algorithm",
2308                  "auto!matic",PRIMALPIVOT);
2309  parameters[numberParameters-1].append("exa!ct");
2310  parameters[numberParameters-1].append("dant!zig");
2311  parameters[numberParameters-1].append("part!ial");
2312  parameters[numberParameters-1].append("steep!est");
2313  parameters[numberParameters-1].append("change");
2314  parameters[numberParameters-1].append("sprint");
2315  parameters[numberParameters-1].setLonghelp
2316    (
2317     "Clp can use any pivot selection algorithm which the user codes as long as it\
2318 implements the features in the abstract pivot base class.  The Dantzig method is implemented\
2319 to show a simple method but its use is deprecated.  Exact devex is the method of choice and there\
2320 are two variants which keep all weights updated but only scan a subset each iteration.\
2321 Partial switches this on while change initially does dantzig until the factorization\
2322 becomes denser.  This is still a work in progress."
2323     ); 
2324  parameters[numberParameters++]=
2325    CbcOrClpParam("primalS!implex","Do primal simplex algorithm",
2326                  PRIMALSIMPLEX);
2327  parameters[numberParameters-1].setLonghelp
2328    (
2329     "This command solves the current model using the primal algorithm.\
2330  The default is to use exact devex.\
2331 The time and iterations may be affected by settings such as presolve, scaling, crash\
2332 and also by column selection  method, infeasibility weight and dual and primal tolerances."
2333     );
2334#endif
2335  parameters[numberParameters++]=
2336    CbcOrClpParam("primalT!olerance","For an optimal solution \
2337no primal infeasibility may exceed this value",
2338                  1.0e-20,1.0e12,PRIMALTOLERANCE);
2339  parameters[numberParameters-1].setLonghelp
2340    (
2341     "Normally the default tolerance is fine, but you may want to increase it a\
2342 bit if a primal run seems to be having a hard time"
2343     ); 
2344#ifdef COIN_HAS_CLP
2345  parameters[numberParameters++]=
2346    CbcOrClpParam("primalW!eight","Initially algorithm acts as if it \
2347costs this much to be infeasible",
2348                  1.0e-20,1.0e20,PRIMALWEIGHT);
2349  parameters[numberParameters-1].setLonghelp
2350    (
2351     "The primal algorithm in Clp is a single phase algorithm as opposed to a two phase\
2352 algorithm where you first get feasible then optimal.  So Clp is minimizing this weight times\
2353 the sum of primal infeasibilities plus the true objective function (in minimization sense).\
2354  Too high a value may mean more iterations, while too low a bound means\
2355 the code may go all the way and then have to increase the weight in order to get feasible.\
2356  OSL had a heuristic to\
2357 adjust bounds, maybe we need that here."
2358     ); 
2359#endif
2360  parameters[numberParameters++]=
2361    CbcOrClpParam("printi!ngOptions","Print options",
2362                  "normal",INTPRINT,3);
2363  parameters[numberParameters-1].append("integer");
2364  parameters[numberParameters-1].append("special");
2365  parameters[numberParameters-1].append("rows");
2366  parameters[numberParameters-1].append("all");
2367  parameters[numberParameters-1].setLonghelp
2368    (
2369     "This changes the amount and format of printing a solution:\nnormal - nonzero column variables \n\
2370integer - nonzero integer column variables\n\
2371special - in format suitable for OsiRowCutDebugger\n\
2372rows - nonzero column variables and row activities\n\
2373all - all column variables and row activities.\n\
2374\nFor non-integer problems 'integer' and 'special' act like 'normal'.  \
2375Also see printMask for controlling output."
2376     ); 
2377  parameters[numberParameters++]=
2378    CbcOrClpParam("printM!ask","Control printing of solution on a  mask",
2379                  PRINTMASK,3);
2380  parameters[numberParameters-1].setLonghelp
2381    (
2382     "If set then only those names which match mask are printed in a solution. \
2383'?' matches any character and '*' matches any set of characters. \
2384 The default is '' i.e. unset so all variables are printed. \
2385This is only active if model has names."
2386     ); 
2387#ifdef COIN_HAS_CBC
2388  parameters[numberParameters++]=
2389    CbcOrClpParam("prio!rityIn","Import priorities etc from file",
2390                  PRIORITYIN,3);
2391  parameters[numberParameters-1].setLonghelp
2392    (
2393     "This will read a file with priorities from the given file name.  It will use the default\
2394 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
2395 is initialized to '', i.e. it must be set.  This can not read from compressed files. \
2396File is in csv format with allowed headings - name, number, priority, direction, up, down, solution.  Exactly one of\
2397 name and number must be given."
2398     ); 
2399  parameters[numberParameters++]=
2400    CbcOrClpParam("probing!Cuts","Whether to use Probing cuts",
2401                  "off",PROBINGCUTS);
2402  parameters[numberParameters-1].append("on");
2403  parameters[numberParameters-1].append("root");
2404  parameters[numberParameters-1].append("ifmove");
2405  parameters[numberParameters-1].append("forceOn");
2406  parameters[numberParameters-1].append("forceOnBut");
2407  parameters[numberParameters-1].append("forceOnStrong");
2408  parameters[numberParameters-1].append("forceOnButStrong");
2409  parameters[numberParameters-1].append("strongRoot");
2410  parameters[numberParameters-1].setLonghelp
2411    (
2412     "This switches on probing cuts (either at root or in entire tree) \
2413See branchAndCut for information on options. \
2414but strong options do more probing"
2415     ); 
2416  parameters[numberParameters++]=
2417    CbcOrClpParam("pumpT!une","Dubious ideas for feasibility pump",
2418                  0,100000000,FPUMPTUNE);
2419  parameters[numberParameters-1].setLonghelp
2420    (
2421     "This fine tunes Feasibility Pump \n\
2422\t>=1000000 use as accumulate switch\n\
2423\t>=1000 use index+1 as number of large loops\n\
2424\t>=100 use 0.05 objvalue as increment\n\
2425\t>=10 use +0.1 objvalue for cutoff (add)\n\
2426\t1 == fix ints at bounds, 2 fix all integral ints, 3 and continuous at bounds"
2427     ); 
2428  parameters[numberParameters-1].setIntValue(0);
2429#endif
2430  parameters[numberParameters++]=
2431    CbcOrClpParam("quit","Stops clp execution",
2432                  EXIT);
2433  parameters[numberParameters-1].setLonghelp
2434    (
2435     "This stops the execution of Clp, end, exit, quit and stop are synonyms"
2436     ); 
2437#ifdef COIN_HAS_CBC
2438  parameters[numberParameters++]=
2439    CbcOrClpParam("ratio!Gap","Stop when gap between best possible and \
2440best less than this fraction of larger of two",
2441                  0.0,1.0e20,GAPRATIO);
2442  parameters[numberParameters-1].setDoubleValue(0.0);
2443  parameters[numberParameters-1].setLonghelp
2444    (
2445     "If the gap between best solution and best possible solution is less than this fraction \
2446of the objective value at the root node then the search will terminate.  See 'allowableGap' for a \
2447way of using absolute value rather than fraction."
2448     ); 
2449#endif
2450#ifdef COIN_HAS_CLP
2451  parameters[numberParameters++]=
2452    CbcOrClpParam("reallyO!bjectiveScale","Scale factor to apply to objective in place",
2453                  -1.0e20,1.0e20,OBJSCALE2,false);
2454  parameters[numberParameters-1].setLonghelp
2455    (
2456     "You can set this to -1.0 to test maximization or other to stress code"
2457     ); 
2458  parameters[numberParameters-1].setDoubleValue(1.0);
2459  parameters[numberParameters++]=
2460    CbcOrClpParam("reallyS!cale","Scales model in place",
2461                  REALLY_SCALE,7,false);
2462#endif
2463#ifdef COIN_HAS_CBC
2464    parameters[numberParameters++]=
2465      CbcOrClpParam("reduce!AndSplitCuts","Whether to use Reduce-and-Split cuts",
2466              "off",REDSPLITCUTS);
2467    parameters[numberParameters-1].append("on");
2468    parameters[numberParameters-1].append("root");
2469    parameters[numberParameters-1].append("ifmove");
2470    parameters[numberParameters-1].append("forceOn");
2471    parameters[numberParameters-1].setLonghelp
2472    (
2473     "This switches on reduce and split  cuts (either at root or in entire tree) \
2474See branchAndCut for information on options."
2475     ); 
2476  parameters[numberParameters++]=
2477    CbcOrClpParam("residual!CapacityCuts","Whether to use Residual Capacity cuts",
2478                  "off",RESIDCUTS);
2479  parameters[numberParameters-1].append("on");
2480  parameters[numberParameters-1].append("root");
2481  parameters[numberParameters-1].append("ifmove");
2482  parameters[numberParameters-1].append("forceOn");
2483  parameters[numberParameters-1].setLonghelp
2484    (
2485     "Residual capacity cuts. \
2486See branchAndCut for information on options."
2487     ); 
2488#endif
2489#ifdef COIN_HAS_CLP
2490  parameters[numberParameters++]=
2491    CbcOrClpParam("restore!Model","Restore model from binary file",
2492                  RESTORE);
2493  parameters[numberParameters-1].setLonghelp
2494    (
2495     "This reads data save by saveModel from the given file.  It will use the default\
2496 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
2497 is initialized to 'default.prob'."
2498     ); 
2499  parameters[numberParameters++]=
2500    CbcOrClpParam("reverse","Reverses sign of objective",
2501                  REVERSE,7,false);
2502  parameters[numberParameters-1].setLonghelp
2503    (
2504     "Useful for testing if maximization works correctly"
2505     ); 
2506  parameters[numberParameters++]=
2507    CbcOrClpParam("rhs!Scale","Scale factor to apply to rhs and bounds",
2508                  -1.0e20,1.0e20,RHSSCALE,false);
2509  parameters[numberParameters-1].setLonghelp
2510    (
2511     "If the rhs or bounds have some very large meaningful values, you may wish to scale them\
2512 internally by this amount.  It can also be set by autoscale"
2513     ); 
2514  parameters[numberParameters-1].setDoubleValue(1.0);
2515#endif
2516#ifdef COIN_HAS_CBC
2517  parameters[numberParameters++]=
2518      CbcOrClpParam("Rens","Whether to try Relaxation Enforced Neighborhood Search",
2519                    "off",RENS);
2520    parameters[numberParameters-1].append("on");
2521    parameters[numberParameters-1].append("200");
2522    parameters[numberParameters-1].append("1000");
2523  parameters[numberParameters-1].setLonghelp
2524    (
2525     "This switches on Relaxation enforced neighborhood Search. \
2526on just does feasibility pump \
2527200 or 1000 does that many nodes."
2528     ); 
2529  parameters[numberParameters++]=
2530      CbcOrClpParam("Rins","Whether to try Relaxed Induced Neighborhood Search",
2531                    "off",RINS);
2532    parameters[numberParameters-1].append("on");
2533    parameters[numberParameters-1].append("often");
2534  parameters[numberParameters-1].setLonghelp
2535    (
2536     "This switches on Relaxed induced neighborhood Search."
2537     ); 
2538  parameters[numberParameters++]=
2539    CbcOrClpParam("round!ingHeuristic","Whether to use Rounding heuristic",
2540                  "off",ROUNDING);
2541  parameters[numberParameters-1].append("on");
2542  parameters[numberParameters-1].append("do");
2543  parameters[numberParameters-1].setLonghelp
2544    (
2545     "This switches on a simple (but effective) rounding heuristic at each node of tree.  \
2546The Do option switches on before preprocessing."
2547     ); 
2548#endif
2549  parameters[numberParameters++]=
2550    CbcOrClpParam("saveM!odel","Save model to binary file",
2551                  SAVE);
2552  parameters[numberParameters-1].setLonghelp
2553    (
2554     "This will save the problem to the given file name for future use\
2555 by restoreModel.  It will use the default\
2556 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
2557 is initialized to 'default.prob'."
2558     ); 
2559  parameters[numberParameters++]=
2560    CbcOrClpParam("saveS!olution","saves solution to file",
2561                  SAVESOL);
2562  parameters[numberParameters-1].setLonghelp
2563    (
2564     "This will write a binary solution file to the given file name.  It will use the default\
2565 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
2566 is initialized to 'solution.file'.  To read the file use fread(int) twice to pick up number of rows \
2567and columns, then fread(double) to pick up objective value, then pick up row activities, row duals, column \
2568activities and reduced costs - see bottom of CbcOrClpParam.cpp for code that reads or writes file. \
2569If name contains '_fix_read_' then does not write but reads and will fix all variables"
2570     ); 
2571  parameters[numberParameters++]=
2572    CbcOrClpParam("scal!ing","Whether to scale problem",
2573                  "off",SCALING);
2574  parameters[numberParameters-1].append("equi!librium");
2575  parameters[numberParameters-1].append("geo!metric");
2576  parameters[numberParameters-1].append("auto!matic");
2577  parameters[numberParameters-1].setLonghelp
2578    (
2579     "Scaling can help in solving problems which might otherwise fail because of lack of\
2580 accuracy.  It can also reduce the number of iterations.  It is not applied if the range\
2581 of elements is small.  When unscaled it is possible that there may be small primal and/or\
2582 infeasibilities."
2583     ); 
2584  parameters[numberParameters-1].setCurrentOption(3); // say auto
2585#ifndef COIN_HAS_CBC
2586  parameters[numberParameters++]=
2587    CbcOrClpParam("sec!onds","Maximum seconds",
2588                  -1.0,1.0e12,TIMELIMIT);
2589  parameters[numberParameters-1].setLonghelp
2590    (
2591     "After this many seconds clp will act as if maximum iterations had been reached \
2592(if value >=0).  \
2593In this program it is really only useful for testing but the library function\n\
2594      \tsetMaximumSeconds(value)\n can be useful."
2595     );
2596#else
2597  parameters[numberParameters++]=
2598    CbcOrClpParam("sec!onds","maximum seconds",
2599                  -1.0,1.0e12,TIMELIMIT_BAB);
2600  parameters[numberParameters-1].setLonghelp
2601    (
2602     "After this many seconds coin solver will act as if maximum nodes had been reached."
2603     );
2604#endif
2605  parameters[numberParameters++]=
2606    CbcOrClpParam("sleep","for debug",
2607                  DUMMY,7,false);
2608  parameters[numberParameters-1].setLonghelp
2609    (
2610     "If passed to solver fom ampl, then ampl will wait so that you can copy .nl file for debug."
2611     ); 
2612#ifdef COIN_HAS_CLP
2613  parameters[numberParameters++]=
2614    CbcOrClpParam("slp!Value","Number of slp passes before primal",
2615                  -1,50000,SLPVALUE,false);
2616  parameters[numberParameters-1].setLonghelp
2617    (
2618     "If you are solving a quadratic problem using primal then it may be helpful to do some \
2619sequential Lps to get a good approximate solution."
2620     ); 
2621#endif
2622  parameters[numberParameters++]=
2623    CbcOrClpParam("solu!tion","Prints solution to file",
2624                  SOLUTION);
2625  parameters[numberParameters-1].setLonghelp
2626    (
2627     "This will write a primitive solution file to the given file name.  It will use the default\
2628 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
2629 is initialized to 'stdout'.  The amount of output can be varied using printi!ngOptions or printMask."
2630     ); 
2631#ifdef COIN_HAS_CLP
2632#ifdef COIN_HAS_CBC
2633  parameters[numberParameters++]=
2634    CbcOrClpParam("solv!e","Solve problem",
2635                  BAB);
2636  parameters[numberParameters-1].setLonghelp
2637    (
2638     "If there are no integer variables then this just solves LP.  If there are integer variables \
2639this does branch and cut."
2640     ); 
2641  parameters[numberParameters++]=
2642    CbcOrClpParam("sos!Options","Whether to use SOS from AMPL",
2643                  "off",SOS);
2644  parameters[numberParameters-1].append("on");
2645  parameters[numberParameters-1].setCurrentOption("on");
2646  parameters[numberParameters-1].setLonghelp
2647    (
2648     "Normally if AMPL says there are SOS variables they should be used, but sometime sthey should\
2649 be turned off - this does so."
2650     ); 
2651  parameters[numberParameters++]=
2652    CbcOrClpParam("slog!Level","Level of detail in Solver output",
2653                  -1,63,SOLVERLOGLEVEL);
2654  parameters[numberParameters-1].setLonghelp
2655    (
2656     "If 0 then there should be no output in normal circumstances.  1 is probably the best\
2657 value for most uses, while 2 and 3 give more information."
2658     );
2659#else
2660  // allow solve as synonym for dual
2661  parameters[numberParameters++]=
2662    CbcOrClpParam("solv!e","Solve problem using dual simplex",
2663                  BAB);
2664  parameters[numberParameters-1].setLonghelp
2665    (
2666     "Just so can use solve for clp as well as in cbc"
2667     ); 
2668#endif
2669#endif
2670#ifdef COIN_HAS_CLP
2671  parameters[numberParameters++]=
2672    CbcOrClpParam("spars!eFactor","Whether factorization treated as sparse",
2673                  "on",SPARSEFACTOR,7,false);
2674  parameters[numberParameters-1].append("off");
2675  parameters[numberParameters++]=
2676    CbcOrClpParam("special!Options","Dubious options for Simplex - see ClpSimplex.hpp",
2677                  0,COIN_INT_MAX,SPECIALOPTIONS,false);
2678  parameters[numberParameters++]=
2679    CbcOrClpParam("sprint!Crash","Whether to try sprint crash",
2680                  -1,5000000,SPRINT);
2681  parameters[numberParameters-1].setLonghelp
2682    (
2683     "For long and thin problems this program may solve a series of small problems\
2684 created by taking a subset of the columns.  I introduced the idea as 'Sprint' after\
2685 an LP code of that name of the 60's which tried the same tactic (not totally successfully).\
2686  Cplex calls it 'sifting'.  -1 is automatic choice, 0 is off, n is number of passes"
2687     ); 
2688  parameters[numberParameters++]=
2689    CbcOrClpParam("stat!istics","Print some statistics",
2690                  STATISTICS);
2691  parameters[numberParameters-1].setLonghelp
2692    (
2693     "This command prints some statistics for the current model.\
2694 If log level >1 then more is printed.\
2695 These are for presolved model if presolve on (and unscaled)."
2696     );
2697#endif
2698  parameters[numberParameters++]=
2699    CbcOrClpParam("stop","Stops clp execution",
2700                  EXIT);
2701  parameters[numberParameters-1].setLonghelp
2702    (
2703     "This stops the execution of Clp, end, exit, quit and stop are synonyms"
2704     ); 
2705#ifdef COIN_HAS_CBC
2706  parameters[numberParameters++]=
2707    CbcOrClpParam("strengthen","Create strengthened problem",
2708                  STRENGTHEN,3);
2709  parameters[numberParameters-1].setLonghelp
2710    (
2711     "This creates a new problem by applying the root node cuts.  All tight constraints \
2712will be in resulting problem"
2713     ); 
2714  parameters[numberParameters++]=
2715    CbcOrClpParam("strong!Branching","Number of variables to look at in strong branching",
2716                  0,999999,STRONGBRANCHING);
2717  parameters[numberParameters-1].setLonghelp
2718    (
2719     "In order to decide which variable to branch on, the code will choose up to this number \
2720of unsatisfied variables to do mini up and down branches on.  Then the most effective one is chosen. \
2721If a variable is branched on many times then the previous average up and down costs may be used - \
2722see number before trust."
2723     ); 
2724#endif
2725#ifdef COIN_HAS_CLP
2726  parameters[numberParameters++]=
2727    CbcOrClpParam("subs!titution","How long a column to substitute for in presolve",
2728                  0,10000,SUBSTITUTION,false);
2729  parameters[numberParameters-1].setLonghelp
2730    (
2731     "Normally Presolve gets rid of 'free' variables when there are no more than 3 \
2732 variables in column.  If you increase this the number of rows may decrease but number of \
2733 elements may increase."
2734     ); 
2735#endif
2736#ifdef COIN_HAS_CBC
2737  parameters[numberParameters++]=
2738    CbcOrClpParam("testO!si","Test OsiObject stuff",
2739                  -1,COIN_INT_MAX,TESTOSI,false);
2740#endif
2741#ifdef CBC_THREAD
2742  parameters[numberParameters++]=
2743    CbcOrClpParam("thread!s","Number of threads to try and use",
2744                  -100,10000,THREADS,false);
2745  parameters[numberParameters-1].setLonghelp
2746    (
2747     "To use multiple threads, set threads to number wanted.  It may be better \
2748to use one or two more than number of cpus available.  If 100+n then n threads and \
2749threads used in sub-trees, if 200+n use threads for root cuts, 300+n - both."
2750     ); 
2751#endif
2752#ifdef COIN_HAS_CBC
2753  parameters[numberParameters++]=
2754    CbcOrClpParam("tighten!Factor","Tighten bounds using this times largest \
2755activity at continuous solution",
2756                  1.0e-3,1.0e20,TIGHTENFACTOR,false);
2757  parameters[numberParameters-1].setLonghelp
2758    (
2759     "This sleazy trick can help on some problems."
2760     ); 
2761#endif
2762#ifdef COIN_HAS_CLP
2763  parameters[numberParameters++]=
2764    CbcOrClpParam("tightLP","Poor person's preSolve for now",
2765                  TIGHTEN,7,false);
2766#endif
2767#ifdef COIN_HAS_CBC
2768  parameters[numberParameters++]=
2769    CbcOrClpParam("trust!PseudoCosts","Number of branches before we trust pseudocosts",
2770                  -3,2000000,NUMBERBEFORE);
2771  parameters[numberParameters-1].setLonghelp
2772    (
2773     "Using strong branching computes pseudo-costs.  After this many times for a variable we just \
2774trust the pseudo costs and do not do any more strong branching."
2775     ); 
2776#endif
2777#ifdef COIN_HAS_CBC
2778  parameters[numberParameters++]=
2779    CbcOrClpParam("tune!PreProcess","Dubious tuning parameters",
2780                  0,20000000,PROCESSTUNE,false);
2781  parameters[numberParameters-1].setLonghelp
2782    (
2783     "For making equality cliques this is minimumsize.  Also for adding \
2784integer slacks.  May be used for more later \
2785If <1000 that is what it does.  If <1000000 - numberPasses is (value/1000)-1 and tune is tune %1000. \
2786If >= 1000000! - numberPasses is (value/1000000)-1 and tune is tune %1000000.  In this case if tune is now still >=10000 \
2787numberPassesPerInnerLoop is changed from 10 to (tune-10000)-1 and tune becomes tune % 10000!!!!! - happy? - \
2788so to keep normal limit on cliques of 5, do 3 major passes (include presolves) but only doing one tightening pass per major pass - \
2789you would use 3010005 (I think)"
2790     ); 
2791  parameters[numberParameters++]=
2792    CbcOrClpParam("two!MirCuts","Whether to use Two phase Mixed Integer Rounding cuts",
2793                  "off",TWOMIRCUTS);
2794  parameters[numberParameters-1].append("on");
2795  parameters[numberParameters-1].append("root");
2796  parameters[numberParameters-1].append("ifmove");
2797  parameters[numberParameters-1].append("forceOn");
2798  parameters[numberParameters-1].append("forceLongOn");
2799  parameters[numberParameters-1].setLonghelp
2800    (
2801     "This switches on two phase mixed integer rounding  cuts (either at root or in entire tree) \
2802See branchAndCut for information on options."
2803     ); 
2804#endif
2805  parameters[numberParameters++]=
2806    CbcOrClpParam("unitTest","Do unit test",
2807                  UNITTEST,3);
2808  parameters[numberParameters-1].setLonghelp
2809    (
2810     "This exercises the unit test for clp"
2811     ); 
2812  parameters[numberParameters++]=
2813    CbcOrClpParam("userClp","Hand coded Clp stuff",
2814                  USERCLP);
2815  parameters[numberParameters-1].setLonghelp
2816    (
2817     "There are times e.g. when using AMPL interface when you may wish to do something unusual.  \
2818Look for USERCLP in main driver and modify sample code."
2819     ); 
2820#ifdef COIN_HAS_CBC
2821  parameters[numberParameters++]=
2822    CbcOrClpParam("userCbc","Hand coded Cbc stuff",
2823                  USERCBC);
2824  parameters[numberParameters-1].setLonghelp
2825    (
2826     "There are times e.g. when using AMPL interface when you may wish to do something unusual.  \
2827Look for USERCBC in main driver and modify sample code."
2828     ); 
2829#endif
2830  parameters[numberParameters++]=
2831    CbcOrClpParam("vector","Whether to use vector? Form of matrix in simplex",
2832                  "off",VECTOR,7,false);
2833  parameters[numberParameters-1].append("on");
2834  parameters[numberParameters-1].setLonghelp
2835    (
2836     "If this is on and ClpPackedMatrix uses extra column copy in odd format."
2837     ); 
2838  parameters[numberParameters++]=
2839    CbcOrClpParam("verbose","Switches on longer help on single ?",
2840                  0,15,VERBOSE,false);
2841  parameters[numberParameters-1].setLonghelp
2842    (
2843     "Set to 1 to get short help with ? list, 2 to get long help, 3 for both.  (add 4 to just get ampl ones)."
2844     ); 
2845  parameters[numberParameters-1].setIntValue(0);
2846#ifdef COIN_HAS_CBC
2847  parameters[numberParameters++]=
2848    CbcOrClpParam("vub!heuristic","Type of vub heuristic",
2849                  -2,20,VUBTRY,false);
2850  parameters[numberParameters-1].setLonghelp
2851    (
2852     "If set will try and fix some integer variables"
2853     ); 
2854  parameters[numberParameters-1].setIntValue(-1);
2855#endif
2856  assert(numberParameters<CBCMAXPARAMETERS);
2857}
2858// Given a parameter type - returns its number in list
2859int whichParam (CbcOrClpParameterType name, 
2860                int numberParameters, CbcOrClpParam *const parameters)
2861{
2862  int i;
2863  for (i=0;i<numberParameters;i++) {
2864    if (parameters[i].type()==name)
2865      break;
2866  }
2867  assert (i<numberParameters);
2868  return i;
2869}
2870#ifdef COIN_HAS_CLP
2871/* Restore a solution from file.
2872   mode 0 normal, 1 swap rows and columns and primal and dual
2873   if 2 set then also change signs
2874*/
2875void restoreSolution(ClpSimplex * lpSolver,std::string fileName,int mode)
2876{
2877  FILE * fp=fopen(fileName.c_str(),"rb");
2878  if (fp) {
2879    int numberRows=lpSolver->numberRows();
2880    int numberColumns=lpSolver->numberColumns();
2881    int numberRowsFile;
2882    int numberColumnsFile;
2883    double objectiveValue;
2884    fread(&numberRowsFile,sizeof(int),1,fp);
2885    fread(&numberColumnsFile,sizeof(int),1,fp);
2886    fread(&objectiveValue,sizeof(double),1,fp);
2887    double * dualRowSolution = lpSolver->dualRowSolution();
2888    double * primalRowSolution = lpSolver->primalRowSolution();
2889    double * dualColumnSolution = lpSolver->dualColumnSolution();
2890    double * primalColumnSolution = lpSolver->primalColumnSolution();
2891    if (mode) {
2892      // swap
2893      int k=numberRows;
2894      numberRows=numberColumns;
2895      numberColumns=k;
2896      double * temp;
2897      temp = dualRowSolution;
2898      dualRowSolution = primalColumnSolution;
2899      primalColumnSolution=temp;
2900      temp = dualColumnSolution;
2901      dualColumnSolution = primalRowSolution;
2902      primalRowSolution=temp;
2903    }
2904    if (numberRows>numberRowsFile||numberColumns>numberColumnsFile) {
2905      std::cout<<"Mismatch on rows and/or columns - giving up"<<std::endl;
2906    } else {
2907      lpSolver->setObjectiveValue(objectiveValue);
2908      if (numberRows==numberRowsFile&&numberColumns==numberColumnsFile) {
2909        fread(primalRowSolution,sizeof(double),numberRows,fp);
2910        fread(dualRowSolution,sizeof(double),numberRows,fp);
2911        fread(primalColumnSolution,sizeof(double),numberColumns,fp);
2912        fread(dualColumnSolution,sizeof(double),numberColumns,fp);
2913      } else {
2914        std::cout<<"Mismatch on rows and/or columns - truncating"<<std::endl;
2915        double * temp = new double [CoinMax(numberRowsFile,numberColumnsFile)];
2916        fread(temp,sizeof(double),numberRowsFile,fp);
2917 CoinMemcpyN(temp,numberRows,primalRowSolution);
2918        fread(temp,sizeof(double),numberRowsFile,fp);
2919 CoinMemcpyN(temp,numberRows,dualRowSolution);
2920        fread(temp,sizeof(double),numberColumnsFile,fp);
2921 CoinMemcpyN(temp,numberColumns,primalColumnSolution);
2922        fread(temp,sizeof(double),numberColumnsFile,fp);
2923 CoinMemcpyN(temp,numberColumns,dualColumnSolution);
2924        delete [] temp;
2925      }
2926      if (mode==3) {
2927        int i;
2928        for (i=0;i<numberRows;i++) {
2929          primalRowSolution[i] = -primalRowSolution[i];
2930          dualRowSolution[i] = -dualRowSolution[i];
2931        }
2932        for (i=0;i<numberColumns;i++) {
2933          primalColumnSolution[i] = -primalColumnSolution[i];
2934          dualColumnSolution[i] = -dualColumnSolution[i];
2935        }
2936      }
2937    }
2938    fclose(fp);
2939  } else {
2940    std::cout<<"Unable to open file "<<fileName<<std::endl;
2941  }
2942}
2943// Dump a solution to file
2944void saveSolution(const ClpSimplex * lpSolver,std::string fileName)
2945{
2946  if (strstr(fileName.c_str(),"_fix_read_")) {
2947    FILE * fp=fopen(fileName.c_str(),"rb");
2948    if (fp) {
2949      ClpSimplex * solver = const_cast<ClpSimplex *>(lpSolver);
2950      restoreSolution(solver,fileName,0);
2951      // fix all
2952      int logLevel=solver->logLevel();
2953      int iColumn;
2954      int numberColumns=solver->numberColumns();
2955      double * primalColumnSolution = 
2956        solver->primalColumnSolution();
2957      double * columnLower = solver->columnLower();
2958      double * columnUpper = solver->columnUpper();
2959      for (iColumn=0;iColumn<numberColumns;iColumn++) {
2960        double value = primalColumnSolution[iColumn];
2961        if (value>columnUpper[iColumn]) {
2962          if (value >columnUpper[iColumn]+1.0e-6&&logLevel>1)
2963            printf("%d value of %g - bounds %g %g\n",
2964                   iColumn,value,columnLower[iColumn],columnUpper[iColumn]);
2965          value=columnUpper[iColumn];
2966        } else if (value<columnLower[iColumn]) {
2967          if (value <columnLower[iColumn]-1.0e-6&&logLevel>1)
2968            printf("%d value of %g - bounds %g %g\n",
2969                   iColumn,value,columnLower[iColumn],columnUpper[iColumn]);
2970          value=columnLower[iColumn];
2971        }
2972        columnLower[iColumn]=value;
2973        columnUpper[iColumn]=value;
2974      }
2975      return;
2976    }
2977  }
2978  FILE * fp=fopen(fileName.c_str(),"wb");
2979  if (fp) {
2980    int numberRows=lpSolver->numberRows();
2981    int numberColumns=lpSolver->numberColumns();
2982    double objectiveValue = lpSolver->objectiveValue();
2983    fwrite(&numberRows,sizeof(int),1,fp);
2984    fwrite(&numberColumns,sizeof(int),1,fp);
2985    fwrite(&objectiveValue,sizeof(double),1,fp);
2986    double * dualRowSolution = lpSolver->dualRowSolution();
2987    double * primalRowSolution = lpSolver->primalRowSolution();
2988    fwrite(primalRowSolution,sizeof(double),numberRows,fp);
2989    fwrite(dualRowSolution,sizeof(double),numberRows,fp);
2990    double * dualColumnSolution = lpSolver->dualColumnSolution();
2991    double * primalColumnSolution = lpSolver->primalColumnSolution();
2992    fwrite(primalColumnSolution,sizeof(double),numberColumns,fp);
2993    fwrite(dualColumnSolution,sizeof(double),numberColumns,fp);
2994    fclose(fp);
2995  } else {
2996    std::cout<<"Unable to open file "<<fileName<<std::endl;
2997  }
2998}
2999#endif
Note: See TracBrowser for help on using the repository browser.