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

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

allow cpp

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