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

Last change on this file since 798 was 798, checked in by ladanyi, 14 years ago

finished switch to subversion

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