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

Last change on this file since 2177 was 2177, checked in by forrest, 5 years ago

minor debug changes

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