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

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

many changes to try and improve performance

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