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

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

modify some printing

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