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

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

new parameters

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