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

Last change on this file since 1976 was 1976, checked in by forrest, 6 years ago

allow use of plusnnnn or minusnnnn as keyword

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 168.8 KB
Line 
1/* $Id: CbcOrClpParam.cpp 1976 2013-08-17 15:24:16Z forrest $ */
2// Copyright (C) 2002, International Business Machines
3// Corporation and others.  All Rights Reserved.
4// This code is licensed under the terms of the Eclipse Public License (EPL).
5
6#include "CoinPragma.hpp"
7#include "CoinTime.hpp"
8#include "CbcOrClpParam.hpp"
9
10#include <string>
11#include <iostream>
12#include <cassert>
13
14#ifdef COIN_HAS_CBC
15#ifdef COIN_HAS_CLP
16#include "OsiClpSolverInterface.hpp"
17#include "ClpSimplex.hpp"
18#endif
19#include "CbcModel.hpp"
20#endif
21#include "CoinHelperFunctions.hpp"
22#ifdef COIN_HAS_CLP
23#include "ClpSimplex.hpp"
24#include "ClpFactorization.hpp"
25#endif
26#ifdef COIN_HAS_READLINE
27#include <readline/readline.h>
28#include <readline/history.h>
29#endif
30#ifdef COIN_HAS_CBC
31// from CoinSolve
32static char coin_prompt[] = "Coin:";
33#else
34static char coin_prompt[] = "Clp:";
35#endif
36#ifdef CLP_CILK
37#ifndef CBC_THREAD
38#define CBC_THREAD
39#endif
40#endif
41#if defined(COIN_HAS_WSMP) && ! defined(USE_EKKWSSMP)
42#ifndef CBC_THREAD
43#define CBC_THREAD
44#endif
45#endif
46#include "ClpConfig.h"
47#ifdef CLP_HAS_ABC
48#include "AbcCommon.hpp"
49#endif
50static bool doPrinting = true;
51std::string afterEquals = "";
52static char printArray[200];
53void setCbcOrClpPrinting(bool yesNo)
54{
55     doPrinting = yesNo;
56}
57//#############################################################################
58// Constructors / Destructor / Assignment
59//#############################################################################
60
61//-------------------------------------------------------------------
62// Default Constructor
63//-------------------------------------------------------------------
64CbcOrClpParam::CbcOrClpParam ()
65     : type_(CBC_PARAM_NOTUSED_INVALID),
66       lowerDoubleValue_(0.0),
67       upperDoubleValue_(0.0),
68       lowerIntValue_(0),
69       upperIntValue_(0),
70       lengthName_(0),
71       lengthMatch_(0),
72       definedKeyWords_(),
73       name_(),
74       shortHelp_(),
75       longHelp_(),
76       action_(CBC_PARAM_NOTUSED_INVALID),
77       currentKeyWord_(-1),
78       display_(0),
79       intValue_(-1),
80       doubleValue_(-1.0),
81       stringValue_(""),
82       whereUsed_(7),
83       fakeKeyWord_(-1),
84       fakeValue_(0)
85{
86}
87// Other constructors
88CbcOrClpParam::CbcOrClpParam (std::string name, std::string help,
89                              double lower, double upper, CbcOrClpParameterType type,
90                              int display)
91     : type_(type),
92       lowerIntValue_(0),
93       upperIntValue_(0),
94       definedKeyWords_(),
95       name_(name),
96       shortHelp_(help),
97       longHelp_(),
98       action_(type),
99       currentKeyWord_(-1),
100       display_(display),
101       intValue_(-1),
102       doubleValue_(-1.0),
103       stringValue_(""),
104       whereUsed_(7),
105       fakeKeyWord_(-1),
106       fakeValue_(0)
107{
108     lowerDoubleValue_ = lower;
109     upperDoubleValue_ = upper;
110     gutsOfConstructor();
111}
112CbcOrClpParam::CbcOrClpParam (std::string name, std::string help,
113                              int lower, int upper, CbcOrClpParameterType type,
114                              int display)
115     : type_(type),
116       lowerDoubleValue_(0.0),
117       upperDoubleValue_(0.0),
118       definedKeyWords_(),
119       name_(name),
120       shortHelp_(help),
121       longHelp_(),
122       action_(type),
123       currentKeyWord_(-1),
124       display_(display),
125       intValue_(-1),
126       doubleValue_(-1.0),
127       stringValue_(""),
128       whereUsed_(7),
129       fakeKeyWord_(-1),
130       fakeValue_(0)
131{
132     gutsOfConstructor();
133     lowerIntValue_ = lower;
134     upperIntValue_ = upper;
135}
136// Other strings will be added by append
137CbcOrClpParam::CbcOrClpParam (std::string name, std::string help,
138                              std::string firstValue,
139                              CbcOrClpParameterType type, int whereUsed,
140                              int display)
141     : type_(type),
142       lowerDoubleValue_(0.0),
143       upperDoubleValue_(0.0),
144       lowerIntValue_(0),
145       upperIntValue_(0),
146       definedKeyWords_(),
147       name_(name),
148       shortHelp_(help),
149       longHelp_(),
150       action_(type),
151       currentKeyWord_(0),
152       display_(display),
153       intValue_(-1),
154       doubleValue_(-1.0),
155       stringValue_(""),
156       whereUsed_(whereUsed),
157       fakeKeyWord_(-1),
158       fakeValue_(0)
159{
160     gutsOfConstructor();
161     definedKeyWords_.push_back(firstValue);
162}
163// Action
164CbcOrClpParam::CbcOrClpParam (std::string name, std::string help,
165                              CbcOrClpParameterType type, int whereUsed,
166                              int display)
167     : type_(type),
168       lowerDoubleValue_(0.0),
169       upperDoubleValue_(0.0),
170       lowerIntValue_(0),
171       upperIntValue_(0),
172       definedKeyWords_(),
173       name_(name),
174       shortHelp_(help),
175       longHelp_(),
176       action_(type),
177       currentKeyWord_(-1),
178       display_(display),
179       intValue_(-1),
180       doubleValue_(-1.0),
181       stringValue_(""),
182       fakeKeyWord_(-1),
183       fakeValue_(0)
184{
185     whereUsed_ = whereUsed;
186     gutsOfConstructor();
187}
188
189//-------------------------------------------------------------------
190// Copy constructor
191//-------------------------------------------------------------------
192CbcOrClpParam::CbcOrClpParam (const CbcOrClpParam & rhs)
193{
194     type_ = rhs.type_;
195     lowerDoubleValue_ = rhs.lowerDoubleValue_;
196     upperDoubleValue_ = rhs.upperDoubleValue_;
197     lowerIntValue_ = rhs.lowerIntValue_;
198     upperIntValue_ = rhs.upperIntValue_;
199     lengthName_ = rhs.lengthName_;
200     lengthMatch_ = rhs.lengthMatch_;
201     definedKeyWords_ = rhs.definedKeyWords_;
202     name_ = rhs.name_;
203     shortHelp_ = rhs.shortHelp_;
204     longHelp_ = rhs.longHelp_;
205     action_ = rhs.action_;
206     currentKeyWord_ = rhs.currentKeyWord_;
207     display_ = rhs.display_;
208     intValue_ = rhs.intValue_;
209     doubleValue_ = rhs.doubleValue_;
210     stringValue_ = rhs.stringValue_;
211     whereUsed_ = rhs.whereUsed_;
212     fakeKeyWord_ = rhs.fakeKeyWord_;
213     fakeValue_ = rhs.fakeValue_;
214}
215
216//-------------------------------------------------------------------
217// Destructor
218//-------------------------------------------------------------------
219CbcOrClpParam::~CbcOrClpParam ()
220{
221}
222
223//----------------------------------------------------------------
224// Assignment operator
225//-------------------------------------------------------------------
226CbcOrClpParam &
227CbcOrClpParam::operator=(const CbcOrClpParam & rhs)
228{
229     if (this != &rhs) {
230          type_ = rhs.type_;
231          lowerDoubleValue_ = rhs.lowerDoubleValue_;
232          upperDoubleValue_ = rhs.upperDoubleValue_;
233          lowerIntValue_ = rhs.lowerIntValue_;
234          upperIntValue_ = rhs.upperIntValue_;
235          lengthName_ = rhs.lengthName_;
236          lengthMatch_ = rhs.lengthMatch_;
237          definedKeyWords_ = rhs.definedKeyWords_;
238          name_ = rhs.name_;
239          shortHelp_ = rhs.shortHelp_;
240          longHelp_ = rhs.longHelp_;
241          action_ = rhs.action_;
242          currentKeyWord_ = rhs.currentKeyWord_;
243          display_ = rhs.display_;
244          intValue_ = rhs.intValue_;
245          doubleValue_ = rhs.doubleValue_;
246          stringValue_ = rhs.stringValue_;
247          whereUsed_ = rhs.whereUsed_;
248          fakeKeyWord_ = rhs.fakeKeyWord_;
249          fakeValue_ = rhs.fakeValue_;
250     }
251     return *this;
252}
253void
254CbcOrClpParam::gutsOfConstructor()
255{
256     std::string::size_type  shriekPos = name_.find('!');
257     lengthName_ = static_cast<unsigned int>(name_.length());
258     if ( shriekPos == std::string::npos ) {
259          //does not contain '!'
260          lengthMatch_ = lengthName_;
261     } else {
262          lengthMatch_ = static_cast<unsigned int>(shriekPos);
263          name_ = name_.substr(0, shriekPos) + name_.substr(shriekPos + 1);
264          lengthName_--;
265     }
266}
267// Sets value of fake keyword to current size of keywords
268void 
269CbcOrClpParam::setFakeKeyWord(int fakeValue)
270{
271  fakeKeyWord_ = static_cast<int>(definedKeyWords_.size());
272  assert (fakeKeyWord_>0);
273  fakeValue_ = fakeValue;
274  assert (fakeValue_>=0);
275}
276/* Returns current parameter option position
277   but if fake keyword returns fakeValue_
278*/
279int 
280CbcOrClpParam::currentOptionAsInteger (  ) const
281{
282  int fakeInteger;
283  return currentOptionAsInteger(fakeInteger);
284}
285/* Returns current parameter option position
286   but if fake keyword returns fakeValue_ and sets
287   fakeInteger to value
288*/
289int 
290CbcOrClpParam::currentOptionAsInteger ( int & fakeInteger ) const
291{
292  fakeInteger=-COIN_INT_MAX;
293  if (fakeKeyWord_<0) {
294    return currentKeyWord_;
295  } else if (currentKeyWord_>=0&&currentKeyWord_<fakeKeyWord_){
296    return currentKeyWord_;
297  } else {
298    // fake
299    if (currentKeyWord_<0)
300      fakeInteger = currentKeyWord_ + 1000;
301    else
302      fakeInteger = currentKeyWord_ - 1000;
303    return fakeValue_;
304  }
305}
306// Returns length of name for printing
307int
308CbcOrClpParam::lengthMatchName (  ) const
309{
310     if (lengthName_ == lengthMatch_)
311          return lengthName_;
312     else
313          return lengthName_ + 2;
314}
315// Insert string (only valid for keywords)
316void
317CbcOrClpParam::append(std::string keyWord)
318{
319     definedKeyWords_.push_back(keyWord);
320}
321
322int
323CbcOrClpParam::matches (std::string input) const
324{
325     // look up strings to do more elegantly
326     if (input.length() > lengthName_) {
327          return 0;
328     } else {
329          unsigned int i;
330          for (i = 0; i < input.length(); i++) {
331               if (tolower(name_[i]) != tolower(input[i]))
332                    break;
333          }
334          if (i < input.length()) {
335               return 0;
336          } else if (i >= lengthMatch_) {
337               return 1;
338          } else {
339               // matched but too short
340               return 2;
341          }
342     }
343}
344// Returns name which could match
345std::string
346CbcOrClpParam::matchName (  ) const
347{
348     if (lengthMatch_ == lengthName_)
349          return name_;
350     else
351          return name_.substr(0, lengthMatch_) + "(" + name_.substr(lengthMatch_) + ")";
352}
353
354// Returns parameter option which matches (-1 if none)
355int
356CbcOrClpParam::parameterOption ( std::string check ) const
357{
358     int numberItems = static_cast<int>(definedKeyWords_.size());
359     if (!numberItems) {
360          return -1;
361     } else {
362          int whichItem = 0;
363          unsigned int it;
364          for (it = 0; it < definedKeyWords_.size(); it++) {
365               std::string thisOne = definedKeyWords_[it];
366               std::string::size_type  shriekPos = thisOne.find('!');
367               size_t length1 = thisOne.length();
368               size_t length2 = length1;
369               if ( shriekPos != std::string::npos ) {
370                    //contains '!'
371                    length2 = shriekPos;
372                    thisOne = thisOne.substr(0, shriekPos) +
373                              thisOne.substr(shriekPos + 1);
374                    length1 = thisOne.length();
375               }
376               if (check.length() <= length1 && length2 <= check.length()) {
377                    unsigned int i;
378                    for (i = 0; i < check.length(); i++) {
379                         if (tolower(thisOne[i]) != tolower(check[i]))
380                              break;
381                    }
382                    if (i < check.length()) {
383                         whichItem++;
384                    } else if (i >= length2) {
385                         break;
386                    }
387               } else {
388                    whichItem++;
389               }
390          }
391          if (whichItem < numberItems) {
392               return whichItem;
393          } else {
394            if (fakeKeyWord_<=0)
395              return -1;
396            // allow plus or minus
397            int n;
398            if (check.substr(0,4)=="plus"||check.substr(0,4)=="PLUS") {
399              n = 4;
400            } else if (check.substr(0,5)=="minus"||check.substr(0,5)=="MINUS") {
401              n = 5;
402            } else {
403              return -1;
404            }
405            int value = 0;
406            std::string field=check.substr(n);
407            if (field != "EOL") {
408              const char * start = field.c_str();
409              char * endPointer = NULL;
410              // check valid
411              value =  static_cast<int>(strtol(start, &endPointer, 10));
412              if (*endPointer != '\0') {
413                return -1;
414              }
415              if (n==4) 
416                return value + 1000;
417              else
418                return -value - 1000;
419            } else {
420              return -1;
421            }
422          }
423     }
424}
425// Prints parameter options
426void
427CbcOrClpParam::printOptions (  ) const
428{
429     std::cout << "<Possible options for " << name_ << " are:";
430     unsigned int it;
431     for (it = 0; it < definedKeyWords_.size(); it++) {
432          std::string thisOne = definedKeyWords_[it];
433          std::string::size_type  shriekPos = thisOne.find('!');
434          if ( shriekPos != std::string::npos ) {
435               //contains '!'
436               thisOne = thisOne.substr(0, shriekPos) +
437                         "(" + thisOne.substr(shriekPos + 1) + ")";
438          }
439          std::cout << " " << thisOne;
440     }
441     assert (currentKeyWord_ >= 0 && currentKeyWord_ < static_cast<int>(definedKeyWords_.size()));
442     std::string current = definedKeyWords_[currentKeyWord_];
443     std::string::size_type  shriekPos = current.find('!');
444     if ( shriekPos != std::string::npos ) {
445          //contains '!'
446          current = current.substr(0, shriekPos) +
447                    "(" + current.substr(shriekPos + 1) + ")";
448     }
449     std::cout << ";\n\tcurrent  " << current << ">" << std::endl;
450}
451// Print action and string
452void
453CbcOrClpParam::printString() const
454{
455     if (name_ == "directory")
456          std::cout << "Current working directory is " << stringValue_ << std::endl;
457     else if (name_.substr(0, 6) == "printM")
458          std::cout << "Current value of printMask is " << stringValue_ << std::endl;
459     else
460          std::cout << "Current default (if $ as parameter) for " << name_
461                    << " is " << stringValue_ << std::endl;
462}
463void CoinReadPrintit(const char * input)
464{
465     int length = static_cast<int>(strlen(input));
466     char temp[101];
467     int i;
468     int n = 0;
469     for (i = 0; i < length; i++) {
470          if (input[i] == '\n') {
471               temp[n] = '\0';
472               std::cout << temp << std::endl;
473               n = 0;
474          } else if (n >= 65 && input[i] == ' ') {
475               temp[n] = '\0';
476               std::cout << temp << std::endl;
477               n = 0;
478          } else if (n || input[i] != ' ') {
479               temp[n++] = input[i];
480          }
481     }
482     if (n) {
483          temp[n] = '\0';
484          std::cout << temp << std::endl;
485     }
486}
487// Print Long help
488void
489CbcOrClpParam::printLongHelp() const
490{
491     if (type_ >= 1 && type_ < 400) {
492          CoinReadPrintit(longHelp_.c_str());
493          if (type_ < CLP_PARAM_INT_SOLVERLOGLEVEL) {
494               printf("<Range of values is %g to %g;\n\tcurrent %g>\n", lowerDoubleValue_, upperDoubleValue_, doubleValue_);
495               assert (upperDoubleValue_ > lowerDoubleValue_);
496          } else if (type_ < CLP_PARAM_STR_DIRECTION) {
497               printf("<Range of values is %d to %d;\n\tcurrent %d>\n", lowerIntValue_, upperIntValue_, intValue_);
498               assert (upperIntValue_ > lowerIntValue_);
499          } else if (type_ < CLP_PARAM_ACTION_DIRECTORY) {
500               printOptions();
501          }
502     }
503}
504#ifdef COIN_HAS_CBC
505int
506CbcOrClpParam::setDoubleParameter (OsiSolverInterface * model, double value)
507{
508     int returnCode;
509     setDoubleParameterWithMessage(model, value, returnCode);
510     if (doPrinting && strlen(printArray))
511          std::cout << printArray << std::endl;
512     return returnCode;
513}
514// Sets double parameter and returns printable string and error code
515const char *
516CbcOrClpParam::setDoubleParameterWithMessage ( OsiSolverInterface * model, double  value , int & returnCode)
517{
518     if (value < lowerDoubleValue_ || value > upperDoubleValue_) {
519          sprintf(printArray, "%g was provided for %s - valid range is %g to %g",
520                  value, name_.c_str(), lowerDoubleValue_, upperDoubleValue_);
521          std::cout << value << " was provided for " << name_ <<
522                    " - valid range is " << lowerDoubleValue_ << " to " <<
523                    upperDoubleValue_ << std::endl;
524          returnCode = 1;
525     } else {
526          double oldValue = doubleValue_;
527          doubleValue_ = value;
528          switch (type_) {
529          case CLP_PARAM_DBL_DUALTOLERANCE:
530               model->getDblParam(OsiDualTolerance, oldValue);
531               model->setDblParam(OsiDualTolerance, value);
532               break;
533          case CLP_PARAM_DBL_PRIMALTOLERANCE:
534               model->getDblParam(OsiPrimalTolerance, oldValue);
535               model->setDblParam(OsiPrimalTolerance, value);
536               break;
537          default:
538               break;
539          }
540          sprintf(printArray, "%s was changed from %g to %g",
541                  name_.c_str(), oldValue, value);
542          returnCode = 0;
543     }
544     return printArray;
545}
546#endif
547#ifdef COIN_HAS_CLP
548int
549CbcOrClpParam::setDoubleParameter (ClpSimplex * model, double value)
550{
551     int returnCode;
552     setDoubleParameterWithMessage(model, value, returnCode);
553     if (doPrinting && strlen(printArray))
554          std::cout << printArray << std::endl;
555     return returnCode;
556}
557// Sets int parameter and returns printable string and error code
558const char *
559CbcOrClpParam::setDoubleParameterWithMessage ( ClpSimplex * model, double value , int & returnCode)
560{
561     double oldValue = doubleValue_;
562     if (value < lowerDoubleValue_ || value > upperDoubleValue_) {
563          sprintf(printArray, "%g was provided for %s - valid range is %g to %g",
564                  value, name_.c_str(), lowerDoubleValue_, upperDoubleValue_);
565          returnCode = 1;
566     } else {
567          sprintf(printArray, "%s was changed from %g to %g",
568                  name_.c_str(), oldValue, value);
569          returnCode = 0;
570          doubleValue_ = value;
571          switch (type_) {
572          case CLP_PARAM_DBL_DUALTOLERANCE:
573               model->setDualTolerance(value);
574               break;
575          case CLP_PARAM_DBL_PRIMALTOLERANCE:
576               model->setPrimalTolerance(value);
577               break;
578          case CLP_PARAM_DBL_ZEROTOLERANCE:
579               model->setSmallElementValue(value);
580               break;
581          case CLP_PARAM_DBL_DUALBOUND:
582               model->setDualBound(value);
583               break;
584          case CLP_PARAM_DBL_PRIMALWEIGHT:
585               model->setInfeasibilityCost(value);
586               break;
587#ifndef COIN_HAS_CBC
588          case CLP_PARAM_DBL_TIMELIMIT:
589               model->setMaximumSeconds(value);
590               break;
591#endif
592          case CLP_PARAM_DBL_OBJSCALE:
593               model->setObjectiveScale(value);
594               break;
595          case CLP_PARAM_DBL_RHSSCALE:
596               model->setRhsScale(value);
597               break;
598          case CLP_PARAM_DBL_PRESOLVETOLERANCE:
599               model->setDblParam(ClpPresolveTolerance, value);
600               break;
601          default:
602               break;
603          }
604     }
605     return printArray;
606}
607double
608CbcOrClpParam::doubleParameter (ClpSimplex * model) const
609{
610     double value;
611     switch (type_) {
612#ifndef COIN_HAS_CBC
613     case CLP_PARAM_DBL_DUALTOLERANCE:
614          value = model->dualTolerance();
615          break;
616     case CLP_PARAM_DBL_PRIMALTOLERANCE:
617          value = model->primalTolerance();
618          break;
619#endif
620     case CLP_PARAM_DBL_ZEROTOLERANCE:
621          value = model->getSmallElementValue();
622          break;
623     case CLP_PARAM_DBL_DUALBOUND:
624          value = model->dualBound();
625          break;
626     case CLP_PARAM_DBL_PRIMALWEIGHT:
627          value = model->infeasibilityCost();
628          break;
629#ifndef COIN_HAS_CBC
630     case CLP_PARAM_DBL_TIMELIMIT:
631          value = model->maximumSeconds();
632          break;
633#endif
634     case CLP_PARAM_DBL_OBJSCALE:
635          value = model->objectiveScale();
636          break;
637     case CLP_PARAM_DBL_RHSSCALE:
638          value = model->rhsScale();
639          break;
640     default:
641          value = doubleValue_;
642          break;
643     }
644     return value;
645}
646int
647CbcOrClpParam::setIntParameter (ClpSimplex * model, int value)
648{
649     int returnCode;
650     setIntParameterWithMessage(model, value, returnCode);
651     if (doPrinting && strlen(printArray))
652          std::cout << printArray << std::endl;
653     return returnCode;
654}
655// Sets int parameter and returns printable string and error code
656const char *
657CbcOrClpParam::setIntParameterWithMessage ( ClpSimplex * model, int value , int & returnCode)
658{
659     int oldValue = intValue_;
660     if (value < lowerIntValue_ || value > upperIntValue_) {
661          sprintf(printArray, "%d was provided for %s - valid range is %d to %d",
662                  value, name_.c_str(), lowerIntValue_, upperIntValue_);
663          returnCode = 1;
664     } else {
665          intValue_ = value;
666          sprintf(printArray, "%s was changed from %d to %d",
667                  name_.c_str(), oldValue, value);
668          returnCode = 0;
669          switch (type_) {
670          case CLP_PARAM_INT_SOLVERLOGLEVEL:
671               model->setLogLevel(value);
672               if (value > 2)
673                    model->factorization()->messageLevel(8);
674               else
675                    model->factorization()->messageLevel(0);
676               break;
677          case CLP_PARAM_INT_MAXFACTOR:
678               model->factorization()->maximumPivots(value);
679               break;
680          case CLP_PARAM_INT_PERTVALUE:
681               model->setPerturbation(value);
682               break;
683          case CLP_PARAM_INT_MAXITERATION:
684               model->setMaximumIterations(value);
685               break;
686          case CLP_PARAM_INT_SPECIALOPTIONS:
687               model->setSpecialOptions(value);
688               break;
689          case CLP_PARAM_INT_RANDOMSEED:
690            {
691              if (value==0) {
692                double time = fabs(CoinGetTimeOfDay());
693                while (time>=COIN_INT_MAX)
694                  time *= 0.5;
695                value = static_cast<int>(time);
696                sprintf(printArray, "using time of day %s was changed from %d to %d",
697                  name_.c_str(), oldValue, value);
698              }
699              model->setRandomSeed(value);
700            }
701               break;
702          case CLP_PARAM_INT_MORESPECIALOPTIONS:
703               model->setMoreSpecialOptions(value);
704               break;
705#ifndef COIN_HAS_CBC
706#ifdef CBC_THREAD
707          case CBC_PARAM_INT_THREADS:
708               model->setNumberThreads(value);
709               break;
710#endif
711#endif
712          default:
713               break;
714          }
715     }
716     return printArray;
717}
718int
719CbcOrClpParam::intParameter (ClpSimplex * model) const
720{
721     int value;
722     switch (type_) {
723#ifndef COIN_HAS_CBC
724     case CLP_PARAM_INT_SOLVERLOGLEVEL:
725          value = model->logLevel();
726          break;
727#endif
728     case CLP_PARAM_INT_MAXFACTOR:
729          value = model->factorization()->maximumPivots();
730          break;
731          break;
732     case CLP_PARAM_INT_PERTVALUE:
733          value = model->perturbation();
734          break;
735     case CLP_PARAM_INT_MAXITERATION:
736          value = model->maximumIterations();
737          break;
738     case CLP_PARAM_INT_SPECIALOPTIONS:
739          value = model->specialOptions();
740          break;
741     case CLP_PARAM_INT_RANDOMSEED:
742          value = model->randomNumberGenerator()->getSeed();
743          break;
744     case CLP_PARAM_INT_MORESPECIALOPTIONS:
745          value = model->moreSpecialOptions();
746          break;
747#ifndef COIN_HAS_CBC
748#ifdef CBC_THREAD
749     case CBC_PARAM_INT_THREADS:
750          value = model->numberThreads();
751          break;
752#endif
753#endif
754     default:
755          value = intValue_;
756          break;
757     }
758     return value;
759}
760#endif
761int
762CbcOrClpParam::checkDoubleParameter (double value) const
763{
764     if (value < lowerDoubleValue_ || value > upperDoubleValue_) {
765          std::cout << value << " was provided for " << name_ <<
766                    " - valid range is " << lowerDoubleValue_ << " to " <<
767                    upperDoubleValue_ << std::endl;
768          return 1;
769     } else {
770          return 0;
771     }
772}
773#ifdef COIN_HAS_CBC
774double
775CbcOrClpParam::doubleParameter (OsiSolverInterface *
776#ifndef NDEBUG
777                                model
778#endif
779                               ) const
780{
781     double value = 0.0;
782     switch (type_) {
783     case CLP_PARAM_DBL_DUALTOLERANCE:
784          assert(model->getDblParam(OsiDualTolerance, value));
785          break;
786     case CLP_PARAM_DBL_PRIMALTOLERANCE:
787          assert(model->getDblParam(OsiPrimalTolerance, value));
788          break;
789     default:
790          return doubleValue_;
791          break;
792     }
793     return value;
794}
795int
796CbcOrClpParam::setIntParameter (OsiSolverInterface * model, int value)
797{
798     int returnCode;
799     setIntParameterWithMessage(model, value, returnCode);
800     if (doPrinting && strlen(printArray))
801          std::cout << printArray << std::endl;
802     return returnCode;
803}
804// Sets int parameter and returns printable string and error code
805const char *
806CbcOrClpParam::setIntParameterWithMessage ( OsiSolverInterface * model, int  value , int & returnCode)
807{
808     if (value < lowerIntValue_ || value > upperIntValue_) {
809          sprintf(printArray, "%d was provided for %s - valid range is %d to %d",
810                  value, name_.c_str(), lowerIntValue_, upperIntValue_);
811          returnCode = 1;
812     } else {
813          int oldValue = intValue_;
814          intValue_ = oldValue;
815          switch (type_) {
816          case CLP_PARAM_INT_SOLVERLOGLEVEL:
817               model->messageHandler()->setLogLevel(value);
818               break;
819          default:
820               break;
821          }
822          sprintf(printArray, "%s was changed from %d to %d",
823                  name_.c_str(), oldValue, value);
824          returnCode = 0;
825     }
826     return printArray;
827}
828int
829CbcOrClpParam::intParameter (OsiSolverInterface * model) const
830{
831     int value = 0;
832     switch (type_) {
833     case CLP_PARAM_INT_SOLVERLOGLEVEL:
834          value = model->messageHandler()->logLevel();
835          break;
836     default:
837          value = intValue_;
838          break;
839     }
840     return value;
841}
842int
843CbcOrClpParam::setDoubleParameter (CbcModel &model, double value)
844{
845     int returnCode;
846     setDoubleParameterWithMessage(model, value, returnCode);
847     if (doPrinting && strlen(printArray))
848          std::cout << printArray << std::endl;
849     return returnCode;
850}
851// Sets double parameter and returns printable string and error code
852const char *
853CbcOrClpParam::setDoubleParameterWithMessage ( CbcModel & model, double  value , int & returnCode)
854{
855     if (value < lowerDoubleValue_ || value > upperDoubleValue_) {
856          sprintf(printArray, "%g was provided for %s - valid range is %g to %g",
857                  value, name_.c_str(), lowerDoubleValue_, upperDoubleValue_);
858          returnCode = 1;
859     } else {
860          double oldValue = doubleValue_;
861          doubleValue_ = value;
862          switch (type_) {
863          case CBC_PARAM_DBL_INFEASIBILITYWEIGHT:
864               oldValue = model.getDblParam(CbcModel::CbcInfeasibilityWeight);
865               model.setDblParam(CbcModel::CbcInfeasibilityWeight, value);
866               break;
867          case CBC_PARAM_DBL_INTEGERTOLERANCE:
868               oldValue = model.getDblParam(CbcModel::CbcIntegerTolerance);
869               model.setDblParam(CbcModel::CbcIntegerTolerance, value);
870               break;
871          case CBC_PARAM_DBL_INCREMENT:
872               oldValue = model.getDblParam(CbcModel::CbcCutoffIncrement);
873               model.setDblParam(CbcModel::CbcCutoffIncrement, value);
874          case CBC_PARAM_DBL_ALLOWABLEGAP:
875               oldValue = model.getDblParam(CbcModel::CbcAllowableGap);
876               model.setDblParam(CbcModel::CbcAllowableGap, value);
877               break;
878          case CBC_PARAM_DBL_GAPRATIO:
879               oldValue = model.getDblParam(CbcModel::CbcAllowableFractionGap);
880               model.setDblParam(CbcModel::CbcAllowableFractionGap, value);
881               break;
882          case CBC_PARAM_DBL_CUTOFF:
883               oldValue = model.getCutoff();
884               model.setCutoff(value);
885               break;
886          case CBC_PARAM_DBL_TIMELIMIT_BAB:
887               oldValue = model.getDblParam(CbcModel::CbcMaximumSeconds) ;
888               {
889                    //OsiClpSolverInterface * clpSolver = dynamic_cast< OsiClpSolverInterface*> (model.solver());
890                    //ClpSimplex * lpSolver = clpSolver->getModelPtr();
891                    //lpSolver->setMaximumSeconds(value);
892                    model.setDblParam(CbcModel::CbcMaximumSeconds, value) ;
893               }
894               break ;
895          case CLP_PARAM_DBL_DUALTOLERANCE:
896          case CLP_PARAM_DBL_PRIMALTOLERANCE:
897               setDoubleParameter(model.solver(), value);
898               return 0; // to avoid message
899          default:
900               break;
901          }
902          sprintf(printArray, "%s was changed from %g to %g",
903                  name_.c_str(), oldValue, value);
904          returnCode = 0;
905     }
906     return printArray;
907}
908double
909CbcOrClpParam::doubleParameter (CbcModel &model) const
910{
911     double value;
912     switch (type_) {
913     case CBC_PARAM_DBL_INFEASIBILITYWEIGHT:
914          value = model.getDblParam(CbcModel::CbcInfeasibilityWeight);
915          break;
916     case CBC_PARAM_DBL_INTEGERTOLERANCE:
917          value = model.getDblParam(CbcModel::CbcIntegerTolerance);
918          break;
919     case CBC_PARAM_DBL_INCREMENT:
920          value = model.getDblParam(CbcModel::CbcCutoffIncrement);
921          break;
922     case CBC_PARAM_DBL_ALLOWABLEGAP:
923          value = model.getDblParam(CbcModel::CbcAllowableGap);
924          break;
925     case CBC_PARAM_DBL_GAPRATIO:
926          value = model.getDblParam(CbcModel::CbcAllowableFractionGap);
927          break;
928     case CBC_PARAM_DBL_CUTOFF:
929          value = model.getCutoff();
930          break;
931     case CBC_PARAM_DBL_TIMELIMIT_BAB:
932          value = model.getDblParam(CbcModel::CbcMaximumSeconds) ;
933          break ;
934     case CLP_PARAM_DBL_DUALTOLERANCE:
935     case CLP_PARAM_DBL_PRIMALTOLERANCE:
936          value = doubleParameter(model.solver());
937          break;
938     default:
939          value = doubleValue_;
940          break;
941     }
942     return value;
943}
944int
945CbcOrClpParam::setIntParameter (CbcModel &model, int value)
946{
947     int returnCode;
948     setIntParameterWithMessage(model, value, returnCode);
949     if (doPrinting && strlen(printArray))
950          std::cout << printArray << std::endl;
951     return returnCode;
952}
953// Sets int parameter and returns printable string and error code
954const char *
955CbcOrClpParam::setIntParameterWithMessage ( CbcModel & model, int value , int & returnCode)
956{
957     if (value < lowerIntValue_ || value > upperIntValue_) {
958          sprintf(printArray, "%d was provided for %s - valid range is %d to %d",
959                  value, name_.c_str(), lowerIntValue_, upperIntValue_);
960          returnCode = 1;
961     } else {
962          int oldValue = intValue_;
963          intValue_ = value;
964          switch (type_) {
965          case CLP_PARAM_INT_LOGLEVEL:
966               oldValue = model.messageHandler()->logLevel();
967               model.messageHandler()->setLogLevel(CoinAbs(value));
968               break;
969          case CLP_PARAM_INT_SOLVERLOGLEVEL:
970               oldValue = model.solver()->messageHandler()->logLevel();
971               model.solver()->messageHandler()->setLogLevel(value);
972               break;
973          case CBC_PARAM_INT_MAXNODES:
974               oldValue = model.getIntParam(CbcModel::CbcMaxNumNode);
975               model.setIntParam(CbcModel::CbcMaxNumNode, value);
976               break;
977          case CBC_PARAM_INT_MAXSOLS:
978               oldValue = model.getIntParam(CbcModel::CbcMaxNumSol);
979               model.setIntParam(CbcModel::CbcMaxNumSol, value);
980               break;
981          case CBC_PARAM_INT_MAXSAVEDSOLS:
982               oldValue = model.maximumSavedSolutions();
983               model.setMaximumSavedSolutions(value);
984               break;
985          case CBC_PARAM_INT_STRONGBRANCHING:
986               oldValue = model.numberStrong();
987               model.setNumberStrong(value);
988               break;
989          case CBC_PARAM_INT_NUMBERBEFORE:
990               oldValue = model.numberBeforeTrust();
991               model.setNumberBeforeTrust(value);
992               break;
993          case CBC_PARAM_INT_NUMBERANALYZE:
994               oldValue = model.numberAnalyzeIterations();
995               model.setNumberAnalyzeIterations(value);
996               break;
997          case CBC_PARAM_INT_CUTPASSINTREE:
998               oldValue = model.getMaximumCutPasses();
999               model.setMaximumCutPasses(value);
1000               break;
1001          case CBC_PARAM_INT_CUTPASS:
1002               oldValue = model.getMaximumCutPassesAtRoot();
1003               model.setMaximumCutPassesAtRoot(value);
1004               break;
1005#ifdef COIN_HAS_CBC
1006#ifdef CBC_THREAD
1007          case CBC_PARAM_INT_THREADS:
1008               oldValue = model.getNumberThreads();
1009               model.setNumberThreads(value);
1010               break;
1011#endif
1012          case CBC_PARAM_INT_RANDOMSEED:
1013               oldValue = model.getRandomSeed();
1014               model.setRandomSeed(value);
1015               break;
1016#endif
1017          default:
1018               break;
1019          }
1020          sprintf(printArray, "%s was changed from %d to %d",
1021                  name_.c_str(), oldValue, value);
1022          returnCode = 0;
1023     }
1024     return printArray;
1025}
1026int
1027CbcOrClpParam::intParameter (CbcModel &model) const
1028{
1029     int value;
1030     switch (type_) {
1031     case CLP_PARAM_INT_LOGLEVEL:
1032          value = model.messageHandler()->logLevel();
1033          break;
1034     case CLP_PARAM_INT_SOLVERLOGLEVEL:
1035          value = model.solver()->messageHandler()->logLevel();
1036          break;
1037     case CBC_PARAM_INT_MAXNODES:
1038          value = model.getIntParam(CbcModel::CbcMaxNumNode);
1039          break;
1040     case CBC_PARAM_INT_MAXSOLS:
1041          value = model.getIntParam(CbcModel::CbcMaxNumSol);
1042          break;
1043     case CBC_PARAM_INT_MAXSAVEDSOLS:
1044          value = model.maximumSavedSolutions();
1045          break;
1046     case CBC_PARAM_INT_STRONGBRANCHING:
1047          value = model.numberStrong();
1048          break;
1049     case CBC_PARAM_INT_NUMBERBEFORE:
1050          value = model.numberBeforeTrust();
1051          break;
1052     case CBC_PARAM_INT_NUMBERANALYZE:
1053          value = model.numberAnalyzeIterations();
1054          break;
1055     case CBC_PARAM_INT_CUTPASSINTREE:
1056          value = model.getMaximumCutPasses();
1057          break;
1058     case CBC_PARAM_INT_CUTPASS:
1059          value = model.getMaximumCutPassesAtRoot();
1060          break;
1061#ifdef COIN_HAS_CBC
1062#ifdef CBC_THREAD
1063     case CBC_PARAM_INT_THREADS:
1064          value = model.getNumberThreads();
1065#endif
1066     case CBC_PARAM_INT_RANDOMSEED:
1067          value = model.getRandomSeed();
1068          break;
1069#endif
1070     default:
1071          value = intValue_;
1072          break;
1073     }
1074     return value;
1075}
1076#endif
1077// Sets current parameter option using string
1078void
1079CbcOrClpParam::setCurrentOption ( const std::string value )
1080{
1081     int action = parameterOption(value);
1082     if (action >= 0)
1083          currentKeyWord_ = action;
1084}
1085// Sets current parameter option
1086void
1087CbcOrClpParam::setCurrentOption ( int value , bool printIt)
1088{
1089     if (printIt && value != currentKeyWord_)
1090          std::cout << "Option for " << name_ << " changed from "
1091                    << definedKeyWords_[currentKeyWord_] << " to "
1092                    << definedKeyWords_[value] << std::endl;
1093
1094     currentKeyWord_ = value;
1095}
1096// Sets current parameter option and returns printable string
1097const char *
1098CbcOrClpParam::setCurrentOptionWithMessage ( int value )
1099{
1100     if (value != currentKeyWord_) {
1101         char current[100];
1102         char newString[100];
1103         if (currentKeyWord_>=0&&(fakeKeyWord_<=0||currentKeyWord_<fakeKeyWord_)) 
1104           strcpy(current,definedKeyWords_[currentKeyWord_].c_str());
1105         else if (currentKeyWord_<0)
1106           sprintf(current,"minus%d",-currentKeyWord_-1000);
1107         else
1108           sprintf(current,"plus%d",currentKeyWord_-1000);
1109         if (value>=0&&(fakeKeyWord_<=0||value<fakeKeyWord_) )
1110           strcpy(newString,definedKeyWords_[value].c_str());
1111         else if (value<0)
1112           sprintf(newString,"minus%d",-value-1000);
1113         else
1114           sprintf(newString,"plus%d",value-1000);
1115         sprintf(printArray, "Option for %s changed from %s to %s",
1116                 name_.c_str(), current, newString);
1117         currentKeyWord_ = value;
1118     } else {
1119          printArray[0] = '\0';
1120     }
1121     return printArray;
1122}
1123void
1124CbcOrClpParam::setIntValue ( int value )
1125{
1126     if (value < lowerIntValue_ || value > upperIntValue_) {
1127          std::cout << value << " was provided for " << name_ <<
1128                    " - valid range is " << lowerIntValue_ << " to " <<
1129                    upperIntValue_ << std::endl;
1130     } else {
1131          intValue_ = value;
1132     }
1133}
1134void
1135CbcOrClpParam::setDoubleValue ( double value )
1136{
1137     if (value < lowerDoubleValue_ || value > upperDoubleValue_) {
1138          std::cout << value << " was provided for " << name_ <<
1139                    " - valid range is " << lowerDoubleValue_ << " to " <<
1140                    upperDoubleValue_ << std::endl;
1141     } else {
1142          doubleValue_ = value;
1143     }
1144}
1145void
1146CbcOrClpParam::setStringValue ( std::string value )
1147{
1148     stringValue_ = value;
1149}
1150static char line[1000];
1151static char * where = NULL;
1152extern int CbcOrClpRead_mode;
1153int CbcOrClpEnvironmentIndex = -1;
1154static size_t fillEnv()
1155{
1156#if defined(_MSC_VER) || defined(__MSVCRT__)
1157     return 0;
1158#else
1159     // Don't think it will work on Windows
1160     char * environ = getenv("CBC_CLP_ENVIRONMENT");
1161     size_t length = 0;
1162     if (environ) {
1163          length = strlen(environ);
1164          if (CbcOrClpEnvironmentIndex < static_cast<int>(length)) {
1165               // find next non blank
1166               char * whereEnv = environ + CbcOrClpEnvironmentIndex;
1167               // munch white space
1168               while (*whereEnv == ' ' || *whereEnv == '\t' || *whereEnv < ' ')
1169                    whereEnv++;
1170               // copy
1171               char * put = line;
1172               while ( *whereEnv != '\0' ) {
1173                    if ( *whereEnv == ' ' || *whereEnv == '\t' || *whereEnv < ' ' ) {
1174                         break;
1175                    }
1176                    *put = *whereEnv;
1177                    put++;
1178                    assert (put - line < 1000);
1179                    whereEnv++;
1180               }
1181               CbcOrClpEnvironmentIndex = static_cast<int>(whereEnv - environ);
1182               *put = '\0';
1183               length = strlen(line);
1184          } else {
1185               length = 0;
1186          }
1187     }
1188     if (!length)
1189          CbcOrClpEnvironmentIndex = -1;
1190     return length;
1191#endif
1192}
1193extern FILE * CbcOrClpReadCommand;
1194// Simple read stuff
1195std::string
1196CoinReadNextField()
1197{
1198     std::string field;
1199     if (!where) {
1200          // need new line
1201#ifdef COIN_HAS_READLINE
1202          if (CbcOrClpReadCommand == stdin) {
1203               // Get a line from the user.
1204               where = readline (coin_prompt);
1205
1206               // If the line has any text in it, save it on the history.
1207               if (where) {
1208                    if ( *where)
1209                         add_history (where);
1210                    strcpy(line, where);
1211                    free(where);
1212               }
1213          } else {
1214               where = fgets(line, 1000, CbcOrClpReadCommand);
1215          }
1216#else
1217          if (CbcOrClpReadCommand == stdin) {
1218               fputs(coin_prompt,stdout);
1219               fflush(stdout);
1220          }
1221          where = fgets(line, 1000, CbcOrClpReadCommand);
1222#endif
1223          if (!where)
1224               return field; // EOF
1225          where = line;
1226          // clean image
1227          char * lastNonBlank = line - 1;
1228          while ( *where != '\0' ) {
1229               if ( *where != '\t' && *where < ' ' ) {
1230                    break;
1231               } else if ( *where != '\t' && *where != ' ') {
1232                    lastNonBlank = where;
1233               }
1234               where++;
1235          }
1236          where = line;
1237          *(lastNonBlank + 1) = '\0';
1238     }
1239     // munch white space
1240     while (*where == ' ' || *where == '\t')
1241          where++;
1242     char * saveWhere = where;
1243     while (*where != ' ' && *where != '\t' && *where != '\0')
1244          where++;
1245     if (where != saveWhere) {
1246          char save = *where;
1247          *where = '\0';
1248          //convert to string
1249          field = saveWhere;
1250          *where = save;
1251     } else {
1252          where = NULL;
1253          field = "EOL";
1254     }
1255     return field;
1256}
1257
1258std::string
1259CoinReadGetCommand(int argc, const char *argv[])
1260{
1261     std::string field = "EOL";
1262     // say no =
1263     afterEquals = "";
1264     while (field == "EOL") {
1265          if (CbcOrClpRead_mode > 0) {
1266               if ((CbcOrClpRead_mode < argc && argv[CbcOrClpRead_mode]) ||
1267                         CbcOrClpEnvironmentIndex >= 0) {
1268                    if (CbcOrClpEnvironmentIndex < 0) {
1269                         field = argv[CbcOrClpRead_mode++];
1270                    } else {
1271                         if (fillEnv()) {
1272                              field = line;
1273                         } else {
1274                              // not there
1275                              continue;
1276                         }
1277                    }
1278                    if (field == "-") {
1279                         std::cout << "Switching to line mode" << std::endl;
1280                         CbcOrClpRead_mode = -1;
1281                         field = CoinReadNextField();
1282                    } else if (field[0] != '-') {
1283                         if (CbcOrClpRead_mode != 2) {
1284                              // now allow std::cout<<"skipping non-command "<<field<<std::endl;
1285                              // field="EOL"; // skip
1286                         } else if (CbcOrClpEnvironmentIndex < 0) {
1287                              // special dispensation - taken as -import name
1288                              CbcOrClpRead_mode--;
1289                              field = "import";
1290                         }
1291                    } else {
1292                         if (field != "--") {
1293                              // take off -
1294                              field = field.substr(1);
1295                         } else {
1296                              // special dispensation - taken as -import --
1297                              CbcOrClpRead_mode--;
1298                              field = "import";
1299                         }
1300                    }
1301               } else {
1302                    field = "";
1303               }
1304          } else {
1305               field = CoinReadNextField();
1306          }
1307     }
1308     // if = then modify and save
1309     std::string::size_type found = field.find('=');
1310     if (found != std::string::npos) {
1311          afterEquals = field.substr(found + 1);
1312          field = field.substr(0, found);
1313     }
1314     //std::cout<<field<<std::endl;
1315     return field;
1316}
1317std::string
1318CoinReadGetString(int argc, const char *argv[])
1319{
1320     std::string field = "EOL";
1321     if (afterEquals == "") {
1322          if (CbcOrClpRead_mode > 0) {
1323               if (CbcOrClpRead_mode < argc || CbcOrClpEnvironmentIndex >= 0) {
1324                    if (CbcOrClpEnvironmentIndex < 0) {
1325                         if (argv[CbcOrClpRead_mode][0] != '-') {
1326                              field = argv[CbcOrClpRead_mode++];
1327                         } else if (!strcmp(argv[CbcOrClpRead_mode], "--")) {
1328                              field = argv[CbcOrClpRead_mode++];
1329                              // -- means import from stdin
1330                              field = "-";
1331                         }
1332                    } else {
1333                         fillEnv();
1334                         field = line;
1335                    }
1336               }
1337          } else {
1338               field = CoinReadNextField();
1339          }
1340     } else {
1341          field = afterEquals;
1342          afterEquals = "";
1343     }
1344     //std::cout<<field<<std::endl;
1345     return field;
1346}
1347// valid 0 - okay, 1 bad, 2 not there
1348int
1349CoinReadGetIntField(int argc, const char *argv[], int * valid)
1350{
1351     std::string field = "EOL";
1352     if (afterEquals == "") {
1353          if (CbcOrClpRead_mode > 0) {
1354               if (CbcOrClpRead_mode < argc || CbcOrClpEnvironmentIndex >= 0) {
1355                    if (CbcOrClpEnvironmentIndex < 0) {
1356                         // may be negative value so do not check for -
1357                         field = argv[CbcOrClpRead_mode++];
1358                    } else {
1359                         fillEnv();
1360                         field = line;
1361                    }
1362               }
1363          } else {
1364               field = CoinReadNextField();
1365          }
1366     } else {
1367          field = afterEquals;
1368          afterEquals = "";
1369     }
1370     long int value = 0;
1371     //std::cout<<field<<std::endl;
1372     if (field != "EOL") {
1373          const char * start = field.c_str();
1374          char * endPointer = NULL;
1375          // check valid
1376          value =  strtol(start, &endPointer, 10);
1377          if (*endPointer == '\0') {
1378               *valid = 0;
1379          } else {
1380               *valid = 1;
1381               std::cout << "String of " << field;
1382          }
1383     } else {
1384          *valid = 2;
1385     }
1386     return static_cast<int>(value);
1387}
1388double
1389CoinReadGetDoubleField(int argc, const char *argv[], int * valid)
1390{
1391     std::string field = "EOL";
1392     if (afterEquals == "") {
1393          if (CbcOrClpRead_mode > 0) {
1394               if (CbcOrClpRead_mode < argc || CbcOrClpEnvironmentIndex >= 0) {
1395                    if (CbcOrClpEnvironmentIndex < 0) {
1396                         // may be negative value so do not check for -
1397                         field = argv[CbcOrClpRead_mode++];
1398                    } else {
1399                         fillEnv();
1400                         field = line;
1401                    }
1402               }
1403          } else {
1404               field = CoinReadNextField();
1405          }
1406     } else {
1407          field = afterEquals;
1408          afterEquals = "";
1409     }
1410     double value = 0.0;
1411     //std::cout<<field<<std::endl;
1412     if (field != "EOL") {
1413          const char * start = field.c_str();
1414          char * endPointer = NULL;
1415          // check valid
1416          value =  strtod(start, &endPointer);
1417          if (*endPointer == '\0') {
1418               *valid = 0;
1419          } else {
1420               *valid = 1;
1421               std::cout << "String of " << field;
1422          }
1423     } else {
1424          *valid = 2;
1425     }
1426     return value;
1427}
1428/*
1429  Subroutine to establish the cbc parameter array. See the description of
1430  class CbcOrClpParam for details. Pulled from C..Main() for clarity.
1431*/
1432void
1433establishParams (int &numberParameters, CbcOrClpParam *const parameters)
1434{
1435     numberParameters = 0;
1436     parameters[numberParameters++] =
1437          CbcOrClpParam("?", "For help", CBC_PARAM_GENERALQUERY, 7, 0);
1438     parameters[numberParameters++] =
1439          CbcOrClpParam("???", "For help", CBC_PARAM_FULLGENERALQUERY, 7, 0);
1440     parameters[numberParameters++] =
1441          CbcOrClpParam("-", "From stdin",
1442                        CLP_PARAM_ACTION_STDIN, 3, 0);
1443#ifdef ABC_INHERIT
1444      parameters[numberParameters++] =
1445          CbcOrClpParam("abc", "Whether to visit Aboca",
1446                        "off", CLP_PARAM_STR_ABCWANTED, 7, 0);
1447     parameters[numberParameters-1].append("one");
1448     parameters[numberParameters-1].append("two");
1449     parameters[numberParameters-1].append("three");
1450     parameters[numberParameters-1].append("four");
1451     parameters[numberParameters-1].append("five");
1452     parameters[numberParameters-1].append("six");
1453     parameters[numberParameters-1].append("seven");
1454     parameters[numberParameters-1].append("eight");
1455     parameters[numberParameters-1].append("on");
1456     parameters[numberParameters-1].append("decide");
1457     parameters[numberParameters-1].setFakeKeyWord(10);
1458     parameters[numberParameters-1].setLonghelp
1459     (
1460          "Decide whether to use A Basic Optimization Code (Accelerated?) \
1461and whether to try going parallel!"
1462     );
1463#endif
1464     parameters[numberParameters++] =
1465          CbcOrClpParam("allC!ommands", "Whether to print less used commands",
1466                        "no", CLP_PARAM_STR_ALLCOMMANDS);
1467     parameters[numberParameters-1].append("more");
1468     parameters[numberParameters-1].append("all");
1469     parameters[numberParameters-1].setLonghelp
1470     (
1471          "For the sake of your sanity, only the more useful and simple commands \
1472are printed out on ?."
1473     );
1474#ifdef COIN_HAS_CBC
1475     parameters[numberParameters++] =
1476          CbcOrClpParam("allow!ableGap", "Stop when gap between best possible and \
1477best less than this",
1478                        0.0, 1.0e20, CBC_PARAM_DBL_ALLOWABLEGAP);
1479     parameters[numberParameters-1].setDoubleValue(0.0);
1480     parameters[numberParameters-1].setLonghelp
1481     (
1482          "If the gap between best solution and best possible solution is less than this \
1483then the search will be terminated.  Also see ratioGap."
1484     );
1485#endif
1486#ifdef COIN_HAS_CLP
1487     parameters[numberParameters++] =
1488          CbcOrClpParam("allS!lack", "Set basis back to all slack and reset solution",
1489                        CLP_PARAM_ACTION_ALLSLACK, 3);
1490     parameters[numberParameters-1].setLonghelp
1491     (
1492          "Mainly useful for tuning purposes.  Normally the first dual or primal will be using an all slack \
1493basis anyway."
1494     );
1495#endif
1496#ifdef COIN_HAS_CBC
1497     parameters[numberParameters++] =
1498          CbcOrClpParam("artif!icialCost", "Costs >= this treated as artificials in feasibility pump",
1499                        0.0, COIN_DBL_MAX, CBC_PARAM_DBL_ARTIFICIALCOST, 1);
1500     parameters[numberParameters-1].setDoubleValue(0.0);
1501     parameters[numberParameters-1].setLonghelp
1502     (
1503          "0.0 off - otherwise variables with costs >= this are treated as artificials and fixed to lower bound in feasibility pump"
1504     );
1505#endif
1506#ifdef COIN_HAS_CLP
1507     parameters[numberParameters++] =
1508          CbcOrClpParam("auto!Scale", "Whether to scale objective, rhs and bounds of problem if they look odd",
1509                        "off", CLP_PARAM_STR_AUTOSCALE, 7, 0);
1510     parameters[numberParameters-1].append("on");
1511     parameters[numberParameters-1].setLonghelp
1512     (
1513          "If you think you may get odd objective values or large equality rows etc then\
1514 it may be worth setting this true.  It is still experimental and you may prefer\
1515 to use objective!Scale and rhs!Scale."
1516     );
1517     parameters[numberParameters++] =
1518          CbcOrClpParam("barr!ier", "Solve using primal dual predictor corrector algorithm",
1519                        CLP_PARAM_ACTION_BARRIER);
1520     parameters[numberParameters-1].setLonghelp
1521     (
1522          "This command solves the current model using the  primal dual predictor \
1523corrector algorithm.  You may want to link in an alternative \
1524ordering and factorization.  It will also solve models \
1525with quadratic objectives."
1526
1527     );
1528     parameters[numberParameters++] =
1529          CbcOrClpParam("basisI!n", "Import basis from bas file",
1530                        CLP_PARAM_ACTION_BASISIN, 3);
1531     parameters[numberParameters-1].setLonghelp
1532     (
1533          "This will read an MPS format basis file from the given file name.  It will use the default\
1534 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
1535 is initialized to '', i.e. it must be set.  If you have libz then it can read compressed\
1536 files 'xxxxxxxx.gz' or xxxxxxxx.bz2."
1537     );
1538     parameters[numberParameters++] =
1539          CbcOrClpParam("basisO!ut", "Export basis as bas file",
1540                        CLP_PARAM_ACTION_BASISOUT);
1541     parameters[numberParameters-1].setLonghelp
1542     (
1543          "This will write an MPS format basis file to the given file name.  It will use the default\
1544 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
1545 is initialized to 'default.bas'."
1546     );
1547     parameters[numberParameters++] =
1548          CbcOrClpParam("biasLU", "Whether factorization biased towards U",
1549                        "UU", CLP_PARAM_STR_BIASLU, 2, 0);
1550     parameters[numberParameters-1].append("UX");
1551     parameters[numberParameters-1].append("LX");
1552     parameters[numberParameters-1].append("LL");
1553     parameters[numberParameters-1].setCurrentOption("LX");
1554#endif
1555#ifdef COIN_HAS_CBC
1556     parameters[numberParameters++] =
1557          CbcOrClpParam("branch!AndCut", "Do Branch and Cut",
1558                        CBC_PARAM_ACTION_BAB);
1559     parameters[numberParameters-1].setLonghelp
1560     (
1561          "This does branch and cut.  There are many parameters which can affect the performance.  \
1562First just try with default settings and look carefully at the log file.  Did cuts help?  Did they take too long?  \
1563Look at output to see which cuts were effective and then do some tuning.  You will see that the \
1564options for cuts are off, on, root and ifmove, forceon.  Off is \
1565obvious, on means that this cut generator will be tried in the branch and cut tree (you can fine tune using \
1566'depth').  Root means just at the root node while 'ifmove' means that cuts will be used in the tree if they \
1567look as if they are doing some good and moving the objective value.  Forceon is same as on but forces code to use \
1568cut generator at every node.  For probing forceonbut just does fixing probing in tree - not strengthening etc.  \
1569If pre-processing reduced the size of the \
1570problem or strengthened many coefficients then it is probably wise to leave it on.  Switch off heuristics \
1571which did not provide solutions.  The other major area to look at is the search.  Hopefully good solutions \
1572were obtained fairly early in the search so the important point is to select the best variable to branch on.  \
1573See whether strong branching did a good job - or did it just take a lot of iterations.  Adjust the strongBranching \
1574and trustPseudoCosts parameters.  If cuts did a good job, then you may wish to \
1575have more rounds of cuts - see passC!uts and passT!ree."
1576     );
1577#endif
1578     parameters[numberParameters++] =
1579          CbcOrClpParam("bscale", "Whether to scale in barrier (and ordering speed)",
1580                        "off", CLP_PARAM_STR_BARRIERSCALE, 7, 0);
1581     parameters[numberParameters-1].append("on");
1582     parameters[numberParameters-1].append("off1");
1583     parameters[numberParameters-1].append("on1");
1584     parameters[numberParameters-1].append("off2");
1585     parameters[numberParameters-1].append("on2");
1586     parameters[numberParameters++] =
1587          CbcOrClpParam("chol!esky", "Which cholesky algorithm",
1588                        "native", CLP_PARAM_STR_CHOLESKY, 7);
1589     parameters[numberParameters-1].append("dense");
1590     //#ifdef FOREIGN_BARRIER
1591#ifdef COIN_HAS_WSMP
1592     parameters[numberParameters-1].append("fudge!Long");
1593     parameters[numberParameters-1].append("wssmp");
1594#else
1595     parameters[numberParameters-1].append("fudge!Long_dummy");
1596     parameters[numberParameters-1].append("wssmp_dummy");
1597#endif
1598#if defined(COIN_HAS_AMD) || defined(COIN_HAS_CHOLMOD) || defined(COIN_HAS_GLPK)
1599     parameters[numberParameters-1].append("Uni!versityOfFlorida");
1600#else
1601     parameters[numberParameters-1].append("Uni!versityOfFlorida_dummy");
1602#endif
1603#ifdef TAUCS_BARRIER
1604     parameters[numberParameters-1].append("Taucs");
1605#else
1606     parameters[numberParameters-1].append("Taucs_dummy");
1607#endif
1608#ifdef COIN_HAS_MUMPS
1609     parameters[numberParameters-1].append("Mumps");
1610#else
1611     parameters[numberParameters-1].append("Mumps_dummy");
1612#endif
1613     parameters[numberParameters-1].setLonghelp
1614     (
1615          "For a barrier code to be effective it needs a good Cholesky ordering and factorization.  \
1616The native ordering and factorization is not state of the art, although acceptable.  \
1617You may want to link in one from another source.  See Makefile.locations for some \
1618possibilities."
1619     );
1620     //#endif
1621#ifdef COIN_HAS_CBC
1622     parameters[numberParameters++] =
1623          CbcOrClpParam("clique!Cuts", "Whether to use Clique cuts",
1624                        "off", CBC_PARAM_STR_CLIQUECUTS);
1625     parameters[numberParameters-1].append("on");
1626     parameters[numberParameters-1].append("root");
1627     parameters[numberParameters-1].append("ifmove");
1628     parameters[numberParameters-1].append("forceOn");
1629     parameters[numberParameters-1].append("onglobal");
1630     parameters[numberParameters-1].setLonghelp
1631     (
1632          "This switches on clique cuts (either at root or in entire tree) \
1633See branchAndCut for information on options."
1634     );
1635     parameters[numberParameters++] =
1636          CbcOrClpParam("combine!Solutions", "Whether to use combine solution heuristic",
1637                        "off", CBC_PARAM_STR_COMBINE);
1638     parameters[numberParameters-1].append("on");
1639     parameters[numberParameters-1].append("both");
1640     parameters[numberParameters-1].append("before");
1641     parameters[numberParameters-1].setLonghelp
1642     (
1643          "This switches on a heuristic which does branch and cut on the problem given by just \
1644using variables which have appeared in one or more solutions. \
1645It obviously only tries after two or more solutions. \
1646See Rounding for meaning of on,both,before"
1647     );
1648     parameters[numberParameters++] =
1649          CbcOrClpParam("combine2!Solutions", "Whether to use crossover solution heuristic",
1650                        "off", CBC_PARAM_STR_CROSSOVER2);
1651     parameters[numberParameters-1].append("on");
1652     parameters[numberParameters-1].append("both");
1653     parameters[numberParameters-1].append("before");
1654     parameters[numberParameters-1].setLonghelp
1655     (
1656          "This switches on a heuristic which does branch and cut on the problem given by \
1657fixing variables which have same value in two or more solutions. \
1658It obviously only tries after two or more solutions. \
1659See Rounding for meaning of on,both,before"
1660     );
1661     parameters[numberParameters++] =
1662          CbcOrClpParam("constraint!fromCutoff", "Whether to use cutoff as constraint",
1663                        "off", CBC_PARAM_STR_CUTOFF_CONSTRAINT);
1664     parameters[numberParameters-1].append("on");
1665     parameters[numberParameters-1].setLonghelp
1666     (
1667          "This adds the objective as a constraint with best solution as RHS"
1668     );
1669     parameters[numberParameters++] =
1670          CbcOrClpParam("cost!Strategy", "How to use costs as priorities",
1671                        "off", CBC_PARAM_STR_COSTSTRATEGY);
1672     parameters[numberParameters-1].append("pri!orities");
1673     parameters[numberParameters-1].append("column!Order?");
1674     parameters[numberParameters-1].append("01f!irst?");
1675     parameters[numberParameters-1].append("01l!ast?");
1676     parameters[numberParameters-1].append("length!?");
1677     parameters[numberParameters-1].append("singletons");
1678     parameters[numberParameters-1].append("nonzero");
1679     parameters[numberParameters-1].setLonghelp
1680     (
1681          "This orders the variables in order of their absolute costs - with largest cost ones being branched on \
1682first.  This primitive strategy can be surprsingly effective.  The column order\
1683 option is obviously not on costs but easy to code here."
1684     );
1685     parameters[numberParameters++] =
1686          CbcOrClpParam("cplex!Use", "Whether to use Cplex!",
1687                        "off", CBC_PARAM_STR_CPX);
1688     parameters[numberParameters-1].append("on");
1689     parameters[numberParameters-1].setLonghelp
1690     (
1691          " If the user has Cplex, but wants to use some of Cbc's heuristics \
1692then you can!  If this is on, then Cbc will get to the root node and then \
1693hand over to Cplex.  If heuristics find a solution this can be significantly \
1694quicker.  You will probably want to switch off Cbc's cuts as Cplex thinks \
1695they are genuine constraints.  It is also probable that you want to switch \
1696off preprocessing, although for difficult problems it is worth trying \
1697both."
1698     );
1699#endif
1700     parameters[numberParameters++] =
1701          CbcOrClpParam("cpp!Generate", "Generates C++ code",
1702                        -1, 50000, CLP_PARAM_INT_CPP, 1);
1703     parameters[numberParameters-1].setLonghelp
1704     (
1705          "Once you like what the stand-alone solver does then this allows \
1706you to generate user_driver.cpp which approximates the code.  \
17070 gives simplest driver, 1 generates saves and restores, 2 \
1708generates saves and restores even for variables at default value. \
17094 bit in cbc generates size dependent code rather than computed values.  \
1710This is now deprecated as you can call stand-alone solver - see \
1711Cbc/examples/driver4.cpp."
1712     );
1713#ifdef COIN_HAS_CLP
1714     parameters[numberParameters++] =
1715          CbcOrClpParam("crash", "Whether to create basis for problem",
1716                        "off", CLP_PARAM_STR_CRASH);
1717     parameters[numberParameters-1].append("on");
1718     parameters[numberParameters-1].append("so!low_halim");
1719     parameters[numberParameters-1].append("lots");
1720#ifdef ABC_INHERIT
1721     parameters[numberParameters-1].append("dual");
1722     parameters[numberParameters-1].append("dw");
1723     parameters[numberParameters-1].append("idiot");
1724#endif
1725     parameters[numberParameters-1].setLonghelp
1726     (
1727          "If crash is set on and there is an all slack basis then Clp will flip or put structural\
1728 variables into basis with the aim of getting dual feasible.  On the whole dual seems to be\
1729 better without it and there are alternative types of 'crash' for primal e.g. 'idiot' or 'sprint'. \
1730I have also added a variant due to Solow and Halim which is as on but just flip.");
1731     parameters[numberParameters++] =
1732          CbcOrClpParam("cross!over", "Whether to get a basic solution after barrier",
1733                        "on", CLP_PARAM_STR_CROSSOVER);
1734     parameters[numberParameters-1].append("off");
1735     parameters[numberParameters-1].append("maybe");
1736     parameters[numberParameters-1].append("presolve");
1737     parameters[numberParameters-1].setLonghelp
1738     (
1739          "Interior point algorithms do not obtain a basic solution (and \
1740the feasibility criterion is a bit suspect (JJF)).  This option will crossover \
1741to a basic solution suitable for ranging or branch and cut.  With the current state \
1742of quadratic it may be a good idea to switch off crossover for quadratic (and maybe \
1743presolve as well) - the option maybe does this."
1744     );
1745#endif
1746#ifdef COIN_HAS_CBC
1747     parameters[numberParameters++] =
1748          CbcOrClpParam("csv!Statistics", "Create one line of statistics",
1749                        CLP_PARAM_ACTION_CSVSTATISTICS, 2, 1);
1750     parameters[numberParameters-1].setLonghelp
1751     (
1752          "This appends statistics to given file name.  It will use the default\
1753 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
1754 is initialized to '', i.e. it must be set.  Adds header if file empty or does not exist."
1755     );
1756     parameters[numberParameters++] =
1757          CbcOrClpParam("cutD!epth", "Depth in tree at which to do cuts",
1758                        -1, 999999, CBC_PARAM_INT_CUTDEPTH);
1759     parameters[numberParameters-1].setLonghelp
1760     (
1761          "Cut generators may be - off, on only at root, on if they look possible \
1762and on.  If they are done every node then that is that, but it may be worth doing them \
1763every so often.  The original method was every so many nodes but it is more logical \
1764to do it whenever depth in tree is a multiple of K.  This option does that and defaults \
1765to -1 (off -> code decides)."
1766     );
1767     parameters[numberParameters-1].setIntValue(-1);
1768     parameters[numberParameters++] =
1769          CbcOrClpParam("cutL!ength", "Length of a cut",
1770                        -1, COIN_INT_MAX, CBC_PARAM_INT_CUTLENGTH);
1771     parameters[numberParameters-1].setLonghelp
1772     (
1773          "At present this only applies to Gomory cuts. -1 (default) leaves as is. \
1774Any value >0 says that all cuts <= this length can be generated both at \
1775root node and in tree. 0 says to use some dynamic lengths.  If value >=10,000,000 \
1776then the length in tree is value%10000000 - so 10000100 means unlimited length \
1777at root and 100 in tree."
1778     );
1779     parameters[numberParameters-1].setIntValue(-1);
1780     parameters[numberParameters++] =
1781          CbcOrClpParam("cuto!ff", "All solutions must be better than this",
1782                        -1.0e60, 1.0e60, CBC_PARAM_DBL_CUTOFF);
1783     parameters[numberParameters-1].setDoubleValue(1.0e50);
1784     parameters[numberParameters-1].setLonghelp
1785     (
1786          "All solutions must be better than this value (in a minimization sense).  \
1787This is also set by code whenever it obtains a solution and is set to value of \
1788objective for solution minus cutoff increment."
1789     );
1790     parameters[numberParameters++] =
1791          CbcOrClpParam("cuts!OnOff", "Switches all cuts on or off",
1792                        "off", CBC_PARAM_STR_CUTSSTRATEGY);
1793     parameters[numberParameters-1].append("on");
1794     parameters[numberParameters-1].append("root");
1795     parameters[numberParameters-1].append("ifmove");
1796     parameters[numberParameters-1].append("forceOn");
1797     parameters[numberParameters-1].setLonghelp
1798     (
1799          "This can be used to switch on or off all cuts (apart from Reduce and Split).  Then you can do \
1800individual ones off or on \
1801See branchAndCut for information on options."
1802     );
1803     parameters[numberParameters++] =
1804          CbcOrClpParam("debug!In", "read valid solution from file",
1805                        CLP_PARAM_ACTION_DEBUG, 7, 1);
1806     parameters[numberParameters-1].setLonghelp
1807     (
1808          "This will read a solution file from the given file name.  It will use the default\
1809 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
1810 is initialized to '', i.e. it must be set.\n\n\
1811If set to create it will create a file called debug.file  after search.\n\n\
1812The idea is that if you suspect a bad cut generator \
1813you can do a good run with debug set to 'create' and then switch on the cuts you suspect and \
1814re-run with debug set to 'debug.file'  The create case has same effect as saveSolution."
1815     );
1816#endif
1817#ifdef COIN_HAS_CLP
1818     parameters[numberParameters++] =
1819          CbcOrClpParam("decomp!ose", "Whether to try decomposition",
1820                        -COIN_INT_MAX, COIN_INT_MAX, CLP_PARAM_INT_DECOMPOSE_BLOCKS, 1);
1821     parameters[numberParameters-1].setLonghelp
1822     (
1823          "0 - off, 1 choose blocks >1 use as blocks \
1824Dantzig Wolfe if primal, Benders if dual \
1825- uses sprint pass for number of passes"
1826     );
1827     parameters[numberParameters-1].setIntValue(0);
1828#if CLP_MULTIPLE_FACTORIZATIONS >0
1829     parameters[numberParameters++] =
1830          CbcOrClpParam("dense!Threshold", "Whether to use dense factorization",
1831                        -1, 10000, CBC_PARAM_INT_DENSE, 1);
1832     parameters[numberParameters-1].setLonghelp
1833     (
1834          "If processed problem <= this use dense factorization"
1835     );
1836     parameters[numberParameters-1].setIntValue(-1);
1837#endif
1838#endif
1839#ifdef COIN_HAS_CBC
1840     parameters[numberParameters++] =
1841          CbcOrClpParam("depth!MiniBab", "Depth at which to try mini BAB",
1842                        -COIN_INT_MAX, COIN_INT_MAX, CBC_PARAM_INT_DEPTHMINIBAB);
1843     parameters[numberParameters-1].setIntValue(-1);
1844     parameters[numberParameters-1].setLonghelp
1845     (
1846          "Rather a complicated parameter but can be useful. -1 means off for large problems but on as if -12 for problems where rows+columns<500, -2 \
1847means use Cplex if it is linked in.  Otherwise if negative then go into depth first complete search fast branch and bound when depth>= -value-2 (so -3 will use this at depth>=1).  This mode is only switched on after 500 nodes.  If you really want to switch it off for small problems then set this to -999.  If >=0 the value doesn't matter very much.  The code will do approximately 100 nodes of fast branch and bound every now and then at depth>=5.  The actual logic is too twisted to describe here."
1848     );
1849     parameters[numberParameters++] =
1850          CbcOrClpParam("dextra3", "Extra double parameter 3",
1851                        -COIN_DBL_MAX, COIN_DBL_MAX, CBC_PARAM_DBL_DEXTRA3, 0);
1852     parameters[numberParameters-1].setDoubleValue(0.0);
1853     parameters[numberParameters++] =
1854          CbcOrClpParam("dextra4", "Extra double parameter 4",
1855                        -COIN_DBL_MAX, COIN_DBL_MAX, CBC_PARAM_DBL_DEXTRA4, 0);
1856     parameters[numberParameters-1].setDoubleValue(0.0);
1857     parameters[numberParameters++] =
1858          CbcOrClpParam("dextra5", "Extra double parameter 5",
1859                        -COIN_DBL_MAX, COIN_DBL_MAX, CBC_PARAM_DBL_DEXTRA5, 0);
1860     parameters[numberParameters-1].setDoubleValue(0.0);
1861     parameters[numberParameters++] =
1862          CbcOrClpParam("Dins", "Whether to try Distance Induced Neighborhood Search",
1863                        "off", CBC_PARAM_STR_DINS);
1864     parameters[numberParameters-1].append("on");
1865     parameters[numberParameters-1].append("both");
1866     parameters[numberParameters-1].append("before");
1867     parameters[numberParameters-1].append("often");
1868     parameters[numberParameters-1].setLonghelp
1869     (
1870          "This switches on Distance induced neighborhood Search. \
1871See Rounding for meaning of on,both,before"
1872     );
1873#endif
1874     parameters[numberParameters++] =
1875          CbcOrClpParam("direction", "Minimize or Maximize",
1876                        "min!imize", CLP_PARAM_STR_DIRECTION);
1877     parameters[numberParameters-1].append("max!imize");
1878     parameters[numberParameters-1].append("zero");
1879     parameters[numberParameters-1].setLonghelp
1880     (
1881          "The default is minimize - use 'direction maximize' for maximization.\n\
1882You can also use the parameters 'maximize' or 'minimize'."
1883     );
1884     parameters[numberParameters++] =
1885          CbcOrClpParam("directory", "Set Default directory for import etc.",
1886                        CLP_PARAM_ACTION_DIRECTORY);
1887     parameters[numberParameters-1].setLonghelp
1888     (
1889          "This sets the directory which import, export, saveModel, restoreModel etc will use.\
1890  It is initialized to './'"
1891     );
1892     parameters[numberParameters++] =
1893          CbcOrClpParam("dirSample", "Set directory where the COIN-OR sample problems are.",
1894                        CLP_PARAM_ACTION_DIRSAMPLE, 7, 1);
1895     parameters[numberParameters-1].setLonghelp
1896     (
1897          "This sets the directory where the COIN-OR sample problems reside. It is\
1898 used only when -unitTest is passed to clp. clp will pick up the test problems\
1899 from this directory.\
1900 It is initialized to '../../Data/Sample'"
1901     );
1902     parameters[numberParameters++] =
1903          CbcOrClpParam("dirNetlib", "Set directory where the netlib problems are.",
1904                        CLP_PARAM_ACTION_DIRNETLIB, 7, 1);
1905     parameters[numberParameters-1].setLonghelp
1906     (
1907          "This sets the directory where the netlib problems reside. One can get\
1908 the netlib problems from COIN-OR or from the main netlib site. This\
1909 parameter is used only when -netlib is passed to clp. clp will pick up the\
1910 netlib problems from this directory. If clp is built without zlib support\
1911 then the problems must be uncompressed.\
1912 It is initialized to '../../Data/Netlib'"
1913     );
1914     parameters[numberParameters++] =
1915          CbcOrClpParam("dirMiplib", "Set directory where the miplib 2003 problems are.",
1916                        CBC_PARAM_ACTION_DIRMIPLIB, 7, 1);
1917     parameters[numberParameters-1].setLonghelp
1918     (
1919          "This sets the directory where the miplib 2003 problems reside. One can\
1920 get the miplib problems from COIN-OR or from the main miplib site. This\
1921 parameter is used only when -miplib is passed to cbc. cbc will pick up the\
1922 miplib problems from this directory. If cbc is built without zlib support\
1923 then the problems must be uncompressed.\
1924 It is initialized to '../../Data/miplib3'"
1925     );
1926#ifdef COIN_HAS_CBC
1927     parameters[numberParameters++] =
1928          CbcOrClpParam("diveO!pt", "Diving options",
1929                        -1, 200000, CBC_PARAM_INT_DIVEOPT, 1);
1930     parameters[numberParameters-1].setLonghelp
1931     (
1932          "If >2 && <8 then modify diving options - \
1933         \n\t3 only at root and if no solution,  \
1934         \n\t4 only at root and if this heuristic has not got solution, \
1935         \n\t5 only at depth <4, \
1936         \n\t6 decay, \
1937         \n\t7 run up to 2 times if solution found 4 otherwise."
1938     );
1939     parameters[numberParameters-1].setIntValue(-1);
1940     parameters[numberParameters++] =
1941          CbcOrClpParam("DivingS!ome", "Whether to try Diving heuristics",
1942                        "off", CBC_PARAM_STR_DIVINGS);
1943     parameters[numberParameters-1].append("on");
1944     parameters[numberParameters-1].append("both");
1945     parameters[numberParameters-1].append("before");
1946     parameters[numberParameters-1].setLonghelp
1947     (
1948          "This switches on a random diving heuristic at various times. \
1949C - Coefficient, F - Fractional, G - Guided, L - LineSearch, P - PseudoCost, V - VectorLength. \
1950You may prefer to use individual on/off \
1951See Rounding for meaning of on,both,before"
1952     );
1953     parameters[numberParameters++] =
1954          CbcOrClpParam("DivingC!oefficient", "Whether to try DiveCoefficient",
1955                        "off", CBC_PARAM_STR_DIVINGC);
1956     parameters[numberParameters-1].append("on");
1957     parameters[numberParameters-1].append("both");
1958     parameters[numberParameters-1].append("before");
1959     parameters[numberParameters++] =
1960          CbcOrClpParam("DivingF!ractional", "Whether to try DiveFractional",
1961                        "off", CBC_PARAM_STR_DIVINGF);
1962     parameters[numberParameters-1].append("on");
1963     parameters[numberParameters-1].append("both");
1964     parameters[numberParameters-1].append("before");
1965     parameters[numberParameters++] =
1966          CbcOrClpParam("DivingG!uided", "Whether to try DiveGuided",
1967                        "off", CBC_PARAM_STR_DIVINGG);
1968     parameters[numberParameters-1].append("on");
1969     parameters[numberParameters-1].append("both");
1970     parameters[numberParameters-1].append("before");
1971     parameters[numberParameters++] =
1972          CbcOrClpParam("DivingL!ineSearch", "Whether to try DiveLineSearch",
1973                        "off", CBC_PARAM_STR_DIVINGL);
1974     parameters[numberParameters-1].append("on");
1975     parameters[numberParameters-1].append("both");
1976     parameters[numberParameters-1].append("before");
1977     parameters[numberParameters++] =
1978          CbcOrClpParam("DivingP!seudoCost", "Whether to try DivePseudoCost",
1979                        "off", CBC_PARAM_STR_DIVINGP);
1980     parameters[numberParameters-1].append("on");
1981     parameters[numberParameters-1].append("both");
1982     parameters[numberParameters-1].append("before");
1983     parameters[numberParameters++] =
1984          CbcOrClpParam("DivingV!ectorLength", "Whether to try DiveVectorLength",
1985                        "off", CBC_PARAM_STR_DIVINGV);
1986     parameters[numberParameters-1].append("on");
1987     parameters[numberParameters-1].append("both");
1988     parameters[numberParameters-1].append("before");
1989     parameters[numberParameters++] =
1990          CbcOrClpParam("doH!euristic", "Do heuristics before any preprocessing",
1991                        CBC_PARAM_ACTION_DOHEURISTIC, 3);
1992     parameters[numberParameters-1].setLonghelp
1993     (
1994          "Normally heuristics are done in branch and bound.  It may be useful to do them outside. \
1995Only those heuristics with 'both' or 'before' set will run.  \
1996Doing this may also set cutoff, which can help with preprocessing."
1997     );
1998#endif
1999#ifdef COIN_HAS_CLP
2000     parameters[numberParameters++] =
2001          CbcOrClpParam("dualB!ound", "Initially algorithm acts as if no \
2002gap between bounds exceeds this value",
2003                        1.0e-20, 1.0e12, CLP_PARAM_DBL_DUALBOUND);
2004     parameters[numberParameters-1].setLonghelp
2005     (
2006          "The dual algorithm in Clp is a single phase algorithm as opposed to a two phase\
2007 algorithm where you first get feasible then optimal.  If a problem has both upper and\
2008 lower bounds then it is trivial to get dual feasible by setting non basic variables\
2009 to correct bound.  If the gap between the upper and lower bounds of a variable is more\
2010 than the value of dualBound Clp introduces fake bounds so that it can make the problem\
2011 dual feasible.  This has the same effect as a composite objective function in the\
2012 primal algorithm.  Too high a value may mean more iterations, while too low a bound means\
2013 the code may go all the way and then have to increase the bounds.  OSL had a heuristic to\
2014 adjust bounds, maybe we need that here."
2015     );
2016     parameters[numberParameters++] =
2017          CbcOrClpParam("dualize", "Solves dual reformulation",
2018                        0, 4, CLP_PARAM_INT_DUALIZE, 1);
2019     parameters[numberParameters-1].setLonghelp
2020     (
2021          "Don't even think about it."
2022     );
2023     parameters[numberParameters++] =
2024          CbcOrClpParam("dualP!ivot", "Dual pivot choice algorithm",
2025                        "auto!matic", CLP_PARAM_STR_DUALPIVOT, 7, 1);
2026     parameters[numberParameters-1].append("dant!zig");
2027     parameters[numberParameters-1].append("partial");
2028     parameters[numberParameters-1].append("steep!est");
2029     parameters[numberParameters-1].setLonghelp
2030     (
2031          "Clp can use any pivot selection algorithm which the user codes as long as it\
2032 implements the features in the abstract pivot base class.  The Dantzig method is implemented\
2033 to show a simple method but its use is deprecated.  Steepest is the method of choice and there\
2034 are two variants which keep all weights updated but only scan a subset each iteration.\
2035 Partial switches this on while automatic decides at each iteration based on information\
2036 about the factorization."
2037     );
2038     parameters[numberParameters++] =
2039          CbcOrClpParam("dualS!implex", "Do dual simplex algorithm",
2040                        CLP_PARAM_ACTION_DUALSIMPLEX);
2041     parameters[numberParameters-1].setLonghelp
2042     (
2043          "This command solves the continuous relaxation of the current model using the dual steepest edge algorithm.\
2044The time and iterations may be affected by settings such as presolve, scaling, crash\
2045 and also by dual pivot method, fake bound on variables and dual and primal tolerances."
2046     );
2047#endif
2048     parameters[numberParameters++] =
2049          CbcOrClpParam("dualT!olerance", "For an optimal solution \
2050no dual infeasibility may exceed this value",
2051                        1.0e-20, 1.0e12, CLP_PARAM_DBL_DUALTOLERANCE);
2052     parameters[numberParameters-1].setLonghelp
2053     (
2054          "Normally the default tolerance is fine, but you may want to increase it a\
2055 bit if a dual run seems to be having a hard time.  One method which can be faster is \
2056to use a large tolerance e.g. 1.0e-4 and dual and then clean up problem using primal and the \
2057correct tolerance (remembering to switch off presolve for this final short clean up phase)."
2058     );
2059#ifdef COIN_HAS_CBC
2060     parameters[numberParameters++] =
2061          CbcOrClpParam("dw!Heuristic", "Whether to try DW heuristic",
2062                        "off", CBC_PARAM_STR_DW);
2063     parameters[numberParameters-1].append("on");
2064     parameters[numberParameters-1].append("both");
2065     parameters[numberParameters-1].append("before");
2066     parameters[numberParameters-1].setLonghelp
2067     (
2068      "See Rounding for meaning of on,both,before"
2069     );
2070#endif
2071#ifdef COIN_HAS_CLP
2072     parameters[numberParameters++] =
2073          CbcOrClpParam("either!Simplex", "Do dual or primal simplex algorithm",
2074                        CLP_PARAM_ACTION_EITHERSIMPLEX);
2075     parameters[numberParameters-1].setLonghelp
2076     (
2077          "This command solves the continuous relaxation of the current model using the dual or primal algorithm,\
2078 based on a dubious analysis of model."
2079     );
2080#endif
2081     parameters[numberParameters++] =
2082          CbcOrClpParam("end", "Stops clp execution",
2083                        CLP_PARAM_ACTION_EXIT);
2084     parameters[numberParameters-1].setLonghelp
2085     (
2086          "This stops execution ; end, exit, quit and stop are synonyms"
2087     );
2088     parameters[numberParameters++] =
2089          CbcOrClpParam("environ!ment", "Read commands from environment",
2090                        CLP_PARAM_ACTION_ENVIRONMENT, 7, 0);
2091     parameters[numberParameters-1].setLonghelp
2092     (
2093          "This starts reading from environment variable CBC_CLP_ENVIRONMENT."
2094     );
2095     parameters[numberParameters++] =
2096          CbcOrClpParam("error!sAllowed", "Whether to allow import errors",
2097                        "off", CLP_PARAM_STR_ERRORSALLOWED, 3);
2098     parameters[numberParameters-1].append("on");
2099     parameters[numberParameters-1].setLonghelp
2100     (
2101          "The default is not to use any model which had errors when reading the mps file.\
2102  Setting this to 'on' will allow all errors from which the code can recover\
2103 simply by ignoring the error.  There are some errors from which the code can not recover \
2104e.g. no ENDATA.  This has to be set before import i.e. -errorsAllowed on -import xxxxxx.mps."
2105     );
2106     parameters[numberParameters++] =
2107          CbcOrClpParam("exit", "Stops clp execution",
2108                        CLP_PARAM_ACTION_EXIT);
2109     parameters[numberParameters-1].setLonghelp
2110     (
2111          "This stops the execution of Clp, end, exit, quit and stop are synonyms"
2112     );
2113#ifdef COIN_HAS_CBC
2114     parameters[numberParameters++] =
2115          CbcOrClpParam("exper!iment", "Whether to use testing features",
2116                        -1, 200, CBC_PARAM_INT_EXPERIMENT, 0);
2117     parameters[numberParameters-1].setLonghelp
2118     (
2119          "Defines how adventurous you want to be in using new ideas. \
21200 then no new ideas, 1 fairly sensible, 2 a bit dubious, 3 you are on your own!"
2121     );
2122     parameters[numberParameters-1].setIntValue(0);
2123     parameters[numberParameters++] =
2124          CbcOrClpParam("expensive!Strong", "Whether to do even more strong branching",
2125                        0, COIN_INT_MAX, CBC_PARAM_INT_STRONG_STRATEGY, 0);
2126     parameters[numberParameters-1].setLonghelp
2127     (
2128      "Strategy for extra strong branching \n\
2129\n\t0 - normal\n\
2130\n\twhen to do all fractional\n\
2131\n\t1 - root node\n\
2132\n\t2 - depth less than modifier\n\
2133\n\t4 - if objective == best possible\n\
2134\n\t6 - as 2+4\n\
2135\n\twhen to do all including satisfied\n\
2136\n\t10 - root node etc.\n\
2137\n\tIf >=100 then do when depth <= strategy/100 (otherwise 5)"
2138     );
2139     parameters[numberParameters-1].setIntValue(0);
2140#endif
2141     parameters[numberParameters++] =
2142          CbcOrClpParam("export", "Export model as mps file",
2143                        CLP_PARAM_ACTION_EXPORT);
2144     parameters[numberParameters-1].setLonghelp
2145     (
2146          "This will write an MPS format file to the given file name.  It will use the default\
2147 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
2148 is initialized to 'default.mps'.  \
2149It can be useful to get rid of the original names and go over to using Rnnnnnnn and Cnnnnnnn.  This can be done by setting 'keepnames' off before importing mps file."
2150     );
2151#ifdef COIN_HAS_CBC
2152     parameters[numberParameters++] =
2153          CbcOrClpParam("extra1", "Extra integer parameter 1",
2154                        -COIN_INT_MAX, COIN_INT_MAX, CBC_PARAM_INT_EXTRA1, 0);
2155     parameters[numberParameters-1].setIntValue(-1);
2156     parameters[numberParameters++] =
2157          CbcOrClpParam("extra2", "Extra integer parameter 2",
2158                        -100, COIN_INT_MAX, CBC_PARAM_INT_EXTRA2, 0);
2159     parameters[numberParameters-1].setIntValue(-1);
2160     parameters[numberParameters++] =
2161          CbcOrClpParam("extra3", "Extra integer parameter 3",
2162                        -1, COIN_INT_MAX, CBC_PARAM_INT_EXTRA3, 0);
2163     parameters[numberParameters-1].setIntValue(-1);
2164     parameters[numberParameters++] =
2165          CbcOrClpParam("extra4", "Extra integer parameter 4",
2166                        -1, COIN_INT_MAX, CBC_PARAM_INT_EXTRA4, 0);
2167     parameters[numberParameters-1].setIntValue(-1);
2168     parameters[numberParameters-1].setLonghelp
2169     (
2170          "This switches on yet more special options!! \
2171The bottom digit is a strategy when to used shadow price stuff e.g. 3 \
2172means use until a solution is found.  The next two digits say what sort \
2173of dual information to use.  After that it goes back to powers of 2 so -\n\
2174\n\t1000 - switches on experimental hotstart\n\
2175\n\t2,4,6000 - switches on experimental methods of stopping cuts\n\
2176\n\t8000 - increase minimum drop gradually\n\
2177\n\t16000 - switches on alternate gomory criterion"
2178     );
2179     parameters[numberParameters++] =
2180       CbcOrClpParam("extraV!ariables", "Allow creation of extra integer variables",
2181                     -COIN_INT_MAX, COIN_INT_MAX, CBC_PARAM_INT_EXTRA_VARIABLES, 0);
2182     parameters[numberParameters-1].setIntValue(0);
2183     parameters[numberParameters-1].setLonghelp
2184     (
2185          "This switches on creation of extra integer variables \
2186to gather all variables with same cost."
2187     );
2188#endif
2189#ifdef COIN_HAS_CLP
2190     parameters[numberParameters++] =
2191          CbcOrClpParam("fact!orization", "Which factorization to use",
2192                        "normal", CLP_PARAM_STR_FACTORIZATION);
2193     parameters[numberParameters-1].append("dense");
2194     parameters[numberParameters-1].append("simple");
2195     parameters[numberParameters-1].append("osl");
2196     parameters[numberParameters-1].setLonghelp
2197     (
2198#ifndef ABC_INHERIT
2199          "The default is to use the normal CoinFactorization, but \
2200other choices are a dense one, osl's or one designed for small problems."
2201#else
2202          "Normally the default is to use the normal CoinFactorization, but \
2203other choices are a dense one, osl's or one designed for small problems. \
2204However if at Aboca then the default is CoinAbcFactorization and other choices are \
2205a dense one, one designed for small problems or if enabled a long factorization."
2206#endif
2207     );
2208     parameters[numberParameters++] =
2209          CbcOrClpParam("fakeB!ound", "All bounds <= this value - DEBUG",
2210                        1.0, 1.0e15, CLP_PARAM_ACTION_FAKEBOUND, 0);
2211#ifdef COIN_HAS_CBC
2212     parameters[numberParameters++] =
2213          CbcOrClpParam("feas!ibilityPump", "Whether to try Feasibility Pump",
2214                        "off", CBC_PARAM_STR_FPUMP);
2215     parameters[numberParameters-1].append("on");
2216     parameters[numberParameters-1].append("both");
2217     parameters[numberParameters-1].append("before");
2218     parameters[numberParameters-1].setLonghelp
2219     (
2220          "This switches on feasibility pump heuristic at root. This is due to Fischetti, Lodi and Glover \
2221and uses a sequence of Lps to try and get an integer feasible solution. \
2222Some fine tuning is available by passFeasibilityPump and also pumpTune. \
2223See Rounding for meaning of on,both,before"
2224     );
2225     parameters[numberParameters++] =
2226          CbcOrClpParam("fix!OnDj", "Try heuristic based on fixing variables with \
2227reduced costs greater than this",
2228                        -1.0e20, 1.0e20, CBC_PARAM_DBL_DJFIX, 1);
2229     parameters[numberParameters-1].setLonghelp
2230     (
2231          "If this is set integer variables with reduced costs greater than this will be fixed \
2232before branch and bound - use with extreme caution!"
2233     );
2234     parameters[numberParameters++] =
2235          CbcOrClpParam("flow!CoverCuts", "Whether to use Flow Cover cuts",
2236                        "off", CBC_PARAM_STR_FLOWCUTS);
2237     parameters[numberParameters-1].append("on");
2238     parameters[numberParameters-1].append("root");
2239     parameters[numberParameters-1].append("ifmove");
2240     parameters[numberParameters-1].append("forceOn");
2241     parameters[numberParameters-1].append("onglobal");
2242     parameters[numberParameters-1].setFakeKeyWord(3);
2243     parameters[numberParameters-1].setLonghelp
2244     (
2245          "This switches on flow cover cuts (either at root or in entire tree) \
2246See branchAndCut for information on options. \
2247Can also enter testing values by plusnn (==ifmove)"
2248     );
2249     parameters[numberParameters++] =
2250          CbcOrClpParam("force!Solution", "Whether to use given solution as crash for BAB",
2251                        -1, 20000000, CLP_PARAM_INT_USESOLUTION);
2252     parameters[numberParameters-1].setIntValue(-1);
2253     parameters[numberParameters-1].setLonghelp
2254     (
2255          "-1 off.  If 1 then tries to branch to solution given by AMPL or priorities file. \
2256If 0 then just tries to set as best solution \
2257If >1 then also does that many nodes on fixed problem."
2258     );
2259     parameters[numberParameters++] =
2260          CbcOrClpParam("fraction!forBAB", "Fraction in feasibility pump",
2261                        1.0e-5, 1.1, CBC_PARAM_DBL_SMALLBAB, 1);
2262     parameters[numberParameters-1].setDoubleValue(0.5);
2263     parameters[numberParameters-1].setLonghelp
2264     (
2265          "After a pass in feasibility pump, variables which have not moved \
2266about are fixed and if the preprocessed model is small enough a few nodes \
2267of branch and bound are done on reduced problem.  Small problem has to be less than this fraction of original."
2268     );
2269#endif
2270     parameters[numberParameters++] =
2271          CbcOrClpParam("gamma!(Delta)", "Whether to regularize barrier",
2272                        "off", CLP_PARAM_STR_GAMMA, 7, 1);
2273     parameters[numberParameters-1].append("on");
2274     parameters[numberParameters-1].append("gamma");
2275     parameters[numberParameters-1].append("delta");
2276     parameters[numberParameters-1].append("onstrong");
2277     parameters[numberParameters-1].append("gammastrong");
2278     parameters[numberParameters-1].append("deltastrong");
2279#endif
2280#ifdef COIN_HAS_CBC
2281      parameters[numberParameters++] =
2282          CbcOrClpParam("GMI!Cuts", "Whether to use alternative Gomory cuts",
2283                        "off", CBC_PARAM_STR_GMICUTS);
2284     parameters[numberParameters-1].append("on");
2285     parameters[numberParameters-1].append("root");
2286     parameters[numberParameters-1].append("ifmove");
2287     parameters[numberParameters-1].append("forceOn");
2288     parameters[numberParameters-1].append("endonly");
2289     parameters[numberParameters-1].append("long");
2290     parameters[numberParameters-1].append("longroot");
2291     parameters[numberParameters-1].append("longifmove");
2292     parameters[numberParameters-1].append("forceLongOn");
2293     parameters[numberParameters-1].append("longendonly");
2294     parameters[numberParameters-1].setLonghelp
2295     (
2296          "This switches on an alternative Gomory cut generator (either at root or in entire tree) \
2297This version is by Giacomo Nannicini and may be more robust \
2298See branchAndCut for information on options."
2299     );
2300     parameters[numberParameters++] =
2301          CbcOrClpParam("gomory!Cuts", "Whether to use Gomory cuts",
2302                        "off", CBC_PARAM_STR_GOMORYCUTS);
2303     parameters[numberParameters-1].append("on");
2304     parameters[numberParameters-1].append("root");
2305     parameters[numberParameters-1].append("ifmove");
2306     parameters[numberParameters-1].append("forceOn");
2307     parameters[numberParameters-1].append("onglobal");
2308     parameters[numberParameters-1].append("forceandglobal");
2309     parameters[numberParameters-1].append("forceLongOn");
2310     parameters[numberParameters-1].append("long");
2311     parameters[numberParameters-1].setLonghelp
2312     (
2313          "The original cuts - beware of imitations!  Having gone out of favor, they are now more \
2314fashionable as LP solvers are more robust and they interact well with other cuts.  They will almost always \
2315give cuts (although in this executable they are limited as to number of variables in cut).  \
2316However the cuts may be dense so it is worth experimenting (Long allows any length). \
2317See branchAndCut for information on options."
2318     );
2319     parameters[numberParameters++] =
2320          CbcOrClpParam("greedy!Heuristic", "Whether to use a greedy heuristic",
2321                        "off", CBC_PARAM_STR_GREEDY);
2322     parameters[numberParameters-1].append("on");
2323     parameters[numberParameters-1].append("both");
2324     parameters[numberParameters-1].append("before");
2325     //parameters[numberParameters-1].append("root");
2326     parameters[numberParameters-1].setLonghelp
2327     (
2328          "Switches on a greedy heuristic which will try and obtain a solution.  It may just fix a \
2329percentage of variables and then try a small branch and cut run. \
2330See Rounding for meaning of on,both,before"
2331     );
2332#endif
2333     parameters[numberParameters++] =
2334          CbcOrClpParam("gsolu!tion", "Puts glpk solution to file",
2335                        CLP_PARAM_ACTION_GMPL_SOLUTION);
2336     parameters[numberParameters-1].setLonghelp
2337     (
2338          "Will write a glpk solution file to the given file name.  It will use the default\
2339 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
2340 is initialized to 'stdout' (this defaults to ordinary solution if stdout). \
2341If problem created from gmpl model - will do any reports."
2342     );
2343#ifdef COIN_HAS_CBC
2344     parameters[numberParameters++] =
2345          CbcOrClpParam("heur!isticsOnOff", "Switches most heuristics on or off",
2346                        "off", CBC_PARAM_STR_HEURISTICSTRATEGY);
2347     parameters[numberParameters-1].append("on");
2348     parameters[numberParameters-1].setLonghelp
2349     (
2350          "This can be used to switch on or off all heuristics.  Then you can do \
2351individual ones off or on.  CbcTreeLocal is not included as it dramatically \
2352alters search."
2353     );
2354#endif
2355     parameters[numberParameters++] =
2356          CbcOrClpParam("help", "Print out version, non-standard options and some help",
2357                        CLP_PARAM_ACTION_HELP, 3);
2358     parameters[numberParameters-1].setLonghelp
2359     (
2360          "This prints out some help to get user started.  If you have printed this then \
2361you should be past that stage:-)"
2362     );
2363#ifdef COIN_HAS_CBC
2364     parameters[numberParameters++] =
2365          CbcOrClpParam("hOp!tions", "Heuristic options",
2366                        -9999999, 9999999, CBC_PARAM_INT_HOPTIONS, 1);
2367     parameters[numberParameters-1].setLonghelp
2368     (
2369          "1 says stop heuristic immediately allowable gap reached. \
2370Others are for feasibility pump - \
23712 says do exact number of passes given, \
23724 only applies if initial cutoff given and says relax after 50 passes, \
2373while 8 will adapt cutoff rhs after first solution if it looks as if code is stalling."
2374     );
2375     parameters[numberParameters-1].setIntValue(0);
2376     parameters[numberParameters++] =
2377          CbcOrClpParam("hot!StartMaxIts", "Maximum iterations on hot start",
2378                        0, COIN_INT_MAX, CBC_PARAM_INT_MAXHOTITS);
2379#endif
2380#ifdef COIN_HAS_CLP
2381     parameters[numberParameters++] =
2382          CbcOrClpParam("idiot!Crash", "Whether to try idiot crash",
2383                        -1, 99999999, CLP_PARAM_INT_IDIOT);
2384     parameters[numberParameters-1].setLonghelp
2385     (
2386          "This is a type of 'crash' which works well on some homogeneous problems.\
2387 It works best on problems with unit elements and rhs but will do something to any model.  It should only be\
2388 used before primal.  It can be set to -1 when the code decides for itself whether to use it,\
2389 0 to switch off or n > 0 to do n passes."
2390     );
2391#endif
2392     parameters[numberParameters++] =
2393          CbcOrClpParam("import", "Import model from mps file",
2394                        CLP_PARAM_ACTION_IMPORT, 3);
2395     parameters[numberParameters-1].setLonghelp
2396     (
2397          "This will read an MPS format file from the given file name.  It will use the default\
2398 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
2399 is initialized to '', i.e. it must be set.  If you have libgz then it can read compressed\
2400 files 'xxxxxxxx.gz' or 'xxxxxxxx.bz2'.  \
2401If 'keepnames' is off, then names are dropped -> Rnnnnnnn and Cnnnnnnn."
2402     );
2403#ifdef COIN_HAS_CBC
2404     parameters[numberParameters++] =
2405          CbcOrClpParam("inc!rement", "A valid solution must be at least this \
2406much better than last integer solution",
2407                        -1.0e20, 1.0e20, CBC_PARAM_DBL_INCREMENT);
2408     parameters[numberParameters-1].setLonghelp
2409     (
2410          "Whenever a solution is found the bound on solutions is set to solution (in a minimization\
2411sense) plus this.  If it is not set then the code will try and work one out e.g. if \
2412all objective coefficients are multiples of 0.01 and only integer variables have entries in \
2413objective then this can be set to 0.01.  Be careful if you set this negative!"
2414     );
2415     parameters[numberParameters++] =
2416          CbcOrClpParam("inf!easibilityWeight", "Each integer infeasibility is expected \
2417to cost this much",
2418                        0.0, 1.0e20, CBC_PARAM_DBL_INFEASIBILITYWEIGHT, 1);
2419     parameters[numberParameters-1].setLonghelp
2420     (
2421          "A primitive way of deciding which node to explore next.  Satisfying each integer infeasibility is \
2422expected to cost this much."
2423     );
2424     parameters[numberParameters++] =
2425          CbcOrClpParam("initialS!olve", "Solve to continuous",
2426                        CLP_PARAM_ACTION_SOLVECONTINUOUS);
2427     parameters[numberParameters-1].setLonghelp
2428     (
2429          "This just solves the problem to continuous - without adding any cuts"
2430     );
2431     parameters[numberParameters++] =
2432          CbcOrClpParam("integerT!olerance", "For an optimal solution \
2433no integer variable may be this away from an integer value",
2434                        1.0e-20, 0.5, CBC_PARAM_DBL_INTEGERTOLERANCE);
2435     parameters[numberParameters-1].setLonghelp
2436     (
2437          "Beware of setting this smaller than the primal tolerance."
2438     );
2439#endif
2440#ifdef COIN_HAS_CLP
2441     parameters[numberParameters++] =
2442          CbcOrClpParam("keepN!ames", "Whether to keep names from import",
2443                        "on", CLP_PARAM_STR_KEEPNAMES);
2444     parameters[numberParameters-1].append("off");
2445     parameters[numberParameters-1].setLonghelp
2446     (
2447          "It saves space to get rid of names so if you need to you can set this to off.  \
2448This needs to be set before the import of model - so -keepnames off -import xxxxx.mps."
2449     );
2450     parameters[numberParameters++] =
2451          CbcOrClpParam("KKT", "Whether to use KKT factorization",
2452                        "off", CLP_PARAM_STR_KKT, 7, 1);
2453     parameters[numberParameters-1].append("on");
2454#endif
2455#ifdef COIN_HAS_CBC
2456     parameters[numberParameters++] =
2457          CbcOrClpParam("knapsack!Cuts", "Whether to use Knapsack cuts",
2458                        "off", CBC_PARAM_STR_KNAPSACKCUTS);
2459     parameters[numberParameters-1].append("on");
2460     parameters[numberParameters-1].append("root");
2461     parameters[numberParameters-1].append("ifmove");
2462     parameters[numberParameters-1].append("forceOn");
2463     parameters[numberParameters-1].append("onglobal");
2464     parameters[numberParameters-1].append("forceandglobal");
2465     parameters[numberParameters-1].setLonghelp
2466     (
2467          "This switches on knapsack cuts (either at root or in entire tree) \
2468See branchAndCut for information on options."
2469     );
2470     parameters[numberParameters++] =
2471          CbcOrClpParam("lagomory!Cuts", "Whether to use Lagrangean Gomory cuts",
2472                        "off", CBC_PARAM_STR_LAGOMORYCUTS);
2473     parameters[numberParameters-1].append("endonlyroot");
2474     parameters[numberParameters-1].append("endcleanroot");
2475     parameters[numberParameters-1].append("endbothroot");
2476     parameters[numberParameters-1].append("endonly");
2477     parameters[numberParameters-1].append("endclean");
2478     parameters[numberParameters-1].append("endboth");
2479     parameters[numberParameters-1].append("onlyaswell");
2480     parameters[numberParameters-1].append("cleanaswell");
2481     parameters[numberParameters-1].append("bothaswell");
2482     parameters[numberParameters-1].append("onlyinstead");
2483     parameters[numberParameters-1].append("cleaninstead");
2484     parameters[numberParameters-1].append("bothinstead");
2485     parameters[numberParameters-1].setLonghelp
2486     (
2487          "This is a gross simplification of 'A Relax-and-Cut Framework for Gomory's Mixed-Integer Cuts' \
2488by Matteo Fischetti & Domenico Salvagnin.  This simplification \
2489just uses original constraints while modifying objective using other cuts. \
2490So you don't use messy constraints generated by Gomory etc. \
2491A variant is to allow non messy cuts e.g. clique cuts. \
2492So 'only' does this while clean also allows integral valued cuts.  \
2493'End' is recommended which waits until other cuts have finished and then \
2494does a few passes. \
2495The length options for gomory cuts are used."
2496     );
2497     parameters[numberParameters++] =
2498          CbcOrClpParam("latwomir!Cuts", "Whether to use Lagrangean TwoMir cuts",
2499                        "off", CBC_PARAM_STR_LATWOMIRCUTS);
2500     parameters[numberParameters-1].append("endonlyroot");
2501     parameters[numberParameters-1].append("endcleanroot");
2502     parameters[numberParameters-1].append("endbothroot");
2503     parameters[numberParameters-1].append("endonly");
2504     parameters[numberParameters-1].append("endclean");
2505     parameters[numberParameters-1].append("endboth");
2506     parameters[numberParameters-1].append("onlyaswell");
2507     parameters[numberParameters-1].append("cleanaswell");
2508     parameters[numberParameters-1].append("bothaswell");
2509     parameters[numberParameters-1].append("onlyinstead");
2510     parameters[numberParameters-1].append("cleaninstead");
2511     parameters[numberParameters-1].append("bothinstead");
2512     parameters[numberParameters-1].setLonghelp
2513     (
2514          "This is a lagrangean relaxation for TwoMir cuts.  See \
2515lagomoryCuts for description of options."
2516     );
2517     parameters[numberParameters++] =
2518          CbcOrClpParam("lift!AndProjectCuts", "Whether to use Lift and Project cuts",
2519                        "off", CBC_PARAM_STR_LANDPCUTS);
2520     parameters[numberParameters-1].append("on");
2521     parameters[numberParameters-1].append("root");
2522     parameters[numberParameters-1].append("ifmove");
2523     parameters[numberParameters-1].append("forceOn");
2524     parameters[numberParameters-1].setLonghelp
2525     (
2526          "Lift and project cuts. \
2527May be slow \
2528See branchAndCut for information on options."
2529     );
2530     parameters[numberParameters++] =
2531          CbcOrClpParam("local!TreeSearch", "Whether to use local treesearch",
2532                        "off", CBC_PARAM_STR_LOCALTREE);
2533     parameters[numberParameters-1].append("on");
2534     parameters[numberParameters-1].setLonghelp
2535     (
2536          "This switches on a local search algorithm when a solution is found.  This is from \
2537Fischetti and Lodi and is not really a heuristic although it can be used as one. \
2538When used from Coin solve it has limited functionality.  It is not switched on when \
2539heuristics are switched on."
2540     );
2541#endif
2542#ifndef COIN_HAS_CBC
2543     parameters[numberParameters++] =
2544          CbcOrClpParam("log!Level", "Level of detail in Solver output",
2545                        -1, 999999, CLP_PARAM_INT_SOLVERLOGLEVEL);
2546#else
2547     parameters[numberParameters++] =
2548          CbcOrClpParam("log!Level", "Level of detail in Coin branch and Cut output",
2549                        -63, 63, CLP_PARAM_INT_LOGLEVEL);
2550     parameters[numberParameters-1].setIntValue(1);
2551#endif
2552     parameters[numberParameters-1].setLonghelp
2553     (
2554          "If 0 then there should be no output in normal circumstances.  1 is probably the best\
2555 value for most uses, while 2 and 3 give more information."
2556     );
2557     parameters[numberParameters++] =
2558          CbcOrClpParam("max!imize", "Set optimization direction to maximize",
2559                        CLP_PARAM_ACTION_MAXIMIZE, 7);
2560     parameters[numberParameters-1].setLonghelp
2561     (
2562          "The default is minimize - use 'maximize' for maximization.\n\
2563You can also use the parameters 'direction maximize'."
2564     );
2565#ifdef COIN_HAS_CLP
2566     parameters[numberParameters++] =
2567          CbcOrClpParam("maxF!actor", "Maximum number of iterations between \
2568refactorizations",
2569                        1, 999999, CLP_PARAM_INT_MAXFACTOR);
2570     parameters[numberParameters-1].setLonghelp
2571     (
2572          "If this is at its initial value of 200 then in this executable clp will guess at a\
2573 value to use.  Otherwise the user can set a value.  The code may decide to re-factorize\
2574 earlier for accuracy."
2575     );
2576     parameters[numberParameters++] =
2577          CbcOrClpParam("maxIt!erations", "Maximum number of iterations before \
2578stopping",
2579                        0, 2147483647, CLP_PARAM_INT_MAXITERATION);
2580     parameters[numberParameters-1].setLonghelp
2581     (
2582          "This can be used for testing purposes.  The corresponding library call\n\
2583      \tsetMaximumIterations(value)\n can be useful.  If the code stops on\
2584 seconds or by an interrupt this will be treated as stopping on maximum iterations.  This is ignored in branchAndCut - use maxN!odes."
2585     );
2586#endif
2587#ifdef COIN_HAS_CBC
2588     parameters[numberParameters++] =
2589          CbcOrClpParam("maxN!odes", "Maximum number of nodes to do",
2590                        -1, 2147483647, CBC_PARAM_INT_MAXNODES);
2591     parameters[numberParameters-1].setLonghelp
2592     (
2593          "This is a repeatable way to limit search.  Normally using time is easier \
2594but then the results may not be repeatable."
2595     );
2596     parameters[numberParameters++] =
2597          CbcOrClpParam("maxSaved!Solutions", "Maximum number of solutions to save",
2598                        0, 2147483647, CBC_PARAM_INT_MAXSAVEDSOLS);
2599     parameters[numberParameters-1].setLonghelp
2600     (
2601          "Number of solutions to save."
2602     );
2603     parameters[numberParameters++] =
2604          CbcOrClpParam("maxSo!lutions", "Maximum number of solutions to get",
2605                        1, 2147483647, CBC_PARAM_INT_MAXSOLS);
2606     parameters[numberParameters-1].setLonghelp
2607     (
2608          "You may want to stop after (say) two solutions or an hour.  \
2609This is checked every node in tree, so it is possible to get more solutions from heuristics."
2610     );
2611#endif
2612     parameters[numberParameters++] =
2613          CbcOrClpParam("min!imize", "Set optimization direction to minimize",
2614                        CLP_PARAM_ACTION_MINIMIZE, 7);
2615     parameters[numberParameters-1].setLonghelp
2616     (
2617          "The default is minimize - use 'maximize' for maximization.\n\
2618This should only be necessary if you have previously set maximization \
2619You can also use the parameters 'direction minimize'."
2620     );
2621#ifdef COIN_HAS_CBC
2622     parameters[numberParameters++] =
2623          CbcOrClpParam("mipO!ptions", "Dubious options for mip",
2624                        0, COIN_INT_MAX, CBC_PARAM_INT_MIPOPTIONS, 0);
2625     parameters[numberParameters++] =
2626          CbcOrClpParam("more!MipOptions", "More dubious options for mip",
2627                        -1, COIN_INT_MAX, CBC_PARAM_INT_MOREMIPOPTIONS, 0);
2628     parameters[numberParameters++] =
2629          CbcOrClpParam("more2!MipOptions", "More more dubious options for mip",
2630                        -1, COIN_INT_MAX, CBC_PARAM_INT_MOREMOREMIPOPTIONS, 0);
2631     parameters[numberParameters-1].setIntValue(0);
2632     parameters[numberParameters++] =
2633          CbcOrClpParam("mixed!IntegerRoundingCuts", "Whether to use Mixed Integer Rounding cuts",
2634                        "off", CBC_PARAM_STR_MIXEDCUTS);
2635     parameters[numberParameters-1].append("on");
2636     parameters[numberParameters-1].append("root");
2637     parameters[numberParameters-1].append("ifmove");
2638     parameters[numberParameters-1].append("forceOn");
2639     parameters[numberParameters-1].append("onglobal");
2640     parameters[numberParameters-1].setLonghelp
2641     (
2642          "This switches on mixed integer rounding cuts (either at root or in entire tree) \
2643See branchAndCut for information on options."
2644     );
2645#endif
2646     parameters[numberParameters++] =
2647          CbcOrClpParam("mess!ages", "Controls if Clpnnnn is printed",
2648                        "off", CLP_PARAM_STR_MESSAGES);
2649     parameters[numberParameters-1].append("on");
2650     parameters[numberParameters-1].setLonghelp
2651     ("The default behavior is to put out messages such as:\n\
2652   Clp0005 2261  Objective 109.024 Primal infeas 944413 (758)\n\
2653but this program turns this off to make it look more friendly.  It can be useful\
2654 to turn them back on if you want to be able to 'grep' for particular messages or if\
2655 you intend to override the behavior of a particular message.  This only affects Clp not Cbc."
2656     );
2657     parameters[numberParameters++] =
2658          CbcOrClpParam("miplib", "Do some of miplib test set",
2659                        CBC_PARAM_ACTION_MIPLIB, 3, 1);
2660#ifdef COIN_HAS_CBC
2661      parameters[numberParameters++] =
2662          CbcOrClpParam("mips!tart", "reads an initial feasible solution from file",
2663                        CBC_PARAM_ACTION_MIPSTART);
2664     parameters[numberParameters-1].setLonghelp
2665     ("\
2666The MIPStart allows one to enter an initial integer feasible solution \
2667to CBC. Values of the main decision variables which are active (have \
2668non-zero values) in this solution are specified in a text  file. The \
2669text file format used is the same of the solutions saved by CBC, but \
2670not all fields are required to be filled. First line may contain the \
2671solution status and will be ignored, remaining lines contain column \
2672indexes, names and values as in this example:\n\
2673\n\
2674Stopped on iterations - objective value 57597.00000000\n\
2675      0  x(1,1,2,2)               1 \n\
2676      1  x(3,1,3,2)               1 \n\
2677      5  v(5,1)                   2 \n\
2678      33 x(8,1,5,2)               1 \n\
2679      ...\n\
2680\n\
2681Column indexes are also ignored since pre-processing can change them. \
2682There is no need to include values for continuous or integer auxiliary \
2683variables, since they can be computed based on main decision variables. \
2684Starting CBC with an integer feasible solution can dramatically improve \
2685its performance: several MIP heuristics (e.g. RINS) rely on having at \
2686least one feasible solution available and can start immediately if the \
2687user provides one. Feasibility Pump (FP) is a heuristic which tries to \
2688overcome the problem of taking too long to find feasible solution (or \
2689not finding at all), but it not always succeeds. If you provide one \
2690starting solution you will probably save some time by disabling FP. \
2691\n\n\
2692Knowledge specific to your problem can be considered to write an \
2693external module to quickly produce an initial feasible solution - some \
2694alternatives are the implementation of simple greedy heuristics or the \
2695solution (by CBC for example) of a simpler model created just to find \
2696a feasible solution. \
2697\n\n\
2698Question and suggestions regarding MIPStart can be directed to\n\
2699haroldo.santos@gmail.com.\
2700");
2701#endif
2702     parameters[numberParameters++] =
2703          CbcOrClpParam("moreS!pecialOptions", "Yet more dubious options for Simplex - see ClpSimplex.hpp",
2704                        0, COIN_INT_MAX, CLP_PARAM_INT_MORESPECIALOPTIONS, 0);
2705#ifdef COIN_HAS_CBC
2706     parameters[numberParameters++] =
2707          CbcOrClpParam("moreT!une", "Yet more dubious ideas for feasibility pump",
2708                        0, 100000000, CBC_PARAM_INT_FPUMPTUNE2, 0);
2709     parameters[numberParameters-1].setLonghelp
2710     (
2711          "Yet more ideas for Feasibility Pump \n\
2712\t/100000 == 1 use box constraints and original obj in cleanup\n\
2713\t/1000 == 1 Pump will run twice if no solution found\n\
2714\t/1000 == 2 Pump will only run after root cuts if no solution found\n\
2715\t/1000 >10 as above but even if solution found\n\
2716\t/100 == 1,3.. exact 1.0 for objective values\n\
2717\t/100 == 2,3.. allow more iterations per pass\n\
2718\t n fix if value of variable same for last n iterations."
2719     );
2720     parameters[numberParameters-1].setIntValue(0);
2721     parameters[numberParameters++] =
2722          CbcOrClpParam("multiple!RootPasses", "Do multiple root passes to collect cuts and solutions",
2723                        0, 100000000, CBC_PARAM_INT_MULTIPLEROOTS, 0);
2724     parameters[numberParameters-1].setIntValue(0);
2725     parameters[numberParameters-1].setLonghelp
2726     (
2727          "Do (in parallel if threads enabled) the root phase this number of times \
2728 and collect all solutions and cuts generated.  The actual format is aabbcc \
2729where aa is number of extra passes, if bb is non zero \
2730then it is number of threads to use (otherwise uses threads setting) and \
2731cc is number of times to do root phase.  Yet another one from the Italian idea factory \
2732(This time - Andrea Lodi , Matteo Fischetti , Michele Monaci , Domenico Salvagnin , \
2733and Andrea Tramontani). \
2734The solvers do not interact with each other.  However if extra passes are specified \
2735then cuts are collected and used in later passes - so there is interaction there." 
2736     );
2737     parameters[numberParameters++] =
2738          CbcOrClpParam("naive!Heuristics", "Whether to try some stupid heuristic",
2739                        "off", CBC_PARAM_STR_NAIVE, 7, 1);
2740     parameters[numberParameters-1].append("on");
2741     parameters[numberParameters-1].append("both");
2742     parameters[numberParameters-1].append("before");
2743     parameters[numberParameters-1].setLonghelp
2744     (
2745          "Really silly stuff e.g. fix all integers with costs to zero!. \
2746Doh option does heuristic before preprocessing"     );
2747#endif
2748#ifdef COIN_HAS_CLP
2749     parameters[numberParameters++] =
2750          CbcOrClpParam("netlib", "Solve entire netlib test set",
2751                        CLP_PARAM_ACTION_NETLIB_EITHER, 3, 1);
2752     parameters[numberParameters-1].setLonghelp
2753     (
2754          "This exercises the unit test for clp and then solves the netlib test set using dual or primal.\
2755The user can set options before e.g. clp -presolve off -netlib"
2756     );
2757     parameters[numberParameters++] =
2758          CbcOrClpParam("netlibB!arrier", "Solve entire netlib test set with barrier",
2759                        CLP_PARAM_ACTION_NETLIB_BARRIER, 3, 1);
2760     parameters[numberParameters-1].setLonghelp
2761     (
2762          "This exercises the unit test for clp and then solves the netlib test set using barrier.\
2763The user can set options before e.g. clp -kkt on -netlib"
2764     );
2765     parameters[numberParameters++] =
2766          CbcOrClpParam("netlibD!ual", "Solve entire netlib test set (dual)",
2767                        CLP_PARAM_ACTION_NETLIB_DUAL, 3, 1);
2768     parameters[numberParameters-1].setLonghelp
2769     (
2770          "This exercises the unit test for clp and then solves the netlib test set using dual.\
2771The user can set options before e.g. clp -presolve off -netlib"
2772     );
2773     parameters[numberParameters++] =
2774          CbcOrClpParam("netlibP!rimal", "Solve entire netlib test set (primal)",
2775                        CLP_PARAM_ACTION_NETLIB_PRIMAL, 3, 1);
2776     parameters[numberParameters-1].setLonghelp
2777     (
2778          "This exercises the unit test for clp and then solves the netlib test set using primal.\
2779The user can set options before e.g. clp -presolve off -netlibp"
2780     );
2781     parameters[numberParameters++] =
2782          CbcOrClpParam("netlibT!une", "Solve entire netlib test set with 'best' algorithm",
2783                        CLP_PARAM_ACTION_NETLIB_TUNE, 3, 1);
2784     parameters[numberParameters-1].setLonghelp
2785     (
2786          "This exercises the unit test for clp and then solves the netlib test set using whatever \
2787works best.  I know this is cheating but it also stresses the code better by doing a \
2788mixture of stuff.  The best algorithm was chosen on a Linux ThinkPad using native cholesky \
2789with University of Florida ordering."
2790     );
2791     parameters[numberParameters++] =
2792          CbcOrClpParam("network", "Tries to make network matrix",
2793                        CLP_PARAM_ACTION_NETWORK, 7, 0);
2794     parameters[numberParameters-1].setLonghelp
2795     (
2796          "Clp will go faster if the matrix can be converted to a network.  The matrix\
2797 operations may be a bit faster with more efficient storage, but the main advantage\
2798 comes from using a network factorization.  It will probably not be as fast as a \
2799specialized network code."
2800     );
2801#ifdef COIN_HAS_CBC
2802     parameters[numberParameters++] =
2803          CbcOrClpParam("nextB!estSolution", "Prints next best saved solution to file",
2804                        CLP_PARAM_ACTION_NEXTBESTSOLUTION);
2805     parameters[numberParameters-1].setLonghelp
2806     (
2807          "To write best solution, just use solution.  This prints next best (if exists) \
2808 and then deletes it. \
2809 This will write a primitive solution file to the given file name.  It will use the default\
2810 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
2811 is initialized to 'stdout'.  The amount of output can be varied using printi!ngOptions or printMask."
2812     );
2813     parameters[numberParameters++] =
2814          CbcOrClpParam("node!Strategy", "What strategy to use to select nodes",
2815                        "hybrid", CBC_PARAM_STR_NODESTRATEGY);
2816     parameters[numberParameters-1].append("fewest");
2817     parameters[numberParameters-1].append("depth");
2818     parameters[numberParameters-1].append("upfewest");
2819     parameters[numberParameters-1].append("downfewest");
2820     parameters[numberParameters-1].append("updepth");
2821     parameters[numberParameters-1].append("downdepth");
2822     parameters[numberParameters-1].setLonghelp
2823     (
2824          "Normally before a solution the code will choose node with fewest infeasibilities. \
2825You can choose depth as the criterion.  You can also say if up or down branch must \
2826be done first (the up down choice will carry on after solution). \
2827Default has now been changed to hybrid which is breadth first on small depth nodes then fewest."
2828     );
2829     parameters[numberParameters++] =
2830          CbcOrClpParam("numberA!nalyze", "Number of analysis iterations",
2831                        -COIN_INT_MAX, COIN_INT_MAX, CBC_PARAM_INT_NUMBERANALYZE, 0);
2832     parameters[numberParameters-1].setLonghelp
2833     (
2834          "This says how many iterations to spend at root node analyzing problem. \
2835This is a first try and will hopefully become more sophisticated."
2836     );
2837#endif
2838     parameters[numberParameters++] =
2839          CbcOrClpParam("objective!Scale", "Scale factor to apply to objective",
2840                        -1.0e20, 1.0e20, CLP_PARAM_DBL_OBJSCALE, 1);
2841     parameters[numberParameters-1].setLonghelp
2842     (
2843          "If the objective function has some very large values, you may wish to scale them\
2844 internally by this amount.  It can also be set by autoscale.  It is applied after scaling.  You are unlikely to need this."
2845     );
2846     parameters[numberParameters-1].setDoubleValue(1.0);
2847#endif
2848#ifdef COIN_HAS_CBC
2849     parameters[numberParameters++] =
2850          CbcOrClpParam("outDup!licates", "takes duplicate rows etc out of integer model",
2851                        CLP_PARAM_ACTION_OUTDUPROWS, 7, 0);
2852#endif
2853     parameters[numberParameters++] =
2854          CbcOrClpParam("output!Format", "Which output format to use",
2855                        1, 6, CLP_PARAM_INT_OUTPUTFORMAT);
2856     parameters[numberParameters-1].setLonghelp
2857     (
2858          "Normally export will be done using normal representation for numbers and two values\
2859 per line.  You may want to do just one per line (for grep or suchlike) and you may wish\
2860 to save with absolute accuracy using a coded version of the IEEE value. A value of 2 is normal.\
2861 otherwise odd values gives one value per line, even two.  Values 1,2 give normal format, 3,4\
2862 gives greater precision, while 5,6 give IEEE values.  When used for exporting a basis 1 does not save \
2863values, 2 saves values, 3 with greater accuracy and 4 in IEEE."
2864     );
2865#ifdef COIN_HAS_CLP
2866     parameters[numberParameters++] =
2867          CbcOrClpParam("para!metrics", "Import data from file and do parametrics",
2868                        CLP_PARAM_ACTION_PARAMETRICS, 3);
2869     parameters[numberParameters-1].setLonghelp
2870     (
2871          "This will read a file with parametric data from the given file name \
2872and then do parametrics.  It will use the default\
2873 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
2874 is initialized to '', i.e. it must be set.  This can not read from compressed files. \
2875File is in modified csv format - a line ROWS will be followed by rows data \
2876while a line COLUMNS will be followed by column data.  The last line \
2877should be ENDATA. The ROWS line must exist and is in the format \
2878ROWS, inital theta, final theta, interval theta, n where n is 0 to get \
2879CLPI0062 message at interval or at each change of theta \
2880and 1 to get CLPI0063 message at each iteration.  If interval theta is 0.0 \
2881or >= final theta then no interval reporting.  n may be missed out when it is \
2882taken as 0.  If there is Row data then \
2883there is a headings line with allowed headings - name, number, \
2884lower(rhs change), upper(rhs change), rhs(change).  Either the lower and upper \
2885fields should be given or the rhs field. \
2886The optional COLUMNS line is followed by a headings line with allowed \
2887headings - name, number, objective(change), lower(change), upper(change). \
2888 Exactly one of name and number must be given for either section and \
2889missing ones have value 0.0."
2890     );
2891#endif
2892#ifdef COIN_HAS_CBC
2893     parameters[numberParameters++] =
2894          CbcOrClpParam("passC!uts", "Number of cut passes at root node",
2895                        -9999999, 9999999, CBC_PARAM_INT_CUTPASS);
2896     parameters[numberParameters-1].setLonghelp
2897     (
2898          "The default is 100 passes if less than 500 columns, 100 passes (but \
2899stop if drop small if less than 5000 columns, 20 otherwise"
2900     );
2901     parameters[numberParameters++] =
2902          CbcOrClpParam("passF!easibilityPump", "How many passes in feasibility pump",
2903                        0, 10000, CBC_PARAM_INT_FPUMPITS);
2904     parameters[numberParameters-1].setLonghelp
2905     (
2906          "This fine tunes Feasibility Pump by doing more or fewer passes."
2907     );
2908     parameters[numberParameters-1].setIntValue(20);
2909#endif
2910#ifdef COIN_HAS_CLP
2911     parameters[numberParameters++] =
2912          CbcOrClpParam("passP!resolve", "How many passes in presolve",
2913                        -200, 100, CLP_PARAM_INT_PRESOLVEPASS, 1);
2914     parameters[numberParameters-1].setLonghelp
2915     (
2916          "Normally Presolve does 5 passes but you may want to do less to make it\
2917 more lightweight or do more if improvements are still being made.  As Presolve will return\
2918 if nothing is being taken out, you should not normally need to use this fine tuning."
2919     );
2920#endif
2921#ifdef COIN_HAS_CBC
2922     parameters[numberParameters++] =
2923          CbcOrClpParam("passT!reeCuts", "Number of cut passes in tree",
2924                        -9999999, 9999999, CBC_PARAM_INT_CUTPASSINTREE);
2925     parameters[numberParameters-1].setLonghelp
2926     (
2927          "The default is one pass"
2928     );
2929#endif
2930#ifdef COIN_HAS_CLP
2931     parameters[numberParameters++] =
2932          CbcOrClpParam("pertV!alue", "Method of perturbation",
2933                        -5000, 102, CLP_PARAM_INT_PERTVALUE, 1);
2934     parameters[numberParameters++] =
2935          CbcOrClpParam("perturb!ation", "Whether to perturb problem",
2936                        "on", CLP_PARAM_STR_PERTURBATION);
2937     parameters[numberParameters-1].append("off");
2938     parameters[numberParameters-1].setLonghelp
2939     (
2940          "Perturbation helps to stop cycling, but Clp uses other measures for this.\
2941  However large problems and especially ones with unit elements and unit rhs or costs\
2942 benefit from perturbation.  Normally Clp tries to be intelligent, but you can switch this off.\
2943  The Clp library has this off by default.  This program has it on by default."
2944     );
2945     parameters[numberParameters++] =
2946          CbcOrClpParam("PFI", "Whether to use Product Form of Inverse in simplex",
2947                        "off", CLP_PARAM_STR_PFI, 7, 0);
2948     parameters[numberParameters-1].append("on");
2949     parameters[numberParameters-1].setLonghelp
2950     (
2951          "By default clp uses Forrest-Tomlin L-U update.  If you are masochistic you can switch it off."
2952     );
2953#endif
2954#ifdef COIN_HAS_CBC
2955     parameters[numberParameters++] =
2956          CbcOrClpParam("pivotAndC!omplement", "Whether to try Pivot and Complement heuristic",
2957                        "off", CBC_PARAM_STR_PIVOTANDCOMPLEMENT);
2958     parameters[numberParameters-1].append("on");
2959     parameters[numberParameters-1].append("both");
2960     parameters[numberParameters-1].append("before");
2961     parameters[numberParameters-1].setLonghelp
2962     (
2963          "stuff needed. \
2964Doh option does heuristic before preprocessing"     );
2965     parameters[numberParameters++] =
2966          CbcOrClpParam("pivotAndF!ix", "Whether to try Pivot and Fix heuristic",
2967                        "off", CBC_PARAM_STR_PIVOTANDFIX);
2968     parameters[numberParameters-1].append("on");
2969     parameters[numberParameters-1].append("both");
2970     parameters[numberParameters-1].append("before");
2971     parameters[numberParameters-1].setLonghelp
2972     (
2973          "stuff needed. \
2974Doh option does heuristic before preprocessing"     );
2975#endif
2976#ifdef COIN_HAS_CLP
2977     parameters[numberParameters++] =
2978          CbcOrClpParam("plus!Minus", "Tries to make +- 1 matrix",
2979                        CLP_PARAM_ACTION_PLUSMINUS, 7, 0);
2980     parameters[numberParameters-1].setLonghelp
2981     (
2982          "Clp will go slightly faster if the matrix can be converted so that the elements are\
2983 not stored and are known to be unit.  The main advantage is memory use.  Clp may automatically\
2984 see if it can convert the problem so you should not need to use this."
2985     );
2986     parameters[numberParameters++] =
2987          CbcOrClpParam("pO!ptions", "Dubious print options",
2988                        0, COIN_INT_MAX, CLP_PARAM_INT_PRINTOPTIONS, 1);
2989     parameters[numberParameters-1].setIntValue(0);
2990     parameters[numberParameters-1].setLonghelp
2991     (
2992          "If this is > 0 then presolve will give more information and branch and cut will give statistics"
2993     );
2994     parameters[numberParameters++] =
2995          CbcOrClpParam("preO!pt", "Presolve options",
2996                        0, COIN_INT_MAX, CLP_PARAM_INT_PRESOLVEOPTIONS, 0);
2997#endif
2998     parameters[numberParameters++] =
2999          CbcOrClpParam("presolve", "Whether to presolve problem",
3000                        "on", CLP_PARAM_STR_PRESOLVE);
3001     parameters[numberParameters-1].append("off");
3002     parameters[numberParameters-1].append("more");
3003     parameters[numberParameters-1].append("file");
3004     parameters[numberParameters-1].setLonghelp
3005     (
3006          "Presolve analyzes the model to find such things as redundant equations, equations\
3007 which fix some variables, equations which can be transformed into bounds etc etc.  For the\
3008 initial solve of any problem this is worth doing unless you know that it will have no effect.  \
3009on will normally do 5 passes while using 'more' will do 10.  If the problem is very large you may need \
3010to write the original to file using 'file'."
3011     );
3012#ifdef COIN_HAS_CBC
3013     parameters[numberParameters++] =
3014          CbcOrClpParam("preprocess", "Whether to use integer preprocessing",
3015                        "off", CBC_PARAM_STR_PREPROCESS);
3016     parameters[numberParameters-1].append("on");
3017     parameters[numberParameters-1].append("save");
3018     parameters[numberParameters-1].append("equal");
3019     parameters[numberParameters-1].append("sos");
3020     parameters[numberParameters-1].append("trysos");
3021     parameters[numberParameters-1].append("equalall");
3022     parameters[numberParameters-1].append("strategy");
3023     parameters[numberParameters-1].append("aggregate");
3024     parameters[numberParameters-1].append("forcesos");
3025     parameters[numberParameters-1].setLonghelp
3026     (
3027          "This tries to reduce size of model in a similar way to presolve and \
3028it also tries to strengthen the model - this can be very useful and is worth trying. \
3029 Save option saves on file presolved.mps.  equal will turn <= cliques into \
3030==.  sos will create sos sets if all 0-1 in sets (well one extra is allowed) \
3031and no overlaps.  trysos is same but allows any number extra.  equalall will turn all \
3032valid inequalities into equalities with integer slacks.  strategy is as \
3033on but uses CbcStrategy."
3034     );
3035#endif
3036#ifdef COIN_HAS_CLP
3037     parameters[numberParameters++] =
3038          CbcOrClpParam("preT!olerance", "Tolerance to use in presolve",
3039                        1.0e-20, 1.0e12, CLP_PARAM_DBL_PRESOLVETOLERANCE);
3040     parameters[numberParameters-1].setLonghelp
3041     (
3042          "The default is 1.0e-8 - you may wish to try 1.0e-7 if presolve says the problem is \
3043infeasible and you have awkward numbers and you are sure the problem is really feasible."
3044     );
3045     parameters[numberParameters++] =
3046          CbcOrClpParam("primalP!ivot", "Primal pivot choice algorithm",
3047                        "auto!matic", CLP_PARAM_STR_PRIMALPIVOT, 7, 1);
3048     parameters[numberParameters-1].append("exa!ct");
3049     parameters[numberParameters-1].append("dant!zig");
3050     parameters[numberParameters-1].append("part!ial");
3051     parameters[numberParameters-1].append("steep!est");
3052     parameters[numberParameters-1].append("change");
3053     parameters[numberParameters-1].append("sprint");
3054     parameters[numberParameters-1].setLonghelp
3055     (
3056          "Clp can use any pivot selection algorithm which the user codes as long as it\
3057 implements the features in the abstract pivot base class.  The Dantzig method is implemented\
3058 to show a simple method but its use is deprecated.  Exact devex is the method of choice and there\
3059 are two variants which keep all weights updated but only scan a subset each iteration.\
3060 Partial switches this on while change initially does dantzig until the factorization\
3061 becomes denser.  This is still a work in progress."
3062     );
3063     parameters[numberParameters++] =
3064          CbcOrClpParam("primalS!implex", "Do primal simplex algorithm",
3065                        CLP_PARAM_ACTION_PRIMALSIMPLEX);
3066     parameters[numberParameters-1].setLonghelp
3067     (
3068          "This command solves the continuous relaxation of the current model using the primal algorithm.\
3069  The default is to use exact devex.\
3070 The time and iterations may be affected by settings such as presolve, scaling, crash\
3071 and also by column selection  method, infeasibility weight and dual and primal tolerances."
3072     );
3073#endif
3074     parameters[numberParameters++] =
3075          CbcOrClpParam("primalT!olerance", "For an optimal solution \
3076no primal infeasibility may exceed this value",
3077                        1.0e-20, 1.0e12, CLP_PARAM_DBL_PRIMALTOLERANCE);
3078     parameters[numberParameters-1].setLonghelp
3079     (
3080          "Normally the default tolerance is fine, but you may want to increase it a\
3081 bit if a primal run seems to be having a hard time"
3082     );
3083#ifdef COIN_HAS_CLP
3084     parameters[numberParameters++] =
3085          CbcOrClpParam("primalW!eight", "Initially algorithm acts as if it \
3086costs this much to be infeasible",
3087                        1.0e-20, 1.0e20, CLP_PARAM_DBL_PRIMALWEIGHT);
3088     parameters[numberParameters-1].setLonghelp
3089     (
3090          "The primal algorithm in Clp is a single phase algorithm as opposed to a two phase\
3091 algorithm where you first get feasible then optimal.  So Clp is minimizing this weight times\
3092 the sum of primal infeasibilities plus the true objective function (in minimization sense).\
3093  Too high a value may mean more iterations, while too low a bound means\
3094 the code may go all the way and then have to increase the weight in order to get feasible.\
3095  OSL had a heuristic to\
3096 adjust bounds, maybe we need that here."
3097     );
3098#endif
3099     parameters[numberParameters++] =
3100          CbcOrClpParam("printi!ngOptions", "Print options",
3101                        "normal", CLP_PARAM_STR_INTPRINT, 3);
3102     parameters[numberParameters-1].append("integer");
3103     parameters[numberParameters-1].append("special");
3104     parameters[numberParameters-1].append("rows");
3105     parameters[numberParameters-1].append("all");
3106     parameters[numberParameters-1].append("csv");
3107     parameters[numberParameters-1].append("bound!ranging");
3108     parameters[numberParameters-1].append("rhs!ranging");
3109     parameters[numberParameters-1].append("objective!ranging");
3110     parameters[numberParameters-1].append("stats");
3111     parameters[numberParameters-1].append("boundsint");
3112     parameters[numberParameters-1].append("boundsall");
3113     parameters[numberParameters-1].setLonghelp
3114     (
3115          "This changes the amount and format of printing a solution:\nnormal - nonzero column variables \n\
3116integer - nonzero integer column variables\n\
3117special - in format suitable for OsiRowCutDebugger\n\
3118rows - nonzero column variables and row activities\n\
3119all - all column variables and row activities.\n\
3120\nFor non-integer problems 'integer' and 'special' act like 'normal'.  \
3121Also see printMask for controlling output."
3122     );
3123     parameters[numberParameters++] =
3124          CbcOrClpParam("printM!ask", "Control printing of solution on a  mask",
3125                        CLP_PARAM_ACTION_PRINTMASK, 3);
3126     parameters[numberParameters-1].setLonghelp
3127     (
3128          "If set then only those names which match mask are printed in a solution. \
3129'?' matches any character and '*' matches any set of characters. \
3130 The default is '' i.e. unset so all variables are printed. \
3131This is only active if model has names."
3132     );
3133#ifdef COIN_HAS_CBC
3134     parameters[numberParameters++] =
3135          CbcOrClpParam("prio!rityIn", "Import priorities etc from file",
3136                        CBC_PARAM_ACTION_PRIORITYIN, 3);
3137     parameters[numberParameters-1].setLonghelp
3138     (
3139          "This will read a file with priorities from the given file name.  It will use the default\
3140 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
3141 is initialized to '', i.e. it must be set.  This can not read from compressed files. \
3142File is in csv format with allowed headings - name, number, priority, direction, up, down, solution.  Exactly one of\
3143 name and number must be given."
3144     );
3145     parameters[numberParameters++] =
3146          CbcOrClpParam("probing!Cuts", "Whether to use Probing cuts",
3147                        "off", CBC_PARAM_STR_PROBINGCUTS);
3148     parameters[numberParameters-1].append("on");
3149     parameters[numberParameters-1].append("root");
3150     parameters[numberParameters-1].append("ifmove");
3151     parameters[numberParameters-1].append("forceOn");
3152     parameters[numberParameters-1].append("onglobal");
3153     parameters[numberParameters-1].append("forceonglobal");
3154     parameters[numberParameters-1].append("forceOnBut");
3155     parameters[numberParameters-1].append("forceOnStrong");
3156     parameters[numberParameters-1].append("forceOnButStrong");
3157     parameters[numberParameters-1].append("strongRoot");
3158     parameters[numberParameters-1].setLonghelp
3159     (
3160          "This switches on probing cuts (either at root or in entire tree) \
3161See branchAndCut for information on options. \
3162but strong options do more probing"
3163     );
3164     parameters[numberParameters++] =
3165          CbcOrClpParam("proximity!Search", "Whether to do proximity search heuristic",
3166                        "off", CBC_PARAM_STR_PROXIMITY);
3167     parameters[numberParameters-1].append("on");
3168     parameters[numberParameters-1].append("both");
3169     parameters[numberParameters-1].append("before");
3170     parameters[numberParameters-1].append("10");
3171     parameters[numberParameters-1].append("100");
3172     parameters[numberParameters-1].append("300");
3173     // but allow numbers after this (returning 1)
3174     parameters[numberParameters-1].setFakeKeyWord(1);
3175     parameters[numberParameters-1].setLonghelp
3176     (
3177          "This switches on a heuristic which looks for a solution close \
3178to incumbent solution (Fischetti and Monaci). \
3179See Rounding for meaning of on,both,before. \
3180Can also set different maxNode settings by plusnnnn (and are 'on'(on==30))."
3181     );
3182     parameters[numberParameters++] =
3183          CbcOrClpParam("pumpC!utoff", "Fake cutoff for use in feasibility pump",
3184                        -COIN_DBL_MAX, COIN_DBL_MAX, CBC_PARAM_DBL_FAKECUTOFF);
3185     parameters[numberParameters-1].setDoubleValue(0.0);
3186     parameters[numberParameters-1].setLonghelp
3187     (
3188          "0.0 off - otherwise add a constraint forcing objective below this value\
3189 in feasibility pump"
3190     );
3191     parameters[numberParameters++] =
3192          CbcOrClpParam("pumpI!ncrement", "Fake increment for use in feasibility pump",
3193                        -COIN_DBL_MAX, COIN_DBL_MAX, CBC_PARAM_DBL_FAKEINCREMENT, 1);
3194     parameters[numberParameters-1].setDoubleValue(0.0);
3195     parameters[numberParameters-1].setLonghelp
3196     (
3197          "0.0 off - otherwise use as absolute increment to cutoff \
3198when solution found in feasibility pump"
3199     );
3200     parameters[numberParameters++] =
3201          CbcOrClpParam("pumpT!une", "Dubious ideas for feasibility pump",
3202                        0, 100000000, CBC_PARAM_INT_FPUMPTUNE);
3203     parameters[numberParameters-1].setLonghelp
3204     (
3205          "This fine tunes Feasibility Pump \n\
3206\t>=10000000 use as objective weight switch\n\
3207\t>=1000000 use as accumulate switch\n\
3208\t>=1000 use index+1 as number of large loops\n\
3209\t==100 use objvalue +0.05*fabs(objvalue) as cutoff OR fakeCutoff if set\n\
3210\t%100 == 10,20 affects how each solve is done\n\
3211\t1 == fix ints at bounds, 2 fix all integral ints, 3 and continuous at bounds. \
3212If accumulate is on then after a major pass, variables which have not moved \
3213are fixed and a small branch and bound is tried."
3214     );
3215     parameters[numberParameters-1].setIntValue(0);
3216#endif
3217     parameters[numberParameters++] =
3218          CbcOrClpParam("quit", "Stops clp execution",
3219                        CLP_PARAM_ACTION_EXIT);
3220     parameters[numberParameters-1].setLonghelp
3221     (
3222          "This stops the execution of Clp, end, exit, quit and stop are synonyms"
3223     );
3224#ifdef COIN_HAS_CBC
3225     parameters[numberParameters++] =
3226          CbcOrClpParam("randomC!bcSeed", "Random seed for Cbc",
3227                        -1, COIN_INT_MAX, CBC_PARAM_INT_RANDOMSEED);
3228     parameters[numberParameters-1].setLonghelp
3229     (
3230          "This sets a random seed for Cbc \
3231- 0 says use time of day, -1 is as now."
3232     );
3233     parameters[numberParameters-1].setIntValue(-1);
3234     parameters[numberParameters++] =
3235          CbcOrClpParam("randomi!zedRounding", "Whether to try randomized rounding heuristic",
3236                        "off", CBC_PARAM_STR_RANDROUND);
3237     parameters[numberParameters-1].append("on");
3238     parameters[numberParameters-1].append("both");
3239     parameters[numberParameters-1].append("before");
3240     parameters[numberParameters-1].setLonghelp
3241     (
3242          "stuff needed. \
3243Doh option does heuristic before preprocessing"     );
3244#endif
3245#ifdef COIN_HAS_CLP
3246     parameters[numberParameters++] =
3247          CbcOrClpParam("randomS!eed", "Random seed for Clp",
3248                        0, COIN_INT_MAX, CLP_PARAM_INT_RANDOMSEED);
3249     parameters[numberParameters-1].setLonghelp
3250     (
3251          "This sets a random seed for Clp \
3252- 0 says use time of day."
3253     );
3254     parameters[numberParameters-1].setIntValue(1234567);
3255#endif
3256#ifdef COIN_HAS_CBC
3257     parameters[numberParameters++] =
3258          CbcOrClpParam("ratio!Gap", "Stop when gap between best possible and \
3259best less than this fraction of larger of two",
3260                        0.0, 1.0e20, CBC_PARAM_DBL_GAPRATIO);
3261     parameters[numberParameters-1].setDoubleValue(0.0);
3262     parameters[numberParameters-1].setLonghelp
3263     (
3264          "If the gap between best solution and best possible solution is less than this fraction \
3265of the objective value at the root node then the search will terminate.  See 'allowableGap' for a \
3266way of using absolute value rather than fraction."
3267     );
3268     parameters[numberParameters++] =
3269          CbcOrClpParam("readS!tored", "Import stored cuts from file",
3270                        CLP_PARAM_ACTION_STOREDFILE, 3, 0);
3271#endif
3272#ifdef COIN_HAS_CLP
3273     parameters[numberParameters++] =
3274          CbcOrClpParam("reallyO!bjectiveScale", "Scale factor to apply to objective in place",
3275                        -1.0e20, 1.0e20, CLP_PARAM_DBL_OBJSCALE2, 0);
3276     parameters[numberParameters-1].setLonghelp
3277     (
3278          "You can set this to -1.0 to test maximization or other to stress code"
3279     );
3280     parameters[numberParameters-1].setDoubleValue(1.0);
3281     parameters[numberParameters++] =
3282          CbcOrClpParam("reallyS!cale", "Scales model in place",
3283                        CLP_PARAM_ACTION_REALLY_SCALE, 7, 0);
3284#endif
3285#ifdef COIN_HAS_CBC
3286     parameters[numberParameters++] =
3287          CbcOrClpParam("reduce!AndSplitCuts", "Whether to use Reduce-and-Split cuts",
3288                        "off", CBC_PARAM_STR_REDSPLITCUTS);
3289     parameters[numberParameters-1].append("on");
3290     parameters[numberParameters-1].append("root");
3291     parameters[numberParameters-1].append("ifmove");
3292     parameters[numberParameters-1].append("forceOn");
3293     parameters[numberParameters-1].setLonghelp
3294     (
3295          "This switches on reduce and split  cuts (either at root or in entire tree). \
3296May be slow \
3297See branchAndCut for information on options."
3298     );
3299      parameters[numberParameters++] =
3300          CbcOrClpParam("reduce2!AndSplitCuts", "Whether to use Reduce-and-Split cuts - style 2",
3301                        "off", CBC_PARAM_STR_REDSPLIT2CUTS);
3302     parameters[numberParameters-1].append("on");
3303     parameters[numberParameters-1].append("root");
3304     parameters[numberParameters-1].append("longOn");
3305     parameters[numberParameters-1].append("longRoot");
3306     parameters[numberParameters-1].setLonghelp
3307     (
3308          "This switches on reduce and split  cuts (either at root or in entire tree) \
3309This version is by Giacomo Nannicini based on Francois Margot's version \
3310Standard setting only uses rows in tableau <=256, long uses all \
3311May be slow \
3312See branchAndCut for information on options."
3313     );
3314     parameters[numberParameters++] =
3315          CbcOrClpParam("reduce2!AndSplitCuts", "Whether to use Reduce-and-Split cuts - style 2",
3316                        "off", CBC_PARAM_STR_REDSPLIT2CUTS);
3317     parameters[numberParameters-1].append("on");
3318     parameters[numberParameters-1].append("root");
3319     parameters[numberParameters-1].append("longOn");
3320     parameters[numberParameters-1].append("longRoot");
3321     parameters[numberParameters-1].setLonghelp
3322     (
3323          "This switches on reduce and split  cuts (either at root or in entire tree) \
3324This version is by Giacomo Nannicini based on Francois Margot's version \
3325Standard setting only uses rows in tableau <=256, long uses all \
3326See branchAndCut for information on options."
3327     );
3328     parameters[numberParameters++] =
3329          CbcOrClpParam("residual!CapacityCuts", "Whether to use Residual Capacity cuts",
3330                        "off", CBC_PARAM_STR_RESIDCUTS);
3331     parameters[numberParameters-1].append("on");
3332     parameters[numberParameters-1].append("root");
3333     parameters[numberParameters-1].append("ifmove");
3334     parameters[numberParameters-1].append("forceOn");
3335     parameters[numberParameters-1].setLonghelp
3336     (
3337          "Residual capacity cuts. \
3338See branchAndCut for information on options."
3339     );
3340#endif
3341#ifdef COIN_HAS_CLP
3342     parameters[numberParameters++] =
3343          CbcOrClpParam("restore!Model", "Restore model from binary file",
3344                        CLP_PARAM_ACTION_RESTORE, 7, 1);
3345     parameters[numberParameters-1].setLonghelp
3346     (
3347          "This reads data save by saveModel from the given file.  It will use the default\
3348 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
3349 is initialized to 'default.prob'."
3350     );
3351     parameters[numberParameters++] =
3352          CbcOrClpParam("reverse", "Reverses sign of objective",
3353                        CLP_PARAM_ACTION_REVERSE, 7, 0);
3354     parameters[numberParameters-1].setLonghelp
3355     (
3356          "Useful for testing if maximization works correctly"
3357     );
3358     parameters[numberParameters++] =
3359          CbcOrClpParam("rhs!Scale", "Scale factor to apply to rhs and bounds",
3360                        -1.0e20, 1.0e20, CLP_PARAM_DBL_RHSSCALE, 0);
3361     parameters[numberParameters-1].setLonghelp
3362     (
3363          "If the rhs or bounds have some very large meaningful values, you may wish to scale them\
3364 internally by this amount.  It can also be set by autoscale.  This should not be needed."
3365     );
3366     parameters[numberParameters-1].setDoubleValue(1.0);
3367#endif
3368#ifdef COIN_HAS_CBC
3369     parameters[numberParameters++] =
3370          CbcOrClpParam("Rens", "Whether to try Relaxation Enforced Neighborhood Search",
3371                        "off", CBC_PARAM_STR_RENS);
3372     parameters[numberParameters-1].append("on");
3373     parameters[numberParameters-1].append("both");
3374     parameters[numberParameters-1].append("before");
3375     parameters[numberParameters-1].append("200");
3376     parameters[numberParameters-1].append("1000");
3377     parameters[numberParameters-1].append("10000");
3378     parameters[numberParameters-1].append("dj");
3379     parameters[numberParameters-1].append("djbefore");
3380     parameters[numberParameters-1].setLonghelp
3381     (
3382          "This switches on Relaxation enforced neighborhood Search. \
3383on just does 50 nodes \
3384200 or 1000 does that many nodes. \
3385Doh option does heuristic before preprocessing"     );
3386     parameters[numberParameters++] =
3387          CbcOrClpParam("Rins", "Whether to try Relaxed Induced Neighborhood Search",
3388                        "off", CBC_PARAM_STR_RINS);
3389     parameters[numberParameters-1].append("on");
3390     parameters[numberParameters-1].append("both");
3391     parameters[numberParameters-1].append("before");
3392     parameters[numberParameters-1].append("often");
3393     parameters[numberParameters-1].setLonghelp
3394     (
3395          "This switches on Relaxed induced neighborhood Search. \
3396Doh option does heuristic before preprocessing"     );
3397     parameters[numberParameters++] =
3398          CbcOrClpParam("round!ingHeuristic", "Whether to use Rounding heuristic",
3399                        "off", CBC_PARAM_STR_ROUNDING);
3400     parameters[numberParameters-1].append("on");
3401     parameters[numberParameters-1].append("both");
3402     parameters[numberParameters-1].append("before");
3403     parameters[numberParameters-1].setLonghelp
3404     (
3405          "This switches on a simple (but effective) rounding heuristic at each node of tree.  \
3406On means do in solve i.e. after preprocessing, \
3407Before means do if doHeuristics used, off otherwise, \
3408and both means do if doHeuristics and in solve."
3409     );
3410
3411#endif
3412     parameters[numberParameters++] =
3413          CbcOrClpParam("saveM!odel", "Save model to binary file",
3414                        CLP_PARAM_ACTION_SAVE, 7, 1);
3415     parameters[numberParameters-1].setLonghelp
3416     (
3417          "This will save the problem to the given file name for future use\
3418 by restoreModel.  It will use the default\
3419 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
3420 is initialized to 'default.prob'."
3421     );
3422     parameters[numberParameters++] =
3423          CbcOrClpParam("saveS!olution", "saves solution to file",
3424                        CLP_PARAM_ACTION_SAVESOL);
3425     parameters[numberParameters-1].setLonghelp
3426     (
3427          "This will write a binary solution file to the given file name.  It will use the default\
3428 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
3429 is initialized to 'solution.file'.  To read the file use fread(int) twice to pick up number of rows \
3430and columns, then fread(double) to pick up objective value, then pick up row activities, row duals, column \
3431activities and reduced costs - see bottom of CbcOrClpParam.cpp for code that reads or writes file. \
3432If name contains '_fix_read_' then does not write but reads and will fix all variables"
3433     );
3434     parameters[numberParameters++] =
3435          CbcOrClpParam("scal!ing", "Whether to scale problem",
3436                        "off", CLP_PARAM_STR_SCALING);
3437     parameters[numberParameters-1].append("equi!librium");
3438     parameters[numberParameters-1].append("geo!metric");
3439     parameters[numberParameters-1].append("auto!matic");
3440     parameters[numberParameters-1].append("dynamic");
3441     parameters[numberParameters-1].append("rows!only");
3442     parameters[numberParameters-1].setLonghelp
3443     (
3444          "Scaling can help in solving problems which might otherwise fail because of lack of\
3445 accuracy.  It can also reduce the number of iterations.  It is not applied if the range\
3446 of elements is small.  When unscaled it is possible that there may be small primal and/or\
3447 infeasibilities."
3448     );
3449     parameters[numberParameters-1].setCurrentOption(3); // say auto
3450#ifndef COIN_HAS_CBC
3451     parameters[numberParameters++] =
3452          CbcOrClpParam("sec!onds", "Maximum seconds",
3453                        -1.0, 1.0e12, CLP_PARAM_DBL_TIMELIMIT);
3454     parameters[numberParameters-1].setLonghelp
3455     (
3456          "After this many seconds clp will act as if maximum iterations had been reached \
3457(if value >=0)."
3458     );
3459#else
3460     parameters[numberParameters++] =
3461          CbcOrClpParam("sec!onds", "maximum seconds",
3462                        -1.0, 1.0e12, CBC_PARAM_DBL_TIMELIMIT_BAB);
3463     parameters[numberParameters-1].setLonghelp
3464     (
3465          "After this many seconds coin solver will act as if maximum nodes had been reached."
3466     );
3467#endif
3468     parameters[numberParameters++] =
3469          CbcOrClpParam("sleep", "for debug",
3470                        CLP_PARAM_ACTION_DUMMY, 7, 0);
3471     parameters[numberParameters-1].setLonghelp
3472     (
3473          "If passed to solver fom ampl, then ampl will wait so that you can copy .nl file for debug."
3474     );
3475#ifdef COIN_HAS_CBC
3476     parameters[numberParameters++] =
3477          CbcOrClpParam("slow!cutpasses", "Maximum number of tries for slower cuts",
3478                        -1, COIN_INT_MAX, CBC_PARAM_INT_MAX_SLOW_CUTS);
3479     parameters[numberParameters-1].setLonghelp
3480     (
3481          "Some cut generators are fairly slow - this limits the number of times they are tried."
3482     );
3483     parameters[numberParameters-1].setIntValue(10);
3484#endif
3485#ifdef COIN_HAS_CLP
3486     parameters[numberParameters++] =
3487          CbcOrClpParam("slp!Value", "Number of slp passes before primal",
3488                        -50000, 50000, CLP_PARAM_INT_SLPVALUE, 1);
3489     parameters[numberParameters-1].setLonghelp
3490     (
3491          "If you are solving a quadratic problem using primal then it may be helpful to do some \
3492sequential Lps to get a good approximate solution."
3493     );
3494#if CLP_MULTIPLE_FACTORIZATIONS > 0
3495     parameters[numberParameters++] =
3496          CbcOrClpParam("small!Factorization", "Whether to use small factorization",
3497                        -1, 10000, CBC_PARAM_INT_SMALLFACT, 1);
3498     parameters[numberParameters-1].setLonghelp
3499     (
3500          "If processed problem <= this use small factorization"
3501     );
3502     parameters[numberParameters-1].setIntValue(-1);
3503#endif
3504#endif
3505     parameters[numberParameters++] =
3506          CbcOrClpParam("solu!tion", "Prints solution to file",
3507                        CLP_PARAM_ACTION_SOLUTION);
3508     parameters[numberParameters-1].setLonghelp
3509     (
3510          "This will write a primitive solution file to the given file name.  It will use the default\
3511 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
3512 is initialized to 'stdout'.  The amount of output can be varied using printi!ngOptions or printMask."
3513     );
3514#ifdef COIN_HAS_CLP
3515#ifdef COIN_HAS_CBC
3516     parameters[numberParameters++] =
3517          CbcOrClpParam("solv!e", "Solve problem",
3518                        CBC_PARAM_ACTION_BAB);
3519     parameters[numberParameters-1].setLonghelp
3520     (
3521          "If there are no integer variables then this just solves LP.  If there are integer variables \
3522this does branch and cut."
3523     );
3524     parameters[numberParameters++] =
3525          CbcOrClpParam("sos!Options", "Whether to use SOS from AMPL",
3526                        "off", CBC_PARAM_STR_SOS);
3527     parameters[numberParameters-1].append("on");
3528     parameters[numberParameters-1].setCurrentOption("on");
3529     parameters[numberParameters-1].setLonghelp
3530     (
3531          "Normally if AMPL says there are SOS variables they should be used, but sometime sthey should\
3532 be turned off - this does so."
3533     );
3534     parameters[numberParameters++] =
3535          CbcOrClpParam("slog!Level", "Level of detail in (LP) Solver output",
3536                        -1, 63, CLP_PARAM_INT_SOLVERLOGLEVEL);
3537     parameters[numberParameters-1].setLonghelp
3538     (
3539          "If 0 then there should be no output in normal circumstances.  1 is probably the best\
3540 value for most uses, while 2 and 3 give more information.  This parameter is only used inside MIP - for Clp use 'log'"
3541     );
3542#else
3543     // allow solve as synonym for possible dual
3544     parameters[numberParameters++] =
3545       CbcOrClpParam("solv!e", "Solve problem using dual simplex (probably)",
3546                        CLP_PARAM_ACTION_EITHERSIMPLEX);
3547     parameters[numberParameters-1].setLonghelp
3548     (
3549          "Just so can use solve for clp as well as in cbc"
3550     );
3551#endif
3552#endif
3553#ifdef COIN_HAS_CLP
3554     parameters[numberParameters++] =
3555          CbcOrClpParam("spars!eFactor", "Whether factorization treated as sparse",
3556                        "on", CLP_PARAM_STR_SPARSEFACTOR, 7, 0);
3557     parameters[numberParameters-1].append("off");
3558     parameters[numberParameters++] =
3559          CbcOrClpParam("special!Options", "Dubious options for Simplex - see ClpSimplex.hpp",
3560                        0, COIN_INT_MAX, CLP_PARAM_INT_SPECIALOPTIONS, 0);
3561     parameters[numberParameters++] =
3562          CbcOrClpParam("sprint!Crash", "Whether to try sprint crash",
3563                        -1, 5000000, CLP_PARAM_INT_SPRINT);
3564     parameters[numberParameters-1].setLonghelp
3565     (
3566          "For long and thin problems this program may solve a series of small problems\
3567 created by taking a subset of the columns.  I introduced the idea as 'Sprint' after\
3568 an LP code of that name of the 60's which tried the same tactic (not totally successfully).\
3569  Cplex calls it 'sifting'.  -1 is automatic choice, 0 is off, n is number of passes"
3570     );
3571     parameters[numberParameters++] =
3572          CbcOrClpParam("stat!istics", "Print some statistics",
3573                        CLP_PARAM_ACTION_STATISTICS);
3574     parameters[numberParameters-1].setLonghelp
3575     (
3576          "This command prints some statistics for the current model.\
3577 If log level >1 then more is printed.\
3578 These are for presolved model if presolve on (and unscaled)."
3579     );
3580#endif
3581     parameters[numberParameters++] =
3582          CbcOrClpParam("stop", "Stops clp execution",
3583                        CLP_PARAM_ACTION_EXIT);
3584     parameters[numberParameters-1].setLonghelp
3585     (
3586          "This stops the execution of Clp, end, exit, quit and stop are synonyms"
3587     );
3588#ifdef COIN_HAS_CBC
3589     parameters[numberParameters++] =
3590          CbcOrClpParam("strat!egy", "Switches on groups of features",
3591                        0, 2, CBC_PARAM_INT_STRATEGY);
3592     parameters[numberParameters-1].setLonghelp
3593     (
3594          "This turns on newer features. \
3595Use 0 for easy problems, 1 is default, 2 is aggressive. \
35961 uses Gomory cuts using tolerance of 0.01 at root, \
3597does a possible restart after 100 nodes if can fix many \
3598and activates a diving and RINS heuristic and makes feasibility pump \
3599more aggressive. \
3600This does not apply to unit tests (where 'experiment' may have similar effects)."
3601     );
3602     parameters[numberParameters-1].setIntValue(1);
3603#ifdef CBC_KEEP_DEPRECATED
3604     parameters[numberParameters++] =
3605          CbcOrClpParam("strengthen", "Create strengthened problem",
3606                        CBC_PARAM_ACTION_STRENGTHEN, 3);
3607     parameters[numberParameters-1].setLonghelp
3608     (
3609          "This creates a new problem by applying the root node cuts.  All tight constraints \
3610will be in resulting problem"
3611     );
3612#endif
3613     parameters[numberParameters++] =
3614          CbcOrClpParam("strong!Branching", "Number of variables to look at in strong branching",
3615                        0, COIN_INT_MAX, CBC_PARAM_INT_STRONGBRANCHING);
3616     parameters[numberParameters-1].setLonghelp
3617     (
3618          "In order to decide which variable to branch on, the code will choose up to this number \
3619of unsatisfied variables to do mini up and down branches on.  Then the most effective one is chosen. \
3620If a variable is branched on many times then the previous average up and down costs may be used - \
3621see number before trust."
3622     );
3623#endif
3624#ifdef COIN_HAS_CLP
3625     parameters[numberParameters++] =
3626          CbcOrClpParam("subs!titution", "How long a column to substitute for in presolve",
3627                        0, 10000, CLP_PARAM_INT_SUBSTITUTION, 0);
3628     parameters[numberParameters-1].setLonghelp
3629     (
3630          "Normally Presolve gets rid of 'free' variables when there are no more than 3 \
3631 variables in column.  If you increase this the number of rows may decrease but number of \
3632 elements may increase."
3633     );
3634#endif
3635#ifdef COIN_HAS_CBC
3636     parameters[numberParameters++] =
3637          CbcOrClpParam("testO!si", "Test OsiObject stuff",
3638                        -1, COIN_INT_MAX, CBC_PARAM_INT_TESTOSI, 0);
3639#endif
3640#ifdef CBC_THREAD
3641     parameters[numberParameters++] =
3642          CbcOrClpParam("thread!s", "Number of threads to try and use",
3643                        -100, 100000, CBC_PARAM_INT_THREADS, 1);
3644     parameters[numberParameters-1].setLonghelp
3645     (
3646          "To use multiple threads, set threads to number wanted.  It may be better \
3647to use one or two more than number of cpus available.  If 100+n then n threads and \
3648search is repeatable (maybe be somewhat slower), \
3649if 200+n use threads for root cuts, 400+n threads used in sub-trees."
3650     );
3651#endif
3652#ifdef COIN_HAS_CBC
3653     parameters[numberParameters++] =
3654          CbcOrClpParam("tighten!Factor", "Tighten bounds using this times largest \
3655activity at continuous solution",
3656                        1.0e-3, 1.0e20, CBC_PARAM_DBL_TIGHTENFACTOR, 0);
3657     parameters[numberParameters-1].setLonghelp
3658     (
3659          "This sleazy trick can help on some problems."
3660     );
3661#endif
3662#ifdef COIN_HAS_CLP
3663     parameters[numberParameters++] =
3664          CbcOrClpParam("tightLP", "Poor person's preSolve for now",
3665                        CLP_PARAM_ACTION_TIGHTEN, 7, 0);
3666#endif
3667     parameters[numberParameters++] =
3668          CbcOrClpParam("timeM!ode", "Whether to use CPU or elapsed time",
3669                        "cpu", CLP_PARAM_STR_TIME_MODE);
3670     parameters[numberParameters-1].append("elapsed");
3671     parameters[numberParameters-1].setLonghelp
3672     (
3673          "cpu uses CPU time for stopping, while elapsed uses elapsed time. \
3674(On Windows, elapsed time is always used)."
3675     );
3676#ifdef COIN_HAS_CBC
3677     parameters[numberParameters++] =
3678          CbcOrClpParam("trust!PseudoCosts", "Number of branches before we trust pseudocosts",
3679                        -3, 2000000000, CBC_PARAM_INT_NUMBERBEFORE);
3680     parameters[numberParameters-1].setLonghelp
3681     (
3682          "Using strong branching computes pseudo-costs.  After this many times for a variable we just \
3683trust the pseudo costs and do not do any more strong branching."
3684     );
3685#endif
3686#ifdef COIN_HAS_CBC
3687     parameters[numberParameters++] =
3688          CbcOrClpParam("tune!PreProcess", "Dubious tuning parameters",
3689                        0, 20000000, CLP_PARAM_INT_PROCESSTUNE, 1);
3690     parameters[numberParameters-1].setLonghelp
3691     (
3692          "For making equality cliques this is minimumsize.  Also for adding \
3693integer slacks.  May be used for more later \
3694If <10000 that is what it does.  If <1000000 - numberPasses is (value/10000)-1 and tune is tune %10000. \
3695If >= 1000000! - numberPasses is (value/1000000)-1 and tune is tune %1000000.  In this case if tune is now still >=10000 \
3696numberPassesPerInnerLoop is changed from 10 to (tune-10000)-1 and tune becomes tune % 10000!!!!! - happy? - \
3697so to keep normal limit on cliques of 5, do 3 major passes (include presolves) but only doing one tightening pass per major pass - \
3698you would use 3010005 (I think)"
3699     );
3700     parameters[numberParameters++] =
3701          CbcOrClpParam("two!MirCuts", "Whether to use Two phase Mixed Integer Rounding cuts",
3702                        "off", CBC_PARAM_STR_TWOMIRCUTS);
3703     parameters[numberParameters-1].append("on");
3704     parameters[numberParameters-1].append("root");
3705     parameters[numberParameters-1].append("ifmove");
3706     parameters[numberParameters-1].append("forceOn");
3707     parameters[numberParameters-1].append("onglobal");
3708     parameters[numberParameters-1].append("forceandglobal");
3709     parameters[numberParameters-1].append("forceLongOn");
3710     parameters[numberParameters-1].setLonghelp
3711     (
3712          "This switches on two phase mixed integer rounding  cuts (either at root or in entire tree) \
3713See branchAndCut for information on options."
3714     );
3715#endif
3716     parameters[numberParameters++] =
3717          CbcOrClpParam("unitTest", "Do unit test",
3718                        CLP_PARAM_ACTION_UNITTEST, 3, 1);
3719     parameters[numberParameters-1].setLonghelp
3720     (
3721          "This exercises the unit test for clp"
3722     );
3723     parameters[numberParameters++] =
3724          CbcOrClpParam("userClp", "Hand coded Clp stuff",
3725                        CLP_PARAM_ACTION_USERCLP, 0, 0);
3726     parameters[numberParameters-1].setLonghelp
3727     (
3728          "There are times e.g. when using AMPL interface when you may wish to do something unusual.  \
3729Look for USERCLP in main driver and modify sample code."
3730     );
3731#ifdef COIN_HAS_CBC
3732     parameters[numberParameters++] =
3733          CbcOrClpParam("userCbc", "Hand coded Cbc stuff",
3734                        CBC_PARAM_ACTION_USERCBC, 0, 0);
3735     parameters[numberParameters-1].setLonghelp
3736     (
3737          "There are times e.g. when using AMPL interface when you may wish to do something unusual.  \
3738Look for USERCBC in main driver and modify sample code. \
3739It is possible you can get same effect by using example driver4.cpp."
3740     );
3741     parameters[numberParameters++] =
3742          CbcOrClpParam("Vnd!VariableNeighborhoodSearch", "Whether to try Variable Neighborhood Search",
3743                        "off", CBC_PARAM_STR_VND);
3744     parameters[numberParameters-1].append("on");
3745     parameters[numberParameters-1].append("both");
3746     parameters[numberParameters-1].append("before");
3747     parameters[numberParameters-1].append("intree");
3748     parameters[numberParameters-1].setLonghelp
3749     (
3750          "This switches on variable neighborhood Search. \
3751Doh option does heuristic before preprocessing"     );
3752#endif
3753     parameters[numberParameters++] =
3754          CbcOrClpParam("vector", "Whether to use vector? Form of matrix in simplex",
3755                        "off", CLP_PARAM_STR_VECTOR, 7, 0);
3756     parameters[numberParameters-1].append("on");
3757     parameters[numberParameters-1].setLonghelp
3758     (
3759          "If this is on ClpPackedMatrix uses extra column copy in odd format."
3760     );
3761     parameters[numberParameters++] =
3762          CbcOrClpParam("verbose", "Switches on longer help on single ?",
3763                        0, 31, CLP_PARAM_INT_VERBOSE, 0);
3764     parameters[numberParameters-1].setLonghelp
3765     (
3766          "Set to 1 to get short help with ? list, 2 to get long help, 3 for both.  (add 4 to just get ampl ones)."
3767     );
3768     parameters[numberParameters-1].setIntValue(0);
3769#ifdef COIN_HAS_CBC
3770     parameters[numberParameters++] =
3771          CbcOrClpParam("vub!heuristic", "Type of vub heuristic",
3772                        -2, 20, CBC_PARAM_INT_VUBTRY, 0);
3773     parameters[numberParameters-1].setLonghelp
3774     (
3775          "If set will try and fix some integer variables"
3776     );
3777     parameters[numberParameters-1].setIntValue(-1);
3778     parameters[numberParameters++] =
3779          CbcOrClpParam("zero!HalfCuts", "Whether to use zero half cuts",
3780                        "off", CBC_PARAM_STR_ZEROHALFCUTS);
3781     parameters[numberParameters-1].append("on");
3782     parameters[numberParameters-1].append("root");
3783     parameters[numberParameters-1].append("ifmove");
3784     parameters[numberParameters-1].append("forceOn");
3785     parameters[numberParameters-1].append("onglobal");
3786     parameters[numberParameters-1].setLonghelp
3787     (
3788          "This switches on zero-half cuts (either at root or in entire tree) \
3789See branchAndCut for information on options.  This implementation was written by \
3790Alberto Caprara."
3791     );
3792#endif
3793     parameters[numberParameters++] =
3794          CbcOrClpParam("zeroT!olerance", "Kill all coefficients \
3795whose absolute value is less than this value",
3796                        1.0e-100, 1.0e-5, CLP_PARAM_DBL_ZEROTOLERANCE);
3797     parameters[numberParameters-1].setLonghelp
3798     (
3799          "This applies to reading mps files (and also lp files \
3800if KILL_ZERO_READLP defined)"
3801     );
3802     parameters[numberParameters-1].setDoubleValue(1.0e-20);
3803     assert(numberParameters < CBCMAXPARAMETERS);
3804}
3805// Given a parameter type - returns its number in list
3806int whichParam (CbcOrClpParameterType name,
3807                int numberParameters, CbcOrClpParam *const parameters)
3808{
3809     int i;
3810     for (i = 0; i < numberParameters; i++) {
3811          if (parameters[i].type() == name)
3812               break;
3813     }
3814     assert (i < numberParameters);
3815     return i;
3816}
3817#ifdef COIN_HAS_CLP
3818/* Restore a solution from file.
3819   mode 0 normal, 1 swap rows and columns and primal and dual
3820   if 2 set then also change signs
3821*/
3822void restoreSolution(ClpSimplex * lpSolver, std::string fileName, int mode)
3823{
3824     FILE * fp = fopen(fileName.c_str(), "rb");
3825     if (fp) {
3826          int numberRows = lpSolver->numberRows();
3827          int numberColumns = lpSolver->numberColumns();
3828          int numberRowsFile;
3829          int numberColumnsFile;
3830          double objectiveValue;
3831          size_t nRead;
3832          nRead = fread(&numberRowsFile, sizeof(int), 1, fp);
3833          if (nRead != 1)
3834               throw("Error in fread");
3835          nRead = fread(&numberColumnsFile, sizeof(int), 1, fp);
3836          if (nRead != 1)
3837               throw("Error in fread");
3838          nRead = fread(&objectiveValue, sizeof(double), 1, fp);
3839          if (nRead != 1)
3840               throw("Error in fread");
3841          double * dualRowSolution = lpSolver->dualRowSolution();
3842          double * primalRowSolution = lpSolver->primalRowSolution();
3843          double * dualColumnSolution = lpSolver->dualColumnSolution();
3844          double * primalColumnSolution = lpSolver->primalColumnSolution();
3845          if (mode) {
3846               // swap
3847               int k = numberRows;
3848               numberRows = numberColumns;
3849               numberColumns = k;
3850               double * temp;
3851               temp = dualRowSolution;
3852               dualRowSolution = primalColumnSolution;
3853               primalColumnSolution = temp;
3854               temp = dualColumnSolution;
3855               dualColumnSolution = primalRowSolution;
3856               primalRowSolution = temp;
3857          }
3858          if (numberRows > numberRowsFile || numberColumns > numberColumnsFile) {
3859               std::cout << "Mismatch on rows and/or columns - giving up" << std::endl;
3860          } else {
3861               lpSolver->setObjectiveValue(objectiveValue);
3862               if (numberRows == numberRowsFile && numberColumns == numberColumnsFile) {
3863                    nRead = fread(primalRowSolution, sizeof(double), numberRows, fp);
3864                    if (nRead != static_cast<size_t>(numberRows))
3865                         throw("Error in fread");
3866                    nRead = fread(dualRowSolution, sizeof(double), numberRows, fp);
3867                    if (nRead != static_cast<size_t>(numberRows))
3868                         throw("Error in fread");
3869                    nRead = fread(primalColumnSolution, sizeof(double), numberColumns, fp);
3870                    if (nRead != static_cast<size_t>(numberColumns))
3871                         throw("Error in fread");
3872                    nRead = fread(dualColumnSolution, sizeof(double), numberColumns, fp);
3873                    if (nRead != static_cast<size_t>(numberColumns))
3874                         throw("Error in fread");
3875               } else {
3876                    std::cout << "Mismatch on rows and/or columns - truncating" << std::endl;
3877                    double * temp = new double [CoinMax(numberRowsFile, numberColumnsFile)];
3878                    nRead = fread(temp, sizeof(double), numberRowsFile, fp);
3879                    if (nRead != static_cast<size_t>(numberRowsFile))
3880                         throw("Error in fread");
3881                    CoinMemcpyN(temp, numberRows, primalRowSolution);
3882                    nRead = fread(temp, sizeof(double), numberRowsFile, fp);
3883                    if (nRead != static_cast<size_t>(numberRowsFile))
3884                         throw("Error in fread");
3885                    CoinMemcpyN(temp, numberRows, dualRowSolution);
3886                    nRead = fread(temp, sizeof(double), numberColumnsFile, fp);
3887                    if (nRead != static_cast<size_t>(numberColumnsFile))
3888                         throw("Error in fread");
3889                    CoinMemcpyN(temp, numberColumns, primalColumnSolution);
3890                    nRead = fread(temp, sizeof(double), numberColumnsFile, fp);
3891                    if (nRead != static_cast<size_t>(numberColumnsFile))
3892                         throw("Error in fread");
3893                    CoinMemcpyN(temp, numberColumns, dualColumnSolution);
3894                    delete [] temp;
3895                           }
3896               if (mode == 3) {
3897                    int i;
3898                    for (i = 0; i < numberRows; i++) {
3899                         primalRowSolution[i] = -primalRowSolution[i];
3900                         dualRowSolution[i] = -dualRowSolution[i];
3901                    }
3902                    for (i = 0; i < numberColumns; i++) {
3903                         primalColumnSolution[i] = -primalColumnSolution[i];
3904                         dualColumnSolution[i] = -dualColumnSolution[i];
3905                    }
3906               }
3907          }
3908          fclose(fp);
3909     } else {
3910          std::cout << "Unable to open file " << fileName << std::endl;
3911     }
3912}
3913// Dump a solution to file
3914void saveSolution(const ClpSimplex * lpSolver, std::string fileName)
3915{
3916     if (strstr(fileName.c_str(), "_fix_read_")) {
3917          FILE * fp = fopen(fileName.c_str(), "rb");
3918          if (fp) {
3919               ClpSimplex * solver = const_cast<ClpSimplex *>(lpSolver);
3920               restoreSolution(solver, fileName, 0);
3921               // fix all
3922               int logLevel = solver->logLevel();
3923               int iColumn;
3924               int numberColumns = solver->numberColumns();
3925               double * primalColumnSolution =
3926                    solver->primalColumnSolution();
3927               double * columnLower = solver->columnLower();
3928               double * columnUpper = solver->columnUpper();
3929               for (iColumn = 0; iColumn < numberColumns; iColumn++) {
3930                    double value = primalColumnSolution[iColumn];
3931                    if (value > columnUpper[iColumn]) {
3932                         if (value > columnUpper[iColumn] + 1.0e-6 && logLevel > 1)
3933                              printf("%d value of %g - bounds %g %g\n",
3934                                     iColumn, value, columnLower[iColumn], columnUpper[iColumn]);
3935                         value = columnUpper[iColumn];
3936                    } else if (value < columnLower[iColumn]) {
3937                         if (value < columnLower[iColumn] - 1.0e-6 && logLevel > 1)
3938                              printf("%d value of %g - bounds %g %g\n",
3939                                     iColumn, value, columnLower[iColumn], columnUpper[iColumn]);
3940                         value = columnLower[iColumn];
3941                    }
3942                    columnLower[iColumn] = value;
3943                    columnUpper[iColumn] = value;
3944               }
3945               return;
3946          }
3947     }
3948     FILE * fp = fopen(fileName.c_str(), "wb");
3949     if (fp) {
3950          int numberRows = lpSolver->numberRows();
3951          int numberColumns = lpSolver->numberColumns();
3952          double objectiveValue = lpSolver->objectiveValue();
3953          size_t nWrite;
3954          nWrite = fwrite(&numberRows, sizeof(int), 1, fp);
3955          if (nWrite != 1)
3956               throw("Error in fwrite");
3957          nWrite = fwrite(&numberColumns, sizeof(int), 1, fp);
3958          if (nWrite != 1)
3959               throw("Error in fwrite");
3960          nWrite = fwrite(&objectiveValue, sizeof(double), 1, fp);
3961          if (nWrite != 1)
3962               throw("Error in fwrite");
3963          double * dualRowSolution = lpSolver->dualRowSolution();
3964          double * primalRowSolution = lpSolver->primalRowSolution();
3965          nWrite = fwrite(primalRowSolution, sizeof(double), numberRows, fp);
3966          if (nWrite != static_cast<size_t>(numberRows))
3967               throw("Error in fwrite");
3968          nWrite = fwrite(dualRowSolution, sizeof(double), numberRows, fp);
3969          if (nWrite != static_cast<size_t>(numberRows))
3970               throw("Error in fwrite");
3971          double * dualColumnSolution = lpSolver->dualColumnSolution();
3972          double * primalColumnSolution = lpSolver->primalColumnSolution();
3973          nWrite = fwrite(primalColumnSolution, sizeof(double), numberColumns, fp);
3974          if (nWrite != static_cast<size_t>(numberColumns))
3975               throw("Error in fwrite");
3976          nWrite = fwrite(dualColumnSolution, sizeof(double), numberColumns, fp);
3977          if (nWrite != static_cast<size_t>(numberColumns))
3978               throw("Error in fwrite");
3979          fclose(fp);
3980     } else {
3981          std::cout << "Unable to open file " << fileName << std::endl;
3982     }
3983}
3984#endif
Note: See TracBrowser for help on using the repository browser.